diff --git a/.gitignore b/.gitignore index 1bd345523..c2c4333ba 100644 --- a/.gitignore +++ b/.gitignore @@ -19,10 +19,10 @@ coverage cover.out # Release output -dist/** -operator-controller.yaml -install.sh -catalogd.yaml +/dist/** +/operator-controller.yaml +/default-catalogs.yaml +/install.sh # vendored files vendor/ diff --git a/.goreleaser.yml b/.goreleaser.yml index d269b20d0..3dbb37482 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -124,9 +124,9 @@ release: disable: '{{ ne .Env.ENABLE_RELEASE_PIPELINE "true" }}' mode: replace extra_files: - - glob: 'operator-controller.yaml' - - glob: './config/catalogs/clustercatalogs/default-catalogs.yaml' - - glob: 'install.sh' + - glob: '{{ .Env.RELEASE_MANIFEST }}' + - glob: '{{ .Env.RELEASE_INSTALL }}' + - glob: '{{ .Env.RELEASE_CATALOGS }}' header: | ## Installation diff --git a/.tilt-support b/.tilt-support index c55d2851d..571b00f62 100644 --- a/.tilt-support +++ b/.tilt-support @@ -5,7 +5,7 @@ load('ext://cert_manager', 'deploy_cert_manager') def deploy_cert_manager_if_needed(): cert_manager_var = '__CERT_MANAGER__' if os.getenv(cert_manager_var) != '1': - deploy_cert_manager(version="v1.15.3") + deploy_cert_manager(version="v1.17.1") os.putenv(cert_manager_var, '1') @@ -130,7 +130,6 @@ def process_yaml(yaml): # data format: # { # 'image': 'quay.io/operator-framework/rukpak', -# 'yaml': 'manifests/overlays/cert-manager', # 'binaries': { # 'core': 'core', # 'crdvalidator': 'crd-validation-webhook', @@ -148,4 +147,3 @@ def deploy_repo(repo, data, tags="", debug=True): build_binary(repo, binary, data['deps'], data['image'], tags, debug) k8s_resource(deployment, port_forwards=['{}:30000'.format(local_port)]) local_port += 1 - process_yaml(kustomize(data['yaml'])) diff --git a/Makefile b/Makefile index 6245c6ccb..0118a2ccc 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,16 @@ SHELL := /usr/bin/env bash -o pipefail .SHELLFLAGS := -ec export ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) +# attempt to generate the VERSION attribute for certificates +# fail if it is unset afterwards, since the side effects are indirect +ifeq ($(strip $(VERSION)),) +VERSION := $(shell git describe --tags --always --dirty) +endif +export VERSION +ifeq ($(strip $(VERSION)),) + $(error undefined VERSION; resulting certs will be invalid) +endif + GOLANG_VERSION := $(shell sed -En 's/^go (.*)$$/\1/p' "go.mod") # Image URL to use all building/pushing image targets ifeq ($(origin IMAGE_REGISTRY), undefined) @@ -25,7 +35,7 @@ endif export CATD_IMAGE_REPO ifeq ($(origin IMAGE_TAG), undefined) -IMAGE_TAG := devel +IMAGE_TAG := $(VERSION) endif export IMAGE_TAG @@ -77,7 +87,20 @@ else $(warning Could not find docker or podman in path! This may result in targets requiring a container runtime failing!) endif -KUSTOMIZE_BUILD_DIR := config/overlays/cert-manager +KUSTOMIZE_RELEASE_OVERLAY := config/overlays/community +KUSTOMIZE_E2E_OVERLAY := config/overlays/community-e2e +KUSTOMIZE_TILT_OVERLAY := config/overlays/community-tilt +KUSTOMIZE_CATALOGS_OVERLAY := config/overlays/default-catalogs + +export RELEASE_MANIFEST := operator-controller.yaml +export RELEASE_INSTALL := install.sh +export RELEASE_CATALOGS := default-catalogs.yaml + +DEV_MANIFESTS_DIR := dev-manifests +DEV_MANIFEST := $(DEV_MANIFESTS_DIR)/operator-controller-dev.yaml +E2E_MANIFEST := $(DEV_MANIFESTS_DIR)/operator-controller-e2e.yaml +TILT_MANIFEST := $(DEV_MANIFESTS_DIR)/operator-controller-tilt.yaml +CATALOGS_MANIFEST := $(DEV_MANIFESTS_DIR)/default-catalogs.yaml # Disable -j flag for make .NOTPARALLEL: @@ -137,7 +160,7 @@ KUSTOMIZE_OPCON_RBAC_DIR := config/base/operator-controller/rbac CRD_WORKING_DIR := crd_work_dir # Due to https://github.com/kubernetes-sigs/controller-tools/issues/837 we can't specify individual files # So we have to generate them together and then move them into place -manifests: $(CONTROLLER_GEN) #EXHELP Generate WebhookConfiguration, ClusterRole, and CustomResourceDefinition objects. +manifests: $(CONTROLLER_GEN) $(KUSTOMIZE) #EXHELP Generate WebhookConfiguration, ClusterRole, and CustomResourceDefinition objects. mkdir $(CRD_WORKING_DIR) $(CONTROLLER_GEN) --load-build-tags=$(GO_BUILD_TAGS) crd paths="./api/v1/..." output:crd:artifacts:config=$(CRD_WORKING_DIR) mv $(CRD_WORKING_DIR)/olm.operatorframework.io_clusterextensions.yaml $(KUSTOMIZE_OPCON_CRDS_DIR) @@ -147,7 +170,12 @@ manifests: $(CONTROLLER_GEN) #EXHELP Generate WebhookConfiguration, ClusterRole, $(CONTROLLER_GEN) --load-build-tags=$(GO_BUILD_TAGS) rbac:roleName=manager-role paths="./internal/operator-controller/..." output:rbac:artifacts:config=$(KUSTOMIZE_OPCON_RBAC_DIR) # Generate the remaining catalogd manifests $(CONTROLLER_GEN) --load-build-tags=$(GO_BUILD_TAGS) rbac:roleName=manager-role paths="./internal/catalogd/..." output:rbac:artifacts:config=$(KUSTOMIZE_CATD_RBAC_DIR) - $(CONTROLLER_GEN) --load-build-tags=$(GO_BUILD_TAGS) webhook paths="./internal/catalogd/..." output:webhook:artifacts:config=$(KUSTOMIZE_CATD_WEBHOOKS_DIR) + mkdir -p $(DEV_MANIFESTS_DIR) + export VERSION=devel && $(KUSTOMIZE) build $(KUSTOMIZE_RELEASE_OVERLAY) | envsubst '$$VERSION' > $(DEV_MANIFEST) + export VERSION=devel && $(KUSTOMIZE) build $(KUSTOMIZE_E2E_OVERLAY) | envsubst '$$VERSION' > $(E2E_MANIFEST) + export VERSION=devel && $(KUSTOMIZE) build $(KUSTOMIZE_TILT_OVERLAY) | envsubst '$$VERSION' > $(TILT_MANIFEST) + export VERSION=devel && $(KUSTOMIZE) build $(KUSTOMIZE_CATALOGS_OVERLAY) | envsubst '$$VERSION' > $(CATALOGS_MANIFEST) + .PHONY: generate generate: $(CONTROLLER_GEN) #EXHELP Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. @@ -201,11 +229,11 @@ E2E_REGISTRY_NAME := docker-registry E2E_REGISTRY_NAMESPACE := operator-controller-e2e export REG_PKG_NAME := registry-operator -export LOCAL_REGISTRY_HOST := $(E2E_REGISTRY_NAME).$(E2E_REGISTRY_NAMESPACE).svc:5000 -export CLUSTER_REGISTRY_HOST := localhost:30000 +export INCLUSTER_REGISTRY_HOST := $(E2E_REGISTRY_NAME).$(E2E_REGISTRY_NAMESPACE).svc:5000 +export LOCAL_REGISTRY_HOST := localhost:30000 export E2E_TEST_CATALOG_V1 := e2e/test-catalog:v1 export E2E_TEST_CATALOG_V2 := e2e/test-catalog:v2 -export CATALOG_IMG := $(LOCAL_REGISTRY_HOST)/$(E2E_TEST_CATALOG_V1) +export CATALOG_IMG := $(INCLUSTER_REGISTRY_HOST)/$(E2E_TEST_CATALOG_V1) .PHONY: test-ext-dev-e2e test-ext-dev-e2e: $(OPERATOR_SDK) $(KUSTOMIZE) $(KIND) #HELP Run extension create, upgrade and delete tests. test/extension-developer-e2e/setup.sh $(OPERATOR_SDK) $(CONTAINER_RUNTIME) $(KUSTOMIZE) $(KIND) $(KIND_CLUSTER_NAME) $(E2E_REGISTRY_NAMESPACE) @@ -230,16 +258,9 @@ test-unit: $(SETUP_ENVTEST) envtest-k8s-bins #HELP Run the unit tests $(UNIT_TEST_DIRS) \ -test.gocoverdir=$(COVERAGE_UNIT_DIR) -.PHONY: image-registry -E2E_REGISTRY_IMAGE=localhost/e2e-test-registry:devel -image-registry: export GOOS=linux -image-registry: export GOARCH=amd64 -image-registry: ## Build the testdata catalog used for e2e tests and push it to the image registry - go build $(GO_BUILD_FLAGS) $(GO_BUILD_EXTRA_FLAGS) -tags '$(GO_BUILD_TAGS)' -ldflags '$(GO_BUILD_LDFLAGS)' -gcflags '$(GO_BUILD_GCFLAGS)' -asmflags '$(GO_BUILD_ASMFLAGS)' -o ./testdata/registry/bin/registry ./testdata/registry/registry.go - go build $(GO_BUILD_FLAGS) $(GO_BUILD_EXTRA_FLAGS) -tags '$(GO_BUILD_TAGS)' -ldflags '$(GO_BUILD_LDFLAGS)' -gcflags '$(GO_BUILD_GCFLAGS)' -asmflags '$(GO_BUILD_ASMFLAGS)' -o ./testdata/push/bin/push ./testdata/push/push.go - $(CONTAINER_RUNTIME) build -f ./testdata/Dockerfile -t $(E2E_REGISTRY_IMAGE) ./testdata - $(CONTAINER_RUNTIME) save $(E2E_REGISTRY_IMAGE) | $(KIND) load image-archive /dev/stdin --name $(KIND_CLUSTER_NAME) - ./testdata/build-test-registry.sh $(E2E_REGISTRY_NAMESPACE) $(E2E_REGISTRY_NAME) $(E2E_REGISTRY_IMAGE) +.PHONY: push-test-images +push-test-images: ## Build the testdata catalog used for e2e tests and push it to the image registry + (cd ./testdata/push && go run ./ --images-path=../images --registry-address=localhost:30000) # When running the e2e suite, you can set the ARTIFACT_PATH variable to the absolute path # of the directory for the operator-controller e2e tests to store the artifacts, which @@ -248,15 +269,15 @@ image-registry: ## Build the testdata catalog used for e2e tests and push it to # for example: ARTIFACT_PATH=/tmp/artifacts make test-e2e .PHONY: test-e2e test-e2e: KIND_CLUSTER_NAME := operator-controller-e2e -test-e2e: KUSTOMIZE_BUILD_DIR := config/overlays/e2e +test-e2e: export MANIFEST := $(E2E_MANIFEST) test-e2e: GO_BUILD_EXTRA_FLAGS := -cover -test-e2e: run image-registry e2e e2e-coverage kind-clean #HELP Run e2e test suite on local kind cluster +test-e2e: run-internal push-test-images e2e e2e-coverage kind-clean #HELP Run e2e test suite on local kind cluster .PHONY: extension-developer-e2e -extension-developer-e2e: KUSTOMIZE_BUILD_DIR := config/overlays/cert-manager extension-developer-e2e: KIND_CLUSTER_NAME := operator-controller-ext-dev-e2e +extension-developer-e2e: export MANIFEST := $(E2E_MANIFEST) extension-developer-e2e: export INSTALL_DEFAULT_CATALOGS := false -extension-developer-e2e: run image-registry test-ext-dev-e2e kind-clean #EXHELP Run extension-developer e2e on local kind cluster +extension-developer-e2e: run-internal push-test-images test-ext-dev-e2e kind-clean #EXHELP Run extension-developer e2e on local kind cluster .PHONY: run-latest-release run-latest-release: @@ -274,7 +295,7 @@ post-upgrade-checks: test-upgrade-e2e: KIND_CLUSTER_NAME := operator-controller-upgrade-e2e test-upgrade-e2e: export TEST_CLUSTER_CATALOG_NAME := test-catalog test-upgrade-e2e: export TEST_CLUSTER_EXTENSION_NAME := test-package -test-upgrade-e2e: kind-cluster run-latest-release image-registry pre-upgrade-setup docker-build kind-load kind-deploy post-upgrade-checks kind-clean #HELP Run upgrade e2e tests on a local kind cluster +test-upgrade-e2e: kind-cluster run-latest-release push-test-images pre-upgrade-setup docker-build kind-load kind-deploy post-upgrade-checks kind-clean #HELP Run upgrade e2e tests on a local kind cluster .PHONY: e2e-coverage e2e-coverage: @@ -288,11 +309,9 @@ kind-load: $(KIND) #EXHELP Loads the currently constructed images into the KIND $(CONTAINER_RUNTIME) save $(CATD_IMG) | $(KIND) load image-archive /dev/stdin --name $(KIND_CLUSTER_NAME) .PHONY: kind-deploy -kind-deploy: export MANIFEST := ./operator-controller.yaml -kind-deploy: export DEFAULT_CATALOG := ./config/catalogs/clustercatalogs/default-catalogs.yaml kind-deploy: manifests $(KUSTOMIZE) - $(KUSTOMIZE) build $(KUSTOMIZE_BUILD_DIR) | sed "s/cert-git-version/cert-$(VERSION)/g" > $(MANIFEST) - envsubst '$$DEFAULT_CATALOG,$$CERT_MGR_VERSION,$$INSTALL_DEFAULT_CATALOGS,$$MANIFEST' < scripts/install.tpl.sh | bash -s + envsubst '$$VERSION' < $$MANIFEST > ./tmp-manifest.yaml + export MANIFEST=./tmp-manifest.yaml && envsubst '$$DEFAULT_CATALOGS,$$CERT_MGR_VERSION,$$INSTALL_DEFAULT_CATALOGS,$$MANIFEST' < scripts/install.tpl.sh | bash -s && rm ./tmp-manifest.yaml .PHONY: kind-cluster kind-cluster: $(KIND) #EXHELP Standup a kind cluster. @@ -306,16 +325,6 @@ kind-clean: $(KIND) #EXHELP Delete the kind cluster. #SECTION Build -# attempt to generate the VERSION attribute for certificates -# fail if it is unset afterwards, since the side effects are indirect -ifeq ($(strip $(VERSION)),) -VERSION := $(shell git describe --tags --always --dirty) -endif -export VERSION -ifeq ($(strip $(VERSION)),) - $(error undefined VERSION; resulting certs will be invalid) -endif - ifeq ($(origin CGO_ENABLED), undefined) CGO_ENABLED := 0 endif @@ -353,12 +362,16 @@ go-build-linux: export GOARCH=amd64 go-build-linux: $(BINARIES) .PHONY: run -run: docker-build kind-cluster kind-load kind-deploy wait #HELP Build the operator-controller then deploy it into a new kind cluster. +run: export MANIFEST := $(DEV_MANIFEST) +run: run-internal #HELP Build the operator-controller then deploy it into a new kind cluster. + +.PHONY: run-internal +run-internal: docker-build kind-cluster kind-load kind-deploy wait CATD_NAMESPACE := olmv1-system wait: kubectl wait --for=condition=Available --namespace=$(CATD_NAMESPACE) deployment/catalogd-controller-manager --timeout=60s - kubectl wait --for=condition=Ready --namespace=$(CATD_NAMESPACE) certificate/catalogd-service-cert # Avoid upgrade test flakes when reissuing cert + kubectl wait --for=condition=Ready --namespace=$(CATD_NAMESPACE) certificate/catalogd-cert # Avoid upgrade test flakes when reissuing cert .PHONY: docker-build docker-build: build-linux #EXHELP Build docker image for operator-controller and catalog with GOOS=linux and local GOARCH. @@ -382,10 +395,11 @@ release: $(GORELEASER) #EXHELP Runs goreleaser for the operator-controller. By d .PHONY: quickstart quickstart: export MANIFEST := https://github.com/operator-framework/operator-controller/releases/download/$(VERSION)/operator-controller.yaml -quickstart: export DEFAULT_CATALOG := "https://github.com/operator-framework/operator-controller/releases/download/$(VERSION)/default-catalogs.yaml" -quickstart: $(KUSTOMIZE) manifests #EXHELP Generate the unified installation release manifests and scripts. - $(KUSTOMIZE) build $(KUSTOMIZE_BUILD_DIR) | sed "s/cert-git-version/cert-$(VERSION)/g" | sed "s/:devel/:$(VERSION)/g" > operator-controller.yaml - envsubst '$$DEFAULT_CATALOG,$$CERT_MGR_VERSION,$$INSTALL_DEFAULT_CATALOGS,$$MANIFEST' < scripts/install.tpl.sh > install.sh +quickstart: export DEFAULT_CATALOGS := "https://github.com/operator-framework/operator-controller/releases/download/$(VERSION)/default-catalogs.yaml" +quickstart: manifests #EXHELP Generate the unified installation release manifests and scripts. + envsubst '$$VERSION' < $(DEV_MANIFEST) > $(RELEASE_MANIFEST) + cp $(CATALOGS_MANIFEST) > $(RELEASE_CATALOGS) + envsubst '$$DEFAULT_CATALOGS,$$CERT_MGR_VERSION,$$INSTALL_DEFAULT_CATALOGS,$$MANIFEST' < scripts/install.tpl.sh > $(RELEASE_INSTALL) ##@ Docs diff --git a/Tiltfile b/Tiltfile index 2d5e36381..cd50b00b6 100644 --- a/Tiltfile +++ b/Tiltfile @@ -1,8 +1,7 @@ -load('.tilt-support', 'deploy_repo') +load('.tilt-support', 'deploy_repo', 'process_yaml') operator_controller = { 'image': 'quay.io/operator-framework/operator-controller', - 'yaml': 'config/overlays/tilt-local-dev/operator-controller', 'binaries': { './cmd/operator-controller': 'operator-controller-controller-manager', }, @@ -13,7 +12,6 @@ deploy_repo('operator-controller', operator_controller, '-tags containers_image_ catalogd = { 'image': 'quay.io/operator-framework/catalogd', - 'yaml': 'config/overlays/tilt-local-dev/catalogd', 'binaries': { './cmd/catalogd': 'catalogd-controller-manager', }, @@ -22,3 +20,4 @@ catalogd = { } deploy_repo('catalogd', catalogd, '-tags containers_image_openpgp') +process_yaml(read_file('dev-manifests/operator-controller-tilt.yaml')) diff --git a/cmd/catalogd/main.go b/cmd/catalogd/main.go index 9499a7006..d0f03060a 100644 --- a/cmd/catalogd/main.go +++ b/cmd/catalogd/main.go @@ -199,6 +199,7 @@ func run(ctx context.Context) error { } cfg.externalAddr = protocol + cfg.externalAddr + setupLog.Info("server certificate", "cert", cfg.certFile, "key", cfg.keyFile) cw, err := certwatcher.New(cfg.certFile, cfg.keyFile) if err != nil { setupLog.Error(err, "failed to initialize certificate watcher") diff --git a/config/README.md b/config/README.md deleted file mode 100644 index 449989b23..000000000 --- a/config/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# OPERATOR-CONTROLLER CONFIG - -## config/overlays/basic-olm - -This includes basic support for an insecure OLMv1 deployment. This configuration uses: -* config/base/catalogd -* config/base/operator-controller -* config/base/common - -## config/overlays/cert-manager - -This includes support for a secure (i.e. with TLS) configuration of OLMv1. This configuration uses: -* config/base/catalogd -* config/base/operator-controller -* config/base/common -* config/components/tls/catalogd -* config/components/tls/operator-controller -* config/components/tls/ca - -This configuration requires cert-manager. - -## config/overlays/e2e - -This provides additional configuration support for end-to-end testing, including code coverage. This configuration uses: -* config/base/catalogd -* config/base/operator-controller -* config/base/common -* config/components/coverage -* config/components/tls/catalogd -* config/components/tls/operator-controller -* config/components/tls/ca - -This configuration requires cert-manager. - -## Base Configuration - -The base configuration specifies a namespace of `olmv1-system`. - -### config/base/catalogd - -This provides the base configuration of catalogd. - -### config/base/operator-controller - -This provides the base configuration of operator-controller. - -### config/base/common - -This provides common components to both operator-controller and catalogd, i.e. namespace. - -## Components - -Each of the `kustomization.yaml` files specify a `Component`, rather than an overlay, and thus, can be used within the overlays. - -### config/components/tls/catalogd - -This provides a basic configuration of catalogd with TLS support. - -This component requires cert-manager. - -### config/components/tls/operator-controller - -This provides a basic configuration of operator-controller with TLS support for catalogd. - -This component requires cert-manager. - -### config/components/tls/ca - -Provides a CA for operator-controller/catalogd operation. - -This component _does not_ specify a namespace, and _must_ be included last. - -This component requires cert-manager. - -### config/components/coverage - -Provides configuration for code coverage. diff --git a/config/base/catalogd/crd/kustomization.yaml b/config/base/catalogd/crd/kustomization.yaml index 36c151281..5ec5d758a 100644 --- a/config/base/catalogd/crd/kustomization.yaml +++ b/config/base/catalogd/crd/kustomization.yaml @@ -1,6 +1,6 @@ -# This kustomization.yaml is not intended to be run by itself, -# since it depends on service name and namespace that are out of this kustomize package. -# It should be run by config/default +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + resources: - bases/olm.operatorframework.io_clustercatalogs.yaml -#+kubebuilder:scaffold:crdkustomizeresource +- mutating_webhook_configuration.yaml \ No newline at end of file diff --git a/config/base/catalogd/crd/mutating_webhook_configuration.yaml b/config/base/catalogd/crd/mutating_webhook_configuration.yaml new file mode 100644 index 000000000..6f19b1605 --- /dev/null +++ b/config/base/catalogd/crd/mutating_webhook_configuration.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: service + namespace: __NAMESPACE_PLACEHOLDER__ + path: /mutate-olm-operatorframework-io-v1-clustercatalog + port: 9443 + failurePolicy: Fail + matchConditions: + - expression: "'name' in object.metadata && (!has(object.metadata.labels) || !('olm.operatorframework.io/metadata.name' in object.metadata.labels) || object.metadata.labels['olm.operatorframework.io/metadata.name'] != object.metadata.name)" + name: MissingOrIncorrectMetadataNameLabel + name: inject-metadata-name.olm.operatorframework.io + rules: + - apiGroups: + - olm.operatorframework.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - clustercatalogs + sideEffects: None + timeoutSeconds: 10 \ No newline at end of file diff --git a/config/base/catalogd/kustomization.yaml b/config/base/catalogd/kustomization.yaml index 9a6bc2512..4bd2a3e57 100644 --- a/config/base/catalogd/kustomization.yaml +++ b/config/base/catalogd/kustomization.yaml @@ -1,8 +1,16 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization -namespace: olmv1-system + +labels: + - pairs: + app.kubernetes.io/name: catalogd + includeTemplates: false + includeSelectors: false + namePrefix: catalogd- + resources: -- crd -- rbac -- manager + - crd + - rbac + - manager + diff --git a/config/base/catalogd/manager/manager.yaml b/config/base/catalogd/manager/deployment.yaml similarity index 87% rename from config/base/catalogd/manager/manager.yaml rename to config/base/catalogd/manager/deployment.yaml index 5c52165ec..0607871c7 100644 --- a/config/base/catalogd/manager/manager.yaml +++ b/config/base/catalogd/manager/deployment.yaml @@ -2,23 +2,16 @@ apiVersion: apps/v1 kind: Deployment metadata: name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ annotations: kubectl.kubernetes.io/default-logs-container: manager - labels: - control-plane: catalogd-controller-manager spec: - selector: - matchLabels: - control-plane: catalogd-controller-manager replicas: 1 minReadySeconds: 5 template: metadata: annotations: kubectl.kubernetes.io/default-container: manager - labels: - control-plane: catalogd-controller-manager spec: affinity: nodeAffinity: @@ -46,7 +39,12 @@ spec: args: - --leader-elect - --metrics-bind-address=:7443 - - --external-address=catalogd-service.olmv1-system.svc + - --external-address=catalogd-service.$(POD_NAMESPACE).svc + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace image: controller:latest name: manager volumeMounts: diff --git a/config/base/catalogd/manager/kustomization.yaml b/config/base/catalogd/manager/kustomization.yaml index 2c10750df..be93f601a 100644 --- a/config/base/catalogd/manager/kustomization.yaml +++ b/config/base/catalogd/manager/kustomization.yaml @@ -1,18 +1,18 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + resources: -- manager.yaml +- deployment.yaml - service.yaml - network_policy.yaml -- webhook/manifests.yaml -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization + +labels: + - pairs: + control-plane: catalogd-controller-manager + includeSelectors: true + includeTemplates: true + images: - name: controller newName: quay.io/operator-framework/catalogd - newTag: devel -patches: -- path: webhook/patch.yaml - target: - group: admissionregistration.k8s.io - kind: MutatingWebhookConfiguration - name: mutating-webhook-configuration - version: v1 + newTag: ${VERSION} diff --git a/config/base/catalogd/manager/network_policy.yaml b/config/base/catalogd/manager/network_policy.yaml index 853b54a37..f11a336f1 100644 --- a/config/base/catalogd/manager/network_policy.yaml +++ b/config/base/catalogd/manager/network_policy.yaml @@ -2,7 +2,7 @@ apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ spec: podSelector: matchLabels: diff --git a/config/base/catalogd/manager/service.yaml b/config/base/catalogd/manager/service.yaml index 693b687f3..1c900a204 100644 --- a/config/base/catalogd/manager/service.yaml +++ b/config/base/catalogd/manager/service.yaml @@ -1,14 +1,9 @@ apiVersion: v1 kind: Service metadata: - labels: - app.kubernetes.io/part-of: olm - app.kubernetes.io/name: catalogd name: service - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ spec: - selector: - control-plane: catalogd-controller-manager ports: - name: http protocol: TCP diff --git a/config/base/catalogd/manager/webhook/manifests.yaml b/config/base/catalogd/manager/webhook/manifests.yaml deleted file mode 100644 index a5842de42..000000000 --- a/config/base/catalogd/manager/webhook/manifests.yaml +++ /dev/null @@ -1,27 +0,0 @@ ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: mutating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-olm-operatorframework-io-v1-clustercatalog - failurePolicy: Fail - name: inject-metadata-name.olm.operatorframework.io - rules: - - apiGroups: - - olm.operatorframework.io - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - clustercatalogs - sideEffects: None - timeoutSeconds: 10 diff --git a/config/base/catalogd/manager/webhook/patch.yaml b/config/base/catalogd/manager/webhook/patch.yaml deleted file mode 100644 index ab8528c76..000000000 --- a/config/base/catalogd/manager/webhook/patch.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# None of these values can be set via the kubebuilder directive, hence this patch -- op: replace - path: /webhooks/0/clientConfig/service/namespace - value: olmv1-system -- op: replace - path: /webhooks/0/clientConfig/service/name - value: catalogd-service -- op: add - path: /webhooks/0/clientConfig/service/port - value: 9443 -# Make sure there's a name defined, otherwise, we can't create a label. This could happen when generateName is set -# Then, if any of the conditions are true, create the label: -# 1. No labels exist -# 2. The olm.operatorframework.io/metadata.name label doesn't exist -# 3. The olm.operatorframework.io/metadata.name label doesn't match the name -- op: add - path: /webhooks/0/matchConditions - value: - - name: MissingOrIncorrectMetadataNameLabel - expression: "'name' in object.metadata && (!has(object.metadata.labels) || !('olm.operatorframework.io/metadata.name' in object.metadata.labels) || object.metadata.labels['olm.operatorframework.io/metadata.name'] != object.metadata.name)" diff --git a/config/base/catalogd/rbac/auth_proxy_role.yaml b/config/base/catalogd/rbac/auth_proxy_role.yaml index 3edf78f58..80e1857c5 100644 --- a/config/base/catalogd/rbac/auth_proxy_role.yaml +++ b/config/base/catalogd/rbac/auth_proxy_role.yaml @@ -1,9 +1,6 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - labels: - app.kubernetes.io/part-of: olm - app.kubernetes.io/name: catalogd name: proxy-role rules: - apiGroups: diff --git a/config/base/catalogd/rbac/auth_proxy_role_binding.yaml b/config/base/catalogd/rbac/auth_proxy_role_binding.yaml index 2efcf8dd8..a4549af04 100644 --- a/config/base/catalogd/rbac/auth_proxy_role_binding.yaml +++ b/config/base/catalogd/rbac/auth_proxy_role_binding.yaml @@ -1,9 +1,6 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - labels: - app.kubernetes.io/part-of: olm - app.kubernetes.io/name: catalogd name: proxy-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io @@ -12,4 +9,4 @@ roleRef: subjects: - kind: ServiceAccount name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ diff --git a/config/base/catalogd/rbac/kustomization.yaml b/config/base/catalogd/rbac/kustomization.yaml index 8ed66bdd1..cb6311a79 100644 --- a/config/base/catalogd/rbac/kustomization.yaml +++ b/config/base/catalogd/rbac/kustomization.yaml @@ -1,14 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + resources: -# All RBAC will be applied under this service account in -# the deployment namespace. You may comment out this resource -# if your manager will use a service account that exists at -# runtime. Be sure to update RoleBinding and ClusterRoleBinding -# subjects if changing service account names. - service_account.yaml - role.yaml - role_binding.yaml - leader_election_role.yaml - leader_election_role_binding.yaml + # The following RBAC configurations are used to protect # the metrics endpoint with authn/authz. These configurations # ensure that only authorized users and service accounts @@ -18,3 +17,9 @@ resources: - auth_proxy_role.yaml - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml + +# The following resources are pre-defined roles for editors and viewers +# of APIs provided by this project. +# TODO: CREATE AND ENABLE EDITOR/VIEWER CLUSTER ROLES FOR CATALOGD TO ALIGN WITH OPERATOR_CONTROLLER +#- clustercatalog_editor_role.yaml +#- clustercatalog_viewer_role.yaml \ No newline at end of file diff --git a/config/base/catalogd/rbac/leader_election_role.yaml b/config/base/catalogd/rbac/leader_election_role.yaml index 37564d084..4506cb96a 100644 --- a/config/base/catalogd/rbac/leader_election_role.yaml +++ b/config/base/catalogd/rbac/leader_election_role.yaml @@ -2,9 +2,6 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - labels: - app.kubernetes.io/part-of: olm - app.kubernetes.io/name: catalogd name: leader-election-role rules: - apiGroups: @@ -20,7 +17,7 @@ rules: - patch - delete - apiGroups: - - coordination.k8s.io + - coordination.k8s.io resources: - leases verbs: diff --git a/config/base/catalogd/rbac/leader_election_role_binding.yaml b/config/base/catalogd/rbac/leader_election_role_binding.yaml index 6ad0ccf99..3197cbe5d 100644 --- a/config/base/catalogd/rbac/leader_election_role_binding.yaml +++ b/config/base/catalogd/rbac/leader_election_role_binding.yaml @@ -1,9 +1,6 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - labels: - app.kubernetes.io/part-of: olm - app.kubernetes.io/name: catalogd name: leader-election-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io @@ -12,4 +9,4 @@ roleRef: subjects: - kind: ServiceAccount name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ diff --git a/config/base/catalogd/rbac/role_binding.yaml b/config/base/catalogd/rbac/role_binding.yaml index a618c0e47..a1eeba75c 100644 --- a/config/base/catalogd/rbac/role_binding.yaml +++ b/config/base/catalogd/rbac/role_binding.yaml @@ -1,9 +1,6 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - labels: - app.kubernetes.io/part-of: olm - app.kubernetes.io/name: catalogd name: manager-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io @@ -12,4 +9,4 @@ roleRef: subjects: - kind: ServiceAccount name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ diff --git a/config/base/catalogd/rbac/service_account.yaml b/config/base/catalogd/rbac/service_account.yaml index 3f0e7af74..0bb7c2c12 100644 --- a/config/base/catalogd/rbac/service_account.yaml +++ b/config/base/catalogd/rbac/service_account.yaml @@ -1,8 +1,5 @@ apiVersion: v1 kind: ServiceAccount metadata: - labels: - app.kubernetes.io/part-of: olm - app.kubernetes.io/name: catalogd name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ diff --git a/config/base/kustomization.yaml b/config/base/kustomization.yaml new file mode 100644 index 000000000..c4a369a26 --- /dev/null +++ b/config/base/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - catalogd + - operator-controller + diff --git a/config/base/operator-controller/crd/kustomization.yaml b/config/base/operator-controller/crd/kustomization.yaml index ec864639d..a390875a6 100644 --- a/config/base/operator-controller/crd/kustomization.yaml +++ b/config/base/operator-controller/crd/kustomization.yaml @@ -1,9 +1,5 @@ -# This kustomization.yaml is not intended to be run by itself, -# since it depends on service name and namespace that are out of this kustomize package. -# It should be run by config/default +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + resources: - bases/olm.operatorframework.io_clusterextensions.yaml - -# the following config is for teaching kustomize how to do kustomization for CRDs. -configurations: -- kustomizeconfig.yaml diff --git a/config/base/operator-controller/crd/kustomizeconfig.yaml b/config/base/operator-controller/crd/kustomizeconfig.yaml deleted file mode 100644 index ec5c150a9..000000000 --- a/config/base/operator-controller/crd/kustomizeconfig.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# This file is for teaching kustomize how to substitute name and namespace reference in CRD -nameReference: -- kind: Service - version: v1 - fieldSpecs: - - kind: CustomResourceDefinition - version: v1 - group: apiextensions.k8s.io - path: spec/conversion/webhook/clientConfig/service/name - -namespace: -- kind: CustomResourceDefinition - version: v1 - group: apiextensions.k8s.io - path: spec/conversion/webhook/clientConfig/service/namespace - create: false - -varReference: -- path: metadata/annotations diff --git a/config/base/operator-controller/kustomization.yaml b/config/base/operator-controller/kustomization.yaml index 1d63fb17f..f42f3b80d 100644 --- a/config/base/operator-controller/kustomization.yaml +++ b/config/base/operator-controller/kustomization.yaml @@ -1,9 +1,17 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization -namespace: olmv1-system + +labels: + - pairs: + app.kubernetes.io/name: operator-controller + includeTemplates: false + includeSelectors: false + namePrefix: operator-controller- + resources: -- crd -- rbac -- manager + - crd + - rbac + - manager + diff --git a/config/base/operator-controller/manager/manager.yaml b/config/base/operator-controller/manager/deployment.yaml similarity index 86% rename from config/base/operator-controller/manager/manager.yaml rename to config/base/operator-controller/manager/deployment.yaml index db34940c3..5f1398607 100644 --- a/config/base/operator-controller/manager/manager.yaml +++ b/config/base/operator-controller/manager/deployment.yaml @@ -2,22 +2,15 @@ apiVersion: apps/v1 kind: Deployment metadata: name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ annotations: kubectl.kubernetes.io/default-logs-container: manager - labels: - control-plane: operator-controller-controller-manager spec: - selector: - matchLabels: - control-plane: operator-controller-controller-manager replicas: 1 template: metadata: annotations: kubectl.kubernetes.io/default-container: manager - labels: - control-plane: operator-controller-controller-manager spec: affinity: nodeAffinity: @@ -76,7 +69,7 @@ spec: cpu: 10m memory: 64Mi terminationMessagePolicy: FallbackToLogsOnError - serviceAccountName: operator-controller-controller-manager + serviceAccountName: controller-manager terminationGracePeriodSeconds: 10 volumes: - name: cache diff --git a/config/base/operator-controller/manager/kustomization.yaml b/config/base/operator-controller/manager/kustomization.yaml index 259f17c9e..763745fbe 100644 --- a/config/base/operator-controller/manager/kustomization.yaml +++ b/config/base/operator-controller/manager/kustomization.yaml @@ -2,11 +2,17 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- manager.yaml +- deployment.yaml - service.yaml - network_policy.yaml +labels: +- pairs: + control-plane: operator-controller-controller-manager + includeSelectors: true + includeTemplates: true + images: - name: controller newName: quay.io/operator-framework/operator-controller - newTag: devel + newTag: ${VERSION} diff --git a/config/base/operator-controller/manager/network_policy.yaml b/config/base/operator-controller/manager/network_policy.yaml index 2e68beabe..0f990d52c 100644 --- a/config/base/operator-controller/manager/network_policy.yaml +++ b/config/base/operator-controller/manager/network_policy.yaml @@ -2,7 +2,7 @@ apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ spec: podSelector: matchLabels: diff --git a/config/base/operator-controller/manager/service.yaml b/config/base/operator-controller/manager/service.yaml index b352a0aa1..4f0fbb6c9 100644 --- a/config/base/operator-controller/manager/service.yaml +++ b/config/base/operator-controller/manager/service.yaml @@ -2,14 +2,10 @@ apiVersion: v1 kind: Service metadata: name: service - namespace: system - labels: - control-plane: operator-controller-controller-manager + namespace: __NAMESPACE_PLACEHOLDER__ spec: ports: - name: https port: 8443 protocol: TCP targetPort: 8443 - selector: - control-plane: operator-controller-controller-manager diff --git a/config/base/operator-controller/rbac/auth_proxy_role_binding.yaml b/config/base/operator-controller/rbac/auth_proxy_role_binding.yaml index ec7acc0a1..a4549af04 100644 --- a/config/base/operator-controller/rbac/auth_proxy_role_binding.yaml +++ b/config/base/operator-controller/rbac/auth_proxy_role_binding.yaml @@ -9,4 +9,4 @@ roleRef: subjects: - kind: ServiceAccount name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ diff --git a/config/base/operator-controller/rbac/kustomization.yaml b/config/base/operator-controller/rbac/kustomization.yaml index 719df5654..47ddaa1ef 100644 --- a/config/base/operator-controller/rbac/kustomization.yaml +++ b/config/base/operator-controller/rbac/kustomization.yaml @@ -1,20 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + resources: -# All RBAC will be applied under this service account in -# the deployment namespace. You may comment out this resource -# if your manager will use a service account that exists at -# runtime. Be sure to update RoleBinding and ClusterRoleBinding -# subjects if changing service account names. - service_account.yaml - role.yaml - role_binding.yaml - leader_election_role.yaml - leader_election_role_binding.yaml -# The following resources are pre-defined roles for editors and viewers -# of APIs provided by this project. -- clusterextension_editor_role.yaml -- clusterextension_viewer_role.yaml - # The following RBAC configurations are used to protect # the metrics endpoint with authn/authz. These configurations # ensure that only authorized users and service accounts @@ -25,3 +18,8 @@ resources: - auth_proxy_role_binding.yaml - auth_proxy_client_clusterrole.yaml +# The following resources are pre-defined roles for editors and viewers +# of APIs provided by this project. +- clusterextension_editor_role.yaml +- clusterextension_viewer_role.yaml + diff --git a/config/base/operator-controller/rbac/leader_election_role_binding.yaml b/config/base/operator-controller/rbac/leader_election_role_binding.yaml index 1d1321ed4..3197cbe5d 100644 --- a/config/base/operator-controller/rbac/leader_election_role_binding.yaml +++ b/config/base/operator-controller/rbac/leader_election_role_binding.yaml @@ -9,4 +9,4 @@ roleRef: subjects: - kind: ServiceAccount name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ diff --git a/config/base/operator-controller/rbac/role.yaml b/config/base/operator-controller/rbac/role.yaml index be89deec1..1b4077e1c 100644 --- a/config/base/operator-controller/rbac/role.yaml +++ b/config/base/operator-controller/rbac/role.yaml @@ -62,7 +62,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: manager-role - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ rules: - apiGroups: - "" diff --git a/config/base/operator-controller/rbac/role_binding.yaml b/config/base/operator-controller/rbac/role_binding.yaml index fa331e3d4..98aa247be 100644 --- a/config/base/operator-controller/rbac/role_binding.yaml +++ b/config/base/operator-controller/rbac/role_binding.yaml @@ -9,13 +9,13 @@ roleRef: subjects: - kind: ServiceAccount name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: manager-rolebinding - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ roleRef: apiGroup: rbac.authorization.k8s.io kind: Role @@ -23,4 +23,4 @@ roleRef: subjects: - kind: ServiceAccount name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ diff --git a/config/base/operator-controller/rbac/service_account.yaml b/config/base/operator-controller/rbac/service_account.yaml index 7cd6025bf..0bb7c2c12 100644 --- a/config/base/operator-controller/rbac/service_account.yaml +++ b/config/base/operator-controller/rbac/service_account.yaml @@ -2,4 +2,4 @@ apiVersion: v1 kind: ServiceAccount metadata: name: controller-manager - namespace: system + namespace: __NAMESPACE_PLACEHOLDER__ diff --git a/config/catalogs/nginx-ingress/kustomization.yaml b/config/catalogs/nginx-ingress/kustomization.yaml deleted file mode 100644 index 7bdced5d6..000000000 --- a/config/catalogs/nginx-ingress/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: -- ../default -- resources/nginx_ingress.yaml -- https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml diff --git a/config/catalogs/nginx-ingress/resources/nginx_ingress.yaml b/config/catalogs/nginx-ingress/resources/nginx_ingress.yaml deleted file mode 100644 index 81f775fba..000000000 --- a/config/catalogs/nginx-ingress/resources/nginx_ingress.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: catalogd-ingress - namespace: olmv1-system -spec: - ingressClassName: nginx - rules: - - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: catalogd-service - port: - number: 80 diff --git a/config/components/cert-manager/catalogd_certificate.yaml b/config/components/cert-manager/catalogd_certificate.yaml new file mode 100644 index 000000000..3e780320c --- /dev/null +++ b/config/components/cert-manager/catalogd_certificate.yaml @@ -0,0 +1,17 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: catalogd-cert + namespace: __NAMESPACE_PLACEHOLDER__ +spec: + secretName: catalogd-cert-${VERSION} + dnsNames: + - catalogd-service.__NAMESPACE_PLACEHOLDER__.svc + - catalogd-service.__NAMESPACE_PLACEHOLDER__.svc.cluster.local + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + kind: Issuer + group: cert-manager.io + name: olmv1-ca diff --git a/config/components/cert-manager/kustomization.yaml b/config/components/cert-manager/kustomization.yaml new file mode 100644 index 000000000..7e3d129ac --- /dev/null +++ b/config/components/cert-manager/kustomization.yaml @@ -0,0 +1,36 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +resources: +- olmv1_ca_issuer.yaml +- catalogd_certificate.yaml +- operator_controller_certificate.yaml + +patches: + - target: + group: apps + version: v1 + kind: Deployment + labelSelector: control-plane=operator-controller-controller-manager + path: patches/operator_controller_deployment.yaml + + - target: + group: apps + version: v1 + kind: Deployment + labelSelector: control-plane=catalogd-controller-manager + path: patches/catalogd_deployment.yaml + + - target: + group: "" + version: v1 + kind: Service + labelSelector: control-plane=catalogd-controller-manager + path: patches/catalogd_service.yaml + + - target: + group: admissionregistration.k8s.io + version: v1 + kind: MutatingWebhookConfiguration + name: mutating-webhook-configuration + path: patches/catalogd_mutatingwebhookconfiguration.yaml \ No newline at end of file diff --git a/config/components/tls/ca/issuers.yaml b/config/components/cert-manager/olmv1_ca_issuer.yaml similarity index 81% rename from config/components/tls/ca/issuers.yaml rename to config/components/cert-manager/olmv1_ca_issuer.yaml index 00e149d56..53eddf48c 100644 --- a/config/components/tls/ca/issuers.yaml +++ b/config/components/cert-manager/olmv1_ca_issuer.yaml @@ -2,7 +2,7 @@ apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: self-sign-issuer - namespace: cert-manager + namespace: __NAMESPACE_PLACEHOLDER__ spec: selfSigned: {} --- @@ -10,7 +10,7 @@ apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: olmv1-ca - namespace: cert-manager + namespace: __NAMESPACE_PLACEHOLDER__ spec: isCA: true commonName: olmv1-ca @@ -27,9 +27,10 @@ spec: group: cert-manager.io --- apiVersion: cert-manager.io/v1 -kind: ClusterIssuer +kind: Issuer metadata: name: olmv1-ca + namespace: __NAMESPACE_PLACEHOLDER__ spec: ca: secretName: olmv1-ca diff --git a/config/components/cert-manager/operator_controller_certificate.yaml b/config/components/cert-manager/operator_controller_certificate.yaml new file mode 100644 index 000000000..50cb7c897 --- /dev/null +++ b/config/components/cert-manager/operator_controller_certificate.yaml @@ -0,0 +1,16 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: operator-controller-cert +spec: + secretName: operator-controller-cert + dnsNames: + - operator-controller-service.__NAMESPACE_PLACEHOLDER__.svc + - operator-controller-service.__NAMESPACE_PLACEHOLDER__.svc.cluster.local + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: olmv1-ca + kind: Issuer + group: cert-manager.io diff --git a/config/components/cert-manager/patches/catalogd_deployment.yaml b/config/components/cert-manager/patches/catalogd_deployment.yaml new file mode 100644 index 000000000..960e8a03e --- /dev/null +++ b/config/components/cert-manager/patches/catalogd_deployment.yaml @@ -0,0 +1,13 @@ +# operator-controller's server cert (e.g. for serving the catalogd API and prometheus metrics) +- op: add + path: /spec/template/spec/volumes/- + value: {"name":"server-cert","secret":{"secretName":"catalogd-cert-${VERSION}","optional":false,"items":[{"key":"tls.crt","path":"tls.crt"},{"key":"tls.key","path":"tls.key"}]}} +- op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: {"name":"server-cert","mountPath":"/var/server-cert"} +- op: add + path: /spec/template/spec/containers/0/args/- + value: "--tls-cert=/var/server-cert/tls.crt" +- op: add + path: /spec/template/spec/containers/0/args/- + value: "--tls-key=/var/server-cert/tls.key" diff --git a/config/components/tls/catalogd/patches/catalogd_webhook.yaml b/config/components/cert-manager/patches/catalogd_mutatingwebhookconfiguration.yaml similarity index 64% rename from config/components/tls/catalogd/patches/catalogd_webhook.yaml rename to config/components/cert-manager/patches/catalogd_mutatingwebhookconfiguration.yaml index cf1a39ec3..725506c3e 100644 --- a/config/components/tls/catalogd/patches/catalogd_webhook.yaml +++ b/config/components/cert-manager/patches/catalogd_mutatingwebhookconfiguration.yaml @@ -1,3 +1,3 @@ - op: add path: /metadata/annotations/cert-manager.io~1inject-ca-from-secret - value: cert-manager/olmv1-ca + value: __NAMESPACE_PLACEHOLDER__/olmv1-ca diff --git a/config/components/tls/catalogd/patches/catalogd_service_port.yaml b/config/components/cert-manager/patches/catalogd_service.yaml similarity index 100% rename from config/components/tls/catalogd/patches/catalogd_service_port.yaml rename to config/components/cert-manager/patches/catalogd_service.yaml diff --git a/config/components/cert-manager/patches/operator_controller_deployment.yaml b/config/components/cert-manager/patches/operator_controller_deployment.yaml new file mode 100644 index 000000000..2554f109b --- /dev/null +++ b/config/components/cert-manager/patches/operator_controller_deployment.yaml @@ -0,0 +1,24 @@ +# operator-controller's server cert (e.g. for serving prometheus metrics) +- op: add + path: /spec/template/spec/volumes/- + value: {"name":"server-cert", "secret":{"secretName":"operator-controller-cert", "optional": false, "items": [{"key": "tls.crt", "path": "tls.cert"}, {"key": "tls.key", "path": "tls.key"}]}} +- op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: {"name":"server-cert", "readOnly": true, "mountPath":"/var/certs/server-cert"} +- op: add + path: /spec/template/spec/containers/0/args/- + value: "--tls-cert=/var/certs/server-cert/tls.cert" +- op: add + path: /spec/template/spec/containers/0/args/- + value: "--tls-key=/var/certs/server-cert/tls.key" + +# catalogd CA, so that operator-controller's http client can verify catalogd's server cert +- op: add + path: /spec/template/spec/volumes/- + value: {"name":"catalogd-ca", "secret":{"secretName":"catalogd-cert-${VERSION}", "optional": false, "items":[{"key": "ca.crt", "path": "ca.crt"}]}} +- op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: {"name":"catalogd-ca", "readOnly": true, "mountPath":"/var/certs/catalogd-ca"} +- op: add + path: /spec/template/spec/containers/0/args/- + value: "--catalogd-cas-dir=/var/certs/catalogd-ca" diff --git a/config/components/coverage/kustomization.yaml b/config/components/coverage/kustomization.yaml deleted file mode 100644 index 5522eb7f8..000000000 --- a/config/components/coverage/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1alpha1 -kind: Component -namespace: olmv1-system -resources: -- manager_e2e_coverage_pvc.yaml -- manager_e2e_coverage_copy_pod.yaml -patches: -- path: manager_e2e_coverage_patch.yaml diff --git a/config/components/coverage/manager_e2e_coverage_patch.yaml b/config/components/coverage/manager_e2e_coverage_patch.yaml deleted file mode 100644 index 171a1607c..000000000 --- a/config/components/coverage/manager_e2e_coverage_patch.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: operator-controller-controller-manager - namespace: olmv1-system -spec: - template: - spec: - containers: - - name: manager - env: - - name: GOCOVERDIR - value: /e2e-coverage - volumeMounts: - - name: e2e-coverage-volume - mountPath: /e2e-coverage - volumes: - - name: e2e-coverage-volume - persistentVolumeClaim: - claimName: e2e-coverage diff --git a/config/components/e2e/cert-manager-namespace/e2e_cluster_issuer.yaml b/config/components/e2e/cert-manager-namespace/e2e_cluster_issuer.yaml new file mode 100644 index 000000000..cf56f707e --- /dev/null +++ b/config/components/e2e/cert-manager-namespace/e2e_cluster_issuer.yaml @@ -0,0 +1,35 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: e2e-self-sign-issuer + namespace: cert-manager +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: e2e-ca + namespace: cert-manager +spec: + isCA: true + commonName: e2e-ca + secretName: e2e-ca + secretTemplate: + annotations: + cert-manager.io/allow-direct-injection: "true" + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: e2e-self-sign-issuer + kind: Issuer + group: cert-manager.io +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: e2e-ca +spec: + ca: + secretName: e2e-ca diff --git a/config/components/e2e/cert-manager-namespace/kustomization.yaml b/config/components/e2e/cert-manager-namespace/kustomization.yaml new file mode 100644 index 000000000..84b2e1f29 --- /dev/null +++ b/config/components/e2e/cert-manager-namespace/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +resources: + - e2e_cluster_issuer.yaml \ No newline at end of file diff --git a/config/components/coverage/manager_e2e_coverage_copy_pod.yaml b/config/components/e2e/install-namespace/coverage_copy_pod.yaml similarity index 96% rename from config/components/coverage/manager_e2e_coverage_copy_pod.yaml rename to config/components/e2e/install-namespace/coverage_copy_pod.yaml index 7794ba97d..5c5c97bf7 100644 --- a/config/components/coverage/manager_e2e_coverage_copy_pod.yaml +++ b/config/components/e2e/install-namespace/coverage_copy_pod.yaml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Pod metadata: name: e2e-coverage-copy-pod + namespace: olmv1-system spec: restartPolicy: Never securityContext: diff --git a/config/components/coverage/manager_e2e_coverage_pvc.yaml b/config/components/e2e/install-namespace/coverage_pvc.yaml similarity index 86% rename from config/components/coverage/manager_e2e_coverage_pvc.yaml rename to config/components/e2e/install-namespace/coverage_pvc.yaml index 126d4d4e6..02c84acfd 100644 --- a/config/components/coverage/manager_e2e_coverage_pvc.yaml +++ b/config/components/e2e/install-namespace/coverage_pvc.yaml @@ -2,6 +2,7 @@ apiVersion: v1 kind: PersistentVolumeClaim metadata: name: e2e-coverage + namespace: olmv1-system spec: accessModes: - ReadWriteOnce diff --git a/config/components/e2e/install-namespace/e2e_dummy_cert.yaml b/config/components/e2e/install-namespace/e2e_dummy_cert.yaml new file mode 100644 index 000000000..e53815f4b --- /dev/null +++ b/config/components/e2e/install-namespace/e2e_dummy_cert.yaml @@ -0,0 +1,15 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: e2e-dummy-cert + namespace: olmv1-system +spec: + secretName: e2e-dummy-cert + commonName: e2e-dummy-cert + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + kind: ClusterIssuer + group: cert-manager.io + name: e2e-ca diff --git a/config/components/e2e/install-namespace/kustomization.yaml b/config/components/e2e/install-namespace/kustomization.yaml new file mode 100644 index 000000000..ab8550b02 --- /dev/null +++ b/config/components/e2e/install-namespace/kustomization.yaml @@ -0,0 +1,23 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +resources: + - coverage_pvc.yaml + - coverage_copy_pod.yaml + - registries_conf_configmap.yaml + - e2e_dummy_cert.yaml + +patches: + - target: + group: apps + version: v1 + kind: Deployment + labelSelector: control-plane=operator-controller-controller-manager + path: patches/operator_controller_deployment.yaml + + - target: + group: apps + version: v1 + kind: Deployment + labelSelector: control-plane=catalogd-controller-manager + path: patches/catalogd_deployment.yaml diff --git a/config/components/e2e/install-namespace/patches/catalogd_deployment.yaml b/config/components/e2e/install-namespace/patches/catalogd_deployment.yaml new file mode 100644 index 000000000..f5d6f2cb9 --- /dev/null +++ b/config/components/e2e/install-namespace/patches/catalogd_deployment.yaml @@ -0,0 +1,10 @@ +# Use the e2e-ca so that catalogd can communicate with the e2e registry. +- op: add + path: /spec/template/spec/volumes/- + value: {"name":"e2e-registry-ca", "secret":{"secretName":"e2e-dummy-cert", "optional": false, "items":[{"key": "ca.crt", "path": "ca.crt"}]}} +- op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: {"name":"e2e-registry-ca", "readOnly": true, "mountPath":"/var/certs/e2e-registry-ca"} +- op: add + path: /spec/template/spec/containers/0/args/- + value: "--pull-cas-dir=/var/certs/e2e-registry-ca" \ No newline at end of file diff --git a/config/components/e2e/install-namespace/patches/operator_controller_deployment.yaml b/config/components/e2e/install-namespace/patches/operator_controller_deployment.yaml new file mode 100644 index 000000000..550321c29 --- /dev/null +++ b/config/components/e2e/install-namespace/patches/operator_controller_deployment.yaml @@ -0,0 +1,32 @@ +# Use the e2e-ca so that operator-controller can communicate with the e2e registry. +- op: add + path: /spec/template/spec/volumes/- + value: {"name":"e2e-registry-ca", "secret":{"secretName":"e2e-dummy-cert", "optional": false, "items":[{"key": "ca.crt", "path": "ca.crt"}]}} +- op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: {"name":"e2e-registry-ca", "readOnly": true, "mountPath":"/var/certs/e2e-registry-ca"} +- op: add + path: /spec/template/spec/containers/0/args/- + value: "--pull-cas-dir=/var/certs/e2e-registry-ca" + +# Setup a custom /etc/containers/registries.conf file, used to verify containers/image integration in e2e tests. +- op: add + path: /spec/template/spec/volumes/- + value: {"name":"e2e-registries-conf", "configMap":{"name":"e2e-registries-conf"}} +- op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: {"name":"e2e-registries-conf", "readOnly": true, "mountPath":"/etc/containers"} + +# Setup e2e code coverage +- op: add + path: /spec/template/spec/containers/0/env + value: [] +- op: add + path: /spec/template/spec/containers/0/env/- + value: {"name":"GOCOVERDIR","value":"/e2e-coverage"} +- op: add + path: /spec/template/spec/volumes/- + value: {"name":"e2e-coverage-volume", "persistentVolumeClaim":{"claimName":"e2e-coverage"}} +- op: add + path: /spec/template/spec/containers/0/volumeMounts/- + value: {"name":"e2e-coverage-volume", "mountPath":"/e2e-coverage"} \ No newline at end of file diff --git a/config/components/registries-conf/registries_conf_configmap.yaml b/config/components/e2e/install-namespace/registries_conf_configmap.yaml similarity index 91% rename from config/components/registries-conf/registries_conf_configmap.yaml rename to config/components/e2e/install-namespace/registries_conf_configmap.yaml index 2604c78f5..e216113a7 100644 --- a/config/components/registries-conf/registries_conf_configmap.yaml +++ b/config/components/e2e/install-namespace/registries_conf_configmap.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: e2e-registries-conf - namespace: system + namespace: olmv1-system data: registries.conf: | [[registry]] diff --git a/config/components/e2e/registry-namespace/certificate.yaml b/config/components/e2e/registry-namespace/certificate.yaml new file mode 100644 index 000000000..86dd1e07b --- /dev/null +++ b/config/components/e2e/registry-namespace/certificate.yaml @@ -0,0 +1,18 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: operator-controller-e2e-registry + namespace: operator-controller-e2e +spec: + secretName: operator-controller-e2e-registry + isCA: true + dnsNames: + - docker-registry.operator-controller-e2e.svc + - docker-registry.operator-controller-e2e.svc.cluster.local + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: e2e-ca + kind: ClusterIssuer + group: cert-manager.io diff --git a/config/components/e2e/registry-namespace/deployment.yaml b/config/components/e2e/registry-namespace/deployment.yaml new file mode 100644 index 000000000..0d4900d5c --- /dev/null +++ b/config/components/e2e/registry-namespace/deployment.yaml @@ -0,0 +1,35 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: docker-registry + namespace: operator-controller-e2e + labels: + app: registry +spec: + replicas: 1 + selector: + matchLabels: + app: registry + template: + metadata: + labels: + app: registry + spec: + containers: + - name: registry + image: registry:3 + imagePullPolicy: IfNotPresent + volumeMounts: + - name: certs-vol + mountPath: "/certs" + env: + - name: REGISTRY_HTTP_ADDR + value: ":5000" + - name: REGISTRY_HTTP_TLS_CERTIFICATE + value: "/certs/tls.crt" + - name: REGISTRY_HTTP_TLS_KEY + value: "/certs/tls.key" + volumes: + - name: certs-vol + secret: + secretName: operator-controller-e2e-registry \ No newline at end of file diff --git a/config/components/e2e/registry-namespace/kustomization.yaml b/config/components/e2e/registry-namespace/kustomization.yaml new file mode 100644 index 000000000..e3d92ae84 --- /dev/null +++ b/config/components/e2e/registry-namespace/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +resources: + - namespace.yaml + - certificate.yaml + - deployment.yaml + - service.yaml \ No newline at end of file diff --git a/config/components/e2e/registry-namespace/namespace.yaml b/config/components/e2e/registry-namespace/namespace.yaml new file mode 100644 index 000000000..1cfb19af0 --- /dev/null +++ b/config/components/e2e/registry-namespace/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: operator-controller-e2e \ No newline at end of file diff --git a/config/components/e2e/registry-namespace/service.yaml b/config/components/e2e/registry-namespace/service.yaml new file mode 100644 index 000000000..114461d77 --- /dev/null +++ b/config/components/e2e/registry-namespace/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: docker-registry + namespace: operator-controller-e2e +spec: + selector: + app: registry + ports: + - name: http + port: 5000 + targetPort: 5000 + nodePort: 30000 + type: NodePort \ No newline at end of file diff --git a/config/components/olmv1-system-namespace/kustomization.yaml b/config/components/olmv1-system-namespace/kustomization.yaml new file mode 100644 index 000000000..1509aba84 --- /dev/null +++ b/config/components/olmv1-system-namespace/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +resources: + - namespace.yaml + +replacements: + - path: namespace-replacements.yaml diff --git a/config/components/olmv1-system-namespace/namespace-replacements.yaml b/config/components/olmv1-system-namespace/namespace-replacements.yaml new file mode 100644 index 000000000..7393ec08d --- /dev/null +++ b/config/components/olmv1-system-namespace/namespace-replacements.yaml @@ -0,0 +1,22 @@ +source: + kind: Namespace + fieldPath: .metadata.name +targets: + - select: + kind: Certificate + reject: + - name: olmv1-ca + fieldPaths: + - "spec.dnsNames.*" + options: + delimiter: "." + index: 1 + create: false + - select: + kind: MutatingWebhookConfiguration + fieldPaths: + - "metadata.annotations.[cert-manager.io/inject-ca-from-secret]" + options: + delimiter: "/" + index: 0 + create: false \ No newline at end of file diff --git a/config/base/common/namespace.yaml b/config/components/olmv1-system-namespace/namespace.yaml similarity index 75% rename from config/base/common/namespace.yaml rename to config/components/olmv1-system-namespace/namespace.yaml index 99d47415f..f49dca111 100644 --- a/config/base/common/namespace.yaml +++ b/config/components/olmv1-system-namespace/namespace.yaml @@ -2,7 +2,6 @@ apiVersion: v1 kind: Namespace metadata: labels: - app.kubernetes.io/part-of: olm pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/enforce-version: latest - name: system + name: olmv1-system diff --git a/config/components/registries-conf/kustomization.yaml b/config/components/registries-conf/kustomization.yaml deleted file mode 100644 index e48262429..000000000 --- a/config/components/registries-conf/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1alpha1 -kind: Component -namespace: olmv1-system -resources: -- registries_conf_configmap.yaml -patches: -- path: manager_e2e_registries_conf_patch.yaml diff --git a/config/components/registries-conf/manager_e2e_registries_conf_patch.yaml b/config/components/registries-conf/manager_e2e_registries_conf_patch.yaml deleted file mode 100644 index aa08a3d24..000000000 --- a/config/components/registries-conf/manager_e2e_registries_conf_patch.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: operator-controller-controller-manager - namespace: olmv1-system -spec: - template: - spec: - containers: - - name: manager - volumeMounts: - - name: e2e-registries-conf - mountPath: /etc/containers - volumes: - - name: e2e-registries-conf - configMap: - name: e2e-registries-conf diff --git a/config/base/common/kustomization.yaml b/config/components/tilt/kustomization.yaml similarity index 69% rename from config/base/common/kustomization.yaml rename to config/components/tilt/kustomization.yaml index c313b5408..d51f05d71 100644 --- a/config/base/common/kustomization.yaml +++ b/config/components/tilt/kustomization.yaml @@ -1,4 +1,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization -resources: -- namespace.yaml + +patches: + + diff --git a/config/components/tls/ca/kustomization.yaml b/config/components/tls/ca/kustomization.yaml deleted file mode 100644 index 5cbe13ad2..000000000 --- a/config/components/tls/ca/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1alpha1 -kind: Component -# No namespace is specified here, otherwise, it will overwrite _all_ the other namespaces! -resources: -- issuers.yaml diff --git a/config/components/tls/catalogd/kustomization.yaml b/config/components/tls/catalogd/kustomization.yaml deleted file mode 100644 index f603a0099..000000000 --- a/config/components/tls/catalogd/kustomization.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1alpha1 -kind: Component -namespace: olmv1-system -resources: -- resources/certificate.yaml -patches: -- target: - kind: Service - labelSelector: app.kubernetes.io/name=catalogd - path: patches/catalogd_service_port.yaml -- target: - kind: Deployment - labelSelector: control-plane=catalogd-controller-manager - path: patches/manager_deployment_certs.yaml -- target: - kind: Deployment - labelSelector: control-plane=catalogd-controller-manager - path: patches/manager_deployment_cacerts.yaml -- target: - group: admissionregistration.k8s.io - kind: MutatingWebhookConfiguration - name: mutating-webhook-configuration - version: v1 - path: patches/catalogd_webhook.yaml diff --git a/config/components/tls/catalogd/patches/manager_deployment_cacerts.yaml b/config/components/tls/catalogd/patches/manager_deployment_cacerts.yaml deleted file mode 100644 index 6b0816706..000000000 --- a/config/components/tls/catalogd/patches/manager_deployment_cacerts.yaml +++ /dev/null @@ -1,9 +0,0 @@ -- op: add - path: /spec/template/spec/volumes/- - value: {"name":"olmv1-certificate", "secret":{"secretName":"catalogd-service-cert-git-version", "optional": false, "items": [{"key": "ca.crt", "path": "olm-ca.crt"}]}} -- op: add - path: /spec/template/spec/containers/0/volumeMounts/- - value: {"name":"olmv1-certificate", "readOnly": true, "mountPath":"/var/ca-certs/"} -- op: add - path: /spec/template/spec/containers/0/args/- - value: "--pull-cas-dir=/var/ca-certs" diff --git a/config/components/tls/catalogd/patches/manager_deployment_certs.yaml b/config/components/tls/catalogd/patches/manager_deployment_certs.yaml deleted file mode 100644 index 3d8b33ac3..000000000 --- a/config/components/tls/catalogd/patches/manager_deployment_certs.yaml +++ /dev/null @@ -1,12 +0,0 @@ -- op: add - path: /spec/template/spec/volumes/- - value: {"name":"catalogserver-certs", "secret":{"secretName":"catalogd-service-cert-git-version"}} -- op: add - path: /spec/template/spec/containers/0/volumeMounts/- - value: {"name":"catalogserver-certs", "mountPath":"/var/certs"} -- op: add - path: /spec/template/spec/containers/0/args/- - value: "--tls-cert=/var/certs/tls.crt" -- op: add - path: /spec/template/spec/containers/0/args/- - value: "--tls-key=/var/certs/tls.key" diff --git a/config/components/tls/catalogd/resources/certificate.yaml b/config/components/tls/catalogd/resources/certificate.yaml deleted file mode 100644 index cacb0bc9b..000000000 --- a/config/components/tls/catalogd/resources/certificate.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: catalogd-service-cert - namespace: system -spec: - secretName: catalogd-service-cert-git-version - dnsNames: - - localhost - - catalogd-service.olmv1-system.svc - - catalogd-service.olmv1-system.svc.cluster.local - privateKey: - algorithm: ECDSA - size: 256 - issuerRef: - kind: ClusterIssuer - group: cert-manager.io - name: olmv1-ca diff --git a/config/components/tls/operator-controller/kustomization.yaml b/config/components/tls/operator-controller/kustomization.yaml deleted file mode 100644 index 6c4e13975..000000000 --- a/config/components/tls/operator-controller/kustomization.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1alpha1 -kind: Component -namespace: olmv1-system -resources: -- resources/manager_cert.yaml -patches: -- target: - kind: Deployment - name: controller-manager - labelSelector: control-plane=operator-controller-controller-manager - path: patches/manager_deployment_cert.yaml diff --git a/config/components/tls/operator-controller/patches/manager_deployment_cert.yaml b/config/components/tls/operator-controller/patches/manager_deployment_cert.yaml deleted file mode 100644 index 8fbdb5592..000000000 --- a/config/components/tls/operator-controller/patches/manager_deployment_cert.yaml +++ /dev/null @@ -1,18 +0,0 @@ -- op: add - path: /spec/template/spec/volumes/- - value: {"name":"olmv1-certificate", "secret":{"secretName":"olmv1-cert", "optional": false, "items": [{"key": "ca.crt", "path": "olm-ca.crt"}, {"key": "tls.crt", "path": "tls.cert"}, {"key": "tls.key", "path": "tls.key"}]}} -- op: add - path: /spec/template/spec/containers/0/volumeMounts/- - value: {"name":"olmv1-certificate", "readOnly": true, "mountPath":"/var/certs/"} -- op: add - path: /spec/template/spec/containers/0/args/- - value: "--catalogd-cas-dir=/var/certs" -- op: add - path: /spec/template/spec/containers/0/args/- - value: "--pull-cas-dir=/var/certs" -- op: add - path: /spec/template/spec/containers/0/args/- - value: "--tls-cert=/var/certs/tls.cert" -- op: add - path: /spec/template/spec/containers/0/args/- - value: "--tls-key=/var/certs/tls.key" diff --git a/config/components/tls/operator-controller/resources/manager_cert.yaml b/config/components/tls/operator-controller/resources/manager_cert.yaml deleted file mode 100644 index 96f131b7e..000000000 --- a/config/components/tls/operator-controller/resources/manager_cert.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: olmv1-cert -spec: - secretName: olmv1-cert - dnsNames: - - operator-controller-service.olmv1-system.svc - - operator-controller-service.olmv1-system.svc.cluster.local - privateKey: - algorithm: ECDSA - size: 256 - issuerRef: - name: olmv1-ca - kind: ClusterIssuer - group: cert-manager.io diff --git a/config/overlays/basic-olm/kustomization.yaml b/config/overlays/basic-olm/kustomization.yaml deleted file mode 100644 index 5975b3c04..000000000 --- a/config/overlays/basic-olm/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# kustomization file for based, non-secure OLMv1 -# DO NOT ADD A NAMESPACE HERE -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- ../../base/catalogd -- ../../base/operator-controller -- ../../base/common diff --git a/config/overlays/cert-manager/kustomization.yaml b/config/overlays/cert-manager/kustomization.yaml deleted file mode 100644 index ea113bb9d..000000000 --- a/config/overlays/cert-manager/kustomization.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# kustomization file for secure OLMv1 -# DO NOT ADD A NAMESPACE HERE -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- ../../base/catalogd -- ../../base/operator-controller -- ../../base/common -components: -- ../../components/tls/catalogd -- ../../components/tls/operator-controller -# ca must be last other components will overwrite the namespaces -- ../../components/tls/ca diff --git a/config/overlays/community-e2e/kustomization.yaml b/config/overlays/community-e2e/kustomization.yaml new file mode 100644 index 000000000..96e430fa8 --- /dev/null +++ b/config/overlays/community-e2e/kustomization.yaml @@ -0,0 +1,11 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../community + +components: + - ../../components/e2e/install-namespace + - ../../components/e2e/cert-manager-namespace + - ../../components/e2e/registry-namespace + diff --git a/config/overlays/community-tilt/kustomization.yaml b/config/overlays/community-tilt/kustomization.yaml new file mode 100644 index 000000000..f054066ed --- /dev/null +++ b/config/overlays/community-tilt/kustomization.yaml @@ -0,0 +1,15 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../community + +patches: + - target: + kind: Deployment + name: catalogd-controller-manager + path: patches/catalogd-deployment.yaml + - target: + kind: Deployment + name: operator-controller-controller-manager + path: patches/operator-controller-deployment.yaml diff --git a/config/overlays/tilt-local-dev/catalogd/patches/dev-deployment.yaml b/config/overlays/community-tilt/patches/catalogd-deployment.yaml similarity index 87% rename from config/overlays/tilt-local-dev/catalogd/patches/dev-deployment.yaml rename to config/overlays/community-tilt/patches/catalogd-deployment.yaml index 4df906921..e1407f121 100644 --- a/config/overlays/tilt-local-dev/catalogd/patches/dev-deployment.yaml +++ b/config/overlays/community-tilt/patches/catalogd-deployment.yaml @@ -7,4 +7,4 @@ value: null - op: remove # remove --leader-elect so container doesn't restart during breakpoints - path: /spec/template/spec/containers/0/args/0 + path: /spec/template/spec/containers/0/args/0 \ No newline at end of file diff --git a/config/overlays/tilt-local-dev/operator-controller/patches/dev-deployment.yaml b/config/overlays/community-tilt/patches/operator-controller-deployment.yaml similarity index 87% rename from config/overlays/tilt-local-dev/operator-controller/patches/dev-deployment.yaml rename to config/overlays/community-tilt/patches/operator-controller-deployment.yaml index b273a0c9b..44d7b6a47 100644 --- a/config/overlays/tilt-local-dev/operator-controller/patches/dev-deployment.yaml +++ b/config/overlays/community-tilt/patches/operator-controller-deployment.yaml @@ -7,4 +7,4 @@ value: null - op: remove # remove --leader-elect so container doesn't restart during breakpoints - path: /spec/template/spec/containers/0/args/2 + path: /spec/template/spec/containers/0/args/2 \ No newline at end of file diff --git a/config/overlays/community/kustomization.yaml b/config/overlays/community/kustomization.yaml new file mode 100644 index 000000000..c1a29c4e1 --- /dev/null +++ b/config/overlays/community/kustomization.yaml @@ -0,0 +1,20 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: olmv1-system + +labels: + - pairs: + app.kubernetes.io/part-of: olm + includeTemplates: false + includeSelectors: false + +resources: +- ../../base/ + +components: +- ../../components/cert-manager +- ../../components/olmv1-system-namespace + + + diff --git a/config/overlays/default-catalogs/kustomization.yaml b/config/overlays/default-catalogs/kustomization.yaml new file mode 100644 index 000000000..1654e6c26 --- /dev/null +++ b/config/overlays/default-catalogs/kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +labels: + - pairs: + app.kubernetes.io/part-of: olm + includeTemplates: false + includeSelectors: false + +resources: +- operatorhubio_clustercatalog.yaml + + + diff --git a/config/samples/catalogd_operatorcatalog.yaml b/config/overlays/default-catalogs/operatorhubio_clustercatalog.yaml similarity index 100% rename from config/samples/catalogd_operatorcatalog.yaml rename to config/overlays/default-catalogs/operatorhubio_clustercatalog.yaml diff --git a/config/overlays/e2e/kustomization.yaml b/config/overlays/e2e/kustomization.yaml deleted file mode 100644 index bc83e9fd3..000000000 --- a/config/overlays/e2e/kustomization.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# kustomization file for all the e2e's -# DO NOT ADD A NAMESPACE HERE -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- ../../base/catalogd -- ../../base/operator-controller -- ../../base/common -components: -- ../../components/tls/catalogd -- ../../components/tls/operator-controller -- ../../components/coverage -- ../../components/registries-conf -# ca must be last or other components will overwrite the namespaces -- ../../components/tls/ca diff --git a/config/overlays/tilt-local-dev/catalogd/kustomization.yaml b/config/overlays/tilt-local-dev/catalogd/kustomization.yaml deleted file mode 100644 index 846656bb4..000000000 --- a/config/overlays/tilt-local-dev/catalogd/kustomization.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# kustomization file for secure operator-controller -# DO NOT ADD A NAMESPACE HERE -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- ../../../base/catalogd -- ../../../base/common -components: -- ../../../components/tls/catalogd -# ca must be last or other components will overwrite the namespaces -- ../../../components/tls/ca - -patches: - - target: - kind: Deployment - name: catalogd-controller-manager - path: patches/dev-deployment.yaml diff --git a/config/overlays/tilt-local-dev/operator-controller/kustomization.yaml b/config/overlays/tilt-local-dev/operator-controller/kustomization.yaml deleted file mode 100644 index 403f2d102..000000000 --- a/config/overlays/tilt-local-dev/operator-controller/kustomization.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# kustomization file for secure operator-controller -# DO NOT ADD A NAMESPACE HERE -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- ../../../base/operator-controller -- ../../../base/common -components: -- ../../../components/tls/operator-controller -# ca must be last or other components will overwrite the namespaces -- ../../../components/tls/ca - -patches: - - target: - kind: Deployment - name: operator-controller-controller-manager - path: patches/dev-deployment.yaml diff --git a/config/samples/olm_v1_clusterextension.yaml b/config/samples/argocd_clusterextension.yaml similarity index 100% rename from config/samples/olm_v1_clusterextension.yaml rename to config/samples/argocd_clusterextension.yaml diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml deleted file mode 100644 index 2a64d96c2..000000000 --- a/config/samples/kustomization.yaml +++ /dev/null @@ -1,4 +0,0 @@ -## Append samples of your project ## -resources: -- olm_v1_clusterextension.yaml -#+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml deleted file mode 100644 index a5842de42..000000000 --- a/config/webhook/manifests.yaml +++ /dev/null @@ -1,27 +0,0 @@ ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: mutating-webhook-configuration -webhooks: -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /mutate-olm-operatorframework-io-v1-clustercatalog - failurePolicy: Fail - name: inject-metadata-name.olm.operatorframework.io - rules: - - apiGroups: - - olm.operatorframework.io - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - clustercatalogs - sideEffects: None - timeoutSeconds: 10 diff --git a/config/catalogs/clustercatalogs/default-catalogs.yaml b/dev-manifests/default-catalogs.yaml similarity index 78% rename from config/catalogs/clustercatalogs/default-catalogs.yaml rename to dev-manifests/default-catalogs.yaml index a656b3509..cb0ea87a4 100644 --- a/config/catalogs/clustercatalogs/default-catalogs.yaml +++ b/dev-manifests/default-catalogs.yaml @@ -1,11 +1,13 @@ apiVersion: olm.operatorframework.io/v1 kind: ClusterCatalog metadata: + labels: + app.kubernetes.io/part-of: olm name: operatorhubio - namespace: olmv1-system spec: + priority: 0 source: - type: Image image: - ref: quay.io/operatorhubio/catalog:latest pollIntervalMinutes: 10 + ref: quay.io/operatorhubio/catalog:latest + type: Image diff --git a/dev-manifests/operator-controller-dev.yaml b/dev-manifests/operator-controller-dev.yaml new file mode 100644 index 000000000..18f3a5dc9 --- /dev/null +++ b/dev-manifests/operator-controller-dev.yaml @@ -0,0 +1,1912 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/part-of: olm + pod-security.kubernetes.io/enforce: restricted + pod-security.kubernetes.io/enforce-version: latest + name: olmv1-system +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: clustercatalogs.olm.operatorframework.io +spec: + group: olm.operatorframework.io + names: + kind: ClusterCatalog + listKind: ClusterCatalogList + plural: clustercatalogs + singular: clustercatalog + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.lastUnpacked + name: LastUnpacked + type: date + - jsonPath: .status.conditions[?(@.type=="Serving")].status + name: Serving + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + ClusterCatalog enables users to make File-Based Catalog (FBC) catalog data available to the cluster. + For more information on FBC, see https://olm.operatorframework.io/docs/reference/file-based-catalogs/#docs + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + spec is the desired state of the ClusterCatalog. + spec is required. + The controller will work to ensure that the desired + catalog is unpacked and served over the catalog content HTTP server. + properties: + availabilityMode: + default: Available + description: |- + availabilityMode allows users to define how the ClusterCatalog is made available to clients on the cluster. + availabilityMode is optional. + + Allowed values are "Available" and "Unavailable" and omitted. + + When omitted, the default value is "Available". + + When set to "Available", the catalog contents will be unpacked and served over the catalog content HTTP server. + Setting the availabilityMode to "Available" tells clients that they should consider this ClusterCatalog + and its contents as usable. + + When set to "Unavailable", the catalog contents will no longer be served over the catalog content HTTP server. + When set to this availabilityMode it should be interpreted the same as the ClusterCatalog not existing. + Setting the availabilityMode to "Unavailable" can be useful in scenarios where a user may not want + to delete the ClusterCatalog all together, but would still like it to be treated as if it doesn't exist. + enum: + - Unavailable + - Available + type: string + priority: + default: 0 + description: |- + priority allows the user to define a priority for a ClusterCatalog. + priority is optional. + + A ClusterCatalog's priority is used by clients as a tie-breaker between ClusterCatalogs that meet the client's requirements. + A higher number means higher priority. + + It is up to clients to decide how to handle scenarios where multiple ClusterCatalogs with the same priority meet their requirements. + When deciding how to break the tie in this scenario, it is recommended that clients prompt their users for additional input. + + When omitted, the default priority is 0 because that is the zero value of integers. + + Negative numbers can be used to specify a priority lower than the default. + Positive numbers can be used to specify a priority higher than the default. + + The lowest possible value is -2147483648. + The highest possible value is 2147483647. + format: int32 + type: integer + source: + description: |- + source allows a user to define the source of a catalog. + A "catalog" contains information on content that can be installed on a cluster. + Providing a catalog source makes the contents of the catalog discoverable and usable by + other on-cluster components. + These on-cluster components may do a variety of things with this information, such as + presenting the content in a GUI dashboard or installing content from the catalog on the cluster. + The catalog source must contain catalog metadata in the File-Based Catalog (FBC) format. + For more information on FBC, see https://olm.operatorframework.io/docs/reference/file-based-catalogs/#docs. + source is a required field. + + Below is a minimal example of a ClusterCatalogSpec that sources a catalog from an image: + + source: + type: Image + image: + ref: quay.io/operatorhubio/catalog:latest + properties: + image: + description: |- + image is used to configure how catalog contents are sourced from an OCI image. + This field is required when type is Image, and forbidden otherwise. + properties: + pollIntervalMinutes: + description: |- + pollIntervalMinutes allows the user to set the interval, in minutes, at which the image source should be polled for new content. + pollIntervalMinutes is optional. + pollIntervalMinutes can not be specified when ref is a digest-based reference. + + When omitted, the image will not be polled for new content. + minimum: 1 + type: integer + ref: + description: |- + ref allows users to define the reference to a container image containing Catalog contents. + ref is required. + ref can not be more than 1000 characters. + + A reference can be broken down into 3 parts - the domain, name, and identifier. + + The domain is typically the registry where an image is located. + It must be alphanumeric characters (lowercase and uppercase) separated by the "." character. + Hyphenation is allowed, but the domain must start and end with alphanumeric characters. + Specifying a port to use is also allowed by adding the ":" character followed by numeric values. + The port must be the last value in the domain. + Some examples of valid domain values are "registry.mydomain.io", "quay.io", "my-registry.io:8080". + + The name is typically the repository in the registry where an image is located. + It must contain lowercase alphanumeric characters separated only by the ".", "_", "__", "-" characters. + Multiple names can be concatenated with the "/" character. + The domain and name are combined using the "/" character. + Some examples of valid name values are "operatorhubio/catalog", "catalog", "my-catalog.prod". + An example of the domain and name parts of a reference being combined is "quay.io/operatorhubio/catalog". + + The identifier is typically the tag or digest for an image reference and is present at the end of the reference. + It starts with a separator character used to distinguish the end of the name and beginning of the identifier. + For a digest-based reference, the "@" character is the separator. + For a tag-based reference, the ":" character is the separator. + An identifier is required in the reference. + + Digest-based references must contain an algorithm reference immediately after the "@" separator. + The algorithm reference must be followed by the ":" character and an encoded string. + The algorithm must start with an uppercase or lowercase alpha character followed by alphanumeric characters and may contain the "-", "_", "+", and "." characters. + Some examples of valid algorithm values are "sha256", "sha256+b64u", "multihash+base58". + The encoded string following the algorithm must be hex digits (a-f, A-F, 0-9) and must be a minimum of 32 characters. + + Tag-based references must begin with a word character (alphanumeric + "_") followed by word characters or ".", and "-" characters. + The tag must not be longer than 127 characters. + + An example of a valid digest-based image reference is "quay.io/operatorhubio/catalog@sha256:200d4ddb2a73594b91358fe6397424e975205bfbe44614f5846033cad64b3f05" + An example of a valid tag-based image reference is "quay.io/operatorhubio/catalog:latest" + maxLength: 1000 + type: string + x-kubernetes-validations: + - message: must start with a valid domain. valid domains must + be alphanumeric characters (lowercase and uppercase) separated + by the "." character. + rule: self.matches('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\b') + - message: a valid name is required. valid names must contain + lowercase alphanumeric characters separated only by the + ".", "_", "__", "-" characters. + rule: self.find('(\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') + != "" + - message: must end with a digest or a tag + rule: self.find('(@.*:)') != "" || self.find(':.*$') != + "" + - message: tag is invalid. the tag must not be more than 127 + characters + rule: 'self.find(''(@.*:)'') == "" ? (self.find('':.*$'') + != "" ? self.find('':.*$'').substring(1).size() <= 127 + : true) : true' + - message: tag is invalid. valid tags must begin with a word + character (alphanumeric + "_") followed by word characters + or ".", and "-" characters + rule: 'self.find(''(@.*:)'') == "" ? (self.find('':.*$'') + != "" ? self.find('':.*$'').matches('':[\\w][\\w.-]*$'') + : true) : true' + - message: digest algorithm is not valid. valid algorithms + must start with an uppercase or lowercase alpha character + followed by alphanumeric characters and may contain the + "-", "_", "+", and "." characters. + rule: 'self.find(''(@.*:)'') != "" ? self.find(''(@.*:)'').matches(''(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:])'') + : true' + - message: digest is not valid. the encoded string must be + at least 32 characters + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').substring(1).size() + >= 32 : true' + - message: digest is not valid. the encoded string must only + contain hex characters (A-F, a-f, 0-9) + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').matches('':[0-9A-Fa-f]*$'') + : true' + required: + - ref + type: object + x-kubernetes-validations: + - message: cannot specify pollIntervalMinutes while using digest-based + image + rule: 'self.ref.find(''(@.*:)'') != "" ? !has(self.pollIntervalMinutes) + : true' + type: + description: |- + type is a reference to the type of source the catalog is sourced from. + type is required. + + The only allowed value is "Image". + + When set to "Image", the ClusterCatalog content will be sourced from an OCI image. + When using an image source, the image field must be set and must be the only field defined for this type. + enum: + - Image + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: image is required when source type is Image, and forbidden + otherwise + rule: 'has(self.type) && self.type == ''Image'' ? has(self.image) + : !has(self.image)' + required: + - source + type: object + status: + description: |- + status contains information about the state of the ClusterCatalog such as: + - Whether or not the catalog contents are being served via the catalog content HTTP server + - Whether or not the ClusterCatalog is progressing to a new state + - A reference to the source from which the catalog contents were retrieved + properties: + conditions: + description: |- + conditions is a representation of the current state for this ClusterCatalog. + + The current condition types are Serving and Progressing. + + The Serving condition is used to represent whether or not the contents of the catalog is being served via the HTTP(S) web server. + When it has a status of True and a reason of Available, the contents of the catalog are being served. + When it has a status of False and a reason of Unavailable, the contents of the catalog are not being served because the contents are not yet available. + When it has a status of False and a reason of UserSpecifiedUnavailable, the contents of the catalog are not being served because the catalog has been intentionally marked as unavailable. + + The Progressing condition is used to represent whether or not the ClusterCatalog is progressing or is ready to progress towards a new state. + When it has a status of True and a reason of Retrying, there was an error in the progression of the ClusterCatalog that may be resolved on subsequent reconciliation attempts. + When it has a status of True and a reason of Succeeded, the ClusterCatalog has successfully progressed to a new state and is ready to continue progressing. + When it has a status of False and a reason of Blocked, there was an error in the progression of the ClusterCatalog that requires manual intervention for recovery. + + In the case that the Serving condition is True with reason Available and Progressing is True with reason Retrying, the previously fetched + catalog contents are still being served via the HTTP(S) web server while we are progressing towards serving a new version of the catalog + contents. This could occur when we've initially fetched the latest contents from the source for this catalog and when polling for changes + to the contents we identify that there are updates to the contents. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + lastUnpacked: + description: |- + lastUnpacked represents the last time the contents of the + catalog were extracted from their source format. As an example, + when using an Image source, the OCI image will be pulled and the + image layers written to a file-system backed cache. We refer to the + act of this extraction from the source format as "unpacking". + format: date-time + type: string + resolvedSource: + description: resolvedSource contains information about the resolved + source based on the source type. + properties: + image: + description: |- + image is a field containing resolution information for a catalog sourced from an image. + This field must be set when type is Image, and forbidden otherwise. + properties: + ref: + description: |- + ref contains the resolved image digest-based reference. + The digest format is used so users can use other tooling to fetch the exact + OCI manifests that were used to extract the catalog contents. + maxLength: 1000 + type: string + x-kubernetes-validations: + - message: must start with a valid domain. valid domains must + be alphanumeric characters (lowercase and uppercase) separated + by the "." character. + rule: self.matches('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\b') + - message: a valid name is required. valid names must contain + lowercase alphanumeric characters separated only by the + ".", "_", "__", "-" characters. + rule: self.find('(\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') + != "" + - message: must end with a digest + rule: self.find('(@.*:)') != "" + - message: digest algorithm is not valid. valid algorithms + must start with an uppercase or lowercase alpha character + followed by alphanumeric characters and may contain the + "-", "_", "+", and "." characters. + rule: 'self.find(''(@.*:)'') != "" ? self.find(''(@.*:)'').matches(''(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:])'') + : true' + - message: digest is not valid. the encoded string must be + at least 32 characters + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').substring(1).size() + >= 32 : true' + - message: digest is not valid. the encoded string must only + contain hex characters (A-F, a-f, 0-9) + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').matches('':[0-9A-Fa-f]*$'') + : true' + required: + - ref + type: object + type: + description: |- + type is a reference to the type of source the catalog is sourced from. + type is required. + + The only allowed value is "Image". + + When set to "Image", information about the resolved image source will be set in the 'image' field. + enum: + - Image + type: string + required: + - image + - type + type: object + x-kubernetes-validations: + - message: image is required when source type is Image, and forbidden + otherwise + rule: 'has(self.type) && self.type == ''Image'' ? has(self.image) + : !has(self.image)' + urls: + description: urls contains the URLs that can be used to access the + catalog. + properties: + base: + description: |- + base is a cluster-internal URL that provides endpoints for + accessing the content of the catalog. + + It is expected that clients append the path for the endpoint they wish + to access. + + Currently, only a single endpoint is served and is accessible at the path + /api/v1. + + The endpoints served for the v1 API are: + - /all - this endpoint returns the entirety of the catalog contents in the FBC format + + As the needs of users and clients of the evolve, new endpoints may be added. + maxLength: 525 + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: isURL(self) + - message: scheme must be either http or https + rule: 'isURL(self) ? (url(self).getScheme() == "http" || url(self).getScheme() + == "https") : true' + required: + - base + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: clusterextensions.olm.operatorframework.io +spec: + group: olm.operatorframework.io + names: + kind: ClusterExtension + listKind: ClusterExtensionList + plural: clusterextensions + singular: clusterextension + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.install.bundle.name + name: Installed Bundle + type: string + - jsonPath: .status.install.bundle.version + name: Version + type: string + - jsonPath: .status.conditions[?(@.type=='Installed')].status + name: Installed + type: string + - jsonPath: .status.conditions[?(@.type=='Progressing')].status + name: Progressing + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ClusterExtension is the Schema for the clusterextensions API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec is an optional field that defines the desired state + of the ClusterExtension. + properties: + install: + description: |- + install is an optional field used to configure the installation options + for the ClusterExtension such as the pre-flight check configuration. + properties: + preflight: + description: |- + preflight is an optional field that can be used to configure the checks that are + run before installation or upgrade of the content for the package specified in the packageName field. + + When specified, it replaces the default preflight configuration for install/upgrade actions. + When not specified, the default configuration will be used. + properties: + crdUpgradeSafety: + description: |- + crdUpgradeSafety is used to configure the CRD Upgrade Safety pre-flight + checks that run prior to upgrades of installed content. + + The CRD Upgrade Safety pre-flight check safeguards from unintended + consequences of upgrading a CRD, such as data loss. + properties: + enforcement: + description: |- + enforcement is a required field, used to configure the state of the CRD Upgrade Safety pre-flight check. + + Allowed values are "None" or "Strict". The default value is "Strict". + + When set to "None", the CRD Upgrade Safety pre-flight check will be skipped + when performing an upgrade operation. This should be used with caution as + unintended consequences such as data loss can occur. + + When set to "Strict", the CRD Upgrade Safety pre-flight check will be run when + performing an upgrade operation. + enum: + - None + - Strict + type: string + required: + - enforcement + type: object + required: + - crdUpgradeSafety + type: object + x-kubernetes-validations: + - message: at least one of [crdUpgradeSafety] are required when + preflight is specified + rule: has(self.crdUpgradeSafety) + type: object + x-kubernetes-validations: + - message: at least one of [preflight] are required when install is + specified + rule: has(self.preflight) + namespace: + description: |- + namespace is a reference to a Kubernetes namespace. + This is the namespace in which the provided ServiceAccount must exist. + It also designates the default namespace where namespace-scoped resources + for the extension are applied to the cluster. + Some extensions may contain namespace-scoped resources to be applied in other namespaces. + This namespace must exist. + + namespace is required, immutable, and follows the DNS label standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters or hyphens (-), + start and end with an alphanumeric character, and be no longer than 63 characters + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + maxLength: 63 + type: string + x-kubernetes-validations: + - message: namespace is immutable + rule: self == oldSelf + - message: namespace must be a valid DNS1123 label + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?$") + serviceAccount: + description: |- + serviceAccount is a reference to a ServiceAccount used to perform all interactions + with the cluster that are required to manage the extension. + The ServiceAccount must be configured with the necessary permissions to perform these interactions. + The ServiceAccount must exist in the namespace referenced in the spec. + serviceAccount is required. + properties: + name: + description: |- + name is a required, immutable reference to the name of the ServiceAccount + to be used for installation and management of the content for the package + specified in the packageName field. + + This ServiceAccount must exist in the installNamespace. + + name follows the DNS subdomain standard as defined in [RFC 1123]. + It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. + + Some examples of valid values are: + - some-serviceaccount + - 123-serviceaccount + - 1-serviceaccount-2 + - someserviceaccount + - some.serviceaccount + + Some examples of invalid values are: + - -some-serviceaccount + - some-serviceaccount- + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + maxLength: 253 + type: string + x-kubernetes-validations: + - message: name is immutable + rule: self == oldSelf + - message: name must be a valid DNS1123 subdomain. It must contain + only lowercase alphanumeric characters, hyphens (-) or periods + (.), start and end with an alphanumeric character, and be + no longer than 253 characters + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + required: + - name + type: object + source: + description: |- + source is a required field which selects the installation source of content + for this ClusterExtension. Selection is performed by setting the sourceType. + + Catalog is currently the only implemented sourceType, and setting the + sourcetype to "Catalog" requires the catalog field to also be defined. + + Below is a minimal example of a source definition (in yaml): + + source: + sourceType: Catalog + catalog: + packageName: example-package + properties: + catalog: + description: |- + catalog is used to configure how information is sourced from a catalog. + This field is required when sourceType is "Catalog", and forbidden otherwise. + properties: + channels: + description: |- + channels is an optional reference to a set of channels belonging to + the package specified in the packageName field. + + A "channel" is a package-author-defined stream of updates for an extension. + + Each channel in the list must follow the DNS subdomain standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. No more than 256 channels can be specified. + + When specified, it is used to constrain the set of installable bundles and + the automated upgrade path. This constraint is an AND operation with the + version field. For example: + - Given channel is set to "foo" + - Given version is set to ">=1.0.0, <1.5.0" + - Only bundles that exist in channel "foo" AND satisfy the version range comparison will be considered installable + - Automatic upgrades will be constrained to upgrade edges defined by the selected channel + + When unspecified, upgrade edges across all channels will be used to identify valid automatic upgrade paths. + + Some examples of valid values are: + - 1.1.x + - alpha + - stable + - stable-v1 + - v1-stable + - dev-preview + - preview + - community + + Some examples of invalid values are: + - -some-channel + - some-channel- + - thisisareallylongchannelnamethatisgreaterthanthemaximumlength + - original_40 + - --default-channel + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + items: + maxLength: 253 + type: string + x-kubernetes-validations: + - message: channels entries must be valid DNS1123 subdomains + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + maxItems: 256 + type: array + packageName: + description: |- + packageName is a reference to the name of the package to be installed + and is used to filter the content from catalogs. + + packageName is required, immutable, and follows the DNS subdomain standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. + + Some examples of valid values are: + - some-package + - 123-package + - 1-package-2 + - somepackage + + Some examples of invalid values are: + - -some-package + - some-package- + - thisisareallylongpackagenamethatisgreaterthanthemaximumlength + - some.package + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + maxLength: 253 + type: string + x-kubernetes-validations: + - message: packageName is immutable + rule: self == oldSelf + - message: packageName must be a valid DNS1123 subdomain. + It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric + character, and be no longer than 253 characters + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + selector: + description: |- + selector is an optional field that can be used + to filter the set of ClusterCatalogs used in the bundle + selection process. + + When unspecified, all ClusterCatalogs will be used in + the bundle selection process. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + upgradeConstraintPolicy: + default: CatalogProvided + description: |- + upgradeConstraintPolicy is an optional field that controls whether + the upgrade path(s) defined in the catalog are enforced for the package + referenced in the packageName field. + + Allowed values are: "CatalogProvided" or "SelfCertified", or omitted. + + When this field is set to "CatalogProvided", automatic upgrades will only occur + when upgrade constraints specified by the package author are met. + + When this field is set to "SelfCertified", the upgrade constraints specified by + the package author are ignored. This allows for upgrades and downgrades to + any version of the package. This is considered a dangerous operation as it + can lead to unknown and potentially disastrous outcomes, such as data + loss. It is assumed that users have independently verified changes when + using this option. + + When this field is omitted, the default value is "CatalogProvided". + enum: + - CatalogProvided + - SelfCertified + type: string + version: + description: |- + version is an optional semver constraint (a specific version or range of versions). When unspecified, the latest version available will be installed. + + Acceptable version ranges are no longer than 64 characters. + Version ranges are composed of comma- or space-delimited values and one or + more comparison operators, known as comparison strings. Additional + comparison strings can be added using the OR operator (||). + + # Range Comparisons + + To specify a version range, you can use a comparison string like ">=3.0, + <3.6". When specifying a range, automatic updates will occur within that + range. The example comparison string means "install any version greater than + or equal to 3.0.0 but less than 3.6.0.". It also states intent that if any + upgrades are available within the version range after initial installation, + those upgrades should be automatically performed. + + # Pinned Versions + + To specify an exact version to install you can use a version range that + "pins" to a specific version. When pinning to a specific version, no + automatic updates will occur. An example of a pinned version range is + "0.6.0", which means "only install version 0.6.0 and never + upgrade from this version". + + # Basic Comparison Operators + + The basic comparison operators and their meanings are: + - "=", equal (not aliased to an operator) + - "!=", not equal + - "<", less than + - ">", greater than + - ">=", greater than OR equal to + - "<=", less than OR equal to + + # Wildcard Comparisons + + You can use the "x", "X", and "*" characters as wildcard characters in all + comparison operations. Some examples of using the wildcard characters: + - "1.2.x", "1.2.X", and "1.2.*" is equivalent to ">=1.2.0, < 1.3.0" + - ">= 1.2.x", ">= 1.2.X", and ">= 1.2.*" is equivalent to ">= 1.2.0" + - "<= 2.x", "<= 2.X", and "<= 2.*" is equivalent to "< 3" + - "x", "X", and "*" is equivalent to ">= 0.0.0" + + # Patch Release Comparisons + + When you want to specify a minor version up to the next major version you + can use the "~" character to perform patch comparisons. Some examples: + - "~1.2.3" is equivalent to ">=1.2.3, <1.3.0" + - "~1" and "~1.x" is equivalent to ">=1, <2" + - "~2.3" is equivalent to ">=2.3, <2.4" + - "~1.2.x" is equivalent to ">=1.2.0, <1.3.0" + + # Major Release Comparisons + + You can use the "^" character to make major release comparisons after a + stable 1.0.0 version is published. If there is no stable version published, // minor versions define the stability level. Some examples: + - "^1.2.3" is equivalent to ">=1.2.3, <2.0.0" + - "^1.2.x" is equivalent to ">=1.2.0, <2.0.0" + - "^2.3" is equivalent to ">=2.3, <3" + - "^2.x" is equivalent to ">=2.0.0, <3" + - "^0.2.3" is equivalent to ">=0.2.3, <0.3.0" + - "^0.2" is equivalent to ">=0.2.0, <0.3.0" + - "^0.0.3" is equvalent to ">=0.0.3, <0.0.4" + - "^0.0" is equivalent to ">=0.0.0, <0.1.0" + - "^0" is equivalent to ">=0.0.0, <1.0.0" + + # OR Comparisons + You can use the "||" character to represent an OR operation in the version + range. Some examples: + - ">=1.2.3, <2.0.0 || >3.0.0" + - "^0 || ^3 || ^5" + + For more information on semver, please see https://semver.org/ + maxLength: 64 + type: string + x-kubernetes-validations: + - message: invalid version expression + rule: self.matches("^(\\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)\\s*(v?(0|[1-9]\\d*|[x|X|\\*])(\\.(0|[1-9]\\d*|x|X|\\*]))?(\\.(0|[1-9]\\d*|x|X|\\*))?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?)\\s*)((?:\\s+|,\\s*|\\s*\\|\\|\\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)\\s*(v?(0|[1-9]\\d*|x|X|\\*])(\\.(0|[1-9]\\d*|x|X|\\*))?(\\.(0|[1-9]\\d*|x|X|\\*]))?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?)\\s*)*$") + required: + - packageName + type: object + sourceType: + description: |- + sourceType is a required reference to the type of install source. + + Allowed values are "Catalog" + + When this field is set to "Catalog", information for determining the + appropriate bundle of content to install will be fetched from + ClusterCatalog resources existing on the cluster. + When using the Catalog sourceType, the catalog field must also be set. + enum: + - Catalog + type: string + required: + - sourceType + type: object + x-kubernetes-validations: + - message: catalog is required when sourceType is Catalog, and forbidden + otherwise + rule: 'has(self.sourceType) && self.sourceType == ''Catalog'' ? + has(self.catalog) : !has(self.catalog)' + required: + - namespace + - serviceAccount + - source + type: object + status: + description: status is an optional field that defines the observed state + of the ClusterExtension. + properties: + conditions: + description: |- + The set of condition types which apply to all spec.source variations are Installed and Progressing. + + The Installed condition represents whether or not the bundle has been installed for this ClusterExtension. + When Installed is True and the Reason is Succeeded, the bundle has been successfully installed. + When Installed is False and the Reason is Failed, the bundle has failed to install. + + The Progressing condition represents whether or not the ClusterExtension is advancing towards a new state. + When Progressing is True and the Reason is Succeeded, the ClusterExtension is making progress towards a new state. + When Progressing is True and the Reason is Retrying, the ClusterExtension has encountered an error that could be resolved on subsequent reconciliation attempts. + When Progressing is False and the Reason is Blocked, the ClusterExtension has encountered an error that requires manual intervention for recovery. + + When the ClusterExtension is sourced from a catalog, if may also communicate a deprecation condition. + These are indications from a package owner to guide users away from a particular package, channel, or bundle. + BundleDeprecated is set if the requested bundle version is marked deprecated in the catalog. + ChannelDeprecated is set if the requested channel is marked deprecated in the catalog. + PackageDeprecated is set if the requested package is marked deprecated in the catalog. + Deprecated is a rollup condition that is present when any of the deprecated conditions are present. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + install: + description: install is a representation of the current installation + status for this ClusterExtension. + properties: + bundle: + description: |- + bundle is a required field which represents the identifying attributes of a bundle. + + A "bundle" is a versioned set of content that represents the resources that + need to be applied to a cluster to install a package. + properties: + name: + description: |- + name is required and follows the DNS subdomain standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. + type: string + x-kubernetes-validations: + - message: packageName must be a valid DNS1123 subdomain. + It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric + character, and be no longer than 253 characters + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + version: + description: |- + version is a required field and is a reference to the version that this bundle represents + version follows the semantic versioning standard as defined in https://semver.org/. + type: string + x-kubernetes-validations: + - message: version must be well-formed semver + rule: self.matches("^([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(-([-0-9A-Za-z]+(\\.[-0-9A-Za-z]+)*))?(\\+([-0-9A-Za-z]+(-\\.[-0-9A-Za-z]+)*))?") + required: + - name + - version + type: object + required: + - bundle + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-leader-election-role + namespace: olmv1-system +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-leader-election-role + namespace: olmv1-system +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-role + namespace: olmv1-system +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-manager-role +rules: +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs/finalizers + verbs: + - update +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs/status + verbs: + - get + - patch + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-clusterextension-editor-role +rules: +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-clusterextension-viewer-role +rules: +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-role +rules: +- apiGroups: + - "" + resources: + - serviceaccounts/token + verbs: + - create +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs + verbs: + - get + - list + - watch +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions/finalizers + verbs: + - update +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions/status + verbs: + - patch + - update +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-leader-election-rolebinding + namespace: olmv1-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: catalogd-leader-election-role +subjects: +- kind: ServiceAccount + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-leader-election-rolebinding + namespace: olmv1-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: operator-controller-leader-election-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-rolebinding + namespace: olmv1-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: operator-controller-manager-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: catalogd-manager-role +subjects: +- kind: ServiceAccount + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: catalogd-proxy-role +subjects: +- kind: ServiceAccount + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: operator-controller-manager-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: operator-controller-proxy-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + control-plane: catalogd-controller-manager + name: catalogd-service + namespace: olmv1-system +spec: + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + - name: webhook + port: 9443 + protocol: TCP + targetPort: 9443 + - name: metrics + port: 7443 + protocol: TCP + targetPort: 7443 + selector: + control-plane: catalogd-controller-manager +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + control-plane: operator-controller-controller-manager + name: operator-controller-service + namespace: olmv1-system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + control-plane: operator-controller-controller-manager +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + kubectl.kubernetes.io/default-logs-container: manager + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + control-plane: catalogd-controller-manager + name: catalogd-controller-manager + namespace: olmv1-system +spec: + minReadySeconds: 5 + replicas: 1 + selector: + matchLabels: + control-plane: catalogd-controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: catalogd-controller-manager + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - arm64 + - ppc64le + - s390x + - key: kubernetes.io/os + operator: In + values: + - linux + containers: + - args: + - --leader-elect + - --metrics-bind-address=:7443 + - --external-address=catalogd-service.$(POD_NAMESPACE).svc + - --tls-cert=/var/server-cert/tls.crt + - --tls-key=/var/server-cert/tls.key + command: + - ./catalogd + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: quay.io/operator-framework/catalogd:devel + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + requests: + cpu: 100m + memory: 200Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/cache/ + name: cache + - mountPath: /var/server-cert + name: server-cert + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: catalogd-controller-manager + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: cache + - name: server-cert + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + optional: false + secretName: catalogd-cert-devel +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + kubectl.kubernetes.io/default-logs-container: manager + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + control-plane: operator-controller-controller-manager + name: operator-controller-controller-manager + namespace: olmv1-system +spec: + replicas: 1 + selector: + matchLabels: + control-plane: operator-controller-controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: operator-controller-controller-manager + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - arm64 + - ppc64le + - s390x + - key: kubernetes.io/os + operator: In + values: + - linux + containers: + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8443 + - --leader-elect + - --tls-cert=/var/certs/server-cert/tls.cert + - --tls-key=/var/certs/server-cert/tls.key + - --catalogd-cas-dir=/var/certs/catalogd-ca + command: + - /operator-controller + image: quay.io/operator-framework/operator-controller:devel + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/cache + name: cache + - mountPath: /var/certs/server-cert + name: server-cert + readOnly: true + - mountPath: /var/certs/catalogd-ca + name: catalogd-ca + readOnly: true + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: operator-controller-controller-manager + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: cache + - name: server-cert + secret: + items: + - key: tls.crt + path: tls.cert + - key: tls.key + path: tls.key + optional: false + secretName: operator-controller-cert + - name: catalogd-ca + secret: + items: + - key: ca.crt + path: ca.crt + optional: false + secretName: catalogd-cert-devel +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/part-of: olm + name: catalogd-cert + namespace: olmv1-system +spec: + dnsNames: + - catalogd-service.olmv1-system.svc + - catalogd-service.olmv1-system.svc.cluster.local + issuerRef: + group: cert-manager.io + kind: Issuer + name: olmv1-ca + privateKey: + algorithm: ECDSA + size: 256 + secretName: catalogd-cert-devel +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/part-of: olm + name: olmv1-ca + namespace: olmv1-system +spec: + commonName: olmv1-ca + isCA: true + issuerRef: + group: cert-manager.io + kind: Issuer + name: self-sign-issuer + privateKey: + algorithm: ECDSA + size: 256 + secretName: olmv1-ca + secretTemplate: + annotations: + cert-manager.io/allow-direct-injection: "true" +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/part-of: olm + name: operator-controller-cert + namespace: olmv1-system +spec: + dnsNames: + - operator-controller-service.olmv1-system.svc + - operator-controller-service.olmv1-system.svc.cluster.local + issuerRef: + group: cert-manager.io + kind: Issuer + name: olmv1-ca + privateKey: + algorithm: ECDSA + size: 256 + secretName: operator-controller-cert +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/part-of: olm + name: olmv1-ca + namespace: olmv1-system +spec: + ca: + secretName: olmv1-ca +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/part-of: olm + name: self-sign-issuer + namespace: olmv1-system +spec: + selfSigned: {} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + control-plane: catalogd-controller-manager + name: catalogd-controller-manager + namespace: olmv1-system +spec: + egress: + - {} + ingress: + - ports: + - port: 7443 + protocol: TCP + - port: 8443 + protocol: TCP + - port: 9443 + protocol: TCP + podSelector: + matchLabels: + control-plane: catalogd-controller-manager + policyTypes: + - Ingress + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + control-plane: operator-controller-controller-manager + name: operator-controller-controller-manager + namespace: olmv1-system +spec: + egress: + - {} + ingress: + - ports: + - port: 8443 + protocol: TCP + podSelector: + matchLabels: + control-plane: operator-controller-controller-manager + policyTypes: + - Ingress + - Egress +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from-secret: olmv1-system/olmv1-ca + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: catalogd-service + namespace: olmv1-system + path: /mutate-olm-operatorframework-io-v1-clustercatalog + port: 9443 + failurePolicy: Fail + matchConditions: + - expression: '''name'' in object.metadata && (!has(object.metadata.labels) || !(''olm.operatorframework.io/metadata.name'' + in object.metadata.labels) || object.metadata.labels[''olm.operatorframework.io/metadata.name''] + != object.metadata.name)' + name: MissingOrIncorrectMetadataNameLabel + name: inject-metadata-name.olm.operatorframework.io + rules: + - apiGroups: + - olm.operatorframework.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - clustercatalogs + sideEffects: None + timeoutSeconds: 10 diff --git a/dev-manifests/operator-controller-e2e.yaml b/dev-manifests/operator-controller-e2e.yaml new file mode 100644 index 000000000..0aa5574db --- /dev/null +++ b/dev-manifests/operator-controller-e2e.yaml @@ -0,0 +1,2132 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/part-of: olm + pod-security.kubernetes.io/enforce: restricted + pod-security.kubernetes.io/enforce-version: latest + name: olmv1-system +--- +apiVersion: v1 +kind: Namespace +metadata: + name: operator-controller-e2e +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: clustercatalogs.olm.operatorframework.io +spec: + group: olm.operatorframework.io + names: + kind: ClusterCatalog + listKind: ClusterCatalogList + plural: clustercatalogs + singular: clustercatalog + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.lastUnpacked + name: LastUnpacked + type: date + - jsonPath: .status.conditions[?(@.type=="Serving")].status + name: Serving + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + ClusterCatalog enables users to make File-Based Catalog (FBC) catalog data available to the cluster. + For more information on FBC, see https://olm.operatorframework.io/docs/reference/file-based-catalogs/#docs + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + spec is the desired state of the ClusterCatalog. + spec is required. + The controller will work to ensure that the desired + catalog is unpacked and served over the catalog content HTTP server. + properties: + availabilityMode: + default: Available + description: |- + availabilityMode allows users to define how the ClusterCatalog is made available to clients on the cluster. + availabilityMode is optional. + + Allowed values are "Available" and "Unavailable" and omitted. + + When omitted, the default value is "Available". + + When set to "Available", the catalog contents will be unpacked and served over the catalog content HTTP server. + Setting the availabilityMode to "Available" tells clients that they should consider this ClusterCatalog + and its contents as usable. + + When set to "Unavailable", the catalog contents will no longer be served over the catalog content HTTP server. + When set to this availabilityMode it should be interpreted the same as the ClusterCatalog not existing. + Setting the availabilityMode to "Unavailable" can be useful in scenarios where a user may not want + to delete the ClusterCatalog all together, but would still like it to be treated as if it doesn't exist. + enum: + - Unavailable + - Available + type: string + priority: + default: 0 + description: |- + priority allows the user to define a priority for a ClusterCatalog. + priority is optional. + + A ClusterCatalog's priority is used by clients as a tie-breaker between ClusterCatalogs that meet the client's requirements. + A higher number means higher priority. + + It is up to clients to decide how to handle scenarios where multiple ClusterCatalogs with the same priority meet their requirements. + When deciding how to break the tie in this scenario, it is recommended that clients prompt their users for additional input. + + When omitted, the default priority is 0 because that is the zero value of integers. + + Negative numbers can be used to specify a priority lower than the default. + Positive numbers can be used to specify a priority higher than the default. + + The lowest possible value is -2147483648. + The highest possible value is 2147483647. + format: int32 + type: integer + source: + description: |- + source allows a user to define the source of a catalog. + A "catalog" contains information on content that can be installed on a cluster. + Providing a catalog source makes the contents of the catalog discoverable and usable by + other on-cluster components. + These on-cluster components may do a variety of things with this information, such as + presenting the content in a GUI dashboard or installing content from the catalog on the cluster. + The catalog source must contain catalog metadata in the File-Based Catalog (FBC) format. + For more information on FBC, see https://olm.operatorframework.io/docs/reference/file-based-catalogs/#docs. + source is a required field. + + Below is a minimal example of a ClusterCatalogSpec that sources a catalog from an image: + + source: + type: Image + image: + ref: quay.io/operatorhubio/catalog:latest + properties: + image: + description: |- + image is used to configure how catalog contents are sourced from an OCI image. + This field is required when type is Image, and forbidden otherwise. + properties: + pollIntervalMinutes: + description: |- + pollIntervalMinutes allows the user to set the interval, in minutes, at which the image source should be polled for new content. + pollIntervalMinutes is optional. + pollIntervalMinutes can not be specified when ref is a digest-based reference. + + When omitted, the image will not be polled for new content. + minimum: 1 + type: integer + ref: + description: |- + ref allows users to define the reference to a container image containing Catalog contents. + ref is required. + ref can not be more than 1000 characters. + + A reference can be broken down into 3 parts - the domain, name, and identifier. + + The domain is typically the registry where an image is located. + It must be alphanumeric characters (lowercase and uppercase) separated by the "." character. + Hyphenation is allowed, but the domain must start and end with alphanumeric characters. + Specifying a port to use is also allowed by adding the ":" character followed by numeric values. + The port must be the last value in the domain. + Some examples of valid domain values are "registry.mydomain.io", "quay.io", "my-registry.io:8080". + + The name is typically the repository in the registry where an image is located. + It must contain lowercase alphanumeric characters separated only by the ".", "_", "__", "-" characters. + Multiple names can be concatenated with the "/" character. + The domain and name are combined using the "/" character. + Some examples of valid name values are "operatorhubio/catalog", "catalog", "my-catalog.prod". + An example of the domain and name parts of a reference being combined is "quay.io/operatorhubio/catalog". + + The identifier is typically the tag or digest for an image reference and is present at the end of the reference. + It starts with a separator character used to distinguish the end of the name and beginning of the identifier. + For a digest-based reference, the "@" character is the separator. + For a tag-based reference, the ":" character is the separator. + An identifier is required in the reference. + + Digest-based references must contain an algorithm reference immediately after the "@" separator. + The algorithm reference must be followed by the ":" character and an encoded string. + The algorithm must start with an uppercase or lowercase alpha character followed by alphanumeric characters and may contain the "-", "_", "+", and "." characters. + Some examples of valid algorithm values are "sha256", "sha256+b64u", "multihash+base58". + The encoded string following the algorithm must be hex digits (a-f, A-F, 0-9) and must be a minimum of 32 characters. + + Tag-based references must begin with a word character (alphanumeric + "_") followed by word characters or ".", and "-" characters. + The tag must not be longer than 127 characters. + + An example of a valid digest-based image reference is "quay.io/operatorhubio/catalog@sha256:200d4ddb2a73594b91358fe6397424e975205bfbe44614f5846033cad64b3f05" + An example of a valid tag-based image reference is "quay.io/operatorhubio/catalog:latest" + maxLength: 1000 + type: string + x-kubernetes-validations: + - message: must start with a valid domain. valid domains must + be alphanumeric characters (lowercase and uppercase) separated + by the "." character. + rule: self.matches('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\b') + - message: a valid name is required. valid names must contain + lowercase alphanumeric characters separated only by the + ".", "_", "__", "-" characters. + rule: self.find('(\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') + != "" + - message: must end with a digest or a tag + rule: self.find('(@.*:)') != "" || self.find(':.*$') != + "" + - message: tag is invalid. the tag must not be more than 127 + characters + rule: 'self.find(''(@.*:)'') == "" ? (self.find('':.*$'') + != "" ? self.find('':.*$'').substring(1).size() <= 127 + : true) : true' + - message: tag is invalid. valid tags must begin with a word + character (alphanumeric + "_") followed by word characters + or ".", and "-" characters + rule: 'self.find(''(@.*:)'') == "" ? (self.find('':.*$'') + != "" ? self.find('':.*$'').matches('':[\\w][\\w.-]*$'') + : true) : true' + - message: digest algorithm is not valid. valid algorithms + must start with an uppercase or lowercase alpha character + followed by alphanumeric characters and may contain the + "-", "_", "+", and "." characters. + rule: 'self.find(''(@.*:)'') != "" ? self.find(''(@.*:)'').matches(''(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:])'') + : true' + - message: digest is not valid. the encoded string must be + at least 32 characters + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').substring(1).size() + >= 32 : true' + - message: digest is not valid. the encoded string must only + contain hex characters (A-F, a-f, 0-9) + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').matches('':[0-9A-Fa-f]*$'') + : true' + required: + - ref + type: object + x-kubernetes-validations: + - message: cannot specify pollIntervalMinutes while using digest-based + image + rule: 'self.ref.find(''(@.*:)'') != "" ? !has(self.pollIntervalMinutes) + : true' + type: + description: |- + type is a reference to the type of source the catalog is sourced from. + type is required. + + The only allowed value is "Image". + + When set to "Image", the ClusterCatalog content will be sourced from an OCI image. + When using an image source, the image field must be set and must be the only field defined for this type. + enum: + - Image + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: image is required when source type is Image, and forbidden + otherwise + rule: 'has(self.type) && self.type == ''Image'' ? has(self.image) + : !has(self.image)' + required: + - source + type: object + status: + description: |- + status contains information about the state of the ClusterCatalog such as: + - Whether or not the catalog contents are being served via the catalog content HTTP server + - Whether or not the ClusterCatalog is progressing to a new state + - A reference to the source from which the catalog contents were retrieved + properties: + conditions: + description: |- + conditions is a representation of the current state for this ClusterCatalog. + + The current condition types are Serving and Progressing. + + The Serving condition is used to represent whether or not the contents of the catalog is being served via the HTTP(S) web server. + When it has a status of True and a reason of Available, the contents of the catalog are being served. + When it has a status of False and a reason of Unavailable, the contents of the catalog are not being served because the contents are not yet available. + When it has a status of False and a reason of UserSpecifiedUnavailable, the contents of the catalog are not being served because the catalog has been intentionally marked as unavailable. + + The Progressing condition is used to represent whether or not the ClusterCatalog is progressing or is ready to progress towards a new state. + When it has a status of True and a reason of Retrying, there was an error in the progression of the ClusterCatalog that may be resolved on subsequent reconciliation attempts. + When it has a status of True and a reason of Succeeded, the ClusterCatalog has successfully progressed to a new state and is ready to continue progressing. + When it has a status of False and a reason of Blocked, there was an error in the progression of the ClusterCatalog that requires manual intervention for recovery. + + In the case that the Serving condition is True with reason Available and Progressing is True with reason Retrying, the previously fetched + catalog contents are still being served via the HTTP(S) web server while we are progressing towards serving a new version of the catalog + contents. This could occur when we've initially fetched the latest contents from the source for this catalog and when polling for changes + to the contents we identify that there are updates to the contents. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + lastUnpacked: + description: |- + lastUnpacked represents the last time the contents of the + catalog were extracted from their source format. As an example, + when using an Image source, the OCI image will be pulled and the + image layers written to a file-system backed cache. We refer to the + act of this extraction from the source format as "unpacking". + format: date-time + type: string + resolvedSource: + description: resolvedSource contains information about the resolved + source based on the source type. + properties: + image: + description: |- + image is a field containing resolution information for a catalog sourced from an image. + This field must be set when type is Image, and forbidden otherwise. + properties: + ref: + description: |- + ref contains the resolved image digest-based reference. + The digest format is used so users can use other tooling to fetch the exact + OCI manifests that were used to extract the catalog contents. + maxLength: 1000 + type: string + x-kubernetes-validations: + - message: must start with a valid domain. valid domains must + be alphanumeric characters (lowercase and uppercase) separated + by the "." character. + rule: self.matches('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\b') + - message: a valid name is required. valid names must contain + lowercase alphanumeric characters separated only by the + ".", "_", "__", "-" characters. + rule: self.find('(\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') + != "" + - message: must end with a digest + rule: self.find('(@.*:)') != "" + - message: digest algorithm is not valid. valid algorithms + must start with an uppercase or lowercase alpha character + followed by alphanumeric characters and may contain the + "-", "_", "+", and "." characters. + rule: 'self.find(''(@.*:)'') != "" ? self.find(''(@.*:)'').matches(''(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:])'') + : true' + - message: digest is not valid. the encoded string must be + at least 32 characters + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').substring(1).size() + >= 32 : true' + - message: digest is not valid. the encoded string must only + contain hex characters (A-F, a-f, 0-9) + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').matches('':[0-9A-Fa-f]*$'') + : true' + required: + - ref + type: object + type: + description: |- + type is a reference to the type of source the catalog is sourced from. + type is required. + + The only allowed value is "Image". + + When set to "Image", information about the resolved image source will be set in the 'image' field. + enum: + - Image + type: string + required: + - image + - type + type: object + x-kubernetes-validations: + - message: image is required when source type is Image, and forbidden + otherwise + rule: 'has(self.type) && self.type == ''Image'' ? has(self.image) + : !has(self.image)' + urls: + description: urls contains the URLs that can be used to access the + catalog. + properties: + base: + description: |- + base is a cluster-internal URL that provides endpoints for + accessing the content of the catalog. + + It is expected that clients append the path for the endpoint they wish + to access. + + Currently, only a single endpoint is served and is accessible at the path + /api/v1. + + The endpoints served for the v1 API are: + - /all - this endpoint returns the entirety of the catalog contents in the FBC format + + As the needs of users and clients of the evolve, new endpoints may be added. + maxLength: 525 + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: isURL(self) + - message: scheme must be either http or https + rule: 'isURL(self) ? (url(self).getScheme() == "http" || url(self).getScheme() + == "https") : true' + required: + - base + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: clusterextensions.olm.operatorframework.io +spec: + group: olm.operatorframework.io + names: + kind: ClusterExtension + listKind: ClusterExtensionList + plural: clusterextensions + singular: clusterextension + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.install.bundle.name + name: Installed Bundle + type: string + - jsonPath: .status.install.bundle.version + name: Version + type: string + - jsonPath: .status.conditions[?(@.type=='Installed')].status + name: Installed + type: string + - jsonPath: .status.conditions[?(@.type=='Progressing')].status + name: Progressing + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ClusterExtension is the Schema for the clusterextensions API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec is an optional field that defines the desired state + of the ClusterExtension. + properties: + install: + description: |- + install is an optional field used to configure the installation options + for the ClusterExtension such as the pre-flight check configuration. + properties: + preflight: + description: |- + preflight is an optional field that can be used to configure the checks that are + run before installation or upgrade of the content for the package specified in the packageName field. + + When specified, it replaces the default preflight configuration for install/upgrade actions. + When not specified, the default configuration will be used. + properties: + crdUpgradeSafety: + description: |- + crdUpgradeSafety is used to configure the CRD Upgrade Safety pre-flight + checks that run prior to upgrades of installed content. + + The CRD Upgrade Safety pre-flight check safeguards from unintended + consequences of upgrading a CRD, such as data loss. + properties: + enforcement: + description: |- + enforcement is a required field, used to configure the state of the CRD Upgrade Safety pre-flight check. + + Allowed values are "None" or "Strict". The default value is "Strict". + + When set to "None", the CRD Upgrade Safety pre-flight check will be skipped + when performing an upgrade operation. This should be used with caution as + unintended consequences such as data loss can occur. + + When set to "Strict", the CRD Upgrade Safety pre-flight check will be run when + performing an upgrade operation. + enum: + - None + - Strict + type: string + required: + - enforcement + type: object + required: + - crdUpgradeSafety + type: object + x-kubernetes-validations: + - message: at least one of [crdUpgradeSafety] are required when + preflight is specified + rule: has(self.crdUpgradeSafety) + type: object + x-kubernetes-validations: + - message: at least one of [preflight] are required when install is + specified + rule: has(self.preflight) + namespace: + description: |- + namespace is a reference to a Kubernetes namespace. + This is the namespace in which the provided ServiceAccount must exist. + It also designates the default namespace where namespace-scoped resources + for the extension are applied to the cluster. + Some extensions may contain namespace-scoped resources to be applied in other namespaces. + This namespace must exist. + + namespace is required, immutable, and follows the DNS label standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters or hyphens (-), + start and end with an alphanumeric character, and be no longer than 63 characters + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + maxLength: 63 + type: string + x-kubernetes-validations: + - message: namespace is immutable + rule: self == oldSelf + - message: namespace must be a valid DNS1123 label + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?$") + serviceAccount: + description: |- + serviceAccount is a reference to a ServiceAccount used to perform all interactions + with the cluster that are required to manage the extension. + The ServiceAccount must be configured with the necessary permissions to perform these interactions. + The ServiceAccount must exist in the namespace referenced in the spec. + serviceAccount is required. + properties: + name: + description: |- + name is a required, immutable reference to the name of the ServiceAccount + to be used for installation and management of the content for the package + specified in the packageName field. + + This ServiceAccount must exist in the installNamespace. + + name follows the DNS subdomain standard as defined in [RFC 1123]. + It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. + + Some examples of valid values are: + - some-serviceaccount + - 123-serviceaccount + - 1-serviceaccount-2 + - someserviceaccount + - some.serviceaccount + + Some examples of invalid values are: + - -some-serviceaccount + - some-serviceaccount- + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + maxLength: 253 + type: string + x-kubernetes-validations: + - message: name is immutable + rule: self == oldSelf + - message: name must be a valid DNS1123 subdomain. It must contain + only lowercase alphanumeric characters, hyphens (-) or periods + (.), start and end with an alphanumeric character, and be + no longer than 253 characters + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + required: + - name + type: object + source: + description: |- + source is a required field which selects the installation source of content + for this ClusterExtension. Selection is performed by setting the sourceType. + + Catalog is currently the only implemented sourceType, and setting the + sourcetype to "Catalog" requires the catalog field to also be defined. + + Below is a minimal example of a source definition (in yaml): + + source: + sourceType: Catalog + catalog: + packageName: example-package + properties: + catalog: + description: |- + catalog is used to configure how information is sourced from a catalog. + This field is required when sourceType is "Catalog", and forbidden otherwise. + properties: + channels: + description: |- + channels is an optional reference to a set of channels belonging to + the package specified in the packageName field. + + A "channel" is a package-author-defined stream of updates for an extension. + + Each channel in the list must follow the DNS subdomain standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. No more than 256 channels can be specified. + + When specified, it is used to constrain the set of installable bundles and + the automated upgrade path. This constraint is an AND operation with the + version field. For example: + - Given channel is set to "foo" + - Given version is set to ">=1.0.0, <1.5.0" + - Only bundles that exist in channel "foo" AND satisfy the version range comparison will be considered installable + - Automatic upgrades will be constrained to upgrade edges defined by the selected channel + + When unspecified, upgrade edges across all channels will be used to identify valid automatic upgrade paths. + + Some examples of valid values are: + - 1.1.x + - alpha + - stable + - stable-v1 + - v1-stable + - dev-preview + - preview + - community + + Some examples of invalid values are: + - -some-channel + - some-channel- + - thisisareallylongchannelnamethatisgreaterthanthemaximumlength + - original_40 + - --default-channel + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + items: + maxLength: 253 + type: string + x-kubernetes-validations: + - message: channels entries must be valid DNS1123 subdomains + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + maxItems: 256 + type: array + packageName: + description: |- + packageName is a reference to the name of the package to be installed + and is used to filter the content from catalogs. + + packageName is required, immutable, and follows the DNS subdomain standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. + + Some examples of valid values are: + - some-package + - 123-package + - 1-package-2 + - somepackage + + Some examples of invalid values are: + - -some-package + - some-package- + - thisisareallylongpackagenamethatisgreaterthanthemaximumlength + - some.package + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + maxLength: 253 + type: string + x-kubernetes-validations: + - message: packageName is immutable + rule: self == oldSelf + - message: packageName must be a valid DNS1123 subdomain. + It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric + character, and be no longer than 253 characters + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + selector: + description: |- + selector is an optional field that can be used + to filter the set of ClusterCatalogs used in the bundle + selection process. + + When unspecified, all ClusterCatalogs will be used in + the bundle selection process. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + upgradeConstraintPolicy: + default: CatalogProvided + description: |- + upgradeConstraintPolicy is an optional field that controls whether + the upgrade path(s) defined in the catalog are enforced for the package + referenced in the packageName field. + + Allowed values are: "CatalogProvided" or "SelfCertified", or omitted. + + When this field is set to "CatalogProvided", automatic upgrades will only occur + when upgrade constraints specified by the package author are met. + + When this field is set to "SelfCertified", the upgrade constraints specified by + the package author are ignored. This allows for upgrades and downgrades to + any version of the package. This is considered a dangerous operation as it + can lead to unknown and potentially disastrous outcomes, such as data + loss. It is assumed that users have independently verified changes when + using this option. + + When this field is omitted, the default value is "CatalogProvided". + enum: + - CatalogProvided + - SelfCertified + type: string + version: + description: |- + version is an optional semver constraint (a specific version or range of versions). When unspecified, the latest version available will be installed. + + Acceptable version ranges are no longer than 64 characters. + Version ranges are composed of comma- or space-delimited values and one or + more comparison operators, known as comparison strings. Additional + comparison strings can be added using the OR operator (||). + + # Range Comparisons + + To specify a version range, you can use a comparison string like ">=3.0, + <3.6". When specifying a range, automatic updates will occur within that + range. The example comparison string means "install any version greater than + or equal to 3.0.0 but less than 3.6.0.". It also states intent that if any + upgrades are available within the version range after initial installation, + those upgrades should be automatically performed. + + # Pinned Versions + + To specify an exact version to install you can use a version range that + "pins" to a specific version. When pinning to a specific version, no + automatic updates will occur. An example of a pinned version range is + "0.6.0", which means "only install version 0.6.0 and never + upgrade from this version". + + # Basic Comparison Operators + + The basic comparison operators and their meanings are: + - "=", equal (not aliased to an operator) + - "!=", not equal + - "<", less than + - ">", greater than + - ">=", greater than OR equal to + - "<=", less than OR equal to + + # Wildcard Comparisons + + You can use the "x", "X", and "*" characters as wildcard characters in all + comparison operations. Some examples of using the wildcard characters: + - "1.2.x", "1.2.X", and "1.2.*" is equivalent to ">=1.2.0, < 1.3.0" + - ">= 1.2.x", ">= 1.2.X", and ">= 1.2.*" is equivalent to ">= 1.2.0" + - "<= 2.x", "<= 2.X", and "<= 2.*" is equivalent to "< 3" + - "x", "X", and "*" is equivalent to ">= 0.0.0" + + # Patch Release Comparisons + + When you want to specify a minor version up to the next major version you + can use the "~" character to perform patch comparisons. Some examples: + - "~1.2.3" is equivalent to ">=1.2.3, <1.3.0" + - "~1" and "~1.x" is equivalent to ">=1, <2" + - "~2.3" is equivalent to ">=2.3, <2.4" + - "~1.2.x" is equivalent to ">=1.2.0, <1.3.0" + + # Major Release Comparisons + + You can use the "^" character to make major release comparisons after a + stable 1.0.0 version is published. If there is no stable version published, // minor versions define the stability level. Some examples: + - "^1.2.3" is equivalent to ">=1.2.3, <2.0.0" + - "^1.2.x" is equivalent to ">=1.2.0, <2.0.0" + - "^2.3" is equivalent to ">=2.3, <3" + - "^2.x" is equivalent to ">=2.0.0, <3" + - "^0.2.3" is equivalent to ">=0.2.3, <0.3.0" + - "^0.2" is equivalent to ">=0.2.0, <0.3.0" + - "^0.0.3" is equvalent to ">=0.0.3, <0.0.4" + - "^0.0" is equivalent to ">=0.0.0, <0.1.0" + - "^0" is equivalent to ">=0.0.0, <1.0.0" + + # OR Comparisons + You can use the "||" character to represent an OR operation in the version + range. Some examples: + - ">=1.2.3, <2.0.0 || >3.0.0" + - "^0 || ^3 || ^5" + + For more information on semver, please see https://semver.org/ + maxLength: 64 + type: string + x-kubernetes-validations: + - message: invalid version expression + rule: self.matches("^(\\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)\\s*(v?(0|[1-9]\\d*|[x|X|\\*])(\\.(0|[1-9]\\d*|x|X|\\*]))?(\\.(0|[1-9]\\d*|x|X|\\*))?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?)\\s*)((?:\\s+|,\\s*|\\s*\\|\\|\\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)\\s*(v?(0|[1-9]\\d*|x|X|\\*])(\\.(0|[1-9]\\d*|x|X|\\*))?(\\.(0|[1-9]\\d*|x|X|\\*]))?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?)\\s*)*$") + required: + - packageName + type: object + sourceType: + description: |- + sourceType is a required reference to the type of install source. + + Allowed values are "Catalog" + + When this field is set to "Catalog", information for determining the + appropriate bundle of content to install will be fetched from + ClusterCatalog resources existing on the cluster. + When using the Catalog sourceType, the catalog field must also be set. + enum: + - Catalog + type: string + required: + - sourceType + type: object + x-kubernetes-validations: + - message: catalog is required when sourceType is Catalog, and forbidden + otherwise + rule: 'has(self.sourceType) && self.sourceType == ''Catalog'' ? + has(self.catalog) : !has(self.catalog)' + required: + - namespace + - serviceAccount + - source + type: object + status: + description: status is an optional field that defines the observed state + of the ClusterExtension. + properties: + conditions: + description: |- + The set of condition types which apply to all spec.source variations are Installed and Progressing. + + The Installed condition represents whether or not the bundle has been installed for this ClusterExtension. + When Installed is True and the Reason is Succeeded, the bundle has been successfully installed. + When Installed is False and the Reason is Failed, the bundle has failed to install. + + The Progressing condition represents whether or not the ClusterExtension is advancing towards a new state. + When Progressing is True and the Reason is Succeeded, the ClusterExtension is making progress towards a new state. + When Progressing is True and the Reason is Retrying, the ClusterExtension has encountered an error that could be resolved on subsequent reconciliation attempts. + When Progressing is False and the Reason is Blocked, the ClusterExtension has encountered an error that requires manual intervention for recovery. + + When the ClusterExtension is sourced from a catalog, if may also communicate a deprecation condition. + These are indications from a package owner to guide users away from a particular package, channel, or bundle. + BundleDeprecated is set if the requested bundle version is marked deprecated in the catalog. + ChannelDeprecated is set if the requested channel is marked deprecated in the catalog. + PackageDeprecated is set if the requested package is marked deprecated in the catalog. + Deprecated is a rollup condition that is present when any of the deprecated conditions are present. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + install: + description: install is a representation of the current installation + status for this ClusterExtension. + properties: + bundle: + description: |- + bundle is a required field which represents the identifying attributes of a bundle. + + A "bundle" is a versioned set of content that represents the resources that + need to be applied to a cluster to install a package. + properties: + name: + description: |- + name is required and follows the DNS subdomain standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. + type: string + x-kubernetes-validations: + - message: packageName must be a valid DNS1123 subdomain. + It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric + character, and be no longer than 253 characters + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + version: + description: |- + version is a required field and is a reference to the version that this bundle represents + version follows the semantic versioning standard as defined in https://semver.org/. + type: string + x-kubernetes-validations: + - message: version must be well-formed semver + rule: self.matches("^([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(-([-0-9A-Za-z]+(\\.[-0-9A-Za-z]+)*))?(\\+([-0-9A-Za-z]+(-\\.[-0-9A-Za-z]+)*))?") + required: + - name + - version + type: object + required: + - bundle + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-leader-election-role + namespace: olmv1-system +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-leader-election-role + namespace: olmv1-system +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-role + namespace: olmv1-system +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-manager-role +rules: +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs/finalizers + verbs: + - update +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs/status + verbs: + - get + - patch + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-clusterextension-editor-role +rules: +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-clusterextension-viewer-role +rules: +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-role +rules: +- apiGroups: + - "" + resources: + - serviceaccounts/token + verbs: + - create +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs + verbs: + - get + - list + - watch +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions/finalizers + verbs: + - update +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions/status + verbs: + - patch + - update +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-leader-election-rolebinding + namespace: olmv1-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: catalogd-leader-election-role +subjects: +- kind: ServiceAccount + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-leader-election-rolebinding + namespace: olmv1-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: operator-controller-leader-election-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-rolebinding + namespace: olmv1-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: operator-controller-manager-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: catalogd-manager-role +subjects: +- kind: ServiceAccount + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: catalogd-proxy-role +subjects: +- kind: ServiceAccount + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: operator-controller-manager-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: operator-controller-proxy-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: v1 +data: + registries.conf: | + [[registry]] + prefix = "mirrored-registry.operator-controller-e2e.svc.cluster.local:5000" + location = "docker-registry.operator-controller-e2e.svc.cluster.local:5000" +kind: ConfigMap +metadata: + name: e2e-registries-conf + namespace: olmv1-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + control-plane: catalogd-controller-manager + name: catalogd-service + namespace: olmv1-system +spec: + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + - name: webhook + port: 9443 + protocol: TCP + targetPort: 9443 + - name: metrics + port: 7443 + protocol: TCP + targetPort: 7443 + selector: + control-plane: catalogd-controller-manager +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + control-plane: operator-controller-controller-manager + name: operator-controller-service + namespace: olmv1-system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + control-plane: operator-controller-controller-manager +--- +apiVersion: v1 +kind: Service +metadata: + name: docker-registry + namespace: operator-controller-e2e +spec: + ports: + - name: http + nodePort: 30000 + port: 5000 + targetPort: 5000 + selector: + app: registry + type: NodePort +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: e2e-coverage + namespace: olmv1-system +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 64Mi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + kubectl.kubernetes.io/default-logs-container: manager + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + control-plane: catalogd-controller-manager + name: catalogd-controller-manager + namespace: olmv1-system +spec: + minReadySeconds: 5 + replicas: 1 + selector: + matchLabels: + control-plane: catalogd-controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: catalogd-controller-manager + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - arm64 + - ppc64le + - s390x + - key: kubernetes.io/os + operator: In + values: + - linux + containers: + - args: + - --leader-elect + - --metrics-bind-address=:7443 + - --external-address=catalogd-service.$(POD_NAMESPACE).svc + - --tls-cert=/var/server-cert/tls.crt + - --tls-key=/var/server-cert/tls.key + - --pull-cas-dir=/var/certs/e2e-registry-ca + command: + - ./catalogd + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: quay.io/operator-framework/catalogd:devel + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + requests: + cpu: 100m + memory: 200Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/cache/ + name: cache + - mountPath: /var/server-cert + name: server-cert + - mountPath: /var/certs/e2e-registry-ca + name: e2e-registry-ca + readOnly: true + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: catalogd-controller-manager + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: cache + - name: server-cert + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + optional: false + secretName: catalogd-cert-devel + - name: e2e-registry-ca + secret: + items: + - key: ca.crt + path: ca.crt + optional: false + secretName: e2e-dummy-cert +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + kubectl.kubernetes.io/default-logs-container: manager + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + control-plane: operator-controller-controller-manager + name: operator-controller-controller-manager + namespace: olmv1-system +spec: + replicas: 1 + selector: + matchLabels: + control-plane: operator-controller-controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: operator-controller-controller-manager + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - arm64 + - ppc64le + - s390x + - key: kubernetes.io/os + operator: In + values: + - linux + containers: + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8443 + - --leader-elect + - --tls-cert=/var/certs/server-cert/tls.cert + - --tls-key=/var/certs/server-cert/tls.key + - --catalogd-cas-dir=/var/certs/catalogd-ca + - --pull-cas-dir=/var/certs/e2e-registry-ca + command: + - /operator-controller + env: + - name: GOCOVERDIR + value: /e2e-coverage + image: quay.io/operator-framework/operator-controller:devel + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/cache + name: cache + - mountPath: /var/certs/server-cert + name: server-cert + readOnly: true + - mountPath: /var/certs/catalogd-ca + name: catalogd-ca + readOnly: true + - mountPath: /var/certs/e2e-registry-ca + name: e2e-registry-ca + readOnly: true + - mountPath: /etc/containers + name: e2e-registries-conf + readOnly: true + - mountPath: /e2e-coverage + name: e2e-coverage-volume + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: operator-controller-controller-manager + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: cache + - name: server-cert + secret: + items: + - key: tls.crt + path: tls.cert + - key: tls.key + path: tls.key + optional: false + secretName: operator-controller-cert + - name: catalogd-ca + secret: + items: + - key: ca.crt + path: ca.crt + optional: false + secretName: catalogd-cert-devel + - name: e2e-registry-ca + secret: + items: + - key: ca.crt + path: ca.crt + optional: false + secretName: e2e-dummy-cert + - configMap: + name: e2e-registries-conf + name: e2e-registries-conf + - name: e2e-coverage-volume + persistentVolumeClaim: + claimName: e2e-coverage +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: registry + name: docker-registry + namespace: operator-controller-e2e +spec: + replicas: 1 + selector: + matchLabels: + app: registry + template: + metadata: + labels: + app: registry + spec: + containers: + - env: + - name: REGISTRY_HTTP_ADDR + value: :5000 + - name: REGISTRY_HTTP_TLS_CERTIFICATE + value: /certs/tls.crt + - name: REGISTRY_HTTP_TLS_KEY + value: /certs/tls.key + image: registry:3 + imagePullPolicy: IfNotPresent + name: registry + volumeMounts: + - mountPath: /certs + name: certs-vol + volumes: + - name: certs-vol + secret: + secretName: operator-controller-e2e-registry +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: e2e-ca + namespace: cert-manager +spec: + commonName: e2e-ca + isCA: true + issuerRef: + group: cert-manager.io + kind: Issuer + name: e2e-self-sign-issuer + privateKey: + algorithm: ECDSA + size: 256 + secretName: e2e-ca + secretTemplate: + annotations: + cert-manager.io/allow-direct-injection: "true" +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/part-of: olm + name: catalogd-cert + namespace: olmv1-system +spec: + dnsNames: + - catalogd-service.olmv1-system.svc + - catalogd-service.olmv1-system.svc.cluster.local + issuerRef: + group: cert-manager.io + kind: Issuer + name: olmv1-ca + privateKey: + algorithm: ECDSA + size: 256 + secretName: catalogd-cert-devel +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: e2e-dummy-cert + namespace: olmv1-system +spec: + commonName: e2e-dummy-cert + issuerRef: + group: cert-manager.io + kind: ClusterIssuer + name: e2e-ca + privateKey: + algorithm: ECDSA + size: 256 + secretName: e2e-dummy-cert +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/part-of: olm + name: olmv1-ca + namespace: olmv1-system +spec: + commonName: olmv1-ca + isCA: true + issuerRef: + group: cert-manager.io + kind: Issuer + name: self-sign-issuer + privateKey: + algorithm: ECDSA + size: 256 + secretName: olmv1-ca + secretTemplate: + annotations: + cert-manager.io/allow-direct-injection: "true" +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/part-of: olm + name: operator-controller-cert + namespace: olmv1-system +spec: + dnsNames: + - operator-controller-service.olmv1-system.svc + - operator-controller-service.olmv1-system.svc.cluster.local + issuerRef: + group: cert-manager.io + kind: Issuer + name: olmv1-ca + privateKey: + algorithm: ECDSA + size: 256 + secretName: operator-controller-cert +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: operator-controller-e2e-registry + namespace: operator-controller-e2e +spec: + dnsNames: + - docker-registry.operator-controller-e2e.svc + - docker-registry.operator-controller-e2e.svc.cluster.local + isCA: true + issuerRef: + group: cert-manager.io + kind: ClusterIssuer + name: e2e-ca + privateKey: + algorithm: ECDSA + size: 256 + secretName: operator-controller-e2e-registry +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: e2e-ca +spec: + ca: + secretName: e2e-ca +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: e2e-self-sign-issuer + namespace: cert-manager +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/part-of: olm + name: olmv1-ca + namespace: olmv1-system +spec: + ca: + secretName: olmv1-ca +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/part-of: olm + name: self-sign-issuer + namespace: olmv1-system +spec: + selfSigned: {} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + control-plane: catalogd-controller-manager + name: catalogd-controller-manager + namespace: olmv1-system +spec: + egress: + - {} + ingress: + - ports: + - port: 7443 + protocol: TCP + - port: 8443 + protocol: TCP + - port: 9443 + protocol: TCP + podSelector: + matchLabels: + control-plane: catalogd-controller-manager + policyTypes: + - Ingress + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + control-plane: operator-controller-controller-manager + name: operator-controller-controller-manager + namespace: olmv1-system +spec: + egress: + - {} + ingress: + - ports: + - port: 8443 + protocol: TCP + podSelector: + matchLabels: + control-plane: operator-controller-controller-manager + policyTypes: + - Ingress + - Egress +--- +apiVersion: v1 +kind: Pod +metadata: + name: e2e-coverage-copy-pod + namespace: olmv1-system +spec: + containers: + - command: + - sleep + - infinity + image: busybox:1.36 + name: tar + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /e2e-coverage + name: e2e-coverage-volume + readOnly: true + restartPolicy: Never + securityContext: + runAsNonRoot: true + runAsUser: 65532 + seccompProfile: + type: RuntimeDefault + volumes: + - name: e2e-coverage-volume + persistentVolumeClaim: + claimName: e2e-coverage + readOnly: true +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from-secret: olmv1-system/olmv1-ca + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: catalogd-service + namespace: olmv1-system + path: /mutate-olm-operatorframework-io-v1-clustercatalog + port: 9443 + failurePolicy: Fail + matchConditions: + - expression: '''name'' in object.metadata && (!has(object.metadata.labels) || !(''olm.operatorframework.io/metadata.name'' + in object.metadata.labels) || object.metadata.labels[''olm.operatorframework.io/metadata.name''] + != object.metadata.name)' + name: MissingOrIncorrectMetadataNameLabel + name: inject-metadata-name.olm.operatorframework.io + rules: + - apiGroups: + - olm.operatorframework.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - clustercatalogs + sideEffects: None + timeoutSeconds: 10 diff --git a/dev-manifests/operator-controller-tilt.yaml b/dev-manifests/operator-controller-tilt.yaml new file mode 100644 index 000000000..a2bb26ade --- /dev/null +++ b/dev-manifests/operator-controller-tilt.yaml @@ -0,0 +1,1890 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/part-of: olm + pod-security.kubernetes.io/enforce: restricted + pod-security.kubernetes.io/enforce-version: latest + name: olmv1-system +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: clustercatalogs.olm.operatorframework.io +spec: + group: olm.operatorframework.io + names: + kind: ClusterCatalog + listKind: ClusterCatalogList + plural: clustercatalogs + singular: clustercatalog + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.lastUnpacked + name: LastUnpacked + type: date + - jsonPath: .status.conditions[?(@.type=="Serving")].status + name: Serving + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + ClusterCatalog enables users to make File-Based Catalog (FBC) catalog data available to the cluster. + For more information on FBC, see https://olm.operatorframework.io/docs/reference/file-based-catalogs/#docs + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + spec is the desired state of the ClusterCatalog. + spec is required. + The controller will work to ensure that the desired + catalog is unpacked and served over the catalog content HTTP server. + properties: + availabilityMode: + default: Available + description: |- + availabilityMode allows users to define how the ClusterCatalog is made available to clients on the cluster. + availabilityMode is optional. + + Allowed values are "Available" and "Unavailable" and omitted. + + When omitted, the default value is "Available". + + When set to "Available", the catalog contents will be unpacked and served over the catalog content HTTP server. + Setting the availabilityMode to "Available" tells clients that they should consider this ClusterCatalog + and its contents as usable. + + When set to "Unavailable", the catalog contents will no longer be served over the catalog content HTTP server. + When set to this availabilityMode it should be interpreted the same as the ClusterCatalog not existing. + Setting the availabilityMode to "Unavailable" can be useful in scenarios where a user may not want + to delete the ClusterCatalog all together, but would still like it to be treated as if it doesn't exist. + enum: + - Unavailable + - Available + type: string + priority: + default: 0 + description: |- + priority allows the user to define a priority for a ClusterCatalog. + priority is optional. + + A ClusterCatalog's priority is used by clients as a tie-breaker between ClusterCatalogs that meet the client's requirements. + A higher number means higher priority. + + It is up to clients to decide how to handle scenarios where multiple ClusterCatalogs with the same priority meet their requirements. + When deciding how to break the tie in this scenario, it is recommended that clients prompt their users for additional input. + + When omitted, the default priority is 0 because that is the zero value of integers. + + Negative numbers can be used to specify a priority lower than the default. + Positive numbers can be used to specify a priority higher than the default. + + The lowest possible value is -2147483648. + The highest possible value is 2147483647. + format: int32 + type: integer + source: + description: |- + source allows a user to define the source of a catalog. + A "catalog" contains information on content that can be installed on a cluster. + Providing a catalog source makes the contents of the catalog discoverable and usable by + other on-cluster components. + These on-cluster components may do a variety of things with this information, such as + presenting the content in a GUI dashboard or installing content from the catalog on the cluster. + The catalog source must contain catalog metadata in the File-Based Catalog (FBC) format. + For more information on FBC, see https://olm.operatorframework.io/docs/reference/file-based-catalogs/#docs. + source is a required field. + + Below is a minimal example of a ClusterCatalogSpec that sources a catalog from an image: + + source: + type: Image + image: + ref: quay.io/operatorhubio/catalog:latest + properties: + image: + description: |- + image is used to configure how catalog contents are sourced from an OCI image. + This field is required when type is Image, and forbidden otherwise. + properties: + pollIntervalMinutes: + description: |- + pollIntervalMinutes allows the user to set the interval, in minutes, at which the image source should be polled for new content. + pollIntervalMinutes is optional. + pollIntervalMinutes can not be specified when ref is a digest-based reference. + + When omitted, the image will not be polled for new content. + minimum: 1 + type: integer + ref: + description: |- + ref allows users to define the reference to a container image containing Catalog contents. + ref is required. + ref can not be more than 1000 characters. + + A reference can be broken down into 3 parts - the domain, name, and identifier. + + The domain is typically the registry where an image is located. + It must be alphanumeric characters (lowercase and uppercase) separated by the "." character. + Hyphenation is allowed, but the domain must start and end with alphanumeric characters. + Specifying a port to use is also allowed by adding the ":" character followed by numeric values. + The port must be the last value in the domain. + Some examples of valid domain values are "registry.mydomain.io", "quay.io", "my-registry.io:8080". + + The name is typically the repository in the registry where an image is located. + It must contain lowercase alphanumeric characters separated only by the ".", "_", "__", "-" characters. + Multiple names can be concatenated with the "/" character. + The domain and name are combined using the "/" character. + Some examples of valid name values are "operatorhubio/catalog", "catalog", "my-catalog.prod". + An example of the domain and name parts of a reference being combined is "quay.io/operatorhubio/catalog". + + The identifier is typically the tag or digest for an image reference and is present at the end of the reference. + It starts with a separator character used to distinguish the end of the name and beginning of the identifier. + For a digest-based reference, the "@" character is the separator. + For a tag-based reference, the ":" character is the separator. + An identifier is required in the reference. + + Digest-based references must contain an algorithm reference immediately after the "@" separator. + The algorithm reference must be followed by the ":" character and an encoded string. + The algorithm must start with an uppercase or lowercase alpha character followed by alphanumeric characters and may contain the "-", "_", "+", and "." characters. + Some examples of valid algorithm values are "sha256", "sha256+b64u", "multihash+base58". + The encoded string following the algorithm must be hex digits (a-f, A-F, 0-9) and must be a minimum of 32 characters. + + Tag-based references must begin with a word character (alphanumeric + "_") followed by word characters or ".", and "-" characters. + The tag must not be longer than 127 characters. + + An example of a valid digest-based image reference is "quay.io/operatorhubio/catalog@sha256:200d4ddb2a73594b91358fe6397424e975205bfbe44614f5846033cad64b3f05" + An example of a valid tag-based image reference is "quay.io/operatorhubio/catalog:latest" + maxLength: 1000 + type: string + x-kubernetes-validations: + - message: must start with a valid domain. valid domains must + be alphanumeric characters (lowercase and uppercase) separated + by the "." character. + rule: self.matches('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\b') + - message: a valid name is required. valid names must contain + lowercase alphanumeric characters separated only by the + ".", "_", "__", "-" characters. + rule: self.find('(\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') + != "" + - message: must end with a digest or a tag + rule: self.find('(@.*:)') != "" || self.find(':.*$') != + "" + - message: tag is invalid. the tag must not be more than 127 + characters + rule: 'self.find(''(@.*:)'') == "" ? (self.find('':.*$'') + != "" ? self.find('':.*$'').substring(1).size() <= 127 + : true) : true' + - message: tag is invalid. valid tags must begin with a word + character (alphanumeric + "_") followed by word characters + or ".", and "-" characters + rule: 'self.find(''(@.*:)'') == "" ? (self.find('':.*$'') + != "" ? self.find('':.*$'').matches('':[\\w][\\w.-]*$'') + : true) : true' + - message: digest algorithm is not valid. valid algorithms + must start with an uppercase or lowercase alpha character + followed by alphanumeric characters and may contain the + "-", "_", "+", and "." characters. + rule: 'self.find(''(@.*:)'') != "" ? self.find(''(@.*:)'').matches(''(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:])'') + : true' + - message: digest is not valid. the encoded string must be + at least 32 characters + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').substring(1).size() + >= 32 : true' + - message: digest is not valid. the encoded string must only + contain hex characters (A-F, a-f, 0-9) + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').matches('':[0-9A-Fa-f]*$'') + : true' + required: + - ref + type: object + x-kubernetes-validations: + - message: cannot specify pollIntervalMinutes while using digest-based + image + rule: 'self.ref.find(''(@.*:)'') != "" ? !has(self.pollIntervalMinutes) + : true' + type: + description: |- + type is a reference to the type of source the catalog is sourced from. + type is required. + + The only allowed value is "Image". + + When set to "Image", the ClusterCatalog content will be sourced from an OCI image. + When using an image source, the image field must be set and must be the only field defined for this type. + enum: + - Image + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: image is required when source type is Image, and forbidden + otherwise + rule: 'has(self.type) && self.type == ''Image'' ? has(self.image) + : !has(self.image)' + required: + - source + type: object + status: + description: |- + status contains information about the state of the ClusterCatalog such as: + - Whether or not the catalog contents are being served via the catalog content HTTP server + - Whether or not the ClusterCatalog is progressing to a new state + - A reference to the source from which the catalog contents were retrieved + properties: + conditions: + description: |- + conditions is a representation of the current state for this ClusterCatalog. + + The current condition types are Serving and Progressing. + + The Serving condition is used to represent whether or not the contents of the catalog is being served via the HTTP(S) web server. + When it has a status of True and a reason of Available, the contents of the catalog are being served. + When it has a status of False and a reason of Unavailable, the contents of the catalog are not being served because the contents are not yet available. + When it has a status of False and a reason of UserSpecifiedUnavailable, the contents of the catalog are not being served because the catalog has been intentionally marked as unavailable. + + The Progressing condition is used to represent whether or not the ClusterCatalog is progressing or is ready to progress towards a new state. + When it has a status of True and a reason of Retrying, there was an error in the progression of the ClusterCatalog that may be resolved on subsequent reconciliation attempts. + When it has a status of True and a reason of Succeeded, the ClusterCatalog has successfully progressed to a new state and is ready to continue progressing. + When it has a status of False and a reason of Blocked, there was an error in the progression of the ClusterCatalog that requires manual intervention for recovery. + + In the case that the Serving condition is True with reason Available and Progressing is True with reason Retrying, the previously fetched + catalog contents are still being served via the HTTP(S) web server while we are progressing towards serving a new version of the catalog + contents. This could occur when we've initially fetched the latest contents from the source for this catalog and when polling for changes + to the contents we identify that there are updates to the contents. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + lastUnpacked: + description: |- + lastUnpacked represents the last time the contents of the + catalog were extracted from their source format. As an example, + when using an Image source, the OCI image will be pulled and the + image layers written to a file-system backed cache. We refer to the + act of this extraction from the source format as "unpacking". + format: date-time + type: string + resolvedSource: + description: resolvedSource contains information about the resolved + source based on the source type. + properties: + image: + description: |- + image is a field containing resolution information for a catalog sourced from an image. + This field must be set when type is Image, and forbidden otherwise. + properties: + ref: + description: |- + ref contains the resolved image digest-based reference. + The digest format is used so users can use other tooling to fetch the exact + OCI manifests that were used to extract the catalog contents. + maxLength: 1000 + type: string + x-kubernetes-validations: + - message: must start with a valid domain. valid domains must + be alphanumeric characters (lowercase and uppercase) separated + by the "." character. + rule: self.matches('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\b') + - message: a valid name is required. valid names must contain + lowercase alphanumeric characters separated only by the + ".", "_", "__", "-" characters. + rule: self.find('(\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') + != "" + - message: must end with a digest + rule: self.find('(@.*:)') != "" + - message: digest algorithm is not valid. valid algorithms + must start with an uppercase or lowercase alpha character + followed by alphanumeric characters and may contain the + "-", "_", "+", and "." characters. + rule: 'self.find(''(@.*:)'') != "" ? self.find(''(@.*:)'').matches(''(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:])'') + : true' + - message: digest is not valid. the encoded string must be + at least 32 characters + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').substring(1).size() + >= 32 : true' + - message: digest is not valid. the encoded string must only + contain hex characters (A-F, a-f, 0-9) + rule: 'self.find(''(@.*:)'') != "" ? self.find('':.*$'').matches('':[0-9A-Fa-f]*$'') + : true' + required: + - ref + type: object + type: + description: |- + type is a reference to the type of source the catalog is sourced from. + type is required. + + The only allowed value is "Image". + + When set to "Image", information about the resolved image source will be set in the 'image' field. + enum: + - Image + type: string + required: + - image + - type + type: object + x-kubernetes-validations: + - message: image is required when source type is Image, and forbidden + otherwise + rule: 'has(self.type) && self.type == ''Image'' ? has(self.image) + : !has(self.image)' + urls: + description: urls contains the URLs that can be used to access the + catalog. + properties: + base: + description: |- + base is a cluster-internal URL that provides endpoints for + accessing the content of the catalog. + + It is expected that clients append the path for the endpoint they wish + to access. + + Currently, only a single endpoint is served and is accessible at the path + /api/v1. + + The endpoints served for the v1 API are: + - /all - this endpoint returns the entirety of the catalog contents in the FBC format + + As the needs of users and clients of the evolve, new endpoints may be added. + maxLength: 525 + type: string + x-kubernetes-validations: + - message: must be a valid URL + rule: isURL(self) + - message: scheme must be either http or https + rule: 'isURL(self) ? (url(self).getScheme() == "http" || url(self).getScheme() + == "https") : true' + required: + - base + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: clusterextensions.olm.operatorframework.io +spec: + group: olm.operatorframework.io + names: + kind: ClusterExtension + listKind: ClusterExtensionList + plural: clusterextensions + singular: clusterextension + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.install.bundle.name + name: Installed Bundle + type: string + - jsonPath: .status.install.bundle.version + name: Version + type: string + - jsonPath: .status.conditions[?(@.type=='Installed')].status + name: Installed + type: string + - jsonPath: .status.conditions[?(@.type=='Progressing')].status + name: Progressing + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ClusterExtension is the Schema for the clusterextensions API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec is an optional field that defines the desired state + of the ClusterExtension. + properties: + install: + description: |- + install is an optional field used to configure the installation options + for the ClusterExtension such as the pre-flight check configuration. + properties: + preflight: + description: |- + preflight is an optional field that can be used to configure the checks that are + run before installation or upgrade of the content for the package specified in the packageName field. + + When specified, it replaces the default preflight configuration for install/upgrade actions. + When not specified, the default configuration will be used. + properties: + crdUpgradeSafety: + description: |- + crdUpgradeSafety is used to configure the CRD Upgrade Safety pre-flight + checks that run prior to upgrades of installed content. + + The CRD Upgrade Safety pre-flight check safeguards from unintended + consequences of upgrading a CRD, such as data loss. + properties: + enforcement: + description: |- + enforcement is a required field, used to configure the state of the CRD Upgrade Safety pre-flight check. + + Allowed values are "None" or "Strict". The default value is "Strict". + + When set to "None", the CRD Upgrade Safety pre-flight check will be skipped + when performing an upgrade operation. This should be used with caution as + unintended consequences such as data loss can occur. + + When set to "Strict", the CRD Upgrade Safety pre-flight check will be run when + performing an upgrade operation. + enum: + - None + - Strict + type: string + required: + - enforcement + type: object + required: + - crdUpgradeSafety + type: object + x-kubernetes-validations: + - message: at least one of [crdUpgradeSafety] are required when + preflight is specified + rule: has(self.crdUpgradeSafety) + type: object + x-kubernetes-validations: + - message: at least one of [preflight] are required when install is + specified + rule: has(self.preflight) + namespace: + description: |- + namespace is a reference to a Kubernetes namespace. + This is the namespace in which the provided ServiceAccount must exist. + It also designates the default namespace where namespace-scoped resources + for the extension are applied to the cluster. + Some extensions may contain namespace-scoped resources to be applied in other namespaces. + This namespace must exist. + + namespace is required, immutable, and follows the DNS label standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters or hyphens (-), + start and end with an alphanumeric character, and be no longer than 63 characters + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + maxLength: 63 + type: string + x-kubernetes-validations: + - message: namespace is immutable + rule: self == oldSelf + - message: namespace must be a valid DNS1123 label + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?$") + serviceAccount: + description: |- + serviceAccount is a reference to a ServiceAccount used to perform all interactions + with the cluster that are required to manage the extension. + The ServiceAccount must be configured with the necessary permissions to perform these interactions. + The ServiceAccount must exist in the namespace referenced in the spec. + serviceAccount is required. + properties: + name: + description: |- + name is a required, immutable reference to the name of the ServiceAccount + to be used for installation and management of the content for the package + specified in the packageName field. + + This ServiceAccount must exist in the installNamespace. + + name follows the DNS subdomain standard as defined in [RFC 1123]. + It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. + + Some examples of valid values are: + - some-serviceaccount + - 123-serviceaccount + - 1-serviceaccount-2 + - someserviceaccount + - some.serviceaccount + + Some examples of invalid values are: + - -some-serviceaccount + - some-serviceaccount- + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + maxLength: 253 + type: string + x-kubernetes-validations: + - message: name is immutable + rule: self == oldSelf + - message: name must be a valid DNS1123 subdomain. It must contain + only lowercase alphanumeric characters, hyphens (-) or periods + (.), start and end with an alphanumeric character, and be + no longer than 253 characters + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + required: + - name + type: object + source: + description: |- + source is a required field which selects the installation source of content + for this ClusterExtension. Selection is performed by setting the sourceType. + + Catalog is currently the only implemented sourceType, and setting the + sourcetype to "Catalog" requires the catalog field to also be defined. + + Below is a minimal example of a source definition (in yaml): + + source: + sourceType: Catalog + catalog: + packageName: example-package + properties: + catalog: + description: |- + catalog is used to configure how information is sourced from a catalog. + This field is required when sourceType is "Catalog", and forbidden otherwise. + properties: + channels: + description: |- + channels is an optional reference to a set of channels belonging to + the package specified in the packageName field. + + A "channel" is a package-author-defined stream of updates for an extension. + + Each channel in the list must follow the DNS subdomain standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. No more than 256 channels can be specified. + + When specified, it is used to constrain the set of installable bundles and + the automated upgrade path. This constraint is an AND operation with the + version field. For example: + - Given channel is set to "foo" + - Given version is set to ">=1.0.0, <1.5.0" + - Only bundles that exist in channel "foo" AND satisfy the version range comparison will be considered installable + - Automatic upgrades will be constrained to upgrade edges defined by the selected channel + + When unspecified, upgrade edges across all channels will be used to identify valid automatic upgrade paths. + + Some examples of valid values are: + - 1.1.x + - alpha + - stable + - stable-v1 + - v1-stable + - dev-preview + - preview + - community + + Some examples of invalid values are: + - -some-channel + - some-channel- + - thisisareallylongchannelnamethatisgreaterthanthemaximumlength + - original_40 + - --default-channel + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + items: + maxLength: 253 + type: string + x-kubernetes-validations: + - message: channels entries must be valid DNS1123 subdomains + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + maxItems: 256 + type: array + packageName: + description: |- + packageName is a reference to the name of the package to be installed + and is used to filter the content from catalogs. + + packageName is required, immutable, and follows the DNS subdomain standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. + + Some examples of valid values are: + - some-package + - 123-package + - 1-package-2 + - somepackage + + Some examples of invalid values are: + - -some-package + - some-package- + - thisisareallylongpackagenamethatisgreaterthanthemaximumlength + - some.package + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + maxLength: 253 + type: string + x-kubernetes-validations: + - message: packageName is immutable + rule: self == oldSelf + - message: packageName must be a valid DNS1123 subdomain. + It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric + character, and be no longer than 253 characters + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + selector: + description: |- + selector is an optional field that can be used + to filter the set of ClusterCatalogs used in the bundle + selection process. + + When unspecified, all ClusterCatalogs will be used in + the bundle selection process. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + upgradeConstraintPolicy: + default: CatalogProvided + description: |- + upgradeConstraintPolicy is an optional field that controls whether + the upgrade path(s) defined in the catalog are enforced for the package + referenced in the packageName field. + + Allowed values are: "CatalogProvided" or "SelfCertified", or omitted. + + When this field is set to "CatalogProvided", automatic upgrades will only occur + when upgrade constraints specified by the package author are met. + + When this field is set to "SelfCertified", the upgrade constraints specified by + the package author are ignored. This allows for upgrades and downgrades to + any version of the package. This is considered a dangerous operation as it + can lead to unknown and potentially disastrous outcomes, such as data + loss. It is assumed that users have independently verified changes when + using this option. + + When this field is omitted, the default value is "CatalogProvided". + enum: + - CatalogProvided + - SelfCertified + type: string + version: + description: |- + version is an optional semver constraint (a specific version or range of versions). When unspecified, the latest version available will be installed. + + Acceptable version ranges are no longer than 64 characters. + Version ranges are composed of comma- or space-delimited values and one or + more comparison operators, known as comparison strings. Additional + comparison strings can be added using the OR operator (||). + + # Range Comparisons + + To specify a version range, you can use a comparison string like ">=3.0, + <3.6". When specifying a range, automatic updates will occur within that + range. The example comparison string means "install any version greater than + or equal to 3.0.0 but less than 3.6.0.". It also states intent that if any + upgrades are available within the version range after initial installation, + those upgrades should be automatically performed. + + # Pinned Versions + + To specify an exact version to install you can use a version range that + "pins" to a specific version. When pinning to a specific version, no + automatic updates will occur. An example of a pinned version range is + "0.6.0", which means "only install version 0.6.0 and never + upgrade from this version". + + # Basic Comparison Operators + + The basic comparison operators and their meanings are: + - "=", equal (not aliased to an operator) + - "!=", not equal + - "<", less than + - ">", greater than + - ">=", greater than OR equal to + - "<=", less than OR equal to + + # Wildcard Comparisons + + You can use the "x", "X", and "*" characters as wildcard characters in all + comparison operations. Some examples of using the wildcard characters: + - "1.2.x", "1.2.X", and "1.2.*" is equivalent to ">=1.2.0, < 1.3.0" + - ">= 1.2.x", ">= 1.2.X", and ">= 1.2.*" is equivalent to ">= 1.2.0" + - "<= 2.x", "<= 2.X", and "<= 2.*" is equivalent to "< 3" + - "x", "X", and "*" is equivalent to ">= 0.0.0" + + # Patch Release Comparisons + + When you want to specify a minor version up to the next major version you + can use the "~" character to perform patch comparisons. Some examples: + - "~1.2.3" is equivalent to ">=1.2.3, <1.3.0" + - "~1" and "~1.x" is equivalent to ">=1, <2" + - "~2.3" is equivalent to ">=2.3, <2.4" + - "~1.2.x" is equivalent to ">=1.2.0, <1.3.0" + + # Major Release Comparisons + + You can use the "^" character to make major release comparisons after a + stable 1.0.0 version is published. If there is no stable version published, // minor versions define the stability level. Some examples: + - "^1.2.3" is equivalent to ">=1.2.3, <2.0.0" + - "^1.2.x" is equivalent to ">=1.2.0, <2.0.0" + - "^2.3" is equivalent to ">=2.3, <3" + - "^2.x" is equivalent to ">=2.0.0, <3" + - "^0.2.3" is equivalent to ">=0.2.3, <0.3.0" + - "^0.2" is equivalent to ">=0.2.0, <0.3.0" + - "^0.0.3" is equvalent to ">=0.0.3, <0.0.4" + - "^0.0" is equivalent to ">=0.0.0, <0.1.0" + - "^0" is equivalent to ">=0.0.0, <1.0.0" + + # OR Comparisons + You can use the "||" character to represent an OR operation in the version + range. Some examples: + - ">=1.2.3, <2.0.0 || >3.0.0" + - "^0 || ^3 || ^5" + + For more information on semver, please see https://semver.org/ + maxLength: 64 + type: string + x-kubernetes-validations: + - message: invalid version expression + rule: self.matches("^(\\s*(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)\\s*(v?(0|[1-9]\\d*|[x|X|\\*])(\\.(0|[1-9]\\d*|x|X|\\*]))?(\\.(0|[1-9]\\d*|x|X|\\*))?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?)\\s*)((?:\\s+|,\\s*|\\s*\\|\\|\\s*)(=||!=|>|<|>=|=>|<=|=<|~|~>|\\^)\\s*(v?(0|[1-9]\\d*|x|X|\\*])(\\.(0|[1-9]\\d*|x|X|\\*))?(\\.(0|[1-9]\\d*|x|X|\\*]))?(-([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?(\\+([0-9A-Za-z\\-]+(\\.[0-9A-Za-z\\-]+)*))?)\\s*)*$") + required: + - packageName + type: object + sourceType: + description: |- + sourceType is a required reference to the type of install source. + + Allowed values are "Catalog" + + When this field is set to "Catalog", information for determining the + appropriate bundle of content to install will be fetched from + ClusterCatalog resources existing on the cluster. + When using the Catalog sourceType, the catalog field must also be set. + enum: + - Catalog + type: string + required: + - sourceType + type: object + x-kubernetes-validations: + - message: catalog is required when sourceType is Catalog, and forbidden + otherwise + rule: 'has(self.sourceType) && self.sourceType == ''Catalog'' ? + has(self.catalog) : !has(self.catalog)' + required: + - namespace + - serviceAccount + - source + type: object + status: + description: status is an optional field that defines the observed state + of the ClusterExtension. + properties: + conditions: + description: |- + The set of condition types which apply to all spec.source variations are Installed and Progressing. + + The Installed condition represents whether or not the bundle has been installed for this ClusterExtension. + When Installed is True and the Reason is Succeeded, the bundle has been successfully installed. + When Installed is False and the Reason is Failed, the bundle has failed to install. + + The Progressing condition represents whether or not the ClusterExtension is advancing towards a new state. + When Progressing is True and the Reason is Succeeded, the ClusterExtension is making progress towards a new state. + When Progressing is True and the Reason is Retrying, the ClusterExtension has encountered an error that could be resolved on subsequent reconciliation attempts. + When Progressing is False and the Reason is Blocked, the ClusterExtension has encountered an error that requires manual intervention for recovery. + + When the ClusterExtension is sourced from a catalog, if may also communicate a deprecation condition. + These are indications from a package owner to guide users away from a particular package, channel, or bundle. + BundleDeprecated is set if the requested bundle version is marked deprecated in the catalog. + ChannelDeprecated is set if the requested channel is marked deprecated in the catalog. + PackageDeprecated is set if the requested package is marked deprecated in the catalog. + Deprecated is a rollup condition that is present when any of the deprecated conditions are present. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + install: + description: install is a representation of the current installation + status for this ClusterExtension. + properties: + bundle: + description: |- + bundle is a required field which represents the identifying attributes of a bundle. + + A "bundle" is a versioned set of content that represents the resources that + need to be applied to a cluster to install a package. + properties: + name: + description: |- + name is required and follows the DNS subdomain standard + as defined in [RFC 1123]. It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric character, + and be no longer than 253 characters. + type: string + x-kubernetes-validations: + - message: packageName must be a valid DNS1123 subdomain. + It must contain only lowercase alphanumeric characters, + hyphens (-) or periods (.), start and end with an alphanumeric + character, and be no longer than 253 characters + rule: self.matches("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$") + version: + description: |- + version is a required field and is a reference to the version that this bundle represents + version follows the semantic versioning standard as defined in https://semver.org/. + type: string + x-kubernetes-validations: + - message: version must be well-formed semver + rule: self.matches("^([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(-([-0-9A-Za-z]+(\\.[-0-9A-Za-z]+)*))?(\\+([-0-9A-Za-z]+(-\\.[-0-9A-Za-z]+)*))?") + required: + - name + - version + type: object + required: + - bundle + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-leader-election-role + namespace: olmv1-system +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-leader-election-role + namespace: olmv1-system +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-role + namespace: olmv1-system +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-manager-role +rules: +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs/finalizers + verbs: + - update +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs/status + verbs: + - get + - patch + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-clusterextension-editor-role +rules: +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-clusterextension-viewer-role +rules: +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-role +rules: +- apiGroups: + - "" + resources: + - serviceaccounts/token + verbs: + - create +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get +- apiGroups: + - olm.operatorframework.io + resources: + - clustercatalogs + verbs: + - get + - list + - watch +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions/finalizers + verbs: + - update +- apiGroups: + - olm.operatorframework.io + resources: + - clusterextensions/status + verbs: + - patch + - update +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-leader-election-rolebinding + namespace: olmv1-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: catalogd-leader-election-role +subjects: +- kind: ServiceAccount + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-leader-election-rolebinding + namespace: olmv1-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: operator-controller-leader-election-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-rolebinding + namespace: olmv1-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: operator-controller-manager-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: catalogd-manager-role +subjects: +- kind: ServiceAccount + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: catalogd-proxy-role +subjects: +- kind: ServiceAccount + name: catalogd-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: operator-controller-manager-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + name: operator-controller-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: operator-controller-proxy-role +subjects: +- kind: ServiceAccount + name: operator-controller-controller-manager + namespace: olmv1-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + control-plane: catalogd-controller-manager + name: catalogd-service + namespace: olmv1-system +spec: + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 8443 + - name: webhook + port: 9443 + protocol: TCP + targetPort: 9443 + - name: metrics + port: 7443 + protocol: TCP + targetPort: 7443 + selector: + control-plane: catalogd-controller-manager +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + control-plane: operator-controller-controller-manager + name: operator-controller-service + namespace: olmv1-system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + control-plane: operator-controller-controller-manager +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + kubectl.kubernetes.io/default-logs-container: manager + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + control-plane: catalogd-controller-manager + name: catalogd-controller-manager + namespace: olmv1-system +spec: + minReadySeconds: 5 + replicas: 1 + selector: + matchLabels: + control-plane: catalogd-controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: catalogd-controller-manager + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - arm64 + - ppc64le + - s390x + - key: kubernetes.io/os + operator: In + values: + - linux + containers: + - args: + - --metrics-bind-address=:7443 + - --external-address=catalogd-service.$(POD_NAMESPACE).svc + - --tls-cert=/var/server-cert/tls.crt + - --tls-key=/var/server-cert/tls.key + command: + - ./catalogd + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: quay.io/operator-framework/catalogd:devel + imagePullPolicy: IfNotPresent + livenessProbe: null + name: manager + readinessProbe: null + resources: + requests: + cpu: 100m + memory: 200Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/cache/ + name: cache + - mountPath: /var/server-cert + name: server-cert + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: catalogd-controller-manager + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: cache + - name: server-cert + secret: + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + optional: false + secretName: catalogd-cert-devel +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + kubectl.kubernetes.io/default-logs-container: manager + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + control-plane: operator-controller-controller-manager + name: operator-controller-controller-manager + namespace: olmv1-system +spec: + replicas: 1 + selector: + matchLabels: + control-plane: operator-controller-controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: operator-controller-controller-manager + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - arm64 + - ppc64le + - s390x + - key: kubernetes.io/os + operator: In + values: + - linux + containers: + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=:8443 + - --tls-cert=/var/certs/server-cert/tls.cert + - --tls-key=/var/certs/server-cert/tls.key + - --catalogd-cas-dir=/var/certs/catalogd-ca + command: + - /operator-controller + image: quay.io/operator-framework/operator-controller:devel + imagePullPolicy: IfNotPresent + livenessProbe: null + name: manager + readinessProbe: null + resources: + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - mountPath: /var/cache + name: cache + - mountPath: /var/certs/server-cert + name: server-cert + readOnly: true + - mountPath: /var/certs/catalogd-ca + name: catalogd-ca + readOnly: true + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: operator-controller-controller-manager + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: cache + - name: server-cert + secret: + items: + - key: tls.crt + path: tls.cert + - key: tls.key + path: tls.key + optional: false + secretName: operator-controller-cert + - name: catalogd-ca + secret: + items: + - key: ca.crt + path: ca.crt + optional: false + secretName: catalogd-cert-devel +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/part-of: olm + name: catalogd-cert + namespace: olmv1-system +spec: + dnsNames: + - catalogd-service.olmv1-system.svc + - catalogd-service.olmv1-system.svc.cluster.local + issuerRef: + group: cert-manager.io + kind: Issuer + name: olmv1-ca + privateKey: + algorithm: ECDSA + size: 256 + secretName: catalogd-cert-devel +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/part-of: olm + name: olmv1-ca + namespace: olmv1-system +spec: + commonName: olmv1-ca + isCA: true + issuerRef: + group: cert-manager.io + kind: Issuer + name: self-sign-issuer + privateKey: + algorithm: ECDSA + size: 256 + secretName: olmv1-ca + secretTemplate: + annotations: + cert-manager.io/allow-direct-injection: "true" +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/part-of: olm + name: operator-controller-cert + namespace: olmv1-system +spec: + dnsNames: + - operator-controller-service.olmv1-system.svc + - operator-controller-service.olmv1-system.svc.cluster.local + issuerRef: + group: cert-manager.io + kind: Issuer + name: olmv1-ca + privateKey: + algorithm: ECDSA + size: 256 + secretName: operator-controller-cert +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/part-of: olm + name: olmv1-ca + namespace: olmv1-system +spec: + ca: + secretName: olmv1-ca +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/part-of: olm + name: self-sign-issuer + namespace: olmv1-system +spec: + selfSigned: {} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + control-plane: catalogd-controller-manager + name: catalogd-controller-manager + namespace: olmv1-system +spec: + egress: + - {} + ingress: + - ports: + - port: 7443 + protocol: TCP + - port: 8443 + protocol: TCP + - port: 9443 + protocol: TCP + podSelector: + matchLabels: + control-plane: catalogd-controller-manager + policyTypes: + - Ingress + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/name: operator-controller + app.kubernetes.io/part-of: olm + control-plane: operator-controller-controller-manager + name: operator-controller-controller-manager + namespace: olmv1-system +spec: + egress: + - {} + ingress: + - ports: + - port: 8443 + protocol: TCP + podSelector: + matchLabels: + control-plane: operator-controller-controller-manager + policyTypes: + - Ingress + - Egress +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from-secret: olmv1-system/olmv1-ca + labels: + app.kubernetes.io/name: catalogd + app.kubernetes.io/part-of: olm + name: catalogd-mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: catalogd-service + namespace: olmv1-system + path: /mutate-olm-operatorframework-io-v1-clustercatalog + port: 9443 + failurePolicy: Fail + matchConditions: + - expression: '''name'' in object.metadata && (!has(object.metadata.labels) || !(''olm.operatorframework.io/metadata.name'' + in object.metadata.labels) || object.metadata.labels[''olm.operatorframework.io/metadata.name''] + != object.metadata.name)' + name: MissingOrIncorrectMetadataNameLabel + name: inject-metadata-name.olm.operatorframework.io + rules: + - apiGroups: + - olm.operatorframework.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - clustercatalogs + sideEffects: None + timeoutSeconds: 10 diff --git a/internal/catalogd/webhook/cluster_catalog_webhook.go b/internal/catalogd/webhook/cluster_catalog_webhook.go index a19a62e73..e2fe5103e 100644 --- a/internal/catalogd/webhook/cluster_catalog_webhook.go +++ b/internal/catalogd/webhook/cluster_catalog_webhook.go @@ -11,8 +11,6 @@ import ( ocv1 "github.com/operator-framework/operator-controller/api/v1" ) -// +kubebuilder:webhook:admissionReviewVersions={v1},failurePolicy=Fail,groups=olm.operatorframework.io,mutating=true,name=inject-metadata-name.olm.operatorframework.io,path=/mutate-olm-operatorframework-io-v1-clustercatalog,resources=clustercatalogs,verbs=create;update,versions=v1,sideEffects=None,timeoutSeconds=10 - // +kubebuilder:rbac:groups=olm.operatorframework.io,resources=clustercatalogs,verbs=get;list;watch;patch;update // ClusterCatalog wraps the external v1.ClusterCatalog type and implements admission.Defaulter diff --git a/internal/operator-controller/controllers/clusterextension_controller.go b/internal/operator-controller/controllers/clusterextension_controller.go index e571174b0..0037c0227 100644 --- a/internal/operator-controller/controllers/clusterextension_controller.go +++ b/internal/operator-controller/controllers/clusterextension_controller.go @@ -93,7 +93,7 @@ type InstalledBundleGetter interface { //+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clusterextensions,verbs=get;list;watch;update;patch //+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clusterextensions/status,verbs=update;patch //+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clusterextensions/finalizers,verbs=update -//+kubebuilder:rbac:namespace=system,groups=core,resources=secrets,verbs=create;update;patch;delete;deletecollection;get;list;watch +//+kubebuilder:rbac:namespace=__NAMESPACE_PLACEHOLDER__,groups=core,resources=secrets,verbs=create;update;patch;delete;deletecollection;get;list;watch //+kubebuilder:rbac:groups=core,resources=serviceaccounts/token,verbs=create //+kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=get //+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings;roles;rolebindings,verbs=list;watch diff --git a/scripts/install.tpl.sh b/scripts/install.tpl.sh index 8088a2515..cbfd722cf 100644 --- a/scripts/install.tpl.sh +++ b/scripts/install.tpl.sh @@ -9,7 +9,7 @@ if [[ -z "$olmv1_manifest" ]]; then exit 1 fi -default_catalogs_manifest=$DEFAULT_CATALOG +default_catalogs_manifest=$DEFAULT_CATALOGS cert_mgr_version=$CERT_MGR_VERSION install_default_catalogs=$INSTALL_DEFAULT_CATALOGS diff --git a/test/e2e/cluster_extension_install_test.go b/test/e2e/cluster_extension_install_test.go index a01124bfb..b111506f3 100644 --- a/test/e2e/cluster_extension_install_test.go +++ b/test/e2e/cluster_extension_install_test.go @@ -712,7 +712,7 @@ func TestClusterExtensionInstallReResolvesWhenCatalogIsPatched(t *testing.T) { // patch imageRef tag on test-catalog image with v2 image t.Log("By patching the catalog ImageRef to point to the v2 catalog") - updatedCatalogImage := fmt.Sprintf("%s/test-catalog:v2", os.Getenv("LOCAL_REGISTRY_HOST")) + updatedCatalogImage := fmt.Sprintf("%s/test-catalog:v2", os.Getenv("INCLUSTER_REGISTRY_HOST")) err := patchTestCatalog(context.Background(), testCatalogName, updatedCatalogImage) require.NoError(t, err) require.EventuallyWithT(t, func(ct *assert.CollectT) { @@ -741,12 +741,12 @@ func TestClusterExtensionInstallReResolvesWhenNewCatalog(t *testing.T) { // Tag the image with the new tag var err error - v1Image := fmt.Sprintf("%s/%s", os.Getenv("CLUSTER_REGISTRY_HOST"), os.Getenv("E2E_TEST_CATALOG_V1")) + v1Image := fmt.Sprintf("%s/%s", os.Getenv("LOCAL_REGISTRY_HOST"), os.Getenv("E2E_TEST_CATALOG_V1")) err = crane.Tag(v1Image, latestImageTag, crane.Insecure) require.NoError(t, err) // create a test-catalog with latest image tag - latestCatalogImage := fmt.Sprintf("%s/e2e/test-catalog:latest", os.Getenv("LOCAL_REGISTRY_HOST")) + latestCatalogImage := fmt.Sprintf("%s/e2e/test-catalog:latest", os.Getenv("INCLUSTER_REGISTRY_HOST")) extensionCatalog, err := createTestCatalog(context.Background(), testCatalogName, latestCatalogImage) require.NoError(t, err) clusterExtensionName := fmt.Sprintf("clusterextension-%s", rand.String(8)) @@ -793,7 +793,7 @@ func TestClusterExtensionInstallReResolvesWhenNewCatalog(t *testing.T) { // update tag on test-catalog image with v2 image t.Log("By updating the catalog tag to point to the v2 catalog") - v2Image := fmt.Sprintf("%s/%s", os.Getenv("CLUSTER_REGISTRY_HOST"), os.Getenv("E2E_TEST_CATALOG_V2")) + v2Image := fmt.Sprintf("%s/%s", os.Getenv("LOCAL_REGISTRY_HOST"), os.Getenv("E2E_TEST_CATALOG_V2")) err = crane.Tag(v2Image, latestImageTag, crane.Insecure) require.NoError(t, err) require.EventuallyWithT(t, func(ct *assert.CollectT) { diff --git a/test/extension-developer-e2e/setup.sh b/test/extension-developer-e2e/setup.sh index 889080ad6..97c41c6cb 100755 --- a/test/extension-developer-e2e/setup.sh +++ b/test/extension-developer-e2e/setup.sh @@ -13,7 +13,7 @@ a KinD cluster with the name specified in the arguments. The following environment variables are required for configuring this script: - \$CATALOG_IMG - the tag for the catalog image that contains the registry+v1 bundle. - \$REG_PKG_NAME - the name of the package for the extension that uses the registry+v1 bundle format. -- \$LOCAL_REGISTRY_HOST - hostname:port of the local docker-registry +- \$INCLUSTER_REGISTRY_HOST - hostname:port of the local docker-registry setup.sh also takes 5 arguments. Usage: @@ -42,8 +42,8 @@ if [[ -z "${REG_PKG_NAME}" ]]; then exit 1 fi -if [[ -z "${LOCAL_REGISTRY_HOST}" ]]; then - echo "\$LOCAL_REGISTRY_HOST is required to be set" +if [[ -z "${INCLUSTER_REGISTRY_HOST}" ]]; then + echo "\$INCLUSTER_REGISTRY_HOST is required to be set" echo "${help}" exit 1 fi @@ -69,7 +69,7 @@ kcluster_name=$5 namespace=$6 reg_img="${DOMAIN}/registry:v0.0.1" -reg_bundle_img="${LOCAL_REGISTRY_HOST}/bundles/registry-v1/registry-bundle:v0.0.1" +reg_bundle_img="${INCLUSTER_REGISTRY_HOST}/bundles/registry-v1/registry-bundle:v0.0.1" catalog_img="${CATALOG_IMG}" reg_pkg_name="${REG_PKG_NAME}" diff --git a/testdata/.gitignore b/testdata/.gitignore deleted file mode 100644 index 1eca1dc7e..000000000 --- a/testdata/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -push/bin -registry/bin diff --git a/testdata/Dockerfile b/testdata/Dockerfile deleted file mode 100644 index 2868542e6..000000000 --- a/testdata/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM gcr.io/distroless/static:nonroot - -WORKDIR / - -COPY registry/bin/registry registry -COPY push/bin/push push - -COPY images images - -EXPOSE 5000 - -USER 65532:65532 diff --git a/testdata/build-test-registry.sh b/testdata/build-test-registry.sh deleted file mode 100755 index 8b1372021..000000000 --- a/testdata/build-test-registry.sh +++ /dev/null @@ -1,141 +0,0 @@ -#!/bin/bash - -set -o errexit -set -o nounset -set -o pipefail - -help=" -build-test-registry.sh is a script to stand up an image registry within a cluster. -Usage: - build-test-registry.sh [NAMESPACE] [NAME] [IMAGE] - -Argument Descriptions: - - NAMESPACE is the namespace that should be created and is the namespace in which the image registry will be created - - NAME is the name that should be used for the image registry Deployment and Service - - IMAGE is the name of the image that should be used to run the image registry -" - -if [[ "$#" -ne 3 ]]; then - echo "Illegal number of arguments passed" - echo "${help}" - exit 1 -fi - -namespace=$1 -name=$2 -image=$3 - -kubectl apply -f - << EOF -apiVersion: v1 -kind: Namespace -metadata: - name: ${namespace} ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: ${namespace}-registry - namespace: ${namespace} -spec: - secretName: ${namespace}-registry - isCA: true - dnsNames: - - ${name}.${namespace}.svc - - ${name}.${namespace}.svc.cluster.local - - ${name}-controller-manager-metrics-service.${namespace}.svc - - ${name}-controller-manager-metrics-service.${namespace}.svc.cluster.local - privateKey: - algorithm: ECDSA - size: 256 - issuerRef: - name: olmv1-ca - kind: ClusterIssuer - group: cert-manager.io ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: ${name} - namespace: ${namespace} - labels: - app: registry -spec: - replicas: 1 - selector: - matchLabels: - app: registry - template: - metadata: - labels: - app: registry - spec: - containers: - - name: registry - image: ${image} - imagePullPolicy: IfNotPresent - command: - - /registry - args: - - "--registry-address=:5000" - volumeMounts: - - name: certs-vol - mountPath: "/certs" - env: - - name: REGISTRY_HTTP_TLS_CERTIFICATE - value: "/certs/tls.crt" - - name: REGISTRY_HTTP_TLS_KEY - value: "/certs/tls.key" - volumes: - - name: certs-vol - secret: - secretName: ${namespace}-registry ---- -apiVersion: v1 -kind: Service -metadata: - name: ${name} - namespace: ${namespace} -spec: - selector: - app: registry - ports: - - name: http - port: 5000 - targetPort: 5000 - nodePort: 30000 - type: NodePort -EOF - -kubectl wait --for=condition=Available -n "${namespace}" "deploy/${name}" --timeout=60s - -kubectl apply -f - << EOF -apiVersion: batch/v1 -kind: Job -metadata: - name: ${name}-push - namespace: "${namespace}" -spec: - template: - spec: - restartPolicy: Never - containers: - - name: push - image: ${image} - command: - - /push - args: - - "--registry-address=${name}.${namespace}.svc:5000" - - "--images-path=/images" - volumeMounts: - - name: certs-vol - mountPath: "/certs" - env: - - name: SSL_CERT_DIR - value: "/certs/" - volumes: - - name: certs-vol - secret: - secretName: ${namespace}-registry -EOF - -kubectl wait --for=condition=Complete -n "${namespace}" "job/${name}-push" --timeout=60s diff --git a/testdata/push/push.go b/testdata/push/push.go index 72989b1dc..9785d474b 100644 --- a/testdata/push/push.go +++ b/testdata/push/push.go @@ -45,12 +45,16 @@ func main() { } // Push the images for name, image := range bundles { - if err := crane.Push(image, fmt.Sprintf("%s/%s", registryAddr, name)); err != nil { + ref := fmt.Sprintf("%s/%s", registryAddr, name) + log.Printf("pushing bundle %q", ref) + if err := crane.Push(image, ref, crane.Insecure); err != nil { log.Fatalf("failed to push bundle images: %s", err.Error()) } } for name, image := range catalogs { - if err := crane.Push(image, fmt.Sprintf("%s/%s", registryAddr, name)); err != nil { + ref := fmt.Sprintf("%s/%s", registryAddr, name) + log.Printf("pushing catalog %q", ref) + if err := crane.Push(image, fmt.Sprintf("%s/%s", registryAddr, name), crane.Insecure); err != nil { log.Fatalf("failed to push catalog images: %s", err.Error()) } } diff --git a/testdata/registry/README.md b/testdata/registry/README.md deleted file mode 100644 index 18c41722a..000000000 --- a/testdata/registry/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Test Registry - -This tool is a bare-bones image registry using the `go-containerregistry` library; it is intended to be used in a test environment only. - -Usage: -``` -Usage of registry: - --registry-address string The address the registry binds to. (default ":12345") -``` - -The server key and cert locations should be set under the following environment variables: -``` - REGISTRY_HTTP_TLS_CERTIFICATE - REGISTRY_HTTP_TLS_KEY -``` diff --git a/testdata/registry/go.mod b/testdata/registry/go.mod deleted file mode 100644 index ce79002d4..000000000 --- a/testdata/registry/go.mod +++ /dev/null @@ -1,8 +0,0 @@ -module registry - -go 1.22.5 - -require ( - github.com/google/go-containerregistry v0.20.2 - github.com/spf13/pflag v1.0.5 -) diff --git a/testdata/registry/go.sum b/testdata/registry/go.sum deleted file mode 100644 index ebadf4aec..000000000 --- a/testdata/registry/go.sum +++ /dev/null @@ -1,36 +0,0 @@ -github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= -github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= -github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE= -github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= -github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo= -github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8= -github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= -github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= -github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/sirupsen/logrus v1.9.1 h1:Ou41VVR3nMWWmTiEUnj0OlsgOSCUFgsPAOl6jRIcVtQ= -github.com/sirupsen/logrus v1.9.1/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= -github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= diff --git a/testdata/registry/registry.go b/testdata/registry/registry.go deleted file mode 100644 index 553d9bcd4..000000000 --- a/testdata/registry/registry.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "flag" - "log" - "net/http" - "os" - "time" - - "github.com/google/go-containerregistry/pkg/registry" - "github.com/spf13/pflag" -) - -const ( - certEnv = "REGISTRY_HTTP_TLS_CERTIFICATE" - keyEnv = "REGISTRY_HTTP_TLS_KEY" -) - -func main() { - var ( - registryAddr string - ) - flag.StringVar(®istryAddr, "registry-address", ":12345", "The address the registry binds to.") - pflag.CommandLine.AddGoFlagSet(flag.CommandLine) - pflag.Parse() - - s := &http.Server{ - Addr: registryAddr, - Handler: registry.New(), - ReadTimeout: 60 * time.Second, - WriteTimeout: 60 * time.Second, - } - - err := s.ListenAndServeTLS(os.Getenv(certEnv), os.Getenv(keyEnv)) - if err != nil { - log.Fatalf("failed to start image registry: %s", err.Error()) - } - - defer s.Close() -}