-
Notifications
You must be signed in to change notification settings - Fork 104
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
Implementation of KEP-30: Immutable Parameters #1575
Conversation
Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
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 did a first pass, looks good overall :) I'll get back to this after lunch.
I would definitely like to see the following (probably e2e?) test though:
- install with immutable
- try to update -> see it fails
Tests for the other scenarios in upgrade would be also nice but I won't block on that :)
@@ -170,6 +170,18 @@ func (i *Instance) TryRemoveFinalizer() bool { | |||
return false | |||
} | |||
|
|||
func (p *Parameter) IsImmutable() bool { |
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.
nice, these methods made the code much nicer 👍
fakeDiscovery.FakedServerVersion = &version.Info{ | ||
GitVersion: "v1.16.0", | ||
} | ||
t.Run(tt.name, func(t *testing.T) { |
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.
hmm why this change?
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.
Mostly because the test was failing and using the t.Run(tt.name, func....
shows the separate cases nicely in IntelliJ when the tests are ran through the IDE
Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
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.
Nice work 👏
Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
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.
Nice work, I left a bunch of nits/suggestions/comments so PTAL
} | ||
|
||
func (p *Parameter) HasDefault() bool { | ||
return p.Default != nil |
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.
what about a nill-check here too?
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.
The nil check is here, right? Did you mean a check against empty string?
I thought about it but decided against it, because an empty string might be a default? I'm not fully sure how we handle that though.
@@ -222,6 +234,44 @@ func GetParamDefinitions(params map[string]string, ov *OperatorVersion) ([]Param | |||
return defs, nil | |||
} | |||
|
|||
// GetChangedParameters returns a list of parameters from ov2 that changed based on the given compare function between ov1 and ov2 | |||
func GetChangedParameters(ov1, ov2 *OperatorVersion, isEqual func(p1, p2 Parameter) bool) []Parameter { |
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.
Actually, the RichParameterDiff
method below already gives you the changed and removed params. Wdyt about reusing it and modifying it to return updated
, added
, and removed
params and remove these methods?
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.
Well, the RichParameterDiff
below works with the actual parameter values, so map[string]string
- the new methods work on the ParameterDefinitions.
Basically the old ones are: Has the parameter values been changed
The new ones are: Have the parameter definitions been changed
They also have a parameter to decide how exactly the parameter was changed, so you can find out if the immutable
flag has changed, or if the required
flag has changed.
I don't think it really makes sense to join these funcs
if reflect.DeepEqual(old.Spec, new.Spec) && reflect.DeepEqual(old.Status, new.Status) { | ||
return admission.Allowed("") | ||
} | ||
|
||
// fetch new OperatorVersion: we always fetch the new one, since if it's an update it's the same as the old one |
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 comment is outdated since we fetch both versions now.
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.
Well - it's still valid, isn't it?
} | ||
|
||
// setImmutableParameterDefaults sets the default values for immutable parameters into the instances parameter map | ||
func setImmutableParameterDefaults(ov *kudov1beta1.OperatorVersion, instance *kudov1beta1.Instance) { |
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 wonder if this is not better suited in the kudoctl 🤔 I was trying to minimize the mutations the IAW is doing to the instance (basically limiting it to PlanExecution
). If we start to set the immutable defaults here, why not the normal defaults too?
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 don't know, why don't we set the defaults here?
I think we should do as little as possible in kudoctl
- I expect people to more and more use the CRDs directly, either with KUDO shim, or directly modifying the instance
CRDs. From my perspective the kudoctl
should only provide convenience functionality but nothing that directly affects the KUDO core funktionality.
@@ -109,6 +109,9 @@ type Parameter struct { | |||
|
|||
// Type specifies the value type. Defaults to `string`. | |||
Type ParameterType `json:"value-type,omitempty"` | |||
|
|||
// Specifies if the parameter can be changed after the initial installation of the operator | |||
Immutable *bool `json:"immutable,omitempty"` |
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.
Why is Immutable
a bool ptr? The immutable -> mutable transition is allowed and doesn't require a validation. So why can't we keep it a bool
and treat all parameters as immutable = false
by default?
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.
Tbh, I'm not sure. I copied it from the required
definition. I was wondering why "required" is a pointer though.
I guess it renders a little cleaner yaml if the bools are not set? But I don't really mind either way.
@@ -376,12 +394,169 @@ func TestValidateUpdate(t *testing.T) { | |||
ov: ov, | |||
wantErr: true, | |||
}, | |||
{ | |||
name: "parameter update to an immutable param IS NOT allowed", |
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.
👏
Signed-off-by: Andreas Neumann <aneumann@mesosphere.com>
What this PR does / why we need it:
Implementation of KEP-30: Immutable Parameters.
https://github.com/kudobuilder/kudo/blob/main/keps/0030-immutable-parameters.md