refactor: make common authn function
This commit is contained in:
@@ -5,15 +5,12 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login"
|
|
||||||
acr "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper"
|
|
||||||
"github.com/docker/attest/internal/embed"
|
"github.com/docker/attest/internal/embed"
|
||||||
|
"github.com/docker/attest/pkg/oci"
|
||||||
"github.com/docker/attest/pkg/tuf"
|
"github.com/docker/attest/pkg/tuf"
|
||||||
"github.com/google/go-containerregistry/pkg/authn"
|
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/empty"
|
"github.com/google/go-containerregistry/pkg/v1/empty"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/google"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/layout"
|
"github.com/google/go-containerregistry/pkg/v1/layout"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||||
)
|
)
|
||||||
@@ -34,15 +31,9 @@ func PushImageToRegistry(image v1.Image, imageName string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to parse image name: %v", err)
|
log.Fatalf("Failed to parse image name: %v", err)
|
||||||
}
|
}
|
||||||
// Create a multi-keychain that will use the default Docker, Google, ECR or ACR keychain
|
|
||||||
keychain := authn.NewMultiKeychain(
|
|
||||||
authn.DefaultKeychain,
|
|
||||||
google.Keychain,
|
|
||||||
authn.NewKeychainFromHelper(ecr.NewECRHelper()),
|
|
||||||
authn.NewKeychainFromHelper(acr.NewACRCredentialsHelper()),
|
|
||||||
)
|
|
||||||
// Push the image to the registry
|
// Push the image to the registry
|
||||||
return remote.Write(ref, image, remote.WithAuthFromKeychain(keychain))
|
return remote.Write(ref, image, oci.MultiKeychainOption())
|
||||||
}
|
}
|
||||||
|
|
||||||
func PushIndexToRegistry(image v1.ImageIndex, imageName string) error {
|
func PushIndexToRegistry(image v1.ImageIndex, imageName string) error {
|
||||||
@@ -51,15 +42,8 @@ func PushIndexToRegistry(image v1.ImageIndex, imageName string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to parse image name: %v", err)
|
log.Fatalf("Failed to parse image name: %v", err)
|
||||||
}
|
}
|
||||||
// Create a multi-keychain that will use the default Docker, Google, ECR or ACR keychain
|
|
||||||
keychain := authn.NewMultiKeychain(
|
|
||||||
authn.DefaultKeychain,
|
|
||||||
google.Keychain,
|
|
||||||
authn.NewKeychainFromHelper(ecr.NewECRHelper()),
|
|
||||||
authn.NewKeychainFromHelper(acr.NewACRCredentialsHelper()),
|
|
||||||
)
|
|
||||||
// Push the index to the registry
|
// Push the index to the registry
|
||||||
return remote.WriteIndex(ref, image, remote.WithAuthFromKeychain(keychain))
|
return remote.WriteIndex(ref, image, oci.MultiKeychainOption())
|
||||||
}
|
}
|
||||||
|
|
||||||
func SaveImageAsOCILayout(image v1.Image, path string) error {
|
func SaveImageAsOCILayout(image v1.Image, path string) error {
|
||||||
|
|||||||
23
pkg/oci/authn.go
Normal file
23
pkg/oci/authn.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package oci
|
||||||
|
|
||||||
|
import (
|
||||||
|
ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login"
|
||||||
|
acr "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper"
|
||||||
|
"github.com/google/go-containerregistry/pkg/authn"
|
||||||
|
"github.com/google/go-containerregistry/pkg/v1/google"
|
||||||
|
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MultiKeychainOption() remote.Option {
|
||||||
|
return remote.WithAuthFromKeychain(MultiKeychainAll())
|
||||||
|
}
|
||||||
|
|
||||||
|
func MultiKeychainAll() authn.Keychain {
|
||||||
|
// Create a multi-keychain that will use the default Docker, Google, ECR or ACR keychain
|
||||||
|
return authn.NewMultiKeychain(
|
||||||
|
authn.DefaultKeychain,
|
||||||
|
google.Keychain,
|
||||||
|
authn.NewKeychainFromHelper(ecr.NewECRHelper()),
|
||||||
|
authn.NewKeychainFromHelper(acr.NewACRCredentialsHelper()),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -6,15 +6,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login"
|
|
||||||
acr "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper"
|
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
"github.com/distribution/reference"
|
"github.com/distribution/reference"
|
||||||
att "github.com/docker/attest/pkg/attestation"
|
att "github.com/docker/attest/pkg/attestation"
|
||||||
"github.com/google/go-containerregistry/pkg/authn"
|
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/google"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/layout"
|
"github.com/google/go-containerregistry/pkg/v1/layout"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||||
"github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common"
|
"github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common"
|
||||||
@@ -245,6 +241,9 @@ func (r *ReferrersResolver) resolveAttestations(ctx context.Context) error {
|
|||||||
return fmt.Errorf("failed to parse reference: %w", err)
|
return fmt.Errorf("failed to parse reference: %w", err)
|
||||||
}
|
}
|
||||||
subjectDigest, err := r.ImageDigest(ctx)
|
subjectDigest, err := r.ImageDigest(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get image digest: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
var referrersSubjectRef name.Digest
|
var referrersSubjectRef name.Digest
|
||||||
if r.referrersRepo != "" {
|
if r.referrersRepo != "" {
|
||||||
@@ -459,14 +458,7 @@ func FetchAttestationManifest(ctx context.Context, image string, platform *v1.Pl
|
|||||||
|
|
||||||
func WithOptions(ctx context.Context, platform *v1.Platform) []remote.Option {
|
func WithOptions(ctx context.Context, platform *v1.Platform) []remote.Option {
|
||||||
// prepare options
|
// prepare options
|
||||||
// Create a multi-keychain that will use the default Docker, Google, ECR or ACR keychain
|
options := []remote.Option{MultiKeychainOption(), remote.WithTransport(HttpTransport()), remote.WithContext(ctx)}
|
||||||
keychain := authn.NewMultiKeychain(
|
|
||||||
authn.DefaultKeychain,
|
|
||||||
google.Keychain,
|
|
||||||
authn.NewKeychainFromHelper(ecr.NewECRHelper()),
|
|
||||||
authn.NewKeychainFromHelper(acr.NewACRCredentialsHelper()),
|
|
||||||
)
|
|
||||||
options := []remote.Option{remote.WithAuthFromKeychain(keychain), remote.WithTransport(HttpTransport()), remote.WithContext(ctx)}
|
|
||||||
|
|
||||||
// add in platform into remote Get operation; this might conflict with an explicit digest, but we are trying anyway
|
// add in platform into remote Get operation; this might conflict with an explicit digest, but we are trying anyway
|
||||||
if platform != nil {
|
if platform != nil {
|
||||||
|
|||||||
@@ -4,12 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login"
|
|
||||||
acr "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper"
|
|
||||||
"github.com/google/go-containerregistry/pkg/authn"
|
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/google"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/layout"
|
"github.com/google/go-containerregistry/pkg/v1/layout"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||||
)
|
)
|
||||||
@@ -53,15 +49,8 @@ func SubjectIndexFromRemote(image string) (*SubjectIndex, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to parse image name: %v", err)
|
log.Fatalf("Failed to parse image name: %v", err)
|
||||||
}
|
}
|
||||||
// Create a multi-keychain that will use the default Docker, Google, ECR or ACR keychain
|
|
||||||
keychain := authn.NewMultiKeychain(
|
|
||||||
authn.DefaultKeychain,
|
|
||||||
google.Keychain,
|
|
||||||
authn.NewKeychainFromHelper(ecr.NewECRHelper()),
|
|
||||||
authn.NewKeychainFromHelper(acr.NewACRCredentialsHelper()),
|
|
||||||
)
|
|
||||||
// Pull the image from the registry
|
// Pull the image from the registry
|
||||||
idx, err := remote.Index(ref, remote.WithAuthFromKeychain(keychain))
|
idx, err := remote.Index(ref, MultiKeychainOption())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to pull image %s: %w", image, err)
|
return nil, fmt.Errorf("failed to pull image %s: %w", image, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login"
|
"github.com/docker/attest/pkg/oci"
|
||||||
acr "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper"
|
|
||||||
"github.com/google/go-containerregistry/pkg/authn"
|
"github.com/google/go-containerregistry/pkg/authn"
|
||||||
"github.com/google/go-containerregistry/pkg/crane"
|
"github.com/google/go-containerregistry/pkg/crane"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/google"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/types"
|
"github.com/google/go-containerregistry/pkg/v1/types"
|
||||||
"github.com/theupdateframework/go-tuf/v2/metadata"
|
"github.com/theupdateframework/go-tuf/v2/metadata"
|
||||||
)
|
)
|
||||||
@@ -121,20 +119,13 @@ func (d *RegistryFetcher) getManifest(ref string) ([]byte, error) {
|
|||||||
var err error
|
var err error
|
||||||
var found bool
|
var found bool
|
||||||
var mf []byte
|
var mf []byte
|
||||||
// Create a multi-keychain that will use the default Docker, Google, ECR or ACR keychain
|
|
||||||
keychain := authn.NewMultiKeychain(
|
|
||||||
authn.DefaultKeychain,
|
|
||||||
google.Keychain,
|
|
||||||
authn.NewKeychainFromHelper(ecr.NewECRHelper()),
|
|
||||||
authn.NewKeychainFromHelper(acr.NewACRCredentialsHelper()),
|
|
||||||
)
|
|
||||||
// Check cache for manifest and only pull if not found
|
// Check cache for manifest and only pull if not found
|
||||||
if mf, found = d.cache.Get(ref); !found {
|
if mf, found = d.cache.Get(ref); !found {
|
||||||
mf, err = crane.Manifest(ref,
|
mf, err = crane.Manifest(ref,
|
||||||
crane.WithUserAgent(d.httpUserAgent),
|
crane.WithUserAgent(d.httpUserAgent),
|
||||||
crane.WithTransport(transportWithTimeout(d.timeout)),
|
crane.WithTransport(transportWithTimeout(d.timeout)),
|
||||||
crane.WithAuth(authn.Anonymous),
|
crane.WithAuth(authn.Anonymous),
|
||||||
crane.WithAuthFromKeychain(keychain))
|
crane.WithAuthFromKeychain(oci.MultiKeychainAll()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -154,7 +145,7 @@ func (d *RegistryFetcher) pullFileLayer(ref string, maxLength int64) ([]byte, er
|
|||||||
crane.WithUserAgent(d.httpUserAgent),
|
crane.WithUserAgent(d.httpUserAgent),
|
||||||
crane.WithTransport(transportWithTimeout(d.timeout)),
|
crane.WithTransport(transportWithTimeout(d.timeout)),
|
||||||
crane.WithAuth(authn.Anonymous),
|
crane.WithAuth(authn.Anonymous),
|
||||||
crane.WithAuthFromKeychain(authn.DefaultKeychain))
|
crane.WithAuthFromKeychain(oci.MultiKeychainAll()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,16 +9,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login"
|
|
||||||
acr "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper"
|
|
||||||
"github.com/docker/attest/internal/embed"
|
"github.com/docker/attest/internal/embed"
|
||||||
"github.com/docker/attest/internal/util"
|
"github.com/docker/attest/internal/util"
|
||||||
"github.com/google/go-containerregistry/pkg/authn"
|
"github.com/docker/attest/pkg/oci"
|
||||||
"github.com/google/go-containerregistry/pkg/crane"
|
"github.com/google/go-containerregistry/pkg/crane"
|
||||||
"github.com/google/go-containerregistry/pkg/name"
|
"github.com/google/go-containerregistry/pkg/name"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/empty"
|
"github.com/google/go-containerregistry/pkg/v1/empty"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/google"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/layout"
|
"github.com/google/go-containerregistry/pkg/v1/layout"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/mutate"
|
"github.com/google/go-containerregistry/pkg/v1/mutate"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||||
@@ -371,22 +368,14 @@ func LoadRegistryTestData(t *testing.T, registry *url.URL, path string) {
|
|||||||
TARGETS_REPO := "tuf-targets"
|
TARGETS_REPO := "tuf-targets"
|
||||||
DELEGATED_ROLE := "test-role"
|
DELEGATED_ROLE := "test-role"
|
||||||
|
|
||||||
// Create a multi-keychain that will use the default Docker, Google, ECR or ACR keychain
|
|
||||||
keychain := authn.NewMultiKeychain(
|
|
||||||
authn.DefaultKeychain,
|
|
||||||
google.Keychain,
|
|
||||||
authn.NewKeychainFromHelper(ecr.NewECRHelper()),
|
|
||||||
authn.NewKeychainFromHelper(acr.NewACRCredentialsHelper()),
|
|
||||||
)
|
|
||||||
|
|
||||||
// push top-level metadata -> metadata:latest
|
// push top-level metadata -> metadata:latest
|
||||||
err := LoadMetadata(filepath.Join(path, "metadata"), registry.Host, METADATA_REPO, METADATA_TAG, keychain)
|
err := LoadMetadata(filepath.Join(path, "metadata"), registry.Host, METADATA_REPO, METADATA_TAG)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// push delegated metadata -> metadata:<DELEGATED_ROLE>
|
// push delegated metadata -> metadata:<DELEGATED_ROLE>
|
||||||
err = LoadMetadata(filepath.Join(path, "metadata", DELEGATED_ROLE), registry.Host, METADATA_REPO, DELEGATED_ROLE, keychain)
|
err = LoadMetadata(filepath.Join(path, "metadata", DELEGATED_ROLE), registry.Host, METADATA_REPO, DELEGATED_ROLE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -418,13 +407,13 @@ func LoadRegistryTestData(t *testing.T, registry *url.URL, path string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
err = remote.Write(ref, img, remote.WithAuthFromKeychain(keychain))
|
err = remote.Write(ref, img, oci.MultiKeychainOption())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
} else if len(mf.Manifests) > 1 {
|
} else if len(mf.Manifests) > 1 {
|
||||||
// delegated target
|
// delegated target
|
||||||
err = remote.WriteIndex(ref, tIdx, remote.WithAuthFromKeychain(keychain))
|
err = remote.WriteIndex(ref, tIdx, oci.MultiKeychainOption())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -435,7 +424,7 @@ func LoadRegistryTestData(t *testing.T, registry *url.URL, path string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LoadMetadata loads TUF metadata from a local path and pushes to a registry
|
// LoadMetadata loads TUF metadata from a local path and pushes to a registry
|
||||||
func LoadMetadata(path, host, repo, tag string, keychain authn.Keychain) error {
|
func LoadMetadata(path, host, repo, tag string) error {
|
||||||
mIdx, err := layout.ImageIndexFromPath(path)
|
mIdx, err := layout.ImageIndexFromPath(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -452,5 +441,5 @@ func LoadMetadata(path, host, repo, tag string, keychain authn.Keychain) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return remote.Write(ref, img, remote.WithAuthFromKeychain(keychain))
|
return remote.Write(ref, img, oci.MultiKeychainOption())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user