refactor fetch attestations funcs

Signed-off-by: Meredith Lancaster <malancas@github.com>
This commit is contained in:
Meredith Lancaster 2024-11-07 14:39:11 -07:00
parent 6d4c74b252
commit ff9b6bb883
3 changed files with 63 additions and 57 deletions

View file

@ -9,8 +9,8 @@ import (
"path/filepath"
"github.com/cli/cli/v2/pkg/cmd/attestation/api"
"github.com/cli/cli/v2/pkg/cmd/attestation/artifact"
"github.com/cli/cli/v2/pkg/cmd/attestation/artifact/oci"
"github.com/google/go-containerregistry/pkg/name"
protobundle "github.com/sigstore/protobuf-specs/gen/pb-go/bundle/v1"
"github.com/sigstore/sigstore-go/pkg/bundle"
)
@ -21,31 +21,11 @@ var ErrUnrecognisedBundleExtension = errors.New("bundle file extension not suppo
var ErrEmptyBundleFile = errors.New("provided bundle file is empty")
type FetchAttestationsConfig struct {
APIClient api.Client
BundlePath string
Digest string
Limit int
Owner string
Repo string
OCIClient oci.Client
UseBundleFromRegistry bool
NameRef name.Reference
}
func (c *FetchAttestationsConfig) IsBundleProvided() bool {
return c.BundlePath != ""
}
func GetAttestations(c FetchAttestationsConfig) ([]*api.Attestation, error) {
if c.IsBundleProvided() {
return GetLocalAttestations(c.BundlePath)
}
if c.UseBundleFromRegistry {
return GetOCIAttestations(c)
}
return GetRemoteAttestations(c)
APIClient api.Client
Digest string
Limit int
Owner string
Repo string
}
// GetLocalAttestations returns a slice of attestations read from a local bundle file.
@ -138,8 +118,8 @@ func GetRemoteAttestations(c FetchAttestationsConfig) ([]*api.Attestation, error
return nil, fmt.Errorf("owner or repo must be provided")
}
func GetOCIAttestations(c FetchAttestationsConfig) ([]*api.Attestation, error) {
attestations, err := c.OCIClient.GetAttestations(c.NameRef, c.Digest)
func GetOCIAttestations(client oci.Client, artifact artifact.DigestedArtifact) ([]*api.Attestation, error) {
attestations, err := client.GetAttestations(artifact.NameRef(), artifact.Digest())
if err != nil {
return nil, fmt.Errorf("failed to fetch OCI attestations: %w", err)
}

View file

@ -0,0 +1,51 @@
package verify
import (
"fmt"
"github.com/cli/cli/v2/internal/text"
"github.com/cli/cli/v2/pkg/cmd/attestation/api"
"github.com/cli/cli/v2/pkg/cmd/attestation/artifact"
"github.com/cli/cli/v2/pkg/cmd/attestation/verification"
)
func getAttestations(o *Options, a artifact.DigestedArtifact) ([]*api.Attestation, string, error) {
if o.BundlePath != "" {
attestations, err := verification.GetLocalAttestations(o.BundlePath)
if err != nil {
msg := fmt.Sprintf("✗ Loading attestations from %s failed\n", a.URL)
return nil, msg, err
}
pluralAttestation := text.Pluralize(len(attestations), "attestation")
msg := fmt.Sprintf("Loaded %s from %s\n", pluralAttestation, o.BundlePath)
return attestations, msg, nil
}
if o.UseBundleFromRegistry {
attestations, err := verification.GetOCIAttestations(o.OCIClient, a)
if err != nil {
msg := "✗ Loading attestations from OCI registry failed\n"
return nil, msg, err
}
pluralAttestation := text.Pluralize(len(attestations), "attestation")
msg := fmt.Sprintf("Loaded %s from %s\n", pluralAttestation, o.ArtifactPath)
return attestations, msg, nil
}
c := verification.FetchAttestationsConfig{
APIClient: o.APIClient,
Digest: a.DigestWithAlg(),
Limit: o.Limit,
Owner: o.Owner,
Repo: o.Repo,
}
attestations, err := verification.GetRemoteAttestations(c)
if err != nil {
msg := "✗ Loading attestations from GitHub API failed\n"
return nil, msg, err
}
pluralAttestation := text.Pluralize(len(attestations), "attestation")
msg := fmt.Sprintf("Loaded %s from GitHub API\n", pluralAttestation)
return attestations, msg, nil
}

View file

@ -6,7 +6,6 @@ import (
"regexp"
"github.com/cli/cli/v2/internal/ghinstance"
"github.com/cli/cli/v2/internal/text"
"github.com/cli/cli/v2/pkg/cmd/attestation/api"
"github.com/cli/cli/v2/pkg/cmd/attestation/artifact"
"github.com/cli/cli/v2/pkg/cmd/attestation/artifact/oci"
@ -222,42 +221,18 @@ func runVerify(opts *Options) error {
opts.Logger.Printf("Loaded digest %s for %s\n", artifact.DigestWithAlg(), artifact.URL)
c := verification.FetchAttestationsConfig{
APIClient: opts.APIClient,
BundlePath: opts.BundlePath,
Digest: artifact.DigestWithAlg(),
Limit: opts.Limit,
Owner: opts.Owner,
Repo: opts.Repo,
OCIClient: opts.OCIClient,
UseBundleFromRegistry: opts.UseBundleFromRegistry,
NameRef: artifact.NameRef(),
}
attestations, err := verification.GetAttestations(c)
attestations, logMsg, err := getAttestations(opts, *artifact)
if err != nil {
if ok := errors.Is(err, api.ErrNoAttestations{}); ok {
opts.Logger.Printf(opts.Logger.ColorScheme.Red("✗ No attestations found for subject %s\n"), artifact.DigestWithAlg())
return err
}
if c.IsBundleProvided() {
opts.Logger.Printf(opts.Logger.ColorScheme.Red("✗ Loading attestations from %s failed\n"), artifact.URL)
} else if c.UseBundleFromRegistry {
opts.Logger.Println(opts.Logger.ColorScheme.Red("✗ Loading attestations from OCI registry failed"))
} else {
opts.Logger.Println(opts.Logger.ColorScheme.Red("✗ Loading attestations from GitHub API failed"))
}
opts.Logger.Printf(opts.Logger.ColorScheme.Red(logMsg))
return err
}
pluralAttestation := text.Pluralize(len(attestations), "attestation")
if c.IsBundleProvided() {
opts.Logger.Printf("Loaded %s from %s\n", pluralAttestation, opts.BundlePath)
} else if c.UseBundleFromRegistry {
opts.Logger.Printf("Loaded %s from %s\n", pluralAttestation, opts.ArtifactPath)
} else {
opts.Logger.Printf("Loaded %s from GitHub API\n", pluralAttestation)
}
// Print the message signifying success fetching attestations
opts.Logger.Printf(logMsg)
// Apply predicate type filter to returned attestations
filteredAttestations := verification.FilterAttestations(ec.PredicateType, attestations)