diff --git a/cmd/cli/kubectl-kyverno/commands/oci/command.go b/cmd/cli/kubectl-kyverno/commands/oci/command.go index 11c4c1b000..45e281d1bf 100644 --- a/cmd/cli/kubectl-kyverno/commands/oci/command.go +++ b/cmd/cli/kubectl-kyverno/commands/oci/command.go @@ -1,8 +1,12 @@ package oci import ( + "io" + + ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/authn/github" + "github.com/google/go-containerregistry/pkg/v1/google" "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/command" "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/commands/oci/pull" "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/commands/oci/push" @@ -14,8 +18,8 @@ func Command() *cobra.Command { keychain := authn.NewMultiKeychain( authn.DefaultKeychain, github.Keychain, - registryclient.AWSKeychain, - registryclient.GCPKeychain, + authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(io.Discard))), + google.Keychain, registryclient.AzureKeychain, ) cmd := &cobra.Command{ diff --git a/cmd/cli/kubectl-kyverno/commands/oci/pull/command_test.go b/cmd/cli/kubectl-kyverno/commands/oci/pull/command_test.go index 056d4ea395..b988ee735f 100644 --- a/cmd/cli/kubectl-kyverno/commands/oci/pull/command_test.go +++ b/cmd/cli/kubectl-kyverno/commands/oci/pull/command_test.go @@ -6,8 +6,10 @@ import ( "strings" "testing" + ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/authn/github" + "github.com/google/go-containerregistry/pkg/v1/google" "github.com/kyverno/kyverno/pkg/registryclient" "github.com/stretchr/testify/assert" ) @@ -15,8 +17,8 @@ import ( var keychain = authn.NewMultiKeychain( authn.DefaultKeychain, github.Keychain, - registryclient.AWSKeychain, - registryclient.GCPKeychain, + authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(io.Discard))), + google.Keychain, registryclient.AzureKeychain, ) diff --git a/cmd/cli/kubectl-kyverno/commands/oci/push/command_test.go b/cmd/cli/kubectl-kyverno/commands/oci/push/command_test.go index bf08d09c3e..ad6eeb9c73 100644 --- a/cmd/cli/kubectl-kyverno/commands/oci/push/command_test.go +++ b/cmd/cli/kubectl-kyverno/commands/oci/push/command_test.go @@ -6,8 +6,10 @@ import ( "strings" "testing" + ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/authn/github" + "github.com/google/go-containerregistry/pkg/v1/google" "github.com/kyverno/kyverno/pkg/registryclient" "github.com/stretchr/testify/assert" ) @@ -15,8 +17,8 @@ import ( var keychain = authn.NewMultiKeychain( authn.DefaultKeychain, github.Keychain, - registryclient.AWSKeychain, - registryclient.GCPKeychain, + authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(io.Discard))), + google.Keychain, registryclient.AzureKeychain, ) diff --git a/go.mod b/go.mod index 1a024bf890..8c4a284fb5 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/Masterminds/sprig/v3 v3.2.3 github.com/aquilax/truncate v1.0.0 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 + github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20240116161626-88cfadc80e8f github.com/blang/semver/v4 v4.0.0 github.com/cenkalti/backoff v2.2.1+incompatible github.com/cyphar/filepath-securejoin v0.2.4 @@ -155,7 +156,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect github.com/aws/smithy-go v1.19.0 // indirect - github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20240116161626-88cfadc80e8f // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/buildkite/agent/v3 v3.62.0 // indirect diff --git a/pkg/registryclient/authn.go b/pkg/registryclient/authn.go index 2986dc69de..0a0397a33f 100644 --- a/pkg/registryclient/authn.go +++ b/pkg/registryclient/authn.go @@ -4,31 +4,17 @@ import ( "context" "net/url" "regexp" - "strings" - "github.com/fluxcd/pkg/oci/auth/aws" "github.com/fluxcd/pkg/oci/auth/azure" - "github.com/fluxcd/pkg/oci/auth/gcp" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" corev1listers "k8s.io/client-go/listers/core/v1" ) -var ( - acrRE = regexp.MustCompile(`.*\.azurecr\.io|.*\.azurecr\.cn|.*\.azurecr\.de|.*\.azurecr\.us`) - ecrPattern = regexp.MustCompile(`(^[a-zA-Z0-9][a-zA-Z0-9-_]*)\.dkr\.ecr(-fips)?\.([a-zA-Z0-9][a-zA-Z0-9-_]*)\.amazonaws\.com(\.cn)?$`) -) +var acrRE = regexp.MustCompile(`.*\.azurecr\.io|.*\.azurecr\.cn|.*\.azurecr\.de|.*\.azurecr\.us`) const ( - mcrHostname = "mcr.microsoft.com" - tokenUsername = "" - - ServiceECR = "ecr" - ServiceECRPublic = "ecr-public" - proxyEndpointScheme = "https://" - programName = "docker-credential-ecr-login" - ecrPublicName = "public.ecr.aws" - ecrPublicEndpoint = proxyEndpointScheme + ecrPublicName + mcrHostname = "mcr.microsoft.com" ) type autoRefreshSecrets struct { @@ -92,54 +78,3 @@ func isACRRegistry(input string) bool { matches := acrRE.FindStringSubmatch(serverURL.Hostname()) return len(matches) != 0 } - -type awskeychain struct{} - -var AWSKeychain authn.Keychain = awskeychain{} - -func (awskeychain) Resolve(resource authn.Resource) (authn.Authenticator, error) { - if !isAWSRegistry(resource.RegistryStr()) { - return authn.Anonymous, nil - } - awsClient := aws.NewClient() - auth, err := awsClient.Login(context.TODO(), true, resource.String()) - if err != nil { - return authn.Anonymous, nil - } - return auth, nil -} - -func isAWSRegistry(input string) bool { - input = strings.TrimPrefix(input, proxyEndpointScheme) - serverURL, err := url.Parse(proxyEndpointScheme + input) - if err != nil { - return false - } - if serverURL.Hostname() == ecrPublicName { - return true - } - matches := ecrPattern.FindStringSubmatch(serverURL.Hostname()) - return len(matches) >= 3 -} - -type gcpkeychain struct{} - -var GCPKeychain authn.Keychain = gcpkeychain{} - -func (gcpkeychain) Resolve(resource authn.Resource) (authn.Authenticator, error) { - if !gcp.ValidHost(resource.RegistryStr()) { - return authn.Anonymous, nil - } - - ref, err := name.ParseReference(resource.String()) - if err != nil { - return authn.Anonymous, nil - } - - gcpClient := gcp.NewClient() - auth, err := gcpClient.Login(context.TODO(), true, resource.String(), ref) - if err != nil { - return authn.Anonymous, nil - } - return auth, nil -} diff --git a/pkg/registryclient/client.go b/pkg/registryclient/client.go index 5d241776ee..fcdab997ad 100644 --- a/pkg/registryclient/client.go +++ b/pkg/registryclient/client.go @@ -4,14 +4,17 @@ import ( "context" "crypto/tls" "fmt" + "io" "net" "net/http" "runtime" "time" + ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/authn/github" "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/google" gcrremote "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/kyverno/kyverno/pkg/tracing" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" @@ -124,10 +127,10 @@ func WithCredentialProviders(credentialProviders ...string) Option { chains = append(chains, authn.DefaultKeychain) } if helpers.Has("google") { - chains = append(chains, GCPKeychain) + chains = append(chains, google.Keychain) } if helpers.Has("amazon") { - chains = append(chains, AWSKeychain) + chains = append(chains, authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(io.Discard)))) } if helpers.Has("azure") { chains = append(chains, AzureKeychain)