-
Notifications
You must be signed in to change notification settings - Fork 276
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: Server-side diff shows incorrect diffs for list related changes #683
base: master
Are you sure you want to change the base?
Conversation
labels: | ||
app: nested-test | ||
spec: | ||
containers: |
Check warning
Code scanning / SonarCloud
Service account permissions should be restricted Medium test
app: nested-test | ||
spec: | ||
containers: | ||
- name: main-container |
Check warning
Code scanning / SonarCloud
Memory limits should be enforced Medium test
labels: | ||
app: nested-test | ||
spec: | ||
containers: |
Check warning
Code scanning / SonarCloud
Service account permissions should be restricted Medium test
app: nested-test | ||
spec: | ||
containers: | ||
- name: main-container |
Check warning
Code scanning / SonarCloud
Memory limits should be enforced Medium test
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #683 +/- ##
==========================================
- Coverage 54.26% 53.36% -0.90%
==========================================
Files 64 64
Lines 6164 6412 +248
==========================================
+ Hits 3345 3422 +77
- Misses 2549 2714 +165
- Partials 270 276 +6 ☔ View full report in Codecov by Sentry. |
Interesting, Sonar should have ignored the test files https://github.com/argoproj/gitops-engine/blob/master/sonar-project.properties#L2. |
Can you try adding spaces around = in sonar-project.properties, please? |
Ah, looks like cloud doesn't support blobs https://docs.sonarsource.com/sonarqube-server/latest/project-administration/analysis-scope/#wildcard-examples. I can't find exact explanation what that means, but would try replacing |
cb8adef
to
a82a668
Compare
Strange, tried a couple different wildcards and they don't exclude the testdata files |
Did you try adding spaces around = ? Tho I swear it worked for me before just like it was in master. |
a82a668
to
5514204
Compare
Yes, just added spaces around '=' and still fails Sonar |
Hm, now I can only think of two things:
|
I would imagine part of this issue is with Lists only due to not having merge keys, does RecursiveDifference only do that whole replacement on lists or does it do it for every object type? If it does it for every object type I am not sure that is the correct action but I will differ to @leoluz |
This RecursiveDIfference only works on sets. This is coming from the kubernetes structured-diff library where the original DIfference comes from. |
https://github.com/kubernetes-sigs/structured-merge-diff/blob/master/fieldpath/set.go#L110 |
@leoluz, do you think we should implement a custom function or ask structured merge diff devs to do it? I feel like the 2nd is better, though would take some time. |
Shall we only remove mfs for leaf nodes or something like that? |
pkg/diff/diff.go
Outdated
@@ -236,15 +236,15 @@ func removeWebhookMutation(predictedLive, live *unstructured.Unstructured, gvkPa | |||
} | |||
if comparison.Added != nil && !comparison.Added.Empty() { | |||
// exclude the added fields owned by this manager from the comparison | |||
comparison.Added = comparison.Added.Difference(mfs) | |||
comparison.Added = comparison.Added.RecursiveDifference(mfs) |
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.
Or, I wonder if we can do something like
predictedLive.ExtractItems(plManagedFields, typed.WithAppendKeyFields())
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.
Or maybe we just remove every prefix of every managed field path.
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 tried this as well, and it results to messed up outputs.
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 if we try to remove managed fields from both live and predicted live before doing the comparison?
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, nvm, I think we should use RecursiveDifference, but only with leaf mfs. What do you think?
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.
One more thought - also remove managed fields from the current live.
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 think we can't use RecursiveDifference because it could incorrectly remove fields added by mutation webhooks.
However, yes, I think what we could do is keep Difference, but do a second pass to remove any leaf nodes that are still in managed fields that weren't caught by Difference.
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 will try out this and also removing manged fields from current live and see if tit works
Why would |
One more thought - do a recursive difference, but only if the field is managed in both live and predicted live. |
In the example
I don't think |
So IIUC in the example above predicted live should contain:
But I don't see why |
5514204
to
3bfc530
Compare
Do I understand correctly, that the problem is with partially managed fields (with children) being considered as fully managed? |
Can you also try just this modification, still with using Difference? Now:
Desired?
|
Here is what's happening exactly: Before Difference() on Line 239
Comparison:
After Difference() on line 239
The bug is that these two fields remain in comparison.Added even after the Difference function because they are not managed fields but their children are. If they are in comparison.Added they will be extracted from predictedLive and cause the diff to not show these fields.
The cause is the Difference function will does a shallow difference and does not recursively check each child. |
This one also did not make a difference. I think because we are still extracting those fields. |
Signed-off-by: Peter Jiang <[email protected]>
3bfc530
to
e8c9005
Compare
Quality Gate failedFailed conditions See analysis details on SonarQube Cloud Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE |
Great analysis!
Looks like fields that are parents of other fields are not managed themselves.
This is due to a key field not specified explicitly, but it can be derived from the path. |
The solution is:
|
@andrii-korotkov-verkada I think this is a good solution. Basically it covers the two edge cases Case 2: Derived fields with managed parents I can start implementing this and @leoluz can confirm if it makes sense |
fixes argoproj/argo-cd#21817
The current Difference function does not remove every field and its children from the set. This causes unwanted the behavior of nested fields not being removed resulting in an incorrect server side diff. Using the RecursiveDifference function instead will do this:
"this removes every field and its children from s that is contained in s2."
Added additional unit test to cover the nested fields scenario.
Before fix:
After fix: