1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 07:26:55 +00:00

refactor: remove manual keychain refresh from client (#7806)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-07-11 15:19:44 +02:00 committed by GitHub
parent dfceb4bf82
commit a135076661
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 49 additions and 52 deletions

View file

@ -27,7 +27,7 @@ func setupRegistryClient(ctx context.Context, logger logr.Logger, client kuberne
}
secrets := strings.Split(imagePullSecrets, ",")
if imagePullSecrets != "" && len(secrets) > 0 {
registryOptions = append(registryOptions, registryclient.WithKeychainPullSecrets(ctx, secretLister, secrets...))
registryOptions = append(registryOptions, registryclient.WithKeychainPullSecrets(secretLister, secrets...))
}
if allowInsecureRegistry {
registryOptions = append(registryOptions, registryclient.WithAllowInsecureRegistry())

View file

@ -54,7 +54,6 @@ type ImageDataClient interface {
type KeychainClient interface {
Keychain() authn.Keychain
RefreshKeychainPullSecrets(ctx context.Context) error
}
type CosignClient interface {

View file

@ -38,7 +38,7 @@ func (f *registryClientFactory) GetClient(ctx context.Context, creds *kyvernov1.
registryOptions = append(registryOptions, registryclient.WithCredentialProviders(providers...))
}
if len(creds.Secrets) > 0 {
registryOptions = append(registryOptions, registryclient.WithKeychainPullSecrets(ctx, f.secretsLister, creds.Secrets...))
registryOptions = append(registryOptions, registryclient.WithKeychainPullSecrets(f.secretsLister, creds.Secrets...))
}
client, err := registryclient.New(registryOptions...)
if err != nil {

View file

@ -17,7 +17,6 @@ type ImageVerifier interface {
type Client interface {
Keychain() authn.Keychain
RefreshKeychainPullSecrets(ctx context.Context) error
BuildRemoteOption(context.Context) remote.Option
}

View file

@ -79,11 +79,6 @@ func getAuthenticator(ctx context.Context, ref string, registryClient images.Cli
if err != nil {
return nil, errors.Wrapf(err, "failed to parse registry reference %s", ref)
}
if err := registryClient.RefreshKeychainPullSecrets(ctx); err != nil {
return nil, errors.Wrapf(err, "failed to refresh image pull secrets")
}
authn, err := registryClient.Keychain().Resolve(&imageResource{parsedRef})
if err != nil {
return nil, errors.Wrapf(err, "failed to resolve auth for %s", parsedRef.String())

View file

@ -0,0 +1,26 @@
package registryclient
import (
"github.com/google/go-containerregistry/pkg/authn"
corev1listers "k8s.io/client-go/listers/core/v1"
)
type autoRefreshSecrets struct {
lister corev1listers.SecretNamespaceLister
imagePullSecrets []string
}
func NewAutoRefreshSecretsKeychain(lister corev1listers.SecretNamespaceLister, imagePullSecrets ...string) (authn.Keychain, error) {
return &autoRefreshSecrets{
lister: lister,
imagePullSecrets: imagePullSecrets,
}, nil
}
func (kc *autoRefreshSecrets) Resolve(resource authn.Resource) (authn.Authenticator, error) {
inner, err := generateKeychainForPullSecrets(kc.lister, kc.imagePullSecrets...)
if err != nil {
return nil, err
}
return inner.Resolve(resource)
}

View file

@ -24,7 +24,7 @@ import (
)
var (
baseKeychain = authn.NewMultiKeychain(
defaultKeychain = authn.NewMultiKeychain(
authn.DefaultKeychain,
google.Keychain,
authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(io.Discard))),
@ -62,22 +62,17 @@ type Client interface {
// BuildRemoteOption builds remote.Option based on client.
BuildRemoteOption(context.Context) remote.Option
// RefreshKeychainPullSecrets loads fresh data from pull secrets (if non-empty) and updates Keychain.
RefreshKeychainPullSecrets(ctx context.Context) error
}
type client struct {
keychain authn.Keychain
transport http.RoundTripper
pullSecretRefresher func(context.Context, *client) error
keychain authn.Keychain
transport http.RoundTripper
}
type config struct {
keychain authn.Keychain
transport *http.Transport
pullSecretRefresher func(context.Context, *client) error
tracing bool
keychain []authn.Keychain
transport *http.Transport
tracing bool
}
// Option is an option to initialize registry client.
@ -86,7 +81,6 @@ type Option = func(*config) error
// New creates a new Client with options
func New(options ...Option) (Client, error) {
cfg := &config{
keychain: baseKeychain,
transport: defaultTransport,
}
for _, opt := range options {
@ -95,9 +89,11 @@ func New(options ...Option) (Client, error) {
}
}
c := &client{
keychain: cfg.keychain,
transport: cfg.transport,
pullSecretRefresher: cfg.pullSecretRefresher,
keychain: defaultKeychain,
transport: cfg.transport,
}
if len(cfg.keychain) > 0 {
c.keychain = authn.NewMultiKeychain(cfg.keychain...)
}
if cfg.tracing {
c.transport = tracing.Transport(cfg.transport, otelhttp.WithFilter(tracing.RequestFilterIsInSpan))
@ -115,19 +111,13 @@ 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(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(
conf.keychain,
freshKeychain,
)
return nil
func WithKeychainPullSecrets(lister corev1listers.SecretNamespaceLister, imagePullSecrets ...string) Option {
return func(c *config) error {
kc, err := NewAutoRefreshSecretsKeychain(lister, imagePullSecrets...)
if err != nil {
return err
}
c.keychain = append(c.keychain, kc)
return nil
}
}
@ -152,7 +142,7 @@ func WithCredentialProviders(credentialProviders ...string) Option {
if helpers.Has("github") {
chains = append(chains, github.Keychain)
}
c.keychain = authn.NewMultiKeychain(chains...)
c.keychain = append(c.keychain, chains...)
return nil
}
}
@ -168,8 +158,7 @@ func WithAllowInsecureRegistry() Option {
// WithLocalKeychain provides initialize keychain with the default local keychain.
func WithLocalKeychain() Option {
return func(c *config) error {
c.pullSecretRefresher = nil
c.keychain = authn.DefaultKeychain
c.keychain = append(c.keychain, authn.DefaultKeychain)
return nil
}
}
@ -194,9 +183,6 @@ func (c *client) BuildRemoteOption(ctx context.Context) remote.Option {
// FetchImageDescriptor fetches Descriptor from registry with given imageRef
// and provides access to metadata about remote artifact.
func (c *client) FetchImageDescriptor(ctx context.Context, imageRef string) (*gcrremote.Descriptor, error) {
if err := c.RefreshKeychainPullSecrets(ctx); err != nil {
return nil, fmt.Errorf("failed to refresh image pull secrets, error: %v", err)
}
parsedRef, err := name.ParseReference(imageRef)
if err != nil {
return nil, fmt.Errorf("failed to parse image reference: %s, error: %v", imageRef, err)
@ -208,14 +194,6 @@ func (c *client) FetchImageDescriptor(ctx context.Context, imageRef string) (*gc
return desc, nil
}
// refreshKeychainPullSecrets loads fresh data from pull secrets (if non-empty) and updates Keychain.
func (c *client) RefreshKeychainPullSecrets(ctx context.Context) error {
if c.pullSecretRefresher == nil {
return nil
}
return c.pullSecretRefresher(ctx, c)
}
func (c *client) Keychain() authn.Keychain {
return c.keychain
}

View file

@ -11,7 +11,7 @@ import (
)
// generateKeychainForPullSecrets generates keychain by fetching secrets data from imagePullSecrets.
func generateKeychainForPullSecrets(ctx context.Context, lister corev1listers.SecretNamespaceLister, imagePullSecrets ...string) (authn.Keychain, error) {
func generateKeychainForPullSecrets(lister corev1listers.SecretNamespaceLister, imagePullSecrets ...string) (authn.Keychain, error) {
var secrets []corev1.Secret
for _, imagePullSecret := range imagePullSecrets {
secret, err := lister.Get(imagePullSecret)
@ -21,5 +21,5 @@ func generateKeychainForPullSecrets(ctx context.Context, lister corev1listers.Se
return nil, err
}
}
return kauth.NewFromPullSecrets(ctx, secrets)
return kauth.NewFromPullSecrets(context.TODO(), secrets)
}