-
Notifications
You must be signed in to change notification settings - Fork 107
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
Late initialization overrides desired value when it is zero-value #105
Comments
/cc @negz @hasheddan |
This is tough because I agree that the solution here is just not using |
It doesn't sound like omitting omitempty goes against conventions:
|
@hasheddan Are you confident it won't have any negative side-effects/behaviour changes? If so I'm okay with it. |
I think I'll need to do some experiments to make sure we're able to capture all three: nil value, zero value, actual value. Or @hasheddan could also play with it and report here. |
@muvaf yep I'll pull some of our real-world examples and show how the change would impact 👍 |
kubernetes-sigs/cluster-api#707 Some more prior art here. Having swapped back in the context of this issue I think we're on the right path. I'm not sure if we want to completely remove
So we'd represent these cases (using an *int field as example) as:
|
https://crossplane.slack.com/archives/CKXQHM7U3/p1581113468101800 Cross-linking some discussion from Slack. I actually now think our late init code is func LateInitializeBool(b *bool, from bool) *bool {
if b != nil || !from {
return b
}
return &from
} In the above case type Example struct {
Field *bool `json:"field,omitempty"`
}
So actually in the case of func LateInitializeBool(b *bool, from bool) *bool {
if b != nil {
return b
}
return &from
} With this logic if the cloud provider specified |
I think the two external issues relating to |
Another option would be to add a flag to the CRDs that disallow late init stuff? This will allow us to have complete control using the Crossplane CRDs. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Crossplane does not currently have enough maintainers to address every issue and pull request. This issue has been automatically marked as |
What happened?
We have implemented late-initialization pattern across the resources. However, it relies upon the field's value being nil or zero-value. Example late-init functions from stack-gcp:
This implementation is buggy because it overrides when the user actually wants the zero-value for that field. For example, the value of field
foo *bool
istrue
in both spec and cloud provider and the user wants to make itfalse
. In that caseLateInitializeBool
will override that value withtrue
because it will assume that zero-value is a case where user doesn't have an opinion about that field and the value from cloud provider will be used. This seems easy to fix for pointer types by converting the function into:But there is a catch. We follow Kubernetes pattern for optional fields in our API design, which means that optional fields have the following jsontag:
The tag
omitempty
actually causes the value to benil
in the Go code if assigned value is zero-value, in this casefalse
. So, it comes asnil
even if user wanted it to befalse
. This works for Kubernetes late-inited fields likepod.spec.nodeName
because those fields will be eventually filled but that's not the case for us. The Go zero-value for a field could actually be the final value that the user wants for that field.I'd like us to discuss not using
omitempty
tag at all, so that zero-values come to the controller as is instead of being converted tonil
. In terms of api-server validation, nothing changes as// +optional
tag is used to mark the fields as required or not in the CRD. Though not usingomitempty
is divergence from the optional/required design pattern that Kubernetes suggests.The text was updated successfully, but these errors were encountered: