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:
parent
dfceb4bf82
commit
a135076661
8 changed files with 49 additions and 52 deletions
|
@ -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())
|
||||
|
|
|
@ -54,7 +54,6 @@ type ImageDataClient interface {
|
|||
|
||||
type KeychainClient interface {
|
||||
Keychain() authn.Keychain
|
||||
RefreshKeychainPullSecrets(ctx context.Context) error
|
||||
}
|
||||
|
||||
type CosignClient interface {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -17,7 +17,6 @@ type ImageVerifier interface {
|
|||
|
||||
type Client interface {
|
||||
Keychain() authn.Keychain
|
||||
RefreshKeychainPullSecrets(ctx context.Context) error
|
||||
BuildRemoteOption(context.Context) remote.Option
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
26
pkg/registryclient/authn.go
Normal file
26
pkg/registryclient/authn.go
Normal 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)
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue