Skip to content

Commit

Permalink
fix: parseImageRef tag parsing (aquasecurity#2411)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry-Danchenko committed Jan 31, 2025
1 parent a742539 commit cc7eacc
Show file tree
Hide file tree
Showing 2 changed files with 282 additions and 10 deletions.
49 changes: 39 additions & 10 deletions pkg/plugins/trivy/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import (
"encoding/json"
"io"
"path/filepath"
"strings"

"github.com/aquasecurity/trivy-operator/pkg/exposedsecretreport"
"github.com/aquasecurity/trivy-operator/pkg/sbomreport"
"github.com/aquasecurity/trivy-operator/pkg/utils"

containerimage "github.com/google/go-containerregistry/pkg/name"

"github.com/aquasecurity/trivy-operator/pkg/apis/aquasecurity/v1alpha1"
Expand Down Expand Up @@ -154,10 +154,10 @@ func (p *plugin) ParseReportData(ctx trivyoperator.PluginContext, imageRef strin
return vulnReport, secretReport, nil, err
}

registry, artifact, err := p.parseImageRef(imageRef, reports.Metadata.ImageID)
registry, artifact, err := ParseImageRef(imageRef, reports.Metadata.ImageID)
if err != nil {
return vulnReport, secretReport, nil, err
}
}

os := p.parseOSRef(reports)

Expand Down Expand Up @@ -212,26 +212,55 @@ func (p *plugin) NewConfigForConfigAudit(ctx trivyoperator.PluginContext) (confi
return getConfig(ctx)
}

func (p *plugin) parseImageRef(imageRef string, imageID string) (v1alpha1.Registry, v1alpha1.Artifact, error) {
ref, err := containerimage.ParseReference(imageRef)
func ParseImageRef(imageRef string, imageID string) (v1alpha1.Registry, v1alpha1.Artifact, error) {
parts := strings.Split(imageRef, "@")
namePart := parts[0]
var hasDigest bool
var hasTag bool
if len(parts) > 1 {
hasDigest = true
}
if len(strings.Split(namePart,":"))>1{
hasTag = true
}

ref, err := containerimage.ParseReference(namePart, containerimage.WeakValidation)
if err != nil {
return v1alpha1.Registry{}, v1alpha1.Artifact{}, err
}

registry := v1alpha1.Registry{
Server: ref.Context().RegistryStr(),
}
artifact := v1alpha1.Artifact{
Repository: ref.Context().RepositoryStr(),
}
switch t := ref.(type) {
case containerimage.Tag:
artifact.Tag = t.TagStr()
case containerimage.Digest:
artifact.Digest = t.DigestStr()

tagged, ok := ref.(containerimage.Tag)
switch {
case ok && hasTag:
artifact.Tag = tagged.TagStr()
case ok && !hasTag && !hasDigest:
artifact.Tag = tagged.TagStr()
case ok && hasTag && hasDigest:
artifact.Tag = tagged.TagStr()
}

if hasDigest {
digestRef, err := containerimage.ParseReference(imageRef, containerimage.WeakValidation)
if err != nil {
return v1alpha1.Registry{}, v1alpha1.Artifact{}, err
}
digested, ok := digestRef.(containerimage.Digest)
if ok {
artifact.Digest = digested.DigestStr()
}
}

if len(artifact.Digest) == 0 {
artifact.Digest = imageID
}

return registry, artifact, nil
}

Expand Down
243 changes: 243 additions & 0 deletions pkg/plugins/trivy/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7628,3 +7628,246 @@ func TestExcludeImages(t *testing.T) {
})
}
}

func TestParseImageRef(t *testing.T) {
testCases := []struct {
name string
// args:
imageRef string
imageID string
// result:
registry v1alpha1.Registry
artifact v1alpha1.Artifact
err error
}{
{
name: "1. repo with latest tag",
imageRef: "quay.io/prometheus-operator/prometheus-operator:latest",
imageID: "sha256:1420cefd4b20014b3361951c22593de6e9a2476bbbadd1759464eab5bfc0d34f",
registry: v1alpha1.Registry{
Server: "quay.io",
},
artifact: v1alpha1.Artifact{
Repository: "prometheus-operator/prometheus-operator",
Digest: "sha256:1420cefd4b20014b3361951c22593de6e9a2476bbbadd1759464eab5bfc0d34f",
Tag: "latest",
},
err: nil,
},
{
name: "2. with tag",
imageRef: "quay.io/prometheus-operator/prometheus-operator:v0.63.0",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "quay.io",
},
artifact: v1alpha1.Artifact{
Repository: "prometheus-operator/prometheus-operator",
Digest: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
Tag: "v0.63.0",
},
},
{
name: "3. repo with digest",
imageRef: "quay.io/prometheus-operator/prometheus-operator@sha256:1420cefd4b20014b3361951c22593de6e9a2476bbbadd1759464eab5bfc0d34f",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "quay.io",
},
artifact: v1alpha1.Artifact{
Repository: "prometheus-operator/prometheus-operator",
Digest: "sha256:1420cefd4b20014b3361951c22593de6e9a2476bbbadd1759464eab5bfc0d34f",
Tag: "",
},
err: nil,
},
{
name: "4. incorrect input",
imageRef: "## some incorrect imput ###",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{},
artifact: v1alpha1.Artifact{},
err: fmt.Errorf("could not parse reference: ## some incorrect imput ###"),
},
{
name: "5. short repo with tag",
imageRef: "prometheus-operator:local",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "index.docker.io",
},
artifact: v1alpha1.Artifact{
Repository: "library/prometheus-operator",
Digest: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
Tag: "local",
},
err: nil,
},
{
name: "6. short repo with default lib with latest tag",
imageRef: "library/nginx:latest",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "index.docker.io",
},
artifact: v1alpha1.Artifact{
Repository: "library/nginx",
Digest: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
Tag: "latest",
},
err: nil,
},
{
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,
},
{
name: "8. repo with private repo with digest",
imageRef: "my-private-repo.company.com/my-app@sha256:1420cefd4b20014b3361951c22593de6e9a2476bbbadd1759464eab5bfc0d34f",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "my-private-repo.company.com",
},
artifact: v1alpha1.Artifact{
Repository: "my-app",
Digest: "sha256:1420cefd4b20014b3361951c22593de6e9a2476bbbadd1759464eab5bfc0d34f",
Tag: "",
},
err: nil,
},
{
name: "9. short image ref with latest tag",
imageRef: "nginx:latest",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "index.docker.io",
},
artifact: v1alpha1.Artifact{
Repository: "library/nginx",
Digest: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
Tag: "latest",
},
err: nil,
},
{
name: "10. artifact registry image ref with tag",
imageRef: "europe-west4-docker.pkg.dev/my-project/my-repo/my-app:1.0.0",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "europe-west4-docker.pkg.dev",
},
artifact: v1alpha1.Artifact{
Repository: "my-project/my-repo/my-app",
Digest: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
Tag: "1.0.0",
},
err: nil,
},
{
name: "11. aws registry image ref with latest tag",
imageRef: "123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app:latest",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "123456789012.dkr.ecr.us-east-1.amazonaws.com",
},
artifact: v1alpha1.Artifact{
Repository: "my-app",
Digest: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
Tag: "latest",
},
err: nil,
},
{
name: "12. azure registry image ref with tag",
imageRef: "myregistry.azurecr.io/my-app:v2.0.1",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "myregistry.azurecr.io",
},
artifact: v1alpha1.Artifact{
Repository: "my-app",
Digest: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
Tag: "v2.0.1",
},
err: nil,
},
{
name: "13. docker registry image ref without tag",
imageRef: "docker.io/library/alpine",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "index.docker.io",
},
artifact: v1alpha1.Artifact{
Repository: "library/alpine",
Digest: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
Tag: "latest",
},
err: nil,
},
{
name: "14. private registry image ref with digest",
imageRef: "my-private-repo.company.com/my-app@sha256:1420cefd4b20014b3361951c22593de6e9a2476bbbadd1759464eab5bfc0d34f",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "my-private-repo.company.com",
},
artifact: v1alpha1.Artifact{
Repository: "my-app",
Digest: "sha256:1420cefd4b20014b3361951c22593de6e9a2476bbbadd1759464eab5bfc0d34f",
Tag: "",
},
err: nil,
},
{
name: "15. private registry image ref tag & with digest",
imageRef: "my-private-repo.company.com/my-app:some-tag@sha256:1420cefd4b20014b3361951c22593de6e9a2476bbbadd1759464eab5bfc0d34f",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "my-private-repo.company.com",
},
artifact: v1alpha1.Artifact{
Repository: "my-app",
Digest: "sha256:1420cefd4b20014b3361951c22593de6e9a2476bbbadd1759464eab5bfc0d34f",
Tag: "some-tag",
},
err: nil,
},
{
name: "16. well known image without tag & digest",
imageRef: "quay.io/centos/centos",
imageID: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
registry: v1alpha1.Registry{
Server: "quay.io",
},
artifact: v1alpha1.Artifact{
Repository: "centos/centos",
Digest: "sha256:2bc57c6bcb194869d18676e003dfed47b87d257fce49667557fb8eb1f324d5d6",
Tag: "latest",
},
err: nil,
},
};
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
registry,artifact,err := trivy.ParseImageRef(tc.imageRef,tc.imageID)
assert.Equal(t, tc.registry, registry)
assert.Equal(t, tc.artifact, artifact)
if tc.err!=nil {
if !assert.Error(t,err) {
assert.Failf(t,"expected","%v but got %v",tc.err,err)
}
}
})
}
}

0 comments on commit cc7eacc

Please sign in to comment.