-
Notifications
You must be signed in to change notification settings - Fork 270
feat(manager): ✨ add region to openStackMachineSpec.ProviderID field from crd identityRef #2193
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
Hi @MatthieuFin. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions 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-sigs/prow repository. |
✅ Deploy Preview for kubernetes-sigs-cluster-api-openstack ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
@@ -422,7 +422,7 @@ func (r *OpenStackMachineReconciler) reconcileMachineState(scope *scope.WithLogg | |||
conditions.MarkTrue(openStackMachine, infrav1.InstanceReadyCondition) | |||
|
|||
// Set properties required by CAPI machine controller | |||
openStackMachine.Spec.ProviderID = ptr.To(fmt.Sprintf("openstack:///%s", *openStackServer.Status.InstanceID)) | |||
openStackMachine.Spec.ProviderID = ptr.To(fmt.Sprintf("openstack://%s/%s", openStackMachine.ObjectMeta.Annotations["cluster.x-k8s.io/openstack.cloud"], *openStackServer.Status.InstanceID)) |
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.
As discussed in slack, lets look into adding this to the API rather than as an annotation. This should be fine as long as any new field is optional, and the behaviour remains unchanged when it is not specified.
Something to think about: we permit the modification of identityRef on objects, but if we added region
and it became part of the providerID
, should it be immutable?
Something else to note here is that we need to preserve the immutability of providerID
. This isn't a problem in the current code, as if we have an instance it's always going to have the same ID. With this change this is no longer true, as the behaviour can change across an upgrade. However we do this, I suggest that we add a check here and only set ProviderID
if it is currently unset.
I've spent much of the morning thinking this through and discussing with @stephenfin and Sean Mooney. Based on that, I'd like to define the following contract:
It's also worth restating that providerID is immutable, so any change we make to it will not be applied to existing Machines. In case anybody else was also fuzzy about the details, here's a restatement of my understanding of OpenStack regions: regions are effectively only a key used in the catalog of services returned by keystone during authentication. Region is not used during authentication. Keystone returns all service endpoints, and the client picks one from the desired region. This means it makes no sense to use a region returned by keystone. Instead we should record the region we used to select and endpoint. i.e. We use the input from the API, not the output from keystone. I propose we could add // Region specifies an OpenStack region to use. If specified, it overrides
// any value in clouds.yaml. If specified for an OpenStackMachine, its
// value will be included in providerID.
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="region is immutable"
// +optional
Region *string `json:"region,omitempty"` I would expect us to use that value explicitly here: cluster-api-provider-openstack/pkg/scope/provider.go Lines 182 to 188 in 934d61d
as well as when setting |
Personally, I prefer don't use the new field cluster-api-provider-openstack/pkg/scope/provider.go Lines 182 to 188 in 934d61d
If you have 2 providers which declare same region name, in this case you cannot differentiate these regions. If we keep them manage separately you could have Currently OCCM don't allow this but maybe a day it will be supported. |
We should maintain compatibility with OCCM, as ultimately that's what's going to consume this value. However, if we're going to call the value we're putting here We could redefine it again in the future to be openstack:// |
Ok, that’s good for me, let’s see if we need to explore this topic further later! And you're right, we'll probably never need to replace the region name, at least it's too early to worry about that. |
/ok-to-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.
This looks great, and thanks for getting this done so quickly. I'm +1 on everything here.
As mentioned we should have apivalidations coverage of all API validations. They're very easy to write and there are lots of examples to copy from.
Ideally I'd also like some e2e test coverage of this. I think we can add this fairly easily by doing some like modifying the MachineDeployment template of the workers of one of the existing e2e scenarios and adding validation in the test suite that providerID is set on the CAPI Machine the way we expect.
Ping me on Slack if I can help with this.
api/v1beta1/identity_types.go
Outdated
// Region specifies an OpenStack region to use. If specified, it overrides | ||
// any value in clouds.yaml. If specified for an OpenStackMachine, its | ||
// value will be included in providerID. | ||
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="region is immutable" |
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 can you add a test to https://github.com/kubernetes-sigs/cluster-api-provider-openstack/blob/main/test/e2e/suites/apivalidations/openstackmachine_test.go to validate that the field is indeed immutable. I think we only need to test it for a single object, and OpenStackMachine makes sense. We should test:
- The value can be set on creation
- The value cannot be modified after creation
- The value cannot be unset after creation
@@ -422,7 +422,7 @@ func (r *OpenStackMachineReconciler) reconcileMachineState(scope *scope.WithLogg | |||
conditions.MarkTrue(openStackMachine, infrav1.InstanceReadyCondition) | |||
|
|||
// Set properties required by CAPI machine controller | |||
openStackMachine.Spec.ProviderID = ptr.To(fmt.Sprintf("openstack:///%s", *openStackServer.Status.InstanceID)) | |||
openStackMachine.Spec.ProviderID = ptr.To(fmt.Sprintf("openstack://%s/%s", openStackMachine.Spec.IdentityRef.Region, *openStackServer.Status.InstanceID)) |
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.
How can we get some test coverage of this?
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.
Whoops! IdentityRef is a pointer and is usually nil.
Incidentally, wouldn't these errors be so much simpler to see if you'd had to write something like openStackMachine.Spec.IdentityRef->Region
instead? Go automatic dereferencing is insidious.
@@ -132,6 +132,35 @@ var _ = Describe("OpenStackMachine API validations", func() { | |||
Expect(k8sClient.Create(ctx, machine)).To(Succeed(), "Creating a machine with max metadata key and value should succeed") | |||
}) | |||
|
|||
It("should allow server identityRef Region field or not set on creation", func() { |
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.
These look great, thanks👌
@@ -18,6 +18,7 @@ package v1beta1 | |||
|
|||
// OpenStackIdentityReference is a reference to an infrastructure | |||
// provider identity to be used to provision cluster resources. | |||
// +kubebuilder:validation:XValidation:rule="(!has(self.region) && !has(oldSelf.region)) || self.region == oldSelf.region",message="region is immutable" |
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'm assuming this change means it didn't work correctly when applied to the field?
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, "self == oldSelf"
as you proposed, permit to set a value on an existing machine without region field defined. To do that I had to create rule on top level object because has(self)
seems not valid syntax.
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.
Thanks. Turns out I was missing some tests in the image API and this was broken: #2197
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.
Glad to have been helpful !
This looks great. Can you squash the commits (into a single commit with a single, coherent description) and I'll approve. Thanks! |
providerID: openstack:///d8a589fa-98ca-4999-92da-bf8d3a2678d3 As mentioned we still need some test coverage of this actually working. I'll approve on the basis that:
If we want to continue working in the future, though, we'll need a test. |
I'm just currently testing on my side before squash that. I did'nt write e2e tests but I agree we need it to be future proof. I'm ok to try writing some tests about that, I'll probably ping you on slack for help on that purpose. |
…from crd identityRef To made CAPO compatible with OCCM multi-cloud deployment we need to manage providerID format with region code as introduced [here](kubernetes/cloud-provider-openstack#1900) (`openstack://region/instance_uuid`). Add Region field to OpenStackIdentityReference type to define region name in providerID string. If specified, it overrides any value in clouds.yaml. An empty or undefined Region field permit to be fully backward compatible. Signed-off-by: MatthieuFin <[email protected]>
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: mdbooth The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/lgtm |
What this PR does / why we need it:
To made CAPO compatible with OCCM multi-cloud deployment we need to manage providerID format with region code as introduced here (
openstack://region/instance_uuid
). Use annotation from OpenstackMachine to define region in providerID field.An empty or undefined annotation permit to be fully backward compatible. Moreover use annotation permit to manage some cluster with new OCCM provider-id string and other cluster with old format by same CAPO instance.
Fixes #2183
Special notes for your reviewer:
OpenStackMachine
to use their ownIdentityRef
#2191 merged to work correctly !