-
Notifications
You must be signed in to change notification settings - Fork 113
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
Gracefully handle ignoreChanges without user needing to refresh a stack #2566
Conversation
Does the PR have any schema changes?Looking good! No breaking changes found. |
Codecov Report
@@ Coverage Diff @@
## master #2566 +/- ##
==========================================
- Coverage 18.64% 18.45% -0.20%
==========================================
Files 47 47
Lines 9434 9523 +89
==========================================
- Hits 1759 1757 -2
- Misses 7576 7667 +91
Partials 99 99
... and 1 file with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
95350fa
to
d53eb7c
Compare
d53eb7c
to
62fe5d5
Compare
… kubectl-patch field manager
62fe5d5
to
0b77bd9
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.
I don't have the context to review on the feature change, but I left some local comments.
fccfebe
to
fb4b755
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.
Good job adding the CSA support!
@@ -498,13 +502,43 @@ func ssaUpdate(c *UpdateConfig, liveOldObj *unstructured.Unstructured, client dy | |||
return currentOutputs, nil | |||
} | |||
|
|||
// handleCSAIgnoreFields handles updating the inputs to use the last known value applied to the cluster. If the value is not present, | |||
// then we use what is declared in state as per the specs of Pulumi's ignoreChanges. | |||
func handleCSAIgnoreFields(c *UpdateConfig, liveOldObj *unstructured.Unstructured) error { |
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've not a good intuition around liveOldObj *unstructured.Unstructur and *UpdateConfig but this looks kind of similar to what I've seen bridged providers have to do for ignoreChanges.. It makes sense with he comment 👍
return fmt.Errorf("unable to parse ignoreField path %q: %w", ignorePath, err) | ||
} | ||
|
||
pathComponents := strings.Split(ipParsed.String(), ".") |
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.
Are we not worried here, this conversion would just work? ipParsed
will have strings or integers (to drill down arrays), for example:
"foo", 0, "barProperty"
Does strings.Split(ipParsed.String(), ".") give you what you expect for the numbers?
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.
Will this ever receive '*' as a path fragment? Pulumi docs permit patterns like this one:
foo.*
But we're lacking great SDK API to make it easy to implement. I wonder if the user specifies that will it hit this code or be resolved higher up the stack.
|
||
pathComponents := strings.Split(ipParsed.String(), ".") | ||
|
||
lastLiveVal, found, err := unstructured.NestedFieldCopy(liveOldObj.Object, pathComponents...) |
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 paths expected by unstructured.NestedFieldCopy map 1:1 to pulumi property paths? No "foo_bar=>fooBar" renaming? No off-by-1 errors? (those may be specific to TF where pulumi paths are shorter than TF paths sometimes).
@@ -527,6 +561,7 @@ func handleSSAIgnoreFields(c *UpdateConfig, liveOldObj *unstructured.Unstructure | |||
return fmt.Errorf("unable to parse ignoreField path %q: %w", ignorePath, err) | |||
} | |||
|
|||
// TODO: Enhance support for ignoreField path to support nested arrays. |
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.
Ah here we go again. Might be worth lifting this comment and the split logic into one helper function so it's in one place.
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 LGTM, I left some comments per Pulumi side but I lack a good intuition yet around this provider.
Note: this is stacked on top of #2570
This PR updates the logic for handling fields added to ignoreChanges. Previously, to accurately ignore a field without hitting an SSA conflict error, the Pulumi user would need to run a refresh BEFORE running
pulumi up
orpulumi preview
. This is due to the provider using the last known value of the ignored field stored in state when computing what should be set in the ignored field when the resource is sent to the k8s API. If drift has occurred on that field and is not reflected in the Pulumi state as it is out of date, then the provider sends old information to the API server resulting in a field conflict error.As we hit the live server to obtain the resources' up to date
resourceVersion
, we can also use this API result to gracefully handle fields marked within ignoreChanges. This PR uses the fieldpath package from upstream k8s libraries to parse the serialized json managed fields entries and compares it to a normalized version of the Pulumi program's ignoreFields value.Fixes: #2542