-
Notifications
You must be signed in to change notification settings - Fork 585
config/v1/types_cluster_version: Add Architecture to DesiredUpdate #1339
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Hello @jottofar! Some important instructions when contributing to openshift/api: For merging purposes, this repository follows the no-Feature-Freeze process which means that in addition to the standard
OR
Who should apply these qe/docs/px labels?
|
|
/assign @deads2k |
|
/test verify |
ce7347d to
f8eea48
Compare
adafd50 to
fa318ea
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of questions
Also, I broke the verify job slightly so I think your CRD is out of date, verify job is fixed now
/test verify
| spec: | ||
| clusterID: foo | ||
| desiredUpdate: | ||
| architecture: Multi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make sure to add at least one test that sets architecture: "" explicitly please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in c9e0d99
config/v1/types_cluster_version.go
Outdated
| type URL string | ||
|
|
||
| // Update represents an administrator update request. | ||
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && has(self.image) ? (self.architecture != '' || self.image != '') : true",message="cannot set both Architecture and Image" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this correct? If we have both architecture and image, you are checking if either of them is non empty. Do you not instead want to check if either of them is empty? You are trying to require that at least one of them is empty in this case right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's correct. Thats why we have message="cannot set both Architecture and Image"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but the validation itself is wrong, and you can see this if you look at the integration test failures which are reporting expected an error, but got nil.
Your current check passes if either value is non-empty. You want it to only pass when one value is empty.
I created 3165600 which demonstrates the diff you need, can you cherry pick that into this branch please
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && has(self.image) ? (self.architecture != '' || self.image != '') : true",message="cannot set both Architecture and Image" | |
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && has(self.image) ? (self.architecture == '' || self.image == '') : true",message="cannot set both Architecture and Image" |
| desiredUpdate: | ||
| architecture: Multi | ||
| expectedError: "Version must be set if Architecture is set" | ||
| onUpdate: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do any of the validations rely on a previously persisted state? If they don't, then we don't need separate update tests and the create validation should cover both cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I am going to remove this test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had meant the entire set of onUpdate, none of them seem necessary since they all duplicate previous test cases IIUC. But I see now why you've got two different ones, it's the transitions from image to both and from architecture to both, makes sense, we should add an onCreate version though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both onUpdate tests are covered by the following onCreate test, so unless I am missing something we do not need to add any new onCreate tests.
- name: Should not allow image and architecture to be set
initial: |
apiVersion: config.openshift.io/v1
kind: ClusterVersion
spec:
clusterID: foo
desiredUpdate:
architecture: Multi
version: 4.11.1
image: bar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have onCreate Should not allow image and architecture to be set which checks that both cannot be set so I'm not sure what can be added to onCreate to replicate the two onUpdates since each of them can start with only one of the values but the onCreate cannot (AFAIK).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I originally added the onUpdate tests to cover a user doing an oc patch for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I can work on this even after the PR is merged. So lets not block the PR to get merged because of this.
c9e0d99 to
cbf78ef
Compare
|
/test integration |
| desiredUpdate: | ||
| architecture: Multi | ||
| expectedError: "Version must be set if Architecture is set" | ||
| onUpdate: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had meant the entire set of onUpdate, none of them seem necessary since they all duplicate previous test cases IIUC. But I see now why you've got two different ones, it's the transitions from image to both and from architecture to both, makes sense, we should add an onCreate version though
config/v1/types_cluster_version.go
Outdated
| type URL string | ||
|
|
||
| // Update represents an administrator update request. | ||
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && has(self.image) ? (self.architecture != '' || self.image != '') : true",message="cannot set both Architecture and Image" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but the validation itself is wrong, and you can see this if you look at the integration test failures which are reporting expected an error, but got nil.
Your current check passes if either value is non-empty. You want it to only pass when one value is empty.
I created 3165600 which demonstrates the diff you need, can you cherry pick that into this branch please
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && has(self.image) ? (self.architecture != '' || self.image != '') : true",message="cannot set both Architecture and Image" | |
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && has(self.image) ? (self.architecture == '' || self.image == '') : true",message="cannot set both Architecture and Image" |
| spec: | ||
| clusterID: foo | ||
| desiredUpdate: | ||
| architecture: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to see this explicitly with the empty string
| architecture: | |
| architecture: "" |
cbf78ef to
42f98d9
Compare
| // architecture. architecture can only be set to Multi thereby | ||
| // only allowing updates from single to multi architecture. If | ||
| // architecture is set image cannot be set and version must be | ||
| // set. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: In other enums, we typically have a statement that says valid values are x,y,z, you have this in the blurb but it would be good to have that as an explicit statement as it gets a bit muddled in here IMO
| // set. | |
| // set. | |
| // Valid values are 'Multi' and empty. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, will fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 08f0ef0
config/v1/types_cluster_version.go
Outdated
| // architecture means either a single architecture or a multi | ||
| // architecture. architecture can only be set to Multi thereby | ||
| // only allowing updates from single to multi architecture. If | ||
| // architecture is set image cannot be set and version must be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need a comma in here else this sentence is a bit hard to read
| // architecture is set image cannot be set and version must be | |
| // architecture is set, image cannot be set and version must be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 08f0ef0
| // architecture is an optional field that indicates the desired | ||
| // value of the cluster architecture. In this context cluster | ||
| // architecture means either a single architecture or a multi | ||
| // architecture. architecture can only be set to Multi thereby |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So there's no way to transition back to the a single arch cluster?
I wonder if we need to explicitly say, "on future updates, if the existing cluster image is multi architecture, then the downloaded image will also be multi architecture. There is no way to convert a cluster from multi to single architecture."
I think I missed this while reviewing before but it seems odd that on future updates, having the field omitted/empty relies on the existing architecture
There is no way to convert a cluster from multi to single architecture
Thinking about this, which I got from trying to understand this API, that's not actually true is it, if I forced an image into the update that was single arch I could force the cluster back to single arch, is that ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about this, which I got from trying to understand this API, that's not actually true is it, if I forced an image into the update that was single arch I could force the cluster back to single arch, is that ok?
That is right. Even if the current ask is only one time migration from single arch to multi arch , we do not want to add any more code to restrict the opposite. Officially we will only document that single to multi is supported. But there will be room for future change of scope.
config/v1/types_cluster_version.go
Outdated
| // +kubebuilder:validation:XValidation:rule='has(self.architecture) && has(self.image) ? (self.architecture == "" || self.image == "") : true',message="cannot set both Architecture and Image" | ||
| // +kubebuilder:validation:XValidation:rule='has(self.architecture) && self.architecture != "" ? self.version != "" : true',message="Version must be set if Architecture is set" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After spending a little time in the debugger, I found out you can't use single quotes to surround these, you have to use double quotes, can you switch the single for double and vice versa in this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, will fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 08f0ef0
08f0ef0 to
27d23fd
Compare
config/v1/types_cluster_version.go
Outdated
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && has(self.image) ? (self.architecture == "" || self.image == "") : true",message="cannot set both Architecture and Image" | ||
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && self.architecture != "" ? self.version != "" : true",message="Version must be set if Architecture is set" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still won't work as you're unquoting mid way through, either we move back to the length based or use single quotes, I don't mind either way tbh
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && has(self.image) ? (self.architecture == "" || self.image == "") : true",message="cannot set both Architecture and Image" | |
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && self.architecture != "" ? self.version != "" : true",message="Version must be set if Architecture is set" | |
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && has(self.image) ? (self.architecture == '' || self.image == '') : true",message="cannot set both Architecture and Image" | |
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && self.architecture != '' ? self.version != '' : true",message="Version must be set if Architecture is set" |
or
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && has(self.image) ? (self.architecture == "" || self.image == "") : true",message="cannot set both Architecture and Image" | |
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && self.architecture != "" ? self.version != "" : true",message="Version must be set if Architecture is set" | |
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && has(self.image) ? (size(self.architecture) == 0 || size(self.image) == 0) : true",message="cannot set both Architecture and Image" | |
| // +kubebuilder:validation:XValidation:rule="has(self.architecture) && size(self.architecture) != 0 ? size(self.version) != 0 : true",message="Version must be set if Architecture is set" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 354e2fb
27d23fd to
354e2fb
Compare
|
@jottofar: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: deads2k, jottofar The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/label px-approved |
Catching up with openshift/cluster-version-operator@9be6175c5f (pkg/cvo/sync_worker: Make expected/actual version mismatch fatal, 2020-08-09, openshift/cluster-version-operator#431), which uses the 'version' property as a sanity check for "is this pullspec the version I'm expecting?". This protects users from compromised or man-in-the-middled upstream update services who attempt downgrade and similar attacks by misrepresenting a recommended update. The text I'm adjusting landed in 354e2fb (config/v1/types_cluster_version: Add Architecture to DesiredUpdate, 2022-12-07, openshift#1339), but version-ignoring was never implemented, so nobody can be relying on that nominal behavior. And as the man-in-the-middle use case demonstrates, version-ignoring would be less safe than the version-match-enforcing behavior that the cluster-version operator has used since 2020.
Catching up with openshift/cluster-version-operator@9be6175c5f (pkg/cvo/sync_worker: Make expected/actual version mismatch fatal, 2020-08-09, openshift/cluster-version-operator#431), which uses the 'version' property as a sanity check for "is this pullspec the version I'm expecting?". This protects users from compromised or man-in-the-middled upstream update services who attempt downgrade and similar attacks by misrepresenting a recommended update. The text I'm adjusting landed in 354e2fb (config/v1/types_cluster_version: Add Architecture to DesiredUpdate, 2022-12-07, openshift#1339), but version-ignoring was never implemented, so nobody can be relying on that nominal behavior. And as the man-in-the-middle use case demonstrates, version-ignoring would be less safe than the version-match-enforcing behavior that the cluster-version operator has used since 2020. I edited types_cluster_version.go by hand, and then updated the other files with: $ hack/update-openapi.sh $ hack/update-codegen-crds.sh
Catching up with openshift/cluster-version-operator@9be6175c5f (pkg/cvo/sync_worker: Make expected/actual version mismatch fatal, 2020-08-09, openshift/cluster-version-operator#431), which uses the 'version' property as a sanity check for "is this pullspec the version I'm expecting?". This protects users from compromised or man-in-the-middled upstream update services who attempt downgrade and similar attacks by misrepresenting a recommended update. The text I'm adjusting landed in 354e2fb (config/v1/types_cluster_version: Add Architecture to DesiredUpdate, 2022-12-07, openshift#1339), but version-ignoring was never implemented, so nobody can be relying on that nominal behavior. And as the man-in-the-middle use case demonstrates, version-ignoring would be less safe than the version-match-enforcing behavior that the cluster-version operator has used since 2020. I edited types_cluster_version.go by hand, and then updated the other files with: $ hack/update-codegen-crds.sh $ hack/update-openapi.sh $ hack/update-swagger-docs.sh
Catching up with openshift/cluster-version-operator@9be6175c5f (pkg/cvo/sync_worker: Make expected/actual version mismatch fatal, 2020-08-09, openshift/cluster-version-operator#431), which uses the 'version' property as a sanity check for "is this pullspec the version I'm expecting?". This protects users from compromised or man-in-the-middled upstream update services who attempt downgrade and similar attacks by misrepresenting a recommended update. The text I'm adjusting landed in 354e2fb (config/v1/types_cluster_version: Add Architecture to DesiredUpdate, 2022-12-07, openshift#1339), but version-ignoring was never implemented, so nobody can be relying on that nominal behavior. And as the man-in-the-middle use case demonstrates, version-ignoring would be less safe than the version-match-enforcing behavior that the cluster-version operator has used since 2020. I edited types_cluster_version.go by hand, and then updated the other files with: $ hack/update-codegen-crds.sh $ hack/update-openapi.sh $ hack/update-swagger-docs.sh
field of ClusterVersion spec to request target architecture per OTA-817.