1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

fix: Allow images to be pulled from insecure registry when allowInsecureRegistry flag is set to true (#10934) (#11243)

* fix: Allow images to be pulled from insecure registry when allowInsecureRegistry flag is set to true (#10934)

Signed-off-by: Pradeep Lakshmi Narasimha <pradeep.vaishnav4@gmail.com>

* Update pkg/registryclient/client.go

Signed-off-by: Vishal Choudhary <vishal.chdhry.work@gmail.com>

---------

Signed-off-by: Pradeep Lakshmi Narasimha <pradeep.vaishnav4@gmail.com>
Signed-off-by: Vishal Choudhary <vishal.chdhry.work@gmail.com>
Co-authored-by: Vishal Choudhary <vishal.choudhary@nirmata.com>
Co-authored-by: Vishal Choudhary <vishal.chdhry.work@gmail.com>
This commit is contained in:
Pradeep Lakshmi Narasimha 2024-10-07 20:59:12 +05:30 committed by GitHub
parent bd3a6f066b
commit 373f942ea9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 54 additions and 21 deletions

View file

@ -60,7 +60,8 @@ func (v *cosignVerifier) VerifySignature(ctx context.Context, opts images.Option
return &images.Response{Digest: results[0].Desc.Digest.String()}, nil return &images.Response{Digest: results[0].Desc.Digest.String()}, nil
} }
ref, err := name.ParseReference(opts.ImageRef) nameOpts := opts.Client.NameOptions()
ref, err := name.ParseReference(opts.ImageRef, nameOpts...)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse image %s", opts.ImageRef) return nil, fmt.Errorf("failed to parse image %s", opts.ImageRef)
} }
@ -301,12 +302,13 @@ func (v *cosignVerifier) FetchAttestations(ctx context.Context, opts images.Opti
return nil, err return nil, err
} }
nameOpts := opts.Client.NameOptions()
signatures, bundleVerified, err := tracing.ChildSpan3( signatures, bundleVerified, err := tracing.ChildSpan3(
ctx, ctx,
"", "",
"VERIFY IMG ATTESTATIONS", "VERIFY IMG ATTESTATIONS",
func(ctx context.Context, span trace.Span) (checkedAttestations []oci.Signature, bundleVerified bool, err error) { func(ctx context.Context, span trace.Span) (checkedAttestations []oci.Signature, bundleVerified bool, err error) {
ref, err := name.ParseReference(opts.ImageRef) ref, err := name.ParseReference(opts.ImageRef, nameOpts...)
if err != nil { if err != nil {
return nil, false, fmt.Errorf("failed to parse image: %w", err) return nil, false, fmt.Errorf("failed to parse image: %w", err)
} }

View file

@ -38,7 +38,8 @@ type Bundle struct {
} }
func verifyBundleAndFetchAttestations(ctx context.Context, opts images.Options) ([]*VerificationResult, error) { func verifyBundleAndFetchAttestations(ctx context.Context, opts images.Options) ([]*VerificationResult, error) {
ref, err := name.ParseReference(opts.ImageRef) nameOpts := opts.Client.NameOptions()
ref, err := name.ParseReference(opts.ImageRef, nameOpts...)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to parse image reference: %v", opts.ImageRef) return nil, errors.Wrapf(err, "failed to parse image reference: %v", opts.ImageRef)
} }

View file

@ -48,7 +48,8 @@ func TestSigstoreBundleSignatureResponse(t *testing.T) {
response, err := verifier.VerifySignature(context.TODO(), opts) response, err := verifier.VerifySignature(context.TODO(), opts)
assert.NilError(t, err) assert.NilError(t, err)
ref, err := name.ParseReference(opts.ImageRef) nameOpts := rc.NameOptions()
ref, err := name.ParseReference(opts.ImageRef, nameOpts...)
assert.NilError(t, err) assert.NilError(t, err)
desc, err := remote.Head(ref) desc, err := remote.Head(ref)
@ -74,7 +75,8 @@ func TestSigstoreBundleAttestation(t *testing.T) {
response, err := verifier.FetchAttestations(context.TODO(), opts) response, err := verifier.FetchAttestations(context.TODO(), opts)
assert.NilError(t, err) assert.NilError(t, err)
ref, err := name.ParseReference(opts.ImageRef) nameOpts := rc.NameOptions()
ref, err := name.ParseReference(opts.ImageRef, nameOpts...)
assert.NilError(t, err) assert.NilError(t, err)
desc, err := remote.Head(ref) desc, err := remote.Head(ref)

View file

@ -25,7 +25,8 @@ func (a *rclientAdapter) ForRef(ctx context.Context, ref string) (*engineapi.Ima
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch image descriptor: %s, error: %v", ref, err) return nil, fmt.Errorf("failed to fetch image descriptor: %s, error: %v", ref, err)
} }
parsedRef, err := name.ParseReference(ref) nameOpts := a.Client.NameOptions()
parsedRef, err := name.ParseReference(ref, nameOpts...)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse image reference: %s, error: %v", ref, err) return nil, fmt.Errorf("failed to parse image reference: %s, error: %v", ref, err)
} }

View file

@ -5,6 +5,7 @@ import (
"io" "io"
"github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
gcrremote "github.com/google/go-containerregistry/pkg/v1/remote" gcrremote "github.com/google/go-containerregistry/pkg/v1/remote"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -62,6 +63,7 @@ type KeychainClient interface {
type RemoteClient interface { type RemoteClient interface {
Options(context.Context) ([]gcrremote.Option, error) Options(context.Context) ([]gcrremote.Option, error)
NameOptions() []name.Option
} }
type RegistryClient interface { type RegistryClient interface {

View file

@ -4,6 +4,7 @@ import (
"context" "context"
"github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
gcrremote "github.com/google/go-containerregistry/pkg/v1/remote" gcrremote "github.com/google/go-containerregistry/pkg/v1/remote"
) )
@ -18,6 +19,7 @@ type ImageVerifier interface {
type Client interface { type Client interface {
Keychain() authn.Keychain Keychain() authn.Keychain
Options(context.Context) ([]gcrremote.Option, error) Options(context.Context) ([]gcrremote.Option, error)
NameOptions() []name.Option
} }
type Options struct { type Options struct {

View file

@ -136,7 +136,8 @@ func (v *notaryVerifier) verifyOutcomes(outcomes []*notation.VerificationOutcome
func (v *notaryVerifier) FetchAttestations(ctx context.Context, opts images.Options) (*images.Response, error) { func (v *notaryVerifier) FetchAttestations(ctx context.Context, opts images.Options) (*images.Response, error) {
v.log.V(2).Info("fetching attestations", "reference", opts.ImageRef, "opts", opts) v.log.V(2).Info("fetching attestations", "reference", opts.ImageRef, "opts", opts)
ref, err := name.ParseReference(opts.ImageRef) nameOpts := opts.Client.NameOptions()
ref, err := name.ParseReference(opts.ImageRef, nameOpts...)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to parse image reference: %s", opts.ImageRef) return nil, errors.Wrapf(err, "failed to parse image reference: %s", opts.ImageRef)
} }
@ -191,7 +192,7 @@ func (v *notaryVerifier) FetchAttestations(ctx context.Context, opts images.Opti
} }
v.log.V(4).Info("extracting statements", "desc", referrer, "repo", ref) v.log.V(4).Info("extracting statements", "desc", referrer, "repo", ref)
statements, err = extractStatements(ctx, ref, referrer, remoteOpts) statements, err = extractStatements(ctx, ref, referrer, remoteOpts, nameOpts)
if err != nil { if err != nil {
msg := err.Error() msg := err.Error()
v.log.V(4).Info("failed to extract statements %s", "err", msg) v.log.V(4).Info("failed to extract statements %s", "err", msg)
@ -272,9 +273,9 @@ func verifyAttestators(ctx context.Context, v *notaryVerifier, ref name.Referenc
return targetDesc, nil return targetDesc, nil
} }
func extractStatements(ctx context.Context, repoRef name.Reference, desc v1.Descriptor, remoteOpts []gcrremote.Option) ([]map[string]interface{}, error) { func extractStatements(ctx context.Context, repoRef name.Reference, desc v1.Descriptor, remoteOpts []gcrremote.Option, nameOpts []name.Option) ([]map[string]interface{}, error) {
statements := make([]map[string]interface{}, 0) statements := make([]map[string]interface{}, 0)
data, err := extractStatement(ctx, repoRef, desc, remoteOpts) data, err := extractStatement(ctx, repoRef, desc, remoteOpts, nameOpts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -286,9 +287,9 @@ func extractStatements(ctx context.Context, repoRef name.Reference, desc v1.Desc
return statements, nil return statements, nil
} }
func extractStatement(ctx context.Context, repoRef name.Reference, desc v1.Descriptor, remoteOpts []gcrremote.Option) (map[string]interface{}, error) { func extractStatement(ctx context.Context, repoRef name.Reference, desc v1.Descriptor, remoteOpts []gcrremote.Option, nameOpts []name.Option) (map[string]interface{}, error) {
refStr := repoRef.Context().RegistryStr() + "/" + repoRef.Context().RepositoryStr() + "@" + desc.Digest.String() refStr := repoRef.Context().RegistryStr() + "/" + repoRef.Context().RepositoryStr() + "@" + desc.Digest.String()
ref, err := name.ParseReference(refStr) ref, err := name.ParseReference(refStr, nameOpts...)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to parse image reference: %s", refStr) return nil, errors.Wrapf(err, "failed to parse image reference: %s", refStr)
} }

View file

@ -47,7 +47,7 @@ func TestExtractStatements(t *testing.T) {
for _, referrer := range referrersDescs.Manifests { for _, referrer := range referrersDescs.Manifests {
if referrer.ArtifactType == "application/vnd.cncf.notary.signature" { if referrer.ArtifactType == "application/vnd.cncf.notary.signature" {
statements, err := extractStatements(context.Background(), ref, referrer, nil) statements, err := extractStatements(context.Background(), ref, referrer, nil, nil)
assert.NilError(t, err) assert.NilError(t, err)
assert.Assert(t, len(statements) == 1) assert.Assert(t, len(statements) == 1)
assert.Assert(t, statements[0]["type"] == referrer.ArtifactType) assert.Assert(t, statements[0]["type"] == referrer.ArtifactType)

View file

@ -20,7 +20,8 @@ type parsedReference struct {
} }
func parseReferenceCrane(ctx context.Context, ref string, registryClient images.Client) (*parsedReference, error) { func parseReferenceCrane(ctx context.Context, ref string, registryClient images.Client) (*parsedReference, error) {
nameRef, err := name.ParseReference(ref) nameOpts := registryClient.NameOptions()
nameRef, err := name.ParseReference(ref, nameOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -36,7 +37,7 @@ func parseReferenceCrane(ctx context.Context, ref string, registryClient images.
} }
if !isDigestReference(ref) { if !isDigestReference(ref) {
nameRef, err = name.ParseReference(GetReferenceFromDescriptor(v1ToOciSpecDescriptor(*desc), nameRef)) nameRef, err = name.ParseReference(GetReferenceFromDescriptor(v1ToOciSpecDescriptor(*desc), nameRef), nameOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -58,17 +58,22 @@ type Client interface {
// Options returns remote.Option configuration for the client. // Options returns remote.Option configuration for the client.
Options(context.Context) ([]gcrremote.Option, error) Options(context.Context) ([]gcrremote.Option, error)
// NameOptions returns name.Option configuration for the client.
NameOptions() []name.Option
} }
type client struct { type client struct {
keychain authn.Keychain keychain authn.Keychain
transport http.RoundTripper transport http.RoundTripper
allowInsecureRegistry bool
} }
type config struct { type config struct {
keychain []authn.Keychain keychain []authn.Keychain
transport *http.Transport transport *http.Transport
tracing bool tracing bool
allowInsecureRegistry bool
} }
// Option is an option to initialize registry client. // Option is an option to initialize registry client.
@ -94,6 +99,9 @@ func New(options ...Option) (Client, error) {
if cfg.tracing { if cfg.tracing {
c.transport = tracing.Transport(cfg.transport, otelhttp.WithFilter(tracing.RequestFilterIsInSpan)) c.transport = tracing.Transport(cfg.transport, otelhttp.WithFilter(tracing.RequestFilterIsInSpan))
} }
if cfg.allowInsecureRegistry {
c.allowInsecureRegistry = true
}
return c, nil return c, nil
} }
@ -147,6 +155,7 @@ func WithCredentialProviders(credentialProviders ...string) Option {
func WithAllowInsecureRegistry() Option { func WithAllowInsecureRegistry() Option {
return func(c *config) error { return func(c *config) error {
c.transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint:gosec c.transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint:gosec
c.allowInsecureRegistry = true
return nil return nil
} }
} }
@ -191,10 +200,22 @@ func (c *client) Options(ctx context.Context) ([]gcrremote.Option, error) {
return opts, nil return opts, nil
} }
// NameOptions returns name.Option config parameters for the client
func (c *client) NameOptions() []name.Option {
nameOpts := []name.Option{}
if c.allowInsecureRegistry {
nameOpts = append(nameOpts, name.Insecure)
}
return nameOpts
}
// FetchImageDescriptor fetches Descriptor from registry with given imageRef // FetchImageDescriptor fetches Descriptor from registry with given imageRef
// and provides access to metadata about remote artifact. // and provides access to metadata about remote artifact.
func (c *client) FetchImageDescriptor(ctx context.Context, imageRef string) (*gcrremote.Descriptor, error) { func (c *client) FetchImageDescriptor(ctx context.Context, imageRef string) (*gcrremote.Descriptor, error) {
parsedRef, err := name.ParseReference(imageRef) nameOpts := c.NameOptions()
parsedRef, err := name.ParseReference(imageRef, nameOpts...)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse image reference: %s, error: %v", imageRef, err) return nil, fmt.Errorf("failed to parse image reference: %s, error: %v", imageRef, err)
} }