From 7dcfe53fbc95ebf279e66198c6518ce6cec5ea27 Mon Sep 17 00:00:00 2001 From: Bryce Palmer Date: Thu, 26 Oct 2023 15:02:58 -0400 Subject: [PATCH] (feature): add skip-tls-verify option for image sources (#201) * (feature): add skip-tls-verify option for image sources Signed-off-by: Bryce Palmer * re-generate manifests Signed-off-by: Bryce Palmer --------- Signed-off-by: Bryce Palmer --- Makefile | 6 +-- api/core/v1alpha1/catalog_types.go | 6 +++ ...atalogd.operatorframework.io_catalogs.yaml | 7 ++++ config/e2e/kustomization.yaml | 30 -------------- internal/source/image_registry_client.go | 11 +++++ internal/source/image_registry_client_test.go | 34 +++++++++++++++ test/e2e/unpack_test.go | 3 +- test/tools/imageregistry/imagebuilder.yaml | 14 +------ test/tools/imageregistry/registry.sh | 41 +------------------ 9 files changed, 66 insertions(+), 86 deletions(-) delete mode 100644 config/e2e/kustomization.yaml diff --git a/Makefile b/Makefile index fb58cb25..b725d1f7 100644 --- a/Makefile +++ b/Makefile @@ -67,8 +67,7 @@ test-e2e: $(GINKGO) ## Run the e2e tests $(GINKGO) --tags $(GO_BUILD_TAGS) $(E2E_FLAGS) -trace -progress $(FOCUS) test/e2e e2e: KIND_CLUSTER_NAME=catalogd-e2e -e2e: DEPLOY_TARGET=e2e -e2e: kind-cluster image-registry install test-e2e kind-cluster-cleanup ## Run e2e test suite on local kind cluster +e2e: run image-registry test-e2e kind-cluster-cleanup ## Run e2e test suite on local kind cluster image-registry: ## Setup in-cluster image registry ./test/tools/imageregistry/registry.sh @@ -154,11 +153,10 @@ kind-load: $(KIND) ## Load the built images onto the local cluster .PHONY: install install: build-container kind-load deploy wait ## Install local catalogd -DEPLOY_TARGET ?= default .PHONY: deploy deploy: $(KUSTOMIZE) ## Deploy Catalogd to the K8s cluster specified in ~/.kube/config. cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMAGE) - $(KUSTOMIZE) build config/${DEPLOY_TARGET} | kubectl apply -f - + $(KUSTOMIZE) build config/default | kubectl apply -f - .PHONY: undeploy undeploy: $(KUSTOMIZE) ## Undeploy Catalogd from the K8s cluster specified in ~/.kube/config. diff --git a/api/core/v1alpha1/catalog_types.go b/api/core/v1alpha1/catalog_types.go index 7475a25b..fd136884 100644 --- a/api/core/v1alpha1/catalog_types.go +++ b/api/core/v1alpha1/catalog_types.go @@ -134,6 +134,12 @@ type ImageSource struct { // specified as a duration (e.g., "5m", "1h", "24h", "etc".). Note that PollInterval may not be // specified for a catalog image referenced by a sha256 digest. PollInterval *metav1.Duration `json:"pollInterval,omitempty"` + // InsecureSkipTLSVerify indicates that TLS certificate validation should be skipped. + // If this option is specified, the HTTPS protocol will still be used to + // fetch the specified image reference. + // This should not be used in a production environment. + // +optional + InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify,omitempty"` } func init() { diff --git a/config/crd/bases/catalogd.operatorframework.io_catalogs.yaml b/config/crd/bases/catalogd.operatorframework.io_catalogs.yaml index c237e471..6564bab8 100644 --- a/config/crd/bases/catalogd.operatorframework.io_catalogs.yaml +++ b/config/crd/bases/catalogd.operatorframework.io_catalogs.yaml @@ -49,6 +49,13 @@ spec: description: Image is the catalog image that backs the content of this catalog. properties: + insecureSkipTLSVerify: + description: InsecureSkipTLSVerify indicates that TLS certificate + validation should be skipped. If this option is specified, + the HTTPS protocol will still be used to fetch the specified + image reference. This should not be used in a production + environment. + type: boolean pollInterval: description: PollInterval indicates the interval at which the image source should be polled for new content, specified diff --git a/config/e2e/kustomization.yaml b/config/e2e/kustomization.yaml deleted file mode 100644 index f02f1c1d..00000000 --- a/config/e2e/kustomization.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- ../default - -patches: - - patch: |- - apiVersion: apps/v1 - kind: Deployment - metadata: - name: controller-manager - namespace: system - spec: - template: - spec: - containers: - - name: manager - volumeMounts: - - mountPath: /etc/ssl/certs/ - name: ca-certs - readOnly: true - volumes: - - name: ca-certs - configMap: - name: docker-registry.catalogd-e2e.svc - defaultMode: 0644 - optional: false - items: - - key: ca-certificates.crt - path: ca-certificates.crt \ No newline at end of file diff --git a/internal/source/image_registry_client.go b/internal/source/image_registry_client.go index 171e929a..a02f7ca4 100644 --- a/internal/source/image_registry_client.go +++ b/internal/source/image_registry_client.go @@ -3,9 +3,11 @@ package source import ( "archive/tar" "context" + "crypto/tls" "errors" "fmt" "io/fs" + "net/http" "os" "path/filepath" "strings" @@ -65,6 +67,15 @@ func (i *ImageRegistry) Unpack(ctx context.Context, catalog *catalogdv1alpha1.Ca remoteOpts = append(remoteOpts, remote.WithAuthFromKeychain(authChain)) } + if catalog.Spec.Source.Image.InsecureSkipTLSVerify { + insecureTransport := remote.DefaultTransport.(*http.Transport).Clone() + if insecureTransport.TLSClientConfig == nil { + insecureTransport.TLSClientConfig = &tls.Config{} // nolint:gosec + } + insecureTransport.TLSClientConfig.InsecureSkipVerify = true // nolint:gosec + remoteOpts = append(remoteOpts, remote.WithTransport(insecureTransport)) + } + digest, isDigest := imgRef.(name.Digest) if isDigest { hexVal := strings.TrimPrefix(digest.DigestStr(), "sha256:") diff --git a/internal/source/image_registry_client_test.go b/internal/source/image_registry_client_test.go index dfa215d3..bdce6670 100644 --- a/internal/source/image_registry_client_test.go +++ b/internal/source/image_registry_client_test.go @@ -299,6 +299,40 @@ func TestImageRegistry(t *testing.T) { return img }(), }, + { + name: "digest ref, insecure specified, happy path", + catalog: &v1alpha1.Catalog{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + }, + Spec: v1alpha1.CatalogSpec{ + Source: v1alpha1.CatalogSource{ + Type: v1alpha1.SourceTypeImage, + Image: &v1alpha1.ImageSource{ + Ref: "", + InsecureSkipTLSVerify: true, + }, + }, + }, + }, + wantErr: false, + refType: "digest", + image: func() v1.Image { + img, err := random.Image(20, 3) + if err != nil { + panic(err) + } + img, err = mutate.Config(img, v1.Config{ + Labels: map[string]string{ + source.ConfigDirLabel: "/configs", + }, + }) + if err != nil { + panic(err) + } + return img + }(), + }, } { t.Run(tt.name, func(t *testing.T) { // Create context, temporary cache directory, diff --git a/test/e2e/unpack_test.go b/test/e2e/unpack_test.go index fde58f8e..6c27dc4a 100644 --- a/test/e2e/unpack_test.go +++ b/test/e2e/unpack_test.go @@ -58,7 +58,8 @@ var _ = Describe("Catalog Unpacking", func() { Source: catalogd.CatalogSource{ Type: catalogd.SourceTypeImage, Image: &catalogd.ImageSource{ - Ref: catalogImageRef(), + Ref: catalogImageRef(), + InsecureSkipTLSVerify: true, }, }, }, diff --git a/test/tools/imageregistry/imagebuilder.yaml b/test/tools/imageregistry/imagebuilder.yaml index 544252c4..1637ce7e 100644 --- a/test/tools/imageregistry/imagebuilder.yaml +++ b/test/tools/imageregistry/imagebuilder.yaml @@ -11,11 +11,9 @@ spec: image: gcr.io/kaniko-project/executor:latest args: ["--dockerfile=/workspace/test-catalog.Dockerfile", "--context=/workspace/", - "--destination=docker-registry.catalogd-e2e.svc:5000/test-catalog:e2e"] + "--destination=docker-registry.catalogd-e2e.svc:5000/test-catalog:e2e", + "--skip-tls-verify"] volumeMounts: - - name: certs - mountPath: /etc/ssl/certs/ - readOnly: true - name: dockerfile mountPath: /workspace/ - name: build-contents @@ -31,11 +29,3 @@ spec: - name: build-contents configMap: name: catalogd-e2e.build-contents - - name: certs - configMap: - name: regcerts - defaultMode: 0644 - optional: false - items: - - key: ca-certificates.crt - path: ca-certificates.crt diff --git a/test/tools/imageregistry/registry.sh b/test/tools/imageregistry/registry.sh index 990937ed..37d5479f 100755 --- a/test/tools/imageregistry/registry.sh +++ b/test/tools/imageregistry/registry.sh @@ -6,10 +6,8 @@ set -e # of catalogd's unpacking process. It does a few things: # 1. Installs cert-manager for creating a self-signed certificate for the image registry # 2. Creates all the resources necessary for deploying the image registry in the catalogd-e2e namespace -# 3. Creates a ConfigMap containing the CA cert for the image registry to be used by the catalogd-controller-manager -# 4. Creates a ConfigMap containing the CA cert for the image registry to be used by the kaniko pod -# 5. Creates ConfigMaps containing the test catalog + Dockerfile to be mounted to the kaniko pod -# 6. Waits for kaniko pod to have Phase == Succeeded, indicating the test catalog image has been built + pushed +# 3. Creates ConfigMaps containing the test catalog + Dockerfile to be mounted to the kaniko pod +# 4. Waits for kaniko pod to have Phase == Succeeded, indicating the test catalog image has been built + pushed # to the test image registry # Usage: # registry.sh @@ -22,41 +20,6 @@ kubectl wait --for=condition=Available --namespace=cert-manager deployment/cert- kubectl apply -f test/tools/imageregistry/imgreg.yaml kubectl wait -n catalogd-e2e --for=condition=Available deployment/docker-registry --timeout=60s -# get cert value -certval=$(kubectl -n catalogd-e2e get secret/catalogd-e2e-registry -o=jsonpath='{.data.ca\.crt}' | base64 -d | sed 's/^/ /') - -kubectl apply -f - << EOF -apiVersion: v1 -kind: Namespace -metadata: - name: catalogd-system -EOF -# create a ConfigMap that contains the CA certs for the image registry -# This one is created for the catalogd-controller-manager -kubectl apply -f - << EOF -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: catalogd-system - name: docker-registry.catalogd-e2e.svc -data: - "ca-certificates.crt": | -${certval} -EOF - -# create a ConfigMap that contains the CA certs for the image registry -# this one is created for the kaniko pod -kubectl apply -f - << EOF -apiVersion: v1 -kind: ConfigMap -metadata: - namespace: catalogd-e2e - name: regcerts -data: - "ca-certificates.crt": | -${certval} -EOF - # Load the testdata onto the cluster as a configmap so it can be used with kaniko kubectl create configmap -n catalogd-e2e --from-file=testdata/catalogs/test-catalog.Dockerfile catalogd-e2e.dockerfile kubectl create configmap -n catalogd-e2e --from-file=testdata/catalogs/test-catalog catalogd-e2e.build-contents