diff --git a/cmd/internal/flag.go b/cmd/internal/flag.go index 73cc888b68..107b39e70f 100644 --- a/cmd/internal/flag.go +++ b/cmd/internal/flag.go @@ -39,6 +39,7 @@ var ( // registry client imagePullSecrets string allowInsecureRegistry bool + enableHelpers string // leader election leaderElectionRetryPeriod time.Duration ) @@ -92,6 +93,7 @@ func initCosignFlags() { func initRegistryClientFlags() { flag.BoolVar(&allowInsecureRegistry, "allowInsecureRegistry", false, "Whether to allow insecure connections to registries. Don't use this for anything but testing.") flag.StringVar(&imagePullSecrets, "imagePullSecrets", "", "Secret resource names for image registry access credentials.") + flag.StringVar(&enableHelpers, "enableHelpers", "", "Credential helpers to enable (default,google,amazon,azure,github), all will be enabled if empty.") } func initLeaderElectionFlags() { diff --git a/cmd/internal/registry.go b/cmd/internal/registry.go index 8eb21ffe71..f8f471fce5 100644 --- a/cmd/internal/registry.go +++ b/cmd/internal/registry.go @@ -31,6 +31,9 @@ func setupRegistryClient(ctx context.Context, logger logr.Logger, client kuberne if allowInsecureRegistry { registryOptions = append(registryOptions, registryclient.WithAllowInsecureRegistry()) } + if len(enableHelpers) > 0 { + registryOptions = append(registryOptions, registryclient.WithCredentialHelpers(strings.Split(enableHelpers, ",")...)) + } registryClient, err := registryclient.New(registryOptions...) checkError(logger, err, "failed to create registry client") return registryClient diff --git a/pkg/registryclient/client.go b/pkg/registryclient/client.go index 3936f5a15c..428579654d 100644 --- a/pkg/registryclient/client.go +++ b/pkg/registryclient/client.go @@ -19,6 +19,7 @@ import ( "github.com/kyverno/kyverno/pkg/tracing" "github.com/sigstore/cosign/pkg/oci/remote" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" + "k8s.io/apimachinery/pkg/util/sets" corev1listers "k8s.io/client-go/listers/core/v1" ) @@ -115,14 +116,14 @@ func NewOrDie(options ...Option) Client { // WithKeychainPullSecrets provides initialize registry client option that allows to use pull secrets. func WithKeychainPullSecrets(ctx context.Context, lister corev1listers.SecretNamespaceLister, imagePullSecrets ...string) Option { - return func(c *config) error { - c.pullSecretRefresher = func(ctx context.Context, c *client) error { + return func(conf *config) error { + conf.pullSecretRefresher = func(ctx context.Context, c *client) error { freshKeychain, err := generateKeychainForPullSecrets(ctx, lister, imagePullSecrets...) if err != nil { return err } c.keychain = authn.NewMultiKeychain( - baseKeychain, + conf.keychain, freshKeychain, ) return nil @@ -131,6 +132,31 @@ func WithKeychainPullSecrets(ctx context.Context, lister corev1listers.SecretNam } } +// WithKeychainPullSecrets provides initialize registry client option that allows to use insecure registries. +func WithCredentialHelpers(credentialHelpers ...string) Option { + return func(c *config) error { + var chains []authn.Keychain + helpers := sets.New(credentialHelpers...) + if helpers.Has("default") { + chains = append(chains, authn.DefaultKeychain) + } + if helpers.Has("google") { + chains = append(chains, google.Keychain) + } + if helpers.Has("amazon") { + chains = append(chains, authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(io.Discard)))) + } + if helpers.Has("azure") { + chains = append(chains, authn.NewKeychainFromHelper(credhelper.NewACRCredentialsHelper())) + } + if helpers.Has("github") { + chains = append(chains, github.Keychain) + } + c.keychain = authn.NewMultiKeychain(chains...) + return nil + } +} + // WithKeychainPullSecrets provides initialize registry client option that allows to use insecure registries. func WithAllowInsecureRegistry() Option { return func(c *config) error {