-
Notifications
You must be signed in to change notification settings - Fork 223
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: parseImageRef tag parsing (#2411) #2412
fix: parseImageRef tag parsing (#2411) #2412
Conversation
cc7eacc
to
b6be3e5
Compare
pkg/plugins/trivy/plugin.go
Outdated
hasTag = true | ||
} | ||
|
||
ref, err := containerimage.ParseReference(namePart, containerimage.WeakValidation) |
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 function calls twice.
pkg/plugins/trivy/plugin.go
Outdated
} | ||
|
||
if hasDigest { | ||
digestRef, err := containerimage.ParseReference(imageRef, containerimage.WeakValidation) |
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 second call.
pkg/plugins/trivy/plugin.go
Outdated
var hasDigest bool | ||
var hasTag 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.
do we really need these variables?
artifact.Digest == ""
means hasDigest is false
, right?
pkg/plugins/trivy/plugin.go
Outdated
if len(parts) > 1 { | ||
hasDigest = true | ||
} | ||
if len(strings.Split(namePart,":"))>1{ | ||
hasTag = true | ||
} |
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 should improve these if-statements
pkg/plugins/trivy/plugin.go
Outdated
case ok && hasTag: | ||
artifact.Tag = tagged.TagStr() | ||
case ok && !hasTag && !hasDigest: | ||
artifact.Tag = tagged.TagStr() | ||
case ok && hasTag && hasDigest: | ||
artifact.Tag = tagged.TagStr() |
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.
ok
should be true
for all cases, right?
and artifact.Tag = tagged.TagStr()
calls for all cases.
honestly it doesn't look like a good way to check tags/digest.
@danchenko-dmitry thanks for your contribution and your time. i left some comments. and think we should refactor this code. |
@danchenko-dmitry please correct me. |
also in any case, you can take a look at |
I've prepared demo repo to demonstrate how it works: |
@danchenko-dmitry thanks! update: artifactTag = strings.TrimPrefix(strings.TrimSuffix(strings.TrimPrefix(imageRef, ref.Context().Name()), "@"+artifactDigest), ":") https://go.dev/play/p/d3BZ2biZf_p I'm not sure about this solution. Just the first idea. wdyt? |
Well, thank you for your support. |
@danchenko-dmitry thanks for your PR! It looks like the tests and the linter are failing. Could you look into fixing those? |
Done. Thanks! |
@@ -155,7 +155,7 @@ func (p *plugin) ParseReportData(ctx trivyoperator.PluginContext, imageRef strin | |||
|
|||
imageDigest := p.getImageDigest(reports) | |||
|
|||
registry, artifact, err := p.parseImageRef(imageRef, imageDigest) | |||
registry, artifact, err := ParseImageRef(imageRef, imageDigest) |
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 do we need 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.
My point is:
- We don't need this function as a method. It doesn't use private or public variables.
- Making it a standalone function simplifies testing (we don't need to initialize the object plugin ...)
pkg/plugins/trivy/plugin_test.go
Outdated
name: "7. short repo with private repo with tag", | ||
imageRef: "my-private-repo.company.com/my-app:1.2.3", | ||
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6", | ||
registry: v1alpha1.Registry{ | ||
Server: "my-private-repo.company.com", | ||
}, | ||
artifact: v1alpha1.Artifact{ | ||
Repository: "my-app", | ||
Digest: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6", | ||
Tag: "1.2.3", | ||
}, | ||
err: 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 are the diifs between "2. with tag"
?
is there a specific case for private repositories in ParseImageRef
?
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.
Agree. I thought that more samples to test in different situations make it more covered by tests.
But your point also has meaning.
Less code - less support. If some case will be needed in the future it is easy to add it.
I will remove duplicates.
server := "" | ||
repository := "" | ||
digest := "" | ||
tag := "" |
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 we really need these variables?
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, these variables "collect" values from two sources: containerimage.NewTag and containerimage.NewDigest.
In cases "server" and "repository" we don't care what source will used when both are available. (because they are equal)
"digest" and "tag" fills if it available.
The whole structure of code was made to simplify flow and remove sophisticated conditions.
I think using these variables (as one place collects data) will be simpler than other any cases.
_tag, _err := containerimage.NewTag(refParts[0], containerimage.WeakValidation) | ||
if _err == nil { | ||
pTag = &_tag | ||
} | ||
artifact := v1alpha1.Artifact{ | ||
Repository: ref.Context().RepositoryStr(), | ||
|
||
_digest, _err := containerimage.NewDigest(imageRef, containerimage.WeakValidation) | ||
if _err == nil { | ||
pDigest = &_digest |
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 looks like rewriting containerimage.ParseReference(imageRef)
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.
Yes, thats right!
It was an aim ... Using ParseReference will cause second call with other arguments.
I've decided to rewrite ParseReference and "customize" it logic & lay code on library then lay on own custom code.
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.
artifact.Tag = strings.TrimPrefix(strings.TrimSuffix(strings.TrimPrefix(imageRef, ref.Context().Name()), "@"+artifactDigest), ":")
doesn't this code work correctly?
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 mean if you keep your test and add this one-line code for digest, will the tests pass?
trivy-operator/pkg/plugins/trivy/plugin.go
Lines 230 to 231 in 164ac24
case containerimage.Digest: | |
artifact.Digest = t.DigestStr() |
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.
artifact.Tag = strings.TrimPrefix(strings.TrimSuffix(strings.TrimPrefix(imageRef, ref.Context().Name()), "@"+artifactDigest), ":")doesn't this code work correctly?
This code works correctly. I've checked it on another PR #2418
So we have two opportunities.
@danchenko-dmitry thanks for your work! I left some comments.
Let me know what you think! |
Totally agree. The previous version of the function wasn't simple and clear. Rewriting was simpler than smooth evolution ...
Yes, I will remove redundant tests. You are right that less code is easiest to maintain.
Thanks for your support! I motivated to do code better. |
in favor #2418 |
Description
I've changed behaviour of parseImageRef func.
before:
In case when imageRef -> "my-private-repo.company.com/my-app:some-tag@sha256:1420cefd4b20014b3361951c22593de6e9a2476bbbadd1759464eab5bfc0d34f"
It returns empty tag in Artifact.Tag;
after:
In new version this behaviour fixed and it returns tag instead empty string.
you can see it it "15. private registry image ref tag & with digest" test.
Related issues
Checklist