-
Notifications
You must be signed in to change notification settings - Fork 6.5k
fix: do not fail on manifest-like yaml files - fixes #21934 #22043
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: do not fail on manifest-like yaml files - fixes #21934 #22043
Conversation
❗ Preview Environment undeploy from Bunnyshell failedSee: Environment Details | Pipeline Logs Available commands (reply to this comment):
|
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.
Couple of things that I'd suggest here doing:
- Please add a test case to validate the behaviour.
- Please fix the failing tests. They are failing because we are not returning an error when the manifest is invalid.
=== FAIL: reposerver/repository TestInvalidManifestsInDir (0.00s)
time="2025-02-27T00:26:33Z" level=info msg="manifest cache miss: &ApplicationSource{RepoURL:,Path:./testdata/invalid-manifests,TargetRevision:,Helm:nil,Kustomize:nil,Directory:&ApplicationSourceDirectory{Recurse:true,Jsonnet:ApplicationSourceJsonnet{ExtVars:[]JsonnetVar{},TLAs:[]JsonnetVar{},Libs:[],},Exclude:,Include:,},Plugin:nil,Chart:,Ref:,Name:,}/mock.Anything"
time="2025-02-27T00:26:33Z" level=info msg="manifest cache miss: &ApplicationSource{RepoURL:,Path:./testdata/invalid-manifests,TargetRevision:,Helm:nil,Kustomize:nil,Directory:&ApplicationSourceDirectory{Recurse:true,Jsonnet:ApplicationSourceJsonnet{ExtVars:[]JsonnetVar{},TLAs:[]JsonnetVar{},Libs:[],},Exclude:,Include:,},Plugin:nil,Chart:,Ref:,Name:,}/mock.Anything"
time="2025-02-27T00:26:33Z" level=warning msg="Failed to unmarshal \"bad.yaml\": file contains 'apiVersion:', 'kind:', and 'metadata:', but is not a valid manifest: failed to unmarshal manifest: error converting YAML to JSON: yaml: line 3: did not find expected key" application=
repository_test.go:680:
Error Trace: /home/runner/work/argo-cd/argo-cd/reposerver/repository/repository_test.go:680
Error: An error is expected but got nil.
Test: TestInvalidManifestsInDir
=== FAIL: reposerver/repository Test_findManifests/invalid_manifest_throws_an_error (0.00s)
time="2025-02-27T00:26:36Z" level=warning msg="Failed to unmarshal \"bad.yaml\": file contains 'apiVersion:', 'kind:', and 'metadata:', but is not a valid manifest: failed to unmarshal manifest: error converting YAML to JSON: yaml: line 3: did not find expected key" test=test
repository_test.go:2810:
Error Trace: /home/runner/work/argo-cd/argo-cd/reposerver/repository/repository_test.go:2810
Error: An error is expected but got nil.
Test: Test_findManifests/invalid_manifest_throws_an_error
adc130b to
07c3dec
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #22043 +/- ##
==========================================
- Coverage 60.01% 59.91% -0.11%
==========================================
Files 342 342
Lines 57845 58582 +737
==========================================
+ Hits 34718 35100 +382
- Misses 20352 20635 +283
- Partials 2775 2847 +72 ☔ View full report in Codecov by Sentry. |
reposerver/repository/repository.go
Outdated
| bytes.Contains(out, []byte("kind:")) && | ||
| bytes.Contains(out, []byte("metadata:")) { | ||
| return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", filename, err) | ||
| logCtx.Warnf("Failed to unmarshal %q: file contains 'apiVersion:', 'kind:', and 'metadata:', but is not a valid manifest: %v", filename, err) |
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 it's an actual invalid yaml which is a manifest?
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.
It would simply log a warning, as mentioned in the PR description.
There's also an "Alternative" section where I suggest adding an annotation to mark non-manifest YAML files. This would maintain the existing behavior and also allow to fix the issue this PR is trying to address.
reposerver/repository/repository.go
Outdated
| out, _ := utfutil.ReadFile(manifestPath, utfutil.UTF8) | ||
| // Otherwise, let's see if it looks like a resource, if yes, we log a warning. | ||
| if bytes.Contains(out, []byte("apiVersion:")) && | ||
| bytes.Contains(out, []byte("kind:")) && | ||
| bytes.Contains(out, []byte("metadata:")) { | ||
| return status.Errorf(codes.FailedPrecondition, "Failed to unmarshal %q: %v", filename, err) | ||
| logCtx.Warnf("Failed to unmarshal %q: file contains 'apiVersion:', 'kind:', and 'metadata:', but is not a valid manifest: %v", filename, err) |
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.
Let's keep the err on line 1749 and log it as part of the warning.
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.
@ishitasequeira Thanks for review.
If the file read fails, I think it doesn't make much sense to run the following if bytes.Contains(out, []byte(...)).
I suggest returning an error instead:
out, rerr := utfutil.ReadFile(manifestPath, utfutil.UTF8)
if rerr != nil {
return status.Errorf(codes.FailedPrecondition, "Failed to read %q: %v", filename, rerr)
}Let me know what 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.
Thanks @CefBoud, that would actually be better and I see that you have already addressed that in your latest commits.
fa97cf5 to
95d7be4
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.
Overall change looks good to me. @CefBoud can you resolve the conflicts?
1d7b0d9 to
d6fe76b
Compare
d6fe76b to
5713321
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 think I disagree with the idea of having this feature merged because the risk of ignoring malformed yaml error that could cause resources to be automatically pruned is just to big.
In my opinion, the only way we can safely ignore "kubernetes-like" file is with an explicit instruction to ignore the file, such as a comment anywhere in the file that would include +argocd:skip-rendering or something like that.
Let me know what you think, maybe i over evaluate the risks here.
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 chiming in, @agaudreault. I mentioned this in the Alternatives section of the PR description, and now that you say it, I believe it's best to stay on the safe side. Adding support for skipping files containing +argocd:skip-rendering seems like the right approach.
I've made the changes. Let me know what you think.
5713321 to
ec3ac3e
Compare
f0ee6cc to
23ae46e
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.
This should also be documented somewhere in the documentation, probably in https://argo-cd.readthedocs.io/en/stable/user-guide/directory/
reposerver/repository/repository.go
Outdated
| if rerr != nil { | ||
| return nil, "", fmt.Errorf("failed to read %q: %w", relPath, rerr) | ||
| } | ||
| // skip file if it contains "+argocd:skip-rendering" |
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.
| // skip file if it contains "+argocd:skip-rendering" | |
| // skip file if it contains "+argocd:skip-rendering" |
reposerver/repository/repository.go
Outdated
| return nil, "", fmt.Errorf("failed to read %q: %w", relPath, rerr) | ||
| } | ||
| // skip file if it contains "+argocd:skip-rendering" | ||
| if bytes.Contains(out, []byte("+argocd:skip-rendering")) { |
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.
Extract as constant and document in go code.
I would also rename to "+argocd:skip-file-rendering" because it might be confusing if this is in a file containing (---) with multiple objects
23ae46e to
9f7b23c
Compare
|
Thanks for the review @agaudreault . I've made the changes and added this to the documentation. |
Signed-off-by: Moncef Abboud <[email protected]>
9f7b23c to
1f702f3
Compare
Signed-off-by: Moncef Abboud <[email protected]> Signed-off-by: dsuhinin <[email protected]>
Signed-off-by: Moncef Abboud <[email protected]> Signed-off-by: dsuhinin <[email protected]>
Signed-off-by: Moncef Abboud <[email protected]> Signed-off-by: enneitex <[email protected]>
Description
Fixes #21934
Repositories may contain YAML files that resemble valid k8s manifests, as they include
apiVersion,metadata, andkind, but are not necessarily valid k8s manifests. An example highlighted in this GitHub issue involves a Helm values file that could be mistaken for a manifest.Currently, these manifest-like YAMLs cause an error in the form of
Failed to unmarshal "{filename}": <nil>that stops the Application from continuing.This PR replaces the error with a warning without stopping execution. The rationale being that manifest-like files are allowed to exist but a warning is issued to provide information on true positives (manifest that are malformed).
Alternative
A potential downside of this change is that invalid manifests (true positives) will only trigger a warning rather than causing a failure. An alternative approach to address this could be to introduce an annotation or comment, such as
# ArgoCD: IgnoreNotAManifest, which can be added to non-manifest YAML files. This would allow those manifests to be ignored if their unmarshalling fails.Testing
#21934 contains a fairly simple way to reproduce the problem. Using this PR's branch should allow the Application to proceed while logging the warning.
Checklist: