Merge pull request #10382 from malancas/refactor-get-attestations-funcs

Refactor `GetLocalAttestations` and clean up custom registry transport
This commit is contained in:
Meredith Lancaster 2025-03-05 11:46:36 -07:00 committed by GitHub
commit 4d44e4f20c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 25 additions and 55 deletions

View file

@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"io"
"net/http"
"strings"
"github.com/google/go-containerregistry/pkg/authn"
@ -69,33 +68,10 @@ func (c LiveClient) GetImageDigest(imgName string) (*v1.Hash, name.Reference, er
return &desc.Digest, name, nil
}
type noncompliantRegistryTransport struct{}
// RoundTrip will check if a request and associated response fulfill the following:
// 1. The response returns a 406 status code
// 2. The request path contains /referrers/
// If both conditions are met, the response's status code will be overwritten to 404
// This is a temporary solution to handle non compliant registries that return
// an unexpected status code 406 when the go-containerregistry library used
// by this code attempts to make a request to the referrers API.
// The go-containerregistry library can handle 404 response but not a 406 response.
// See the related go-containerregistry issue: https://github.com/google/go-containerregistry/issues/1962
func (a *noncompliantRegistryTransport) RoundTrip(req *http.Request) (*http.Response, error) {
resp, err := http.DefaultTransport.RoundTrip(req)
if err != nil {
return resp, err
}
if resp.StatusCode == http.StatusNotAcceptable && strings.Contains(req.URL.Path, "/referrers/") {
resp.StatusCode = http.StatusNotFound
}
return resp, nil
}
func (c LiveClient) GetAttestations(ref name.Reference, digest string) ([]*api.Attestation, error) {
attestations := make([]*api.Attestation, 0)
transportOpts := []remote.Option{remote.WithTransport(&noncompliantRegistryTransport{}), remote.WithAuthFromKeychain(authn.DefaultKeychain)}
transportOpts := []remote.Option{remote.WithAuthFromKeychain(authn.DefaultKeychain)}
referrers, err := remote.Referrers(ref.Context().Digest(digest), transportOpts...)
if err != nil {
return attestations, fmt.Errorf("error getting referrers: %w", err)

View file

@ -29,43 +29,37 @@ type FetchRemoteAttestationsParams struct {
// GetLocalAttestations returns a slice of attestations read from a local bundle file.
func GetLocalAttestations(path string) ([]*api.Attestation, error) {
var attestations []*api.Attestation
var err error
fileExt := filepath.Ext(path)
switch fileExt {
case ".json":
attestations, err := loadBundleFromJSONFile(path)
if err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) {
return nil, fmt.Errorf("bundle could not be loaded from JSON file at %s", path)
} else if errors.Is(err, bundle.ErrValidation) {
return nil, err
}
return nil, fmt.Errorf("bundle content could not be parsed")
}
return attestations, nil
case ".jsonl":
attestations, err := loadBundlesFromJSONLinesFile(path)
if err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) {
return nil, fmt.Errorf("bundles could not be loaded from JSON lines file at %s", path)
} else if errors.Is(err, bundle.ErrValidation) {
return nil, err
}
return nil, fmt.Errorf("bundle content could not be parsed")
}
return attestations, nil
if fileExt == ".json" {
attestations, err = loadBundleFromJSONFile(path)
} else if fileExt == ".jsonl" {
attestations, err = loadBundlesFromJSONLinesFile(path)
} else {
return nil, ErrUnrecognisedBundleExtension
}
return nil, ErrUnrecognisedBundleExtension
if err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) {
return nil, fmt.Errorf("could not load content from file path %s: %w", path, err)
} else if errors.Is(err, bundle.ErrValidation) {
return nil, err
}
return nil, fmt.Errorf("bundle content could not be parsed: %w", err)
}
return attestations, nil
}
func loadBundleFromJSONFile(path string) ([]*api.Attestation, error) {
localAttestation, err := bundle.LoadJSONFromPath(path)
b, err := bundle.LoadJSONFromPath(path)
if err != nil {
return nil, err
}
return []*api.Attestation{{Bundle: localAttestation}}, nil
return []*api.Attestation{{Bundle: b}}, nil
}
func loadBundlesFromJSONLinesFile(path string) ([]*api.Attestation, error) {

View file

@ -92,7 +92,7 @@ func TestGetLocalAttestations(t *testing.T) {
path := "../test/data/not-found-bundle.json"
attestations, err := GetLocalAttestations(path)
require.ErrorContains(t, err, "bundle could not be loaded from JSON file")
require.ErrorContains(t, err, "could not load content from file path")
require.Nil(t, attestations)
})
@ -100,7 +100,7 @@ func TestGetLocalAttestations(t *testing.T) {
path := "../test/data/not-found-bundle.jsonl"
attestations, err := GetLocalAttestations(path)
require.ErrorContains(t, err, "bundles could not be loaded from JSON lines file")
require.ErrorContains(t, err, "could not load content from file path")
require.Nil(t, attestations)
})