-
Notifications
You must be signed in to change notification settings - Fork 101
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
fix replica names for CloudSQLInstance #400
fix replica names for CloudSQLInstance #400
Conversation
9c68f55
to
629f05b
Compare
Signed-off-by: fahed dorgaa <[email protected]>
629f05b
to
d2bcb4a
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.
Thanks for your contribution, @fahedouch .
I don't really agree on this solution for this problem. The LateInitialize
function responsibility is "initialize optional fields that are empty in K8S API but are filled in the provider API", this means that this function is not supposed to change field values often, just on the first reconcile loop for optional fields that the user didn't specified any value.
The design problem for this is that the "source of truth" for the spec.ReplicaNames
is going to be the provider API and not Kubernetes, which is not what we really want.
The problem here is that the field spec.ReplicaNames
is empty when we have no replicas. Then, when we create the first one, this field is LateInitialized
, because it was empty. When we create the second one, it doesn't change the value (and it shouldn't) because it already has a value in there.
The expected behavior for this field looks like a Observation
field, where it just mirrors the value from the API, which is a value not defined by the user. A super common example of an Observation
field would be a resource ID.
But when I tried to look to the CloudSQL API documentation, I saw that this field is part of body requests, which made me confused.
We can create replicas pointing to a master using spec.masterInstanceName
, but we don't need to specify in the master desired state (the YAML that represents the master instance) which replicas it has? Maybe we should move this field to status
? I would love some input from other maintainer, what do you think, @turkenh ?
Should we always define spec.masterInstanceName
for replica instances spec and also change the spec.ReplicaNames
array from the master spec to make it "consistent"? Or should we move spec.ReplicaNames
to the status
struct?
hi @Feggah , thank you for the review.
this sentence is missing a part ( from https://github.com/crossplane/crossplane-runtime/blob/master/pkg/reconciler/managed/reconciler.go#L312-L315) :
I guess we consider adding values to slices also here ( this should be added to the comment above ) |
That's interesting. I saw that the documentation that you linked is saying that we can add keys to maps on late initialization, but it isn't saying to add items to an array. I don't know why this isn't there, so I would like some input from other older maintainer to understand how can we solve this problem, @fahedouch . Maybe @hasheddan or @negz could help me here? |
@Feggah @hasheddan @negz
WDYT ? |
If I recall correctly, this isn't supported for CRDs, but only built-in Kubernetes types. Is that no longer the case? |
I had a little more time to read this thread today. Without having familiarity with the CloudSQLInstance field this PR addresses, I can say that @Feggah is right that it's not safe to late initialize array elements. When a Crossplane provider reconciles a managed resource the process is:
During step 2 we're careful to only copy actual to desired state when the desired state was empty - i.e. when the creator of the managed resource had no opinions about that particular setting. The When an array has (e.g.) one element in the desired state, we have to assume the creator of the array is explicitly stating that they want one element - not two, three, etc and that Crossplane should keep trying to make sure there's only one element regardless of what happens to the actual state (e.g. via someone editing it outside of Crossplane).
This is related to initializing objects that are array elements. In some rare cases we do this already. We never late init entire elements into the array, but we might late init a field of an object that is itself an array element if we have a reliable way of matching array elements. For example: spec:
widgets:
- name: first-widget
size: big # We might late init this field if it's optional, was not specified, and we can merge array elements by name.
# We would never late init an entire element into this array.
- name: second-widget |
@negz |
Signed-off-by: fahed dorgaa [email protected]
Description of your changes
LateInitializeStringSlice
does not correctly populate Slice replica names. It must be intialized byin.ReplicaNames
itselfFixes #392
I have:
make reviewable test
to ensure this PR is ready for review.How has this code been tested
I added unit test