Skip to content

Commit

Permalink
update HasUniqueTag logic to fall back to the value the user provided…
Browse files Browse the repository at this point in the history
…, if they do not provide a sha, or a latest tag

Signed-off-by: Adam D. Cornett <adc@redhat.com>
  • Loading branch information
acornett21 authored and bcrochet committed Aug 15, 2022
1 parent ee9cf5b commit a33ea50
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 16 deletions.
25 changes: 17 additions & 8 deletions certification/internal/policy/container/has_unique_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,26 @@ type hasUniqueTagCheck struct {

func (p *hasUniqueTagCheck) Validate(ctx context.Context, imgRef certification.ImageReference) (bool, error) {
imgRepo := fmt.Sprintf("%s/%s", imgRef.ImageRegistry, imgRef.ImageRepository)
tags, err := p.getDataToValidate(ctx, imgRepo)
if err != nil {
return false, fmt.Errorf("Error: failed to get tags list for %s: %v", imgRepo, err)

tags := make([]string, 0)
var err error
// if sha or latest tag is passed in `/tags/list` must be exposed and available to validate that the image is being tagged properly
if strings.HasPrefix(imgRef.ImageTagOrSha, "sha256:") || imgRef.ImageTagOrSha == "latest" {
tags, err = p.getDataToValidate(ctx, imgRepo)
if err != nil {
return false, fmt.Errorf("failed to get tags list for %s: %v", imgRepo, err)
}
}

if len(tags) < 1 {
if !strings.HasPrefix(imgRef.ImageTagOrSha, "sha256:") {
tags = append(tags, imgRef.ImageTagOrSha)
} else {
return false, fmt.Errorf("Error: no tags found for %s: cannot assert tag from digest", imgRepo)
// if tags is of length zero we know that either
// the partners registry returned an empty list so fall back
// or the value imgRef.ImageTagOrSha did not meet the previous conditions so falling back to use the value passed in
if len(tags) == 0 {
if strings.HasPrefix(imgRef.ImageTagOrSha, "sha256:") {
return false, fmt.Errorf("no tags found for %s: cannot assert tag from digest", imgRepo)
}

tags = append(tags, imgRef.ImageTagOrSha)
}

return p.validate(tags)
Expand Down
55 changes: 47 additions & 8 deletions certification/internal/policy/container/has_unique_tag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ var _ = Describe("UniqueTag", func() {
// Set up a fake registry.
registryLogger := log.New(io.Discard, "", log.Ldate)
s := httptest.NewServer(registry.New(registry.Logger(registryLogger)))
DeferCleanup(func() {
s.Close()
})
DeferCleanup(s.Close)
u, err := url.Parse(s.URL)
Expect(err).ToNot(HaveOccurred())
src = fmt.Sprintf("%s/test/preflight", u.Host)
Expand All @@ -52,24 +50,60 @@ var _ = Describe("UniqueTag", func() {
Describe("Checking for unique tags", func() {
Context("When it has tags other than latest", func() {
It("should pass Validate", func() {
ok, err := hasUniqueTagCheck.Validate(context.TODO(), certification.ImageReference{ImageRegistry: host, ImageRepository: "test/tags"})
ok, err := hasUniqueTagCheck.Validate(context.TODO(), certification.ImageReference{ImageRegistry: host, ImageRepository: "test/tags", ImageTagOrSha: "sha256:12345"})
Expect(err).ToNot(HaveOccurred())
Expect(ok).To(BeTrue())
})
})
Context("When it has tags other than latest and registry throws an error", func() {
BeforeEach(func() {
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
DeferCleanup(s.Close)

u, err := url.Parse(s.URL)
Expect(err).ToNot(HaveOccurred())
dst = fmt.Sprintf("%s/test/tags", u.Host)
host = u.Host
})
It("should throw an error", func() {
ok, err := hasUniqueTagCheck.Validate(context.TODO(), certification.ImageReference{ImageRegistry: host, ImageRepository: "test/tags", ImageTagOrSha: "sha256:12345"})
Expect(err).To(HaveOccurred())
Expect(ok).To(BeFalse())
})
})

Context("When it has only latest tag", func() {
It("should not pass Validate", func() {
ok, err := hasUniqueTagCheck.Validate(context.TODO(), certification.ImageReference{ImageRegistry: host, ImageRepository: "test/preflight"})
ok, err := hasUniqueTagCheck.Validate(context.TODO(), certification.ImageReference{ImageRegistry: host, ImageRepository: "test/preflight", ImageTagOrSha: "latest"})
Expect(err).ToNot(HaveOccurred())
Expect(ok).To(BeFalse())
})
})
Context("When it has only latest tag and the registry throws an error", func() {
BeforeEach(func() {
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
DeferCleanup(s.Close)

u, err := url.Parse(s.URL)
Expect(err).ToNot(HaveOccurred())
dst = fmt.Sprintf("%s/test/tags", u.Host)
host = u.Host
})
It("should throw an error", func() {
ok, err := hasUniqueTagCheck.Validate(context.TODO(), certification.ImageReference{ImageRegistry: host, ImageRepository: "test/preflight", ImageTagOrSha: "latest"})
Expect(err).To(HaveOccurred())
Expect(ok).To(BeFalse())
})
})
Context("When registry returns an empty tag list", func() {
BeforeEach(func() {
s := httptest.NewServer(http.HandlerFunc(mockRegistry))
DeferCleanup(func() {
s.Close()
})
DeferCleanup(s.Close)

u, err := url.Parse(s.URL)
Expect(err).ToNot(HaveOccurred())
host = u.Host
Expand All @@ -79,6 +113,11 @@ var _ = Describe("UniqueTag", func() {
Expect(err).ToNot(HaveOccurred())
Expect(ok).To(BeTrue())
})
It("should fail Validate", func() {
ok, err := hasUniqueTagCheck.Validate(context.TODO(), certification.ImageReference{ImageRegistry: host, ImageRepository: "test/notags", ImageTagOrSha: "sha256:12345"})
Expect(err).To(HaveOccurred())
Expect(ok).To(BeFalse())
})
})
})

Expand Down

0 comments on commit a33ea50

Please sign in to comment.