diff --git a/.github/workflows/operator.yaml b/.github/workflows/operator.yaml
index 9be940dcc7..15a2342324 100644
--- a/.github/workflows/operator.yaml
+++ b/.github/workflows/operator.yaml
@@ -1,72 +1,183 @@
-name: Operator tests Workflow
+name: Operator Test Workflow
on:
push:
+ branches:
+ - main
paths-ignore:
- '.gitignore'
- 'LICENSE'
- 'README*'
- 'docs/**'
- '.github/workflows/**'
- branches: [ main ]
+ - 'operator/install/**'
+
pull_request:
+ branches:
+ - main
paths-ignore:
- '.gitignore'
- 'LICENSE'
- 'README*'
- 'docs/**'
- branches: [ main ]
+ - '.github/workflows/**'
+ - 'operator/install/**'
concurrency:
- # Only run once for latest commit per ref and cancel other (previous) runs.
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
- tests:
- name: Operator Basic tests
- runs-on: ubuntu-22.04
+
+ operator-build-test:
+ name: Build and Test Operator
+ runs-on: ubuntu-latest
+ if: github.repository_owner == 'Apicurio' && !contains(github.event.*.labels.*.name, 'DO NOT MERGE')
steps:
- - name: Checkout Code
- uses: actions/checkout@v3
+
+ - name: Configure env. variables 1
+ run: |
+ echo "UUID=$(uuidgen)" >> $GITHUB_ENV
+
+ # We need tho push the bundle image because opm always pulls; the catalog image because OLM
+ # deploys it with `imagePullPolicy: Always`; and also the operator image itself for the same reason.
+ - name: Configure env. variables 2
+ run: |
+ echo "IMAGE=ttl.sh/apicurio-registry-operator-$UUID:8h" >> $GITHUB_ENV
+ echo "BUNDLE_IMAGE=ttl.sh/apicurio-registry-operator-bundle-$UUID:8h" >> $GITHUB_ENV
+ echo "CATALOG_IMAGE=ttl.sh/apicurio-registry-operator-catalog-$UUID:8h" >> $GITHUB_ENV
+ echo "ADDITIONAL_CATALOG_IMAGE=" >> $GITHUB_ENV
+
+ - name: Checkout ${{ github.ref }}
+ uses: actions/checkout@v4
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
+ with:
+ java-version: '17'
+ distribution: temurin
+ cache: maven
- name: Enable port-forwarding
run: |
- sudo apt-get -y install socat
+ sudo apt-get -y install socat
- - name: Setup Minikube-Kubernetes
+ - name: Setup Minikube
uses: manusa/actions-setup-minikube@v2.13.0
with:
- minikube version: v1.28.0
+ minikube version: v1.33.1
kubernetes version: v1.25.0
github token: ${{ secrets.GITHUB_TOKEN }}
start args: '--force'
- - name: Enable minikube ingress
+ - name: Enable minikube features
run: |
minikube addons enable ingress
+ minikube addons enable olm
- name: Setup minikube tunnel
run: |
- minikube tunnel &
+ minikube tunnel &
+
+ - name: Build and run local tests on Minikube
+ run: |
+ cd operator
+ make BUILD_OPTS="--no-transfer-progress" build
+
+ - name: Build temporary operator image
+ run: |
+ cd operator
+ make image-build image-push
+
+ - name: Build temporary operator bundle
+ run: |
+ cd operator
+ make bundle
+
+ - name: Build temporary operator catalog
+ run: |
+ cd operator
+ make catalog
+
+ - name: Run remote tests on Minikube
+ run: |
+ cd operator
+ mvn clean verify --no-transfer-progress -DskipOperatorTests=false -Dtest.operator.deployment=remote \
+ -Dtest.operator.deployment-target=minikube -Dtest.operator.catalog-image=$(make catalog-image-get)
+
+ operator-publish:
+ name: Publish Operator
+ runs-on: ubuntu-latest
+ needs: operator-build-test
+ if: github.event_name == 'push'
+ steps:
+
+ # Do not publish (version)-snapshot tag, instead use `latest-snapshot`.
+ - name: Configure env. variables
+ run: |
+ echo "IMAGE_TAG=latest-snapshot" >> $GITHUB_ENV
+ echo "BUNDLE_IMAGE_TAG=latest-snapshot" >> $GITHUB_ENV
+
+ - name: Checkout ${{ github.ref }}
+ uses: actions/checkout@v4
- name: Set up JDK 17
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: '17'
- distribution: 'temurin'
- cache: 'maven'
+ distribution: temurin
+ cache: maven
+
+ - name: Build
+ run: |
+ cd operator
+ make BUILD_OPTS="--no-transfer-progress" SKIP_TESTS=true build
+
+ - name: Login to quay.io registry
+ run: |
+ docker login -u "${{ secrets.QUAY_USERNAME }}" -p "${{ secrets.QUAY_PASSWORD }}" quay.io
- - name: Workaround jackson-coreutils
+ - name: Build and publish operator image # TODO: Also push to DockerHub Registry
run: |
- # upstream issue: https://github.com/java-json-tools/jackson-coreutils/issues/59
- rm -rf ~/.m2/repository/com/github/java-json-tools
- mkdir -p /tmp/coreutils-workaround
- ( cd /tmp/coreutils-workaround && mvn dependency:get -DremoteRepositories=https://repo1.maven.org/maven2 -Dartifact=com.github.java-json-tools:jackson-coreutils:2.0 )
+ cd operator
+ make image-build image-push
- - name: Run the tests in local mode
- run: ./mvnw clean verify -P '!external_repos' -DskipOperatorTests=false -pl operator/controller -am
+ - name: Build and publish operator bundle
+ run: |
+ cd operator
+ make bundle
+
+ operator-check-install-file:
+ name: Check Operator Install file
+ runs-on: ubuntu-latest
+ needs: operator-publish
+ steps:
+
+ - name: Checkout Code
+ uses: actions/checkout@v3
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
+ with:
+ java-version: '17'
+ distribution: temurin
+ cache: maven
+
+ - name: Build
+ run: |
+ cd operator
+ make BUILD_OPTS="--no-transfer-progress" SKIP_TESTS=true build
+
+ - name: Update install file
+ run: |
+ cd operator
+ make INSTALL_FILE=install/install.yaml dist-install-file
- - name: Run the tests in remote mode
+ - name: Check install file
run: |
- ./mvnw clean package -P '!external_repos' -pl operator/controller -am -Dquarkus.container-image.build=true
- ./mvnw clean verify -P '!external_repos' -DskipOperatorTests=false -pl operator/controller -am -Dtest.operator.deployment=remote -Dtest.operator.deployment-target=minikube
+ git add operator/install/install.yaml || true
+ if ! git diff --cached --exit-code &> /dev/null; then
+ echo 'Install file needs to be updated. Please run "cd operator; make INSTALL_FILE=install/install.yaml dist-install-file" and commit the result.';
+ exit 1;
+ else
+ echo "No changes to the install file.";
+ fi
diff --git a/operator/.gitignore b/operator/.gitignore
new file mode 100644
index 0000000000..46ef8bfd6e
--- /dev/null
+++ b/operator/.gitignore
@@ -0,0 +1,2 @@
+controller/src/main/deploy/crd/apicurioregistries3.registry.apicur.io-v1.yml
+install/apicurio-registry-operator-*-SNAPSHOT.yaml
diff --git a/operator/Makefile b/operator/Makefile
new file mode 100644
index 0000000000..4e4f56a1a8
--- /dev/null
+++ b/operator/Makefile
@@ -0,0 +1,401 @@
+# Run `make` for a list of targets, and `make config-show` to show the current configuration.
+
+########## Config
+
+SHELL = /usr/bin/env bash -o pipefail
+.SHELLFLAGS = -ec
+
+VERSION ?= $(shell mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
+LC_VERSION ?= $(shell echo "$(VERSION)" | tr A-Z a-z)
+LC_VERSION_SUFFIX ?= $(shell echo "$(LC_VERSION)" | sed -n 's/[^-]*\(-.*\)/\1/p')
+
+BUILD_OPTS ?=
+
+SKIP_TESTS ?= false
+ifneq ($(SKIP_TESTS),true)
+ override BUILD_OPTS += -DskipOperatorTests=false
+endif
+
+IMAGE_REGISTRY ?= quay.io/apicurio
+IMAGE_NAME ?= apicurio-registry-operator
+IMAGE_TAG ?= $(LC_VERSION)
+
+IMAGE ?= $(IMAGE_REGISTRY)/$(IMAGE_NAME):$(IMAGE_TAG)
+ADDITIONAL_IMAGE ?= $(IMAGE_REGISTRY)/$(IMAGE_NAME):$(ADDITIONAL_IMAGE_TAG)
+
+REGISTRY_APP_IMAGE ?= quay.io/apicurio/apicurio-registry:latest-snapshot
+REGISTRY_UI_IMAGE ?= quay.io/apicurio/apicurio-registry-ui:latest-snapshot
+
+NAMESPACE ?= default
+
+### Bundle
+
+PACKAGE_NAME ?= apicurio-registry
+PACKAGE= ?= $(PACKAGE_NAME).v$(LC_VERSION)
+
+CHANNELS ?= 3.x
+DEFAULT_CHANNEL ?= $(CHANNELS)
+
+BUNDLE_OPTS ?= --package $(PACKAGE_NAME) --version $(LC_VERSION) --channels=$(CHANNELS) --default-channel=$(DEFAULT_CHANNEL)
+BUNDLE_DIR ?= target/bundle/$(PACKAGE_NAME)/$(LC_VERSION)
+
+# TODO Replaces:
+# PREVIOUS_PACKAGE_VERSION =
+# REPLACES = $(PACKAGE_NAME).v$(PREVIOUS_PACKAGE_VERSION)
+
+BUNDLE_IMAGE_NAME ?= $(IMAGE_NAME)-bundle
+BUNDLE_IMAGE_TAG ?= $(LC_VERSION)
+BUNDLE_IMAGE ?= $(IMAGE_REGISTRY)/$(BUNDLE_IMAGE_NAME):$(BUNDLE_IMAGE_TAG)
+ADDITIONAL_BUNDLE_IMAGE ?= $(IMAGE_REGISTRY)/$(BUNDLE_IMAGE_NAME):$(ADDITIONAL_BUNDLE_TAG)
+
+### Catalog
+
+CATALOG_NAMESPACE ?= openshift-marketplace
+
+CATALOG_DIR ?= controller/src/test/deploy/catalog
+CATALOG_TARGET_DIR ?= target/catalog
+
+CATALOG_IMAGE_NAME ?= $(IMAGE_NAME)-catalog
+CATALOG_IMAGE_TAG ?= $(LC_VERSION)
+CATALOG_IMAGE ?= $(IMAGE_REGISTRY)/$(CATALOG_IMAGE_NAME):$(CATALOG_IMAGE_TAG)
+ADDITIONAL_CATALOG_IMAGE_TAG ?= latest$(LC_VERSION_SUFFIX)
+ADDITIONAL_CATALOG_IMAGE ?= $(IMAGE_REGISTRY)/$(CATALOG_IMAGE_NAME):$(ADDITIONAL_CATALOG_IMAGE_TAG)
+
+### Install
+
+INSTALL_NAMESPACE ?= PLACEHOLDER_NAMESPACE
+INSTALL_FILE ?= install/apicurio-registry-operator-$(VERSION).yaml
+
+DIST_TARGET_DIR ?= target/dist
+
+### Other
+
+OS ?= linux
+ARCH ?= amd64
+
+DATE=$(shell date -Idate)
+
+CC_RED = $(shell echo -e "\033[0;31m")
+CC_YELLOW = $(shell echo -e "\033[0;33m")
+CC_CYAN = $(shell echo -e "\033[0;36m")
+CC_END = $(shell echo -e "\033[0m")
+
+### Kustomize variables
+
+export PLACEHOLDER_NAMESPACE := $(NAMESPACE)
+
+export PLACEHOLDER_VERSION := $(VERSION)
+export PLACEHOLDER_LC_VERSION := $(LC_VERSION)
+
+export PLACEHOLDER_IMAGE := $(IMAGE)
+export PLACEHOLDER_REGISTRY_APP_IMAGE := $(REGISTRY_APP_IMAGE)
+export PLACEHOLDER_REGISTRY_UI_IMAGE := $(REGISTRY_UI_IMAGE)
+
+export PLACEHOLDER_DATE := $(DATE)
+
+export PLACEHOLDER_PACKAGE := $(PACKAGE)
+export PLACEHOLDER_BUNDLE_IMAGE := $(BUNDLE_IMAGE)
+
+export PLACEHOLDER_CATALOG_NAMESPACE := $(CATALOG_NAMESPACE)
+export PLACEHOLDER_CATALOG_IMAGE := $(CATALOG_IMAGE)
+
+
+
+########## Help
+
+
+.DEFAULT_GOAL = help
+.PHONY: help
+help: ## TODO
+ @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "$(CC_CYAN)%-30s$(CC_END) %s\n", $$1, $$2}'
+
+
+.PHONY: config-show
+config-show: ## TODO
+ @echo "$(CC_YELLOW)==============================================$(CC_END)"
+ @echo "Configuration properties:"
+ @echo ""
+ @echo "$(CC_CYAN)Operator$(CC_END)"
+ @echo "VERSION=$(VERSION)"
+ @echo "LC_VERSION=$(LC_VERSION)"
+ifneq ($(LC_VERSION_SUFFIX),)
+ @echo "LC_VERSION_SUFFIX=$(LC_VERSION_SUFFIX)"
+endif
+ @echo "NAMESPACE=$(NAMESPACE)"
+ @echo "SKIP_TESTS=$(SKIP_TESTS)"
+ @echo "BUILD_OPTS=$(BUILDS_OPTS)"
+ @echo "IMAGE=$(IMAGE)"
+ifneq ($(ADDITIONAL_IMAGE),)
+ifneq ($(ADDITIONAL_IMAGE_TAG),)
+ @echo "ADDITIONAL_IMAGE=$(ADDITIONAL_IMAGE)"
+endif
+endif
+ @echo ""
+ @echo "$(CC_CYAN)Operand$(CC_END)"
+ @echo "REGISTRY_APP_IMAGE=$(REGISTRY_APP_IMAGE)"
+ @echo "REGISTRY_UI_IMAGE=$(REGISTRY_UI_IMAGE)"
+ @echo ""
+ @echo "$(CC_CYAN)Bundle$(CC_END)"
+ @echo "PACKAGE_NAME=$(PACKAGE_NAME)"
+ @echo "CHANNELS=$(CHANNELS)"
+ @echo "DEFAULT_CHANNEL=$(DEFAULT_CHANNEL)"
+ @echo "BUNDLE_IMAGE=$(BUNDLE_IMAGE)"
+ifneq ($(ADDITIONAL_BUNDLE_IMAGE),)
+ifneq ($(ADDITIONAL_BUNDLE_IMAGE_TAG),)
+ @echo "ADDITIONAL_BUNDLE_IMAGE=$(ADDITIONAL_BUNDLE_IMAGE)"
+endif
+endif
+ @echo ""
+ @echo "$(CC_CYAN)Catalog$(CC_END)"
+ @echo "CATALOG_IMAGE=$(CATALOG_IMAGE)"
+ifneq ($(ADDITIONAL_CATALOG_IMAGE),)
+ifneq ($(ADDITIONAL_CATALOG_IMAGE_TAG),)
+ @echo "ADDITIONAL_CATALOG_IMAGE=$(ADDITIONAL_CATALOG_IMAGE)"
+endif
+endif
+ @echo ""
+ @echo "$(CC_CYAN)Other$(CC_END)"
+ @echo "OS=$(OS)"
+ @echo "ARCH=$(ARCH)"
+ @echo "DATE=$(DATE)"
+ @echo "$(CC_YELLOW)==============================================$(CC_END)"
+
+
+########## Tools
+
+
+define target_dir
+ @{ \
+ if [ -d $(1) ]; \
+ then \
+ if [[ $(1) == target/* ]]; \
+ then \
+ rm -rf "$(1)"; \
+ fi; \
+ fi; \
+ mkdir -p $(1); \
+ }
+endef
+
+
+OPERATOR_SDK_VERSION ?= 1.37.0
+OPERATOR_SDK = $(shell pwd)/target/bin/operator-sdk
+.PHONY: install-operator-sdk
+install-operator-sdk: ## Install operator-sdk v1.37.0
+ @{ \
+ if [ ! -f $(OPERATOR_SDK) ]; \
+ then \
+ mkdir -p $(dir $(OPERATOR_SDK)); \
+ curl -sSLo $(OPERATOR_SDK) "https://github.com/operator-framework/operator-sdk/releases/download/v$(OPERATOR_SDK_VERSION)/operator-sdk_$(OS)_$(ARCH)"; \
+ chmod +x $(OPERATOR_SDK); \
+ fi; \
+ }
+
+
+.PHONY: install-opm
+OPM_VERSION ?= 1.48.0
+OPM = $(shell pwd)/target/bin/opm
+install-opm: ## Install opm v1.48.0
+ @{ \
+ if [ ! -f $(OPM) ]; \
+ then \
+ mkdir -p $(dir $(OPM)); \
+ curl -sSLo $(OPM) "https://github.com/operator-framework/operator-registry/releases/download/v$(OPM_VERSION)/$(OS)-$(ARCH)-opm"; \
+ chmod +x $(OPM); \
+ fi; \
+ }
+
+
+YQ_VERSION ?= 4.27.5
+YQ = $(shell pwd)/target/bin/yq
+.PHONY: install-yq
+install-yq: ## Install yq v4.27.5
+ @{ \
+ if [ ! -f $(YQ) ]; \
+ then \
+ mkdir -p $(dir $(YQ)); \
+ curl -sSLo $(YQ) "https://github.com/mikefarah/yq/releases/download/v$(YQ_VERSION)/yq_$(OS)_$(ARCH)"; \
+ chmod +x $(YQ); \
+ fi; \
+ }
+
+
+########## Targets
+
+
+.PHONY: build
+build: ## TODO
+ mvn clean install $(BUILD_OPTS)
+
+
+.PHONY: image-build
+image-build: ## TODO
+ docker build -f controller/src/main/docker/Dockerfile.jvm -t $(IMAGE) controller/target
+ifneq ($(ADDITIONAL_IMAGE),)
+ifneq ($(ADDITIONAL_IMAGE_TAG),)
+ docker tag $(IMAGE) $(ADDITIONAL_IMAGE)
+endif
+endif
+
+
+.PHONY: image-push
+image-push: ## TODO
+ docker push $(IMAGE)
+ifneq ($(ADDITIONAL_IMAGE),)
+ifneq ($(ADDITIONAL_IMAGE_TAG),)
+ docker push $(ADDITIONAL_IMAGE)
+endif
+endif
+
+
+.PHONY: image
+image: image-build image-push ## TODO
+
+
+.PHONY: deploy
+deploy: ## Deploy the Operator to a cluster using kubectl
+ kubectl create namespace $(NAMESPACE) || true
+ kubectl kustomize controller/src/main/deploy/install | envsubst | kubectl -n $(NAMESPACE) apply -f -
+
+
+.PHONY: undeploy
+undeploy: ## TODO
+ kubectl kustomize controller/src/main/deploy/install | envsubst | kubectl -n $(NAMESPACE) delete -f -
+
+
+.PHONY: dist-install-file
+dist-install-file: ## TODO
+ export PLACEHOLDER_NAMESPACE=$(INSTALL_NAMESPACE) && \
+ kubectl kustomize controller/src/main/deploy/install | envsubst >$(INSTALL_FILE)
+
+
+.PHONY: dist
+dist: dist-install-file ## TODO
+ $(call target_dir, $(DIST_TARGET_DIR))
+ cp -rt $(DIST_TARGET_DIR) controller/src/main/deploy/dist-template/*
+ # Licenses
+ cp -t $(DIST_TARGET_DIR) target/generated-resources/licenses.xml
+ sed -i '\|^.*.*.*$$|d' $(DIST_TARGET_DIR)/licenses.xml
+ # Examples
+ mkdir -p $(DIST_TARGET_DIR)/examples
+ cp -t $(DIST_TARGET_DIR)/examples controller/src/main/deploy/examples/*
+ rm $(DIST_TARGET_DIR)/examples/kustomization.yaml
+ cp -rt $(DIST_TARGET_DIR)/examples controller/src/main/resources/k8s/examples/*
+ cp -rt $(DIST_TARGET_DIR)/examples controller/src/test/resources/k8s/examples/*
+ # Install
+ cp $(INSTALL_FILE) $(DIST_TARGET_DIR)/install.yaml
+ # Archive
+ cd $(DIST_TARGET_DIR) && tar -zcf ../apicurio-registry-operator-$(VERSION).tar.gz *
+
+
+.PHONY: quickstart
+quickstart: build image-build image-push deploy ## TODO
+
+
+.PHONY: bundle-build
+bundle-build: install-operator-sdk install-yq ## Generate bundle metadata
+ $(call target_dir, $(BUNDLE_DIR))
+ kubectl kustomize controller/src/main/deploy/csv | envsubst | $(OPERATOR_SDK) generate bundle -q --output-dir $(BUNDLE_DIR) $(BUNDLE_OPTS)
+ # Post-process annotations.yaml
+ $(YQ) '... comments = ""' -i $(BUNDLE_DIR)/metadata/annotations.yaml
+ $(YQ) '.annotations = (.annotations | to_entries | del(.[] | select(.key == "operators.operatorframework.io.metrics.*")) | from_entries)' -i $(BUNDLE_DIR)/metadata/annotations.yaml
+ $(YQ) '.annotations."com.redhat.openshift.versions" = "v4.12"' -i $(BUNDLE_DIR)/metadata/annotations.yaml
+ $(YQ) 'sort_keys(..)' -i $(BUNDLE_DIR)/metadata/annotations.yaml
+ # Post-process bundle.Dockerfile
+ mv bundle.Dockerfile $(BUNDLE_DIR)
+ sed -i '\|^# .*$$|d' $(BUNDLE_DIR)/bundle.Dockerfile
+ sed -i '\|^LABEL operators\.operatorframework.io\.metrics\..*$$|d' $(BUNDLE_DIR)/bundle.Dockerfile
+ sed -i 's|^FROM scratch$$|FROM scratch\n\nLABEL com.redhat.openshift.versions=v4.12|g' $(BUNDLE_DIR)/bundle.Dockerfile
+ # Validate
+ $(OPERATOR_SDK) bundle validate $(BUNDLE_DIR)
+
+
+.PHONY: bundle-image-build
+bundle-image-build: ## TODO
+ docker build -f $(BUNDLE_DIR)/bundle.Dockerfile -t $(BUNDLE_IMAGE) .
+ifneq ($(ADDITIONAL_BUNDLE_IMAGE),)
+ifneq ($(ADDITIONAL_BUNDLE_TAG),)
+ docker tag $(BUNDLE_IMAGE) $(ADDITIONAL_BUNDLE_IMAGE)
+endif
+endif
+
+
+.PHONY: bundle-image-push
+bundle-image-push: ## TODO
+ docker push $(BUNDLE_IMAGE)
+ifneq ($(ADDITIONAL_BUNDLE_IMAGE),)
+ifneq ($(ADDITIONAL_BUNDLE_TAG),)
+ docker push $(ADDITIONAL_BUNDLE_IMAGE)
+endif
+endif
+
+
+.PHONY: bundle
+bundle: bundle-build bundle-image-build bundle-image-push ## TODO
+
+
+.PHONY: catalog-build
+catalog-build: install-opm ## TODO
+ $(call target_dir, $(CATALOG_TARGET_DIR))
+ # Create catalog.yaml
+ mkdir -p $(CATALOG_TARGET_DIR)/configs
+ cat $(CATALOG_DIR)/catalog.template.yaml | envsubst > $(CATALOG_TARGET_DIR)/catalog.yaml
+ # Build
+ cd $(CATALOG_TARGET_DIR) && $(OPM) alpha render-template basic catalog.yaml --output=yaml > configs/index.yaml
+ cd $(CATALOG_TARGET_DIR) && $(OPM) generate dockerfile configs
+
+
+.PHONY: catalog-image-build
+catalog-image-build: ## TODO
+ docker build -f $(CATALOG_TARGET_DIR)/configs.Dockerfile -t $(CATALOG_IMAGE) $(CATALOG_TARGET_DIR)
+ifneq ($(ADDITIONAL_CATALOG_IMAGE),)
+ifneq ($(ADDITIONAL_CATALOG_IMAGE_TAG),)
+ docker tag $(CATALOG_IMAGE) $(ADDITIONAL_CATALOG_IMAGE)
+endif
+endif
+
+
+.PHONY: catalog-image-push
+catalog-image-push: ## TODO
+ docker push $(CATALOG_IMAGE)
+ifneq ($(ADDITIONAL_CATALOG_IMAGE),)
+ifneq ($(ADDITIONAL_CATALOG_IMAGE_TAG),)
+ docker push $(ADDITIONAL_CATALOG_IMAGE)
+endif
+endif
+
+.PHONY: catalog-image-get
+catalog-image-get: ## TODO
+ @echo -n $(CATALOG_IMAGE)
+
+.PHONY: catalog
+catalog: catalog-build catalog-image-build catalog-image-push ## TODO
+
+
+.PHONY: catalog-deploy
+catalog-deploy: ## TODO
+ kubectl create namespace $(CATALOG_NAMESPACE) || true
+ cat $(CATALOG_DIR)/catalog-source.yaml | envsubst | kubectl -n $(CATALOG_NAMESPACE) apply -f -
+
+
+.PHONY: catalog-undeploy
+catalog-undeploy: ## TODO
+ cat $(CATALOG_DIR)/catalog-source.yaml | envsubst | kubectl -n $(CATALOG_NAMESPACE) delete -f -
+
+
+.PHONY: catalog-subscription-deploy
+catalog-subscription-deploy: ## TODO
+ kubectl create namespace $(NAMESPACE) || true
+ cat $(CATALOG_DIR)/operator-group.yaml | envsubst | kubectl -n $(NAMESPACE) apply -f -
+ cat $(CATALOG_DIR)/subscription.yaml | envsubst | kubectl -n $(NAMESPACE) apply -f -
+
+
+.PHONY: catalog-subscription-undeploy
+catalog-subscription-undeploy: ## TODO
+ cat $(CATALOG_DIR)/subscription.yaml | envsubst | kubectl -n $(NAMESPACE) delete -f -
+ kubectl -n $(NAMESPACE) delete clusterserviceversion $(PACKAGE)
+
+
+.PHONY: dev
+dev:
+ mvn quarkus:dev
diff --git a/operator/README.md b/operator/README.md
new file mode 100644
index 0000000000..4ed2b8b49a
--- /dev/null
+++ b/operator/README.md
@@ -0,0 +1,380 @@
+# Apicurio Registry Operator
+
+This Apicurio Registry subproject makes use of `make` to execute common tasks. To show an overview of the available
+commands, run `make help`. To show the current configuration, run `make config-show`. Configuration is passed either as
+an environment variable, or with the command, e.g. `make SKIP_TESTS=true build`. This README assumes you are in the same directory, unless stated otherwise.
+
+## Prerequisites
+
+### Build
+
+| Tool | Version |
+|-----------------|---------|
+| JDK | 17 |
+| Maven | TODO |
+| Docker / Podman | TODO |
+
+### Test and Deploy
+
+| Platform | Version |
+|------------|---------|
+| Kubernetes | 1.25+ |
+| OpenShift | 4.12+ |
+
+## Quickstart
+
+### Published Version Quickstart (TODO)
+
+You can install a published version of the Apicurio Registry Operator from the OperatorHub, or Operator Marketplace (on
+OpenShift). Alternatively, you can use the following steps:
+
+1. Log in to your Kubernetes or OpenShift cluster with `kubectl` or `oc`.
+2. Choose a namespace where the operator will be deployed:
+ ```shell
+ export NAMESPACE=apicurio-registry
+ ```
+3. Choose a released version, e.g.:
+ ```shell
+ export VERSION=TODO
+ ```
+ You can use `main` to install the latest development version.
+4. Run:
+ ```shell
+ curl -sSL "https://raw.githubusercontent.com/Apicurio/apicurio-registry/$VERSION/operator/install/install.yaml" | sed "s/PLACEHOLDER_NAMESPACE/$NAMESPACE/g" | kubectl -n $NAMESPACE apply -f -
+ kubectl -n $NAMESPACE apply -f controller/src/main/deploy/examples/simple-apicurioregistry3.yaml
+ ```
+
+### Local Development Quickstart
+
+For the fastest iteration during development, you can run the operator on your local machine, against a local or remote cluster.
+
+The following steps have been tested for OpenShift:
+
+1. Log in to your OpenShift cluster with `kubectl` or `oc`.
+2. Choose a namespace where the operator will be deployed:
+ ```shell
+ export NAMESPACE=apicurio-registry
+ ```
+3. Build the operator:
+ ```shell
+ make SKIP_TESTS=true build
+ ```
+ *NOTE: This step only has to be repeated when the API model changes.*
+
+4. Run:
+ ```shell
+ make dev
+ ```
+ This will run the operator in Quarkus development mode with live reload.
+
+5. Apply an example Apicurio Registry CR:
+ ```shell
+ kubectl apply -f controller/src/main/deploy/examples/simple.apicurioregistry3.yaml
+ ```
+
+### On-cluster Development Quickstart
+
+1. Create an image repository for your operator build, e.g. `quay.io/foo/apicurio-registry-operator`:
+ ```shell
+ export IMAGE_REGISTRY=quay.io/foo
+ ```
+2. Log in to your Kubernetes or OpenShift cluster with `kubectl` or `oc`.
+3. Create a namespace where the operator will be deployed:
+ ```shell
+ export NAMESPACE=apicurio-registry
+ ```
+4. Run:
+ ```shell
+ make SKIP_TESTS=true quickstart
+ ```
+5. Deploy Apicurio Registry:
+ ```shell
+ kubectl apply -f controller/src/main/deploy/examples/simple.apicurioregistry3.yaml
+ ```
+
+After you're done, run `make undeploy`.
+
+### Step-by-Step On-cluster Development Quickstart
+
+To build the operator executable, run:
+
+```shell
+make build
+```
+
+Available options:
+
+| Option | Type | Default value | Description |
+|------------|------------------|---------------|---------------------------|
+| SKIP_TESTS | `true` / `false` | `false` | - |
+| BUILD_OPTS | string | - | Additional Maven options. |
+
+*NOTE: The operator is part of Apicurio Registry within a single multi-module Maven project. You can skip this step if you
+have built the entire project already.*
+
+then, to build the operator image, run:
+
+```shell
+make image-build
+```
+
+Available options:
+
+| Option | Type | Default value | Description |
+|----------------------|--------|--------------------------------|---------------------------------------|
+| IMAGE_REGISTRY | string | `quay.io/apicurio` | - |
+| IMAGE_NAME | string | `apicurio-registry-operator` | - |
+| IMAGE_TAG | string | *(current version, lowercase)* | - |
+| ADDITIONAL_IMAGE_TAG | string | - | Tag the image with an additional tag. |
+
+After the image is built, push it by running:
+
+```shell
+make image-push
+```
+
+*Options are the same as `image-build`.*
+
+You can now deploy the operator to your current cluster (as configured by `kubectl`):
+
+```shell
+make deploy
+```
+
+Available options:
+
+| Option | Type | Default value | Description |
+|--------------------|--------|---------------------------------------------------------|---------------------------------------------------|
+| NAMESPACE | string | `default` | Namespace to which the operator will be deployed. |
+| REGISTRY_APP_IMAGE | string | `quay.io/apicurio/apicurio-registry:latest-snapshot` | - |
+| REGISTRY_UI_IMAGE | string | `quay.io/apicurio/apicurio-registry-ui:latest-snapshot` | - |
+
+To remove the operator from your cluster, run:
+
+```shell
+make undeploy
+```
+
+Available options:
+
+| Option | Type | Default value | Description |
+|-----------|--------|---------------|---------------------------------------------------|
+| NAMESPACE | string | `default` | Namespace to which the operator will be deployed. |
+
+## Testing
+
+*NOTE: This section is mostly specific to the `operator/controller` module, since the tests in the `operator/model` are very simple.*
+
+There are 2 ways to run the operator tests, and they should stay interchangeable.
+
+- `local` runs the operator on the developer machine (**the default**). OLM tests cannot be run locally.
+- `remote` runs the operator in a cluster (requires additional prerequisites, see below).
+
+The Maven property `-DskipOperatorTests=false` is used to explicitly enable the testing of the operator modules, since they require a cluster to run against.
+
+### Local Tests
+
+1. Create a Minikube cluster, unless you already have a cluster available:
+ ```shell
+ minikube start
+ ```
+
+2. To enable testing of Ingresses on Minikube, run (in a separate terminal):
+ ```shell
+ minikube addons enable ingress
+ minikube tunnel
+ ```
+
+3. Run:
+ ```shell
+ mvn clean verify -DskipOperatorTests=false
+ ```
+ or
+ ```shell
+ make build
+ ```
+
+Available Maven options:
+
+| Option | Type | Default value | Description |
+|---------------------------------|---------------------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
+| test.operator.deployment | `local` / `remote` | `local` | Specifies the way that the operator is deployed for testing. |
+| test.operator.ingress-skip | `true` / `false` | `false` | Skip testing of Ingresses. Useful when testing on clusters without an Ingress controller or without an accessible base hostname. |
+| test.operator.ingress-host | string | - | Used when testing Ingresses. For some clusters, you might need to provide the base hostname from where the applications on your cluster are accessible. |
+| test.operator.cleanup | `true` / `false` | `true` | Clean test namespaces from the cluster after the tests finish. |
+
+### Remote Tests
+
+1. Create a Minikube cluster, unless you already have a cluster available:
+ ```shell
+ minikube start
+ ```
+
+2. To enable testing of Ingresses and OLM on Minikube, run (in a separate terminal):
+ ```shell
+ minikube addons enable ingress
+ minikybe addons enable olm
+ minikube tunnel
+ ```
+
+3. Build and push the operator image, bundle image, and catalog image (for OLM tests):
+ ```shell
+ make SKIP_TESTS=true build image-build image-push bundle catalog
+ ```
+
+4. Run:
+ ```shell
+ mvn clean verify -DskipOperatorTests=false -Dtest.operator.deployment=remote -Dtest.operator.deployment-target=minikube -Dtest.operator.catalog-image=$(make catalog-image-get)
+ ```
+
+Maven options for the remote tests are same as those for the local tests, but the following options are additionally available:
+
+| Option | Type | Default value | Description |
+|---------------------------------|---------------------------|-----------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| test.operator.deployment-target | `kubernetes` / `minikube` | `kubernetes` | Modify the deployment for the given cluster type. *NOTE: This should only be necessary for minikube with a shared docker daemon, but the OLM tests still require the bundle and catalog images to be pushed to a remote registry. Please report to us if you find out otherwise.* |
+| test.operator.install-file | string | `operator/controller/target/test-install.yaml` | The install file that is used to deploy the operator for testing, generated during build. *NOTE: More information about the install file are below in the __Distribution and Release__ section.* |
+| test.operator.olm-skip | `true` / `false` | `false` | Skip OLM tests. |
+| test.operator.catalog-image | string | `quay.io/apicurio/apicurio-registry-operator-catalog:latest-snapshot` | Catalog image that is used to deploy the operator for testing with OLM. |
+
+## Distribution and Release
+
+### Install File
+
+You can create an installation file with the resources required to run the operator as follows:
+
+```shell
+make dist-install-file
+```
+
+Available options:
+
+| Option | Type | Default value | Description |
+|--------------------|--------|-----------------------------------------------------------------|-------------|
+| INSTALL_FILE | string | `install/apicurio-registry-operator-`*(current version)*`.yaml` | - |
+| INSTALL_NAMESPACE | string | `PLACEHOLDER_NAMESPACE` | - |
+| IMAGE_REGISTRY | string | `quay.io/apicurio` | - |
+| IMAGE_NAME | string | `apicurio-registry-operator` | - |
+| IMAGE_TAG | string | *(current version, lowercase)* | - |
+| REGISTRY_APP_IMAGE | string | `quay.io/apicurio/apicurio-registry:latest-snapshot` | - |
+| REGISTRY_UI_IMAGE | string | `quay.io/apicurio/apicurio-registry-ui:latest-snapshot` | - |
+
+*NOTE: The CRD file must have been generated using `make build`.*
+
+### Distribution Archive
+
+You can also create a `tar.gz` archive that contains the installation file, installation instructions, examples, license
+information, and other by running:
+
+```shell
+make dist
+```
+
+Available options:
+
+| Option | Type | Default value | Description |
+|--------------------|--------|----------------------------------------------------------------|-------------|
+| IMAGE_REGISTRY | string | `quay.io/apicurio` | - |
+| IMAGE_NAME | string | `apicurio-registry-operator` | - |
+| IMAGE_TAG | string | *(current version, lowercase)* | - |
+| REGISTRY_APP_IMAGE | string | `quay.io/apicurio/apicurio-registry:latest-snapshot` | - |
+| REGISTRY_UI_IMAGE | string | `quay.io/apicurio/apicurio-registry-ui:latest-snapshot` | - |
+
+*NOTE: The CRD file and licenses must have been generated using `make build`.*
+
+## OLM
+
+### Operator Bundle
+
+You can create an OLM bundle files by running:
+
+```shell
+make bundle-build
+```
+
+Available options:
+
+| Option | Type | Default value | Description |
+|--------------------------|------------------|--------------------------------|-------------|
+| BUNDLE_CHANNEL | string | `3.x` | - |
+| BUNDLE_VERSION | string | *(current version, lowercase)* | - |
+| PREVIOUS_PACKAGE_VERSION | string | **TODO** | - |
+
+*NOTE: The CRD file must have been generated using `make build`.*
+
+Then, to create a bundle image, run:
+
+```shell
+make bundle-image-build
+```
+
+Available options:
+
+| Option | Type | Default value | Description |
+|-----------------------|--------|-------------------------------------|---------------------------------------|
+| IMAGE_REGISTRY | string | `quay.io/apicurio` | - |
+| BUNDLE_IMAGE_NAME | string | `apicurio-registry-operator-bundle` | - |
+| BUNDLE_IMAGE_TAG | string | *(current version, lowercase)* | - |
+| ADDITIONAL_BUNDLE_TAG | string | - | Tag the image with an additional tag. |
+
+After the bundle image is built, push it by running:
+
+```shell
+make bundle-image-push
+```
+
+*Options are the same as `bundle-image-build`.*
+
+### Operator Catalog
+
+After you have built and pushed the bundle image, you can build a catalog to use with OLM:
+
+*NOTE: We do not currently release our own upstream catalog image, we only build one for testing.*
+
+```shell
+make catalog-build
+```
+
+Then, to create a catalog image, run:
+
+```shell
+make catalog-image-build
+```
+
+Available options:
+
+| Option | Type | Default value | Description |
+|------------------------|--------|---------------------------------------------------------------------|---------------------------------------|
+| IMAGE_REGISTRY | string | `quay.io/apicurio` | - |
+| CATALOG_IMAGE_NAME | string | `apicurio-registry-operator-catalog` | - |
+| CATALOG_IMAGE_TAG | string | *(current version, lowercase)* | - |
+| ADDITIONAL_CATALOG_TAG | string | `latest` *(with version suffix, lowercase, e.g. `latest-snapshot`)* | Tag the image with an additional tag. |
+
+After the catalog image is built, push it by running:
+
+```shell
+make catalog-image-push
+```
+
+*Options are the same as `catalog-image-build`.*
+
+### OLM On-cluster Quickstart
+
+After you have built and pushed the bundle and catalog images, to deploy the operator to the cluster using OLM, run:
+
+```shell
+make catalog-deploy
+make catalog-subscription-deploy
+```
+
+Available options:
+
+| Option | Type | Default value | Description |
+|-------------------|--------|-------------------------|---------------------------------------------------|
+| NAMESPACE | string | `default` | Namespace to which the operator will be deployed. |
+| CATALOG_NAMESPACE | string | `openshift-marketplace` | - |
+
+## Notes
+
+### Watched Namespaces
+
+Namespace that are watched by the operator are configured using `APICURIO_OPERATOR_WATCHED_NAMESPACES` environment variable. Its value is configured to reflect the OLM annotation `olm.targetNamespaces` by default. This means that if the operator is not installed by OLM (e.g. using the install file), the annotation is empty, which means the operator will watch **all namespaces**. Because of this, cluster-level RBAC resources are used by default. In the future, we may release additional install file with reduced permissions, intended to be used when the operator only manages its own namespace.
diff --git a/operator/controller/README.md b/operator/controller/README.md
index d9ae0ccbd6..fd8ef6d894 100644
--- a/operator/controller/README.md
+++ b/operator/controller/README.md
@@ -1,46 +1,6 @@
# Operator Controller
-This is the module containing the actual reconciliation logic.
-
-## Build
-
-```
-mvn clean install -DskipTests
-```
-
-## Test
-
-There are 2 ways to run the operator in those tests and they should stay interchangeable.
-
-- `local` runs the operator on the developer machine
-- `remote` runs the operator in the cluster
-
-the Maven property `-DskipOperatorTests` is used to explicitly enable the testing of this module.
-
-to control the execution there are a few flags:
-
-- `test.operator.deployment-target` the deployment file to be used `kubernetes` / `minikube` / `openshift`
-- `test.operator.deployment` will be `local` or `remote`
-- `test.operator.cleanup` a boolean to remove all of the created resources after the test finishes
-
-To execute the tests in `remote` mode you need to perform the following steps:
-
-- start `minikube`
-- run `eval $(minikube -p minikube docker-env)` in the teerminal yuo are going to build the container image
-- build the image `mvn clean package -Dquarkus.container-image.build=true -f operator/controller/pom.xml`
-- run the tests `mvn verify -f operator/controller/pom.xml -Dtest.operator.deployment=remote -Dquarkus.kubernetes.deployment-target=minikube -DskipOperatorTests=false`
-
-#### Testing of Ingresses
-
-To allow the testing of Ingresses when using minikube, run:
- ```shell
- minikube addons enable ingress
- minikube tunnel
- ```
-
-On other clusters, you might need to provide `test.operator.ingress-host` property that contains the base hostname from where applications on your cluster are accessible.
-
-If your cluster does not have an accessible ingress host, you can skip them using `test.operator.ingress-skip=true` (**not recommended**).
+This is the module containing the actual reconciliation logic, and this README is specific to that. For more general information about the operator, see `../README.md`.
## PodTemplateSpec merging
diff --git a/operator/controller/pom.xml b/operator/controller/pom.xml
index d7514a8d46..b11dc3157e 100644
--- a/operator/controller/pom.xml
+++ b/operator/controller/pom.xml
@@ -21,48 +21,17 @@
io.apicurio
apicurio-registry-operator-model
- ${project.version}
-
io.quarkiverse.operatorsdk
quarkus-operator-sdk
-
- io.quarkus
- quarkus-resteasy-jackson
-
-
- io.quarkus
- quarkus-openshift
-
-
- io.quarkus
- quarkus-minikube
-
io.quarkus
quarkus-kubernetes-client
-
- org.bouncycastle
- bcprov-jdk15on
- ${bouncycastle.version}
-
-
- org.bouncycastle
- bcpkix-jdk15on
- ${bouncycastle.version}
-
-
- io.quarkus
- quarkus-container-image-jib
-
-
- io.quarkus
- quarkus-test-common
- test
-
+
+
io.quarkus
quarkus-junit5
@@ -71,12 +40,11 @@
org.assertj
assertj-core
- ${assertj.core.version}
+ test
org.awaitility
awaitility
- ${awaitility.version}
test
@@ -89,10 +57,30 @@
lombok
provided
+
+
+
+
+ true
+ src/main/resources
+
+ application.properties
+
+
+
+ false
+ src/main/resources
+
+ application.properties
+
+
+
+
+
io.quarkus
quarkus-maven-plugin
@@ -104,6 +92,33 @@
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+
+
+ copy-crd
+
+ copy-resources
+
+ generate-resources
+
+ ${projectRoot}/operator/controller/src/main/deploy/crd
+
+
+ ${projectRoot}/operator/model/target/classes/META-INF/fabric8
+
+ apicurioregistries3.registry.apicur.io-v1.yml
+
+
+
+
+
+
+
+
maven-surefire-plugin
@@ -116,6 +131,49 @@
+
+
+
+
+
+ prepare-operator-tests
+
+
+ skipOperatorTests
+ false
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+
+ create-test-install-file
+
+ exec
+
+ pre-integration-test
+
+ ${projectRoot}/operator
+ make
+
+ INSTALL_FILE=${build.directory}/test-install.yaml
+ dist-install-file
+
+
+
+
+
+
+
+
+
+
+
diff --git a/operator/controller/src/main/deploy/crd/kustomization.yaml b/operator/controller/src/main/deploy/crd/kustomization.yaml
new file mode 100644
index 0000000000..8f5b0e0edf
--- /dev/null
+++ b/operator/controller/src/main/deploy/crd/kustomization.yaml
@@ -0,0 +1,13 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+ - apicurioregistries3.registry.apicur.io-v1.yml
+
+labels:
+ - pairs:
+ app: apicurio-registry-operator
+ app.kubernetes.io/name: apicurio-registry-operator
+ app.kubernetes.io/version: ${PLACEHOLDER_VERSION}
+ app.kubernetes.io/component: operator
+ app.kubernetes.io/part-of: apicurio-registry
diff --git a/operator/controller/src/main/deploy/csv/apicurio-registry.clusterserviceversion.yaml b/operator/controller/src/main/deploy/csv/apicurio-registry.clusterserviceversion.yaml
new file mode 100644
index 0000000000..a56ea92f7e
--- /dev/null
+++ b/operator/controller/src/main/deploy/csv/apicurio-registry.clusterserviceversion.yaml
@@ -0,0 +1,108 @@
+apiVersion: operators.coreos.com/v1alpha1
+kind: ClusterServiceVersion
+metadata:
+ annotations:
+ alm-examples: '[]'
+ capabilities: Basic Install
+ categories: Streaming & Messaging
+ certified: 'false'
+ description: Deploy and manage Apicurio Registry 3 on Kubernetes.
+ repository: https://github.com/Apicurio/apicurio-registry/tree/main/operator
+ support: Apicurio
+ operators.openshift.io/infrastructure-features: '[]'
+ features.operators.openshift.io/disconnected: 'false' # TODO: Support disconnected install
+ features.operators.openshift.io/proxy-aware: 'false'
+ features.operators.openshift.io/fips-compliant: 'false'
+ features.operators.openshift.io/tls-profiles: 'false'
+ features.operators.openshift.io/token-auth-aws: 'false'
+ features.operators.openshift.io/token-auth-azure: 'false'
+ features.operators.openshift.io/token-auth-gcp: 'false'
+ features.operators.openshift.io/cnf: 'false'
+ features.operators.openshift.io/cni: 'false'
+ features.operators.openshift.io/csi: 'false'
+ name: apicurio-registry.v0.0.0
+ namespace: PLACEHOLDER_NAMESPACE
+spec:
+ apiservicedefinitions: {}
+ customresourcedefinitions:
+ owned:
+ - description: ApicurioRegistry3 represents an instance of Apicurio Registry version 3.
+ displayName: Apicurio Registry 3
+ kind: ApicurioRegistry3
+ name: apicurioregistries3.registry.apicur.io
+ version: v1
+ description: |
+ ## Apicurio Registry 3
+
+ Apicurio Registry stores and retrieves API designs and event schemas,
+ and gives you control of their evolution.
+
+ **Features**
+ - Supports: Apache Avro, AsyncAPI, GraphQL, JSON Schema, Kafka Connect Schema, OpenAPI, Protobuf
+ - Allows you manage event schemas and API designs using the Apicurio Registry web console,
+ REST API, Maven plug-in, or Java client
+ - Includes Serializers and Deserializers for Kafka client integration
+ - Configurable rules to control schema validity and evolution (compatibility)
+ - Storage options: Kafka, PostgreSQL, MySQL, SQL Server, in-memory
+ - Compatible with Confluent APIs
+ - Runs on a lightweight Quarkus platform
+
+ ## Apicurio Registry 3 Operator
+
+ Provides a quick and easy way to deploy and manage Apicurio Registry 3 on Kubernetes.
+
+ **Features**
+ - Supports installation and configuration of Apicurio Registry 3
+ - Perform a rolling upgrade of Apicurio Registry 3
+
+ ## Prerequisites
+
+ This operator does not deploy storage for Apicurio Registry 3. Therefore, some storage options require that the chosen persistence service is already set up.
+
+ ## License
+
+ Apicurio Registry 3 and Apicurio Registry 3 Operator are licensed under the [Apache 2.0 license](https://github.com/Apicurio/apicurio-registry/blob/main/LICENSE)
+ displayName: Apicurio Registry 3
+ icon:
+ - base64data: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI3LjEuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAxODAgMjAwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAxODAgMjAwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Cgkuc3Qwe2ZpbGw6Izc1OEVCRjt9Cgkuc3Qxe2VuYWJsZS1iYWNrZ3JvdW5kOm5ldyAgICA7fQo8L3N0eWxlPgo8cGF0aCBkPSJNODEuOCwxMTIuOGMtMC4xLDAtMC4yLDAtMC4yLDB2MGMtOS43LTAuNi0xOC4xLTEwLjktMTguMS0xOC40YzAuMi01LjgsMC41LTEyLjgsMC44LTEzLjljNS40LTMwLjIsMjguMS01NC40LDU3LjQtNjIKCWMtMTAuNS01LjQtMjIuNC04LjUtMzUtOC41QzQ0LjQsMTAsMTAsNDQuNCwxMCw4Ni43VjE1NWMwLDE0LjgsMTIsMjYuNywyNi43LDI2LjdzMjYuNy0xMiwyNi43LTI2Ljd2LTE0LjNjMC0xMC40LDgtMTguOCwxOC4yLTE5LjUKCXYwYzAuMSwwLDAuMiwwLDAuMiwwYzIuMywwLDQuMi0xLjksNC4yLTQuMlM4NC4xLDExMi44LDgxLjgsMTEyLjhMODEuOCwxMTIuOHoiLz4KPGc+Cgk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTQ2LjcsNDdjNC4xLDAsOC4xLDAuMywxMiwwLjljLTQuOS04LjMtMTEuMi0xNS42LTE4LjctMjEuNUMxMTIuNSwyOSw4OS4yLDQ1LjcsNzcuMyw2OS4xCgkJYzQuMS0zLjUsOS40LTUuNywxNS4yLTUuN2MxLjcsMCwzLjMsMC4yLDQuOSwwLjVDMTExLDUzLjQsMTI4LjEsNDcsMTQ2LjcsNDdMMTQ2LjcsNDd6Ii8+Cgk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTY1LjMsNjIuN2MtNi45LTEuOS0xNC4xLTIuOS0yMS41LTIuOWMtMTMuMiwwLTI1LjcsMy4yLTM2LjcsOC45YzUuMyw0LjMsOC43LDEwLjgsOC43LDE4LjF2Ny44CgkJYzAsNy41LTguNCwxNy43LTE4LjEsMTguNHYwYy0wLjEsMC0wLjIsMC0wLjIsMGMtMi4zLDAtNC4yLDEuOS00LjIsNC4yczEuOSw0LjIsNC4yLDQuMmMwLjEsMCwwLjIsMCwwLjIsMHYwCgkJYzkuOCwwLjcsMTcuNiw4LjUsMTguMSwxOC40VjE1NWMwLDE0LjgsMTIsMjYuNywyNi43LDI2LjdzMjYuNy0xMiwyNi43LTI2LjdWODYuN0MxNjkuMiw3OC4zLDE2Ny44LDcwLjIsMTY1LjMsNjIuN0wxNjUuMyw2Mi43eiIKCQkvPgo8L2c+Cjwvc3ZnPgo=
+ mediatype: image/svg+xml
+ install:
+ spec:
+ deployments: null
+ strategy: ''
+ installModes:
+ - supported: true
+ type: OwnNamespace
+ - supported: true
+ type: SingleNamespace
+ - supported: true
+ type: MultiNamespace
+ - supported: true
+ type: AllNamespaces
+ keywords:
+ - integration
+ - streaming
+ - messaging
+ - api
+ - schemas
+ - registry
+ - apicurio
+ - apicurio-registry
+ links:
+ - name: Website
+ url: https://www.apicur.io/
+ - name: GitHub
+ url: https://github.com/Apicurio/apicurio-registry/
+ - name: Issues
+ url: https://github.com/Apicurio/apicurio-registry/issues
+ - name: Twitter
+ url: https://twitter.com/Apicurio
+ maintainers:
+ - email: apicurio@lists.jboss.org
+ name: Apicurio
+ maturity: alpha
+ provider:
+ name: Apicurio
+ selector: {}
+ version: 0.0.0
+ minKubeVersion: 1.25.0
diff --git a/operator/controller/src/main/deploy/csv/kustomization.yaml b/operator/controller/src/main/deploy/csv/kustomization.yaml
new file mode 100644
index 0000000000..d9e95f0aee
--- /dev/null
+++ b/operator/controller/src/main/deploy/csv/kustomization.yaml
@@ -0,0 +1,21 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+ - ../rbac/cluster
+ - ../crd
+ - ../operator
+ - ../examples
+ - apicurio-registry.clusterserviceversion.yaml
+
+patches:
+ - target:
+ kind: ClusterServiceVersion
+ name: apicurio-registry.v0.0.0
+ patch: |-
+ - op: add
+ path: /metadata/annotations/createdAt
+ value: ${PLACEHOLDER_DATE}
+ - op: add
+ path: /metadata/annotations/containerImage
+ value: ${PLACEHOLDER_IMAGE}
diff --git a/operator/controller/src/main/deploy/dist-template/README.adoc b/operator/controller/src/main/deploy/dist-template/README.adoc
new file mode 100644
index 0000000000..5e1591c6e0
--- /dev/null
+++ b/operator/controller/src/main/deploy/dist-template/README.adoc
@@ -0,0 +1,34 @@
+= Apicurio Registry Operator Distribution Bundle
+
+This directory contains installation files for the Apicurio Registry Operator, with example `ApicurioRegistry3` custom resource files.
+Docker images for the operator and the operand are distributed using a public registry.
+
+== Installation
+
+.Procedure
+. Choose a namespace where the operator will be deployed:
++
+[source,bash]
+----
+export NAMESPACE=apicurio-registry
+kubectl create namespace $NAMESPACE
+----
+
+. Kubernetes resources required for the installation are present inside `install.yaml` file.
+Apply the installation file:
++
+[source,bash]
+----
+cat install.yaml | sed "s/PLACEHOLDER_NAMESPACE/$NAMESPACE/g" | kubectl -n $NAMESPACE apply -f -
+----
+
+== Deploy Apicurio Registry
+
+After the Apicurio Registry Operator has been deployed, it can deploy an Apicurio Registry instance.
+
+To create a new Apicurio Registry deployment, the fastest way is to use one of the example `ApicurioRegistry3` custom resources:
+
+[source,bash]
+----
+kubectl -n $NAMESPACE apply -f examples/simple.apicurioregistry3.yaml
+----
diff --git a/operator/controller/src/main/deploy/examples/kustomization.yaml b/operator/controller/src/main/deploy/examples/kustomization.yaml
new file mode 100644
index 0000000000..73d8a670c1
--- /dev/null
+++ b/operator/controller/src/main/deploy/examples/kustomization.yaml
@@ -0,0 +1,5 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+ - simple.apicurioregistry3.yaml
diff --git a/operator/controller/src/main/deploy/examples/simple.apicurioregistry3.yaml b/operator/controller/src/main/deploy/examples/simple.apicurioregistry3.yaml
new file mode 100644
index 0000000000..938458f6a4
--- /dev/null
+++ b/operator/controller/src/main/deploy/examples/simple.apicurioregistry3.yaml
@@ -0,0 +1,9 @@
+apiVersion: registry.apicur.io/v1
+kind: ApicurioRegistry3
+metadata:
+ name: simple-apicurioregistry3
+spec:
+ app:
+ host: simple-apicurioregistry3-app.apps.yourcluster.example
+ ui:
+ host: simple-apicurioregistry3-ui.apps.yourcluster.example
diff --git a/operator/controller/src/main/deploy/install/kustomization.yaml b/operator/controller/src/main/deploy/install/kustomization.yaml
new file mode 100644
index 0000000000..7d57ce34b2
--- /dev/null
+++ b/operator/controller/src/main/deploy/install/kustomization.yaml
@@ -0,0 +1,15 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+ - ../crd
+ - ../rbac/cluster
+ - ../operator
+
+labels:
+ - pairs:
+ app: apicurio-registry-operator
+ app.kubernetes.io/name: apicurio-registry-operator
+ app.kubernetes.io/version: ${PLACEHOLDER_VERSION}
+ app.kubernetes.io/component: operator
+ app.kubernetes.io/part-of: apicurio-registry
diff --git a/operator/controller/src/main/deploy/operator/kustomization.yaml b/operator/controller/src/main/deploy/operator/kustomization.yaml
new file mode 100644
index 0000000000..49bc00af93
--- /dev/null
+++ b/operator/controller/src/main/deploy/operator/kustomization.yaml
@@ -0,0 +1,45 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+ - operator.yaml
+
+labels:
+ - pairs:
+ app: apicurio-registry-operator
+ app.kubernetes.io/name: apicurio-registry-operator
+ app.kubernetes.io/version: ${PLACEHOLDER_VERSION}
+ app.kubernetes.io/component: operator
+ app.kubernetes.io/part-of: apicurio-registry
+ includeSelectors: true
+ includeTemplates: true
+
+images:
+ - name: PLACEHOLDER_IMAGE
+ newName: ${PLACEHOLDER_IMAGE}
+
+patches:
+ - target:
+ kind: Deployment
+ name: apicurio-registry-operator
+ patch: |-
+ - op: add
+ path: /metadata/name
+ # Workaround for https://github.com/operator-framework/operator-lifecycle-manager/issues/1608
+ # See https://github.com/operator-framework/operator-lifecycle-manager/issues/952#issuecomment-639657949
+ value: apicurio-registry-operator-v${PLACEHOLDER_LC_VERSION}
+ - op: add
+ path: /spec/template/spec/containers/0/env/-
+ value:
+ name: REGISTRY_VERSION
+ value: ${PLACEHOLDER_VERSION}
+ - op: add
+ path: /spec/template/spec/containers/0/env/-
+ value:
+ name: REGISTRY_APP_IMAGE
+ value: ${PLACEHOLDER_REGISTRY_APP_IMAGE}
+ - op: add
+ path: /spec/template/spec/containers/0/env/-
+ value:
+ name: REGISTRY_UI_IMAGE
+ value: ${PLACEHOLDER_REGISTRY_UI_IMAGE}
diff --git a/operator/controller/src/main/deploy/operator/operator.yaml b/operator/controller/src/main/deploy/operator/operator.yaml
new file mode 100644
index 0000000000..2d23763b5d
--- /dev/null
+++ b/operator/controller/src/main/deploy/operator/operator.yaml
@@ -0,0 +1,49 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: apicurio-registry-operator
+ namespace: ${PLACEHOLDER_NAMESPACE}
+spec:
+ replicas: 1
+ selector:
+ matchLabels: { }
+ template:
+ metadata:
+ labels: { }
+ spec:
+ containers:
+ - name: apicurio-registry-operator
+ image: PLACEHOLDER_IMAGE
+ imagePullPolicy: Always
+ env:
+ - name: APICURIO_OPERATOR_WATCHED_NAMESPACES
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.annotations['olm.targetNamespaces']
+ - name: QUARKUS_PROFILE
+ value: prod
+ ports:
+ - name: http
+ containerPort: 8080
+ protocol: TCP
+ startupProbe:
+ httpGet:
+ path: /q/health/started
+ port: 8080
+ failureThreshold: 6 # 60s
+ readinessProbe:
+ httpGet:
+ path: /q/health/ready
+ port: 8080
+ livenessProbe:
+ httpGet:
+ path: /q/health/live
+ port: 8080
+ resources: # TODO
+ requests:
+ cpu: 100m
+ memory: 100Mi
+ limits:
+ cpu: 200m
+ memory: 500Mi
+ serviceAccountName: apicurio-registry-operator
diff --git a/operator/controller/src/main/deploy/rbac/base/kustomization.yaml b/operator/controller/src/main/deploy/rbac/base/kustomization.yaml
new file mode 100644
index 0000000000..97367eab94
--- /dev/null
+++ b/operator/controller/src/main/deploy/rbac/base/kustomization.yaml
@@ -0,0 +1,5 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+ - service-account.yaml
diff --git a/operator/controller/src/main/deploy/rbac/base/service-account.yaml b/operator/controller/src/main/deploy/rbac/base/service-account.yaml
new file mode 100644
index 0000000000..22553bd258
--- /dev/null
+++ b/operator/controller/src/main/deploy/rbac/base/service-account.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: apicurio-registry-operator
diff --git a/operator/controller/src/main/deploy/rbac/cluster/cluster-role-binding.yaml b/operator/controller/src/main/deploy/rbac/cluster/cluster-role-binding.yaml
new file mode 100644
index 0000000000..2f6a47db9f
--- /dev/null
+++ b/operator/controller/src/main/deploy/rbac/cluster/cluster-role-binding.yaml
@@ -0,0 +1,14 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: apicurio-registry-operator-clusterrolebinding
+
+subjects:
+ - kind: ServiceAccount
+ namespace: ${PLACEHOLDER_NAMESPACE}
+ name: apicurio-registry-operator
+
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: apicurio-registry-operator-clusterrole
diff --git a/operator/controller/src/main/deploy/rbac/cluster/cluster-role.yaml b/operator/controller/src/main/deploy/rbac/cluster/cluster-role.yaml
new file mode 100644
index 0000000000..5db5b96b24
--- /dev/null
+++ b/operator/controller/src/main/deploy/rbac/cluster/cluster-role.yaml
@@ -0,0 +1,51 @@
+# Note: Do not forget to update deploy/rbac/single-namespace/kustomization.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: apicurio-registry-operator-clusterrole
+
+rules:
+
+ - apiGroups:
+ - registry.apicur.io
+ resources:
+ - apicurioregistries3
+ - apicurioregistries3/status
+ verbs:
+ - '*'
+
+ - apiGroups:
+ - apps
+ resources:
+ - deployments
+ verbs:
+ - '*'
+
+ - apiGroups:
+ - events.k8s.io
+ resources:
+ - events
+ verbs:
+ - '*'
+
+ - apiGroups:
+ - ""
+ resources:
+ - pods
+ - services
+ verbs:
+ - '*'
+
+ - apiGroups:
+ - apiextensions.k8s.io
+ resources:
+ - customresourcedefinitions
+ verbs:
+ - get
+
+ - apiGroups:
+ - networking.k8s.io
+ resources:
+ - ingresses
+ verbs:
+ - "*"
diff --git a/operator/controller/src/main/deploy/rbac/cluster/kustomization.yaml b/operator/controller/src/main/deploy/rbac/cluster/kustomization.yaml
new file mode 100644
index 0000000000..f8b2855a81
--- /dev/null
+++ b/operator/controller/src/main/deploy/rbac/cluster/kustomization.yaml
@@ -0,0 +1,15 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+resources:
+ - ../base
+ - cluster-role.yaml
+ - cluster-role-binding.yaml
+
+labels:
+ - pairs:
+ app: apicurio-registry-operator
+ app.kubernetes.io/name: apicurio-registry-operator
+ app.kubernetes.io/version: ${PLACEHOLDER_VERSION}
+ app.kubernetes.io/component: operator
+ app.kubernetes.io/part-of: apicurio-registry
diff --git a/operator/controller/src/main/docker/Dockerfile.jvm b/operator/controller/src/main/docker/Dockerfile.jvm
new file mode 100644
index 0000000000..ca66e45d77
--- /dev/null
+++ b/operator/controller/src/main/docker/Dockerfile.jvm
@@ -0,0 +1,17 @@
+FROM registry.access.redhat.com/ubi8/openjdk-17-runtime:latest
+
+ENV JAVA_APP_DIR=/deployments \
+ APP_URL="quarkus-app" \
+ JAVA_OPTIONS="-Djava.util.logging.manager=org.jboss.logmanager.LogManager" \
+ AB_ENABLED=jmx_exporter
+
+ADD "$APP_URL" /deployments
+
+USER root
+
+# Set appropriate permissions and ownership
+RUN chmod -R "ug=rwx" /deployments \
+ && chown -R 1001:0 /deployments
+
+# Set user for running the container, according to OpenShift best practices
+USER 1001
diff --git a/operator/controller/src/main/java/io/apicurio/registry/operator/ApicurioRegistry3Reconciler.java b/operator/controller/src/main/java/io/apicurio/registry/operator/ApicurioRegistry3Reconciler.java
index 39a983a467..e56d50a124 100644
--- a/operator/controller/src/main/java/io/apicurio/registry/operator/ApicurioRegistry3Reconciler.java
+++ b/operator/controller/src/main/java/io/apicurio/registry/operator/ApicurioRegistry3Reconciler.java
@@ -56,6 +56,7 @@
}
)
// spotless:on
+// TODO: When renaming, do not forget to update application.properties (until we have a test for this).
public class ApicurioRegistry3Reconciler implements Reconciler,
ErrorStatusHandler, Cleaner {
diff --git a/operator/controller/src/main/java/io/apicurio/registry/operator/Configuration.java b/operator/controller/src/main/java/io/apicurio/registry/operator/Configuration.java
new file mode 100644
index 0000000000..1cfaa27c3b
--- /dev/null
+++ b/operator/controller/src/main/java/io/apicurio/registry/operator/Configuration.java
@@ -0,0 +1,26 @@
+package io.apicurio.registry.operator;
+
+import org.eclipse.microprofile.config.ConfigProvider;
+
+public class Configuration {
+
+ private Configuration() {
+ }
+
+ public static String getAppImage() {
+ return ConfigProvider.getConfig().getOptionalValue("registry.app.image", String.class)
+ .orElseThrow(() -> new OperatorException(
+ "Required configuration option 'registry.app.image' is not set."));
+ }
+
+ public static String getUIImage() {
+ return ConfigProvider.getConfig().getOptionalValue("registry.ui.image", String.class).orElseThrow(
+ () -> new OperatorException("Required configuration option 'registry.ui.image' is not set."));
+ }
+
+ public static String getDefaultBaseHost() {
+ return ConfigProvider.getConfig()
+ .getOptionalValue("apicurio.operator.default-base-host", String.class).map(v -> "." + v)
+ .orElse("");
+ }
+}
diff --git a/operator/controller/src/main/java/io/apicurio/registry/operator/resource/ResourceFactory.java b/operator/controller/src/main/java/io/apicurio/registry/operator/resource/ResourceFactory.java
index 4e5c826e59..65bae740a5 100644
--- a/operator/controller/src/main/java/io/apicurio/registry/operator/resource/ResourceFactory.java
+++ b/operator/controller/src/main/java/io/apicurio/registry/operator/resource/ResourceFactory.java
@@ -1,6 +1,7 @@
package io.apicurio.registry.operator.resource;
import com.fasterxml.jackson.core.JsonProcessingException;
+import io.apicurio.registry.operator.Configuration;
import io.apicurio.registry.operator.OperatorException;
import io.apicurio.registry.operator.api.v1.ApicurioRegistry3;
import io.fabric8.kubernetes.api.model.*;
@@ -49,11 +50,12 @@ public Deployment getDefaultAppDeployment(ApicurioRegistry3 primary) {
} else {
r.getSpec().setTemplate(new PodTemplateSpec());
}
+
mergeDeploymentPodTemplateSpec(
// spotless:off
r.getSpec().getTemplate(),
APP_CONTAINER_NAME,
- "quay.io/apicurio/apicurio-registry:latest-snapshot",
+ Configuration.getAppImage(),
List.of(new ContainerPortBuilder().withName("http").withProtocol("TCP").withContainerPort(8080).build()),
new ProbeBuilder().withHttpGet(new HTTPGetActionBuilder().withPath("/health/ready").withPort(new IntOrString(8080)).withScheme("HTTP").build()).build(),
new ProbeBuilder().withHttpGet(new HTTPGetActionBuilder().withPath("/health/live").withPort(new IntOrString(8080)).withScheme("HTTP").build()).build(),
@@ -81,11 +83,12 @@ public Deployment getDefaultUIDeployment(ApicurioRegistry3 primary) {
} else {
r.getSpec().setTemplate(new PodTemplateSpec());
}
+
mergeDeploymentPodTemplateSpec(
// spotless:off
r.getSpec().getTemplate(),
UI_CONTAINER_NAME,
- "quay.io/apicurio/apicurio-registry-ui:latest-snapshot",
+ Configuration.getUIImage(),
List.of(new ContainerPortBuilder().withName("http").withProtocol("TCP").withContainerPort(8080).build()),
new ProbeBuilder().withHttpGet(new HTTPGetActionBuilder().withPath("/config.js").withPort(new IntOrString(8080)).withScheme("HTTP").build()).build(),
new ProbeBuilder().withHttpGet(new HTTPGetActionBuilder().withPath("/config.js").withPort(new IntOrString(8080)).withScheme("HTTP").build()).build(),
diff --git a/operator/controller/src/main/java/io/apicurio/registry/operator/utils/IngressUtils.java b/operator/controller/src/main/java/io/apicurio/registry/operator/utils/IngressUtils.java
index c1ece83f7e..123399e68c 100644
--- a/operator/controller/src/main/java/io/apicurio/registry/operator/utils/IngressUtils.java
+++ b/operator/controller/src/main/java/io/apicurio/registry/operator/utils/IngressUtils.java
@@ -1,12 +1,12 @@
package io.apicurio.registry.operator.utils;
+import io.apicurio.registry.operator.Configuration;
import io.apicurio.registry.operator.OperatorException;
import io.apicurio.registry.operator.api.v1.ApicurioRegistry3;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.networking.v1.HTTPIngressPath;
import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
import io.fabric8.kubernetes.api.model.networking.v1.IngressRule;
-import org.eclipse.microprofile.config.ConfigProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,11 +37,8 @@ public static String getHost(String component, ApicurioRegistry3 p) {
throw new OperatorException("Unexpected value: " + component);
}
if (host == null) {
- var defaultBaseHost = ConfigProvider.getConfig()
- .getOptionalValue("apicurio.operator.default-base-host", String.class).map(v -> "." + v)
- .orElse("");
host = "%s-%s.%s%s".formatted(p.getMetadata().getName(), component,
- p.getMetadata().getNamespace(), defaultBaseHost);
+ p.getMetadata().getNamespace(), Configuration.getDefaultBaseHost());
}
log.debug("Host for component {} is {}", component, host);
return host;
diff --git a/operator/controller/src/main/resources/application.properties b/operator/controller/src/main/resources/application.properties
index 111af3f2da..d44b4cbf24 100644
--- a/operator/controller/src/main/resources/application.properties
+++ b/operator/controller/src/main/resources/application.properties
@@ -25,7 +25,6 @@ quarkus.http.port=8080
# OSDK
-quarkus.container-image.builder=jib
quarkus.operator-sdk.crd.apply=false
%dev.quarkus.operator-sdk.crd.apply=true
%test.quarkus.operator-sdk.crd.apply=true
@@ -33,6 +32,8 @@ quarkus.operator-sdk.crd.generate=false
quarkus.operator-sdk.crd.validate=true
quarkus.operator-sdk.enable-ssa=false
+quarkus.operator-sdk.controllers."ApicurioRegistry3Reconciler".namespaces=${apicurio.operator.watched-namespaces}
+
# Kubernetes
%dev.quarkus.kubernetes-client.trust-certs=true
@@ -43,3 +44,26 @@ quarkus.operator-sdk.enable-ssa=false
quarkus.vertx.max-event-loop-execute-time=8s
%test.quarkus.operator-sdk.start-operator=false
+
+%test.registry.app.image=quay.io/apicurio/apicurio-registry:latest-snapshot
+%dev.registry.app.image=quay.io/apicurio/apicurio-registry:latest-snapshot
+%test.registry.ui.image=quay.io/apicurio/apicurio-registry-ui:latest-snapshot
+%dev.registry.ui.image=quay.io/apicurio/apicurio-registry-ui:latest-snapshot
+
+# Test Only =====
+
+%test.test.operator.project-version=${project.version}
+%test.test.operator.project-root=${projectRoot}
+
+# Local / Both
+
+%test.test.operator.deployment=local
+%test.test.operator.ingress-skip=false
+%test.test.operator.cleanup=true
+
+# Remote
+
+%test.test.operator.deployment-target=kubernetes
+%test.test.operator.install-file=${build.directory}/test-install.yaml
+%test.test.operator.olm-skip=false
+%test.test.operator.catalog-image=quay.io/apicurio/apicurio-registry-operator-catalog:latest-snapshot
diff --git a/operator/controller/src/test/deploy/catalog/catalog-source.yaml b/operator/controller/src/test/deploy/catalog/catalog-source.yaml
new file mode 100644
index 0000000000..63d13604bc
--- /dev/null
+++ b/operator/controller/src/test/deploy/catalog/catalog-source.yaml
@@ -0,0 +1,13 @@
+apiVersion: operators.coreos.com/v1alpha1
+kind: CatalogSource
+metadata:
+ name: apicurio-registry-operator-catalog
+ namespace: ${PLACEHOLDER_CATALOG_NAMESPACE}
+spec:
+ sourceType: grpc
+ displayName: Apicurio Registry Catalog
+ publisher: Apicurio
+ image: ${PLACEHOLDER_CATALOG_IMAGE}
+ updateStrategy:
+ registryPoll:
+ interval: 30s # Development value
diff --git a/operator/controller/src/test/deploy/catalog/catalog.template.yaml b/operator/controller/src/test/deploy/catalog/catalog.template.yaml
new file mode 100644
index 0000000000..8f98c5aa6a
--- /dev/null
+++ b/operator/controller/src/test/deploy/catalog/catalog.template.yaml
@@ -0,0 +1,13 @@
+schema: olm.template.basic
+entries:
+ - schema: olm.package
+ name: apicurio-registry
+ defaultChannel: 3.x
+ - schema: olm.channel
+ package: apicurio-registry
+ name: 3.x
+ entries:
+ - name: apicurio-registry.v${PLACEHOLDER_LC_VERSION}
+ # TODO: Replaces
+ - schema: olm.bundle
+ image: ${PLACEHOLDER_BUNDLE_IMAGE}
diff --git a/operator/controller/src/test/deploy/catalog/operator-group.yaml b/operator/controller/src/test/deploy/catalog/operator-group.yaml
new file mode 100644
index 0000000000..4644373e6f
--- /dev/null
+++ b/operator/controller/src/test/deploy/catalog/operator-group.yaml
@@ -0,0 +1,8 @@
+apiVersion: operators.coreos.com/v1
+kind: OperatorGroup
+metadata:
+ name: apicurio-registry-operator-group
+ namespace: ${PLACEHOLDER_NAMESPACE}
+spec:
+ targetNamespaces:
+ - ${PLACEHOLDER_NAMESPACE}
diff --git a/operator/controller/src/test/deploy/catalog/subscription.yaml b/operator/controller/src/test/deploy/catalog/subscription.yaml
new file mode 100644
index 0000000000..5a9faba11c
--- /dev/null
+++ b/operator/controller/src/test/deploy/catalog/subscription.yaml
@@ -0,0 +1,12 @@
+apiVersion: operators.coreos.com/v1alpha1
+kind: Subscription
+metadata:
+ name: apicurio-registry-operator-subscription
+ namespace: ${PLACEHOLDER_NAMESPACE}
+spec:
+ sourceNamespace: ${PLACEHOLDER_CATALOG_NAMESPACE}
+ source: apicurio-registry-operator-catalog
+ name: apicurio-registry
+ channel: 3.x
+ startingCSV: ${PLACEHOLDER_PACKAGE}
+ installPlanApproval: Automatic
diff --git a/operator/controller/src/test/java/io/apicurio/registry/operator/it/ITBase.java b/operator/controller/src/test/java/io/apicurio/registry/operator/it/ITBase.java
index 51b4748c2f..aebac041ef 100644
--- a/operator/controller/src/test/java/io/apicurio/registry/operator/it/ITBase.java
+++ b/operator/controller/src/test/java/io/apicurio/registry/operator/it/ITBase.java
@@ -3,9 +3,8 @@
import io.apicurio.registry.operator.Constants;
import io.apicurio.registry.operator.api.v1.ApicurioRegistry3;
import io.fabric8.kubernetes.api.model.HasMetadata;
-import io.fabric8.kubernetes.api.model.KubernetesList;
import io.fabric8.kubernetes.api.model.NamespaceBuilder;
-import io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding;
+import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
@@ -23,13 +22,17 @@
import org.junit.jupiter.api.*;
import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.time.Duration;
+import java.util.List;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
-public class ITBase {
+public abstract class ITBase {
public static final String DEPLOYMENT_TARGET = "test.operator.deployment-target";
public static final String OPERATOR_DEPLOYMENT_PROP = "test.operator.deployment";
@@ -38,6 +41,7 @@ public class ITBase {
public static final String CLEANUP = "test.operator.cleanup";
public static final String GENERATED_RESOURCES_FOLDER = "target/kubernetes/";
public static final String CRD_FILE = "../model/target/classes/META-INF/fabric8/apicurioregistries3.registry.apicur.io-v1.yml";
+ public static final String REMOTE_TESTS_INSTALL_FILE = "test.operator.install-file";
public enum OperatorDeployment {
local, remote
@@ -59,24 +63,22 @@ public static void before() throws Exception {
configuration = CDI.current().select(QuarkusConfigurationService.class).get();
reconcilers = CDI.current().select(new TypeLiteral<>() {
});
- operatorDeployment = ConfigProvider.getConfig()
- .getOptionalValue(OPERATOR_DEPLOYMENT_PROP, OperatorDeployment.class)
- .orElse(OperatorDeployment.local);
- deploymentTarget = ConfigProvider.getConfig().getOptionalValue(DEPLOYMENT_TARGET, String.class)
- .orElse("k8s");
- cleanup = ConfigProvider.getConfig().getOptionalValue(CLEANUP, Boolean.class).orElse(true);
+ operatorDeployment = ConfigProvider.getConfig().getValue(OPERATOR_DEPLOYMENT_PROP,
+ OperatorDeployment.class);
+ deploymentTarget = ConfigProvider.getConfig().getValue(DEPLOYMENT_TARGET, String.class);
+ cleanup = ConfigProvider.getConfig().getValue(CLEANUP, Boolean.class);
setDefaultAwaitilityTimings();
- calculateNamespace();
- createK8sClient();
+ namespace = calculateNamespace();
+ client = createK8sClient(namespace);
createCRDs();
- createNamespace();
+ createNamespace(client, namespace);
portForwardManager = new PortForwardManager(client, namespace);
ingressManager = new IngressManager(client, namespace);
if (operatorDeployment == OperatorDeployment.remote) {
- createGeneratedResources();
+ createTestResources();
} else {
createOperator();
registerReconcilers();
@@ -93,48 +95,39 @@ public void beforeEach(TestInfo testInfo) {
+ "------- Deployment target: " + deploymentTarget);
}
- private static void createK8sClient() {
- client = new KubernetesClientBuilder()
+ static KubernetesClient createK8sClient(String namespace) {
+ return new KubernetesClientBuilder()
.withConfig(new ConfigBuilder(Config.autoConfigure(null)).withNamespace(namespace).build())
.build();
}
- private static void createGeneratedResources() throws Exception {
+ private static List loadTestResources() throws IOException {
+ var installFilePath = Path
+ .of(ConfigProvider.getConfig().getValue(REMOTE_TESTS_INSTALL_FILE, String.class));
+ var installFileRaw = Files.readString(installFilePath);
+ // We're not editing the deserialized resources to replicate the user experience
+ installFileRaw = installFileRaw.replace("PLACEHOLDER_NAMESPACE", namespace);
+ return Serialization.unmarshal(installFileRaw);
+ }
+
+ private static void createTestResources() throws Exception {
Log.info("Creating generated resources into Namespace " + namespace);
- try (var fis = new FileInputStream(GENERATED_RESOURCES_FOLDER + deploymentTarget + ".json")) {
- KubernetesList resources = Serialization.unmarshal(fis);
-
- resources.getItems().stream().forEach(r -> {
- if (r.getKind().equals("ClusterRoleBinding") && r instanceof ClusterRoleBinding) {
- var crb = (ClusterRoleBinding) r;
- crb.getSubjects().stream().forEach(s -> s.setNamespace(namespace));
- // TODO: We need to patch the generated resources, because the referenced ClusterRole name
- // is
- // wrong.
- if ("apicurioregistry3reconciler-cluster-role-binding"
- .equals(crb.getMetadata().getName())) {
- crb.getRoleRef().setName("apicurioregistry3reconciler-cluster-role");
- }
- }
- client.resource(r).inNamespace(namespace).createOrReplace();
- });
- }
+ loadTestResources().forEach(r -> {
+ if ("minikube".equals(deploymentTarget) && r instanceof Deployment d) {
+ // See https://stackoverflow.com/a/46101923
+ d.getSpec().getTemplate().getSpec().getContainers()
+ .forEach(c -> c.setImagePullPolicy("IfNotPresent"));
+ }
+ client.resource(r).inNamespace(namespace).createOrReplace();
+ });
}
- private static void cleanGeneratedResources() throws Exception {
+ private static void cleanTestResources() throws Exception {
if (cleanup) {
Log.info("Deleting generated resources from Namespace " + namespace);
- try (var fis = new FileInputStream(GENERATED_RESOURCES_FOLDER + deploymentTarget + ".json")) {
- KubernetesList resources = Serialization.unmarshal(fis);
-
- resources.getItems().stream().forEach(r -> {
- if (r.getKind().equals("ClusterRoleBinding") && r instanceof ClusterRoleBinding) {
- var crb = (ClusterRoleBinding) r;
- crb.getSubjects().stream().forEach(s -> s.setNamespace(namespace));
- }
- client.resource(r).inNamespace(namespace).delete();
- });
- }
+ loadTestResources().forEach(r -> {
+ client.resource(r).inNamespace(namespace).delete();
+ });
}
}
@@ -168,7 +161,7 @@ private static void createOperator() {
});
}
- private static void createNamespace() {
+ static void createNamespace(KubernetesClient client, String namespace) {
Log.info("Creating Namespace " + namespace);
client.resource(
new NamespaceBuilder().withNewMetadata().addToLabels("app", "apicurio-registry-operator-test")
@@ -176,11 +169,11 @@ private static void createNamespace() {
.create();
}
- private static void calculateNamespace() {
- namespace = ("apicurio-registry-operator-test-" + UUID.randomUUID()).substring(0, 63);
+ static String calculateNamespace() {
+ return ("apicurio-registry-operator-test-" + UUID.randomUUID()).substring(0, 63);
}
- private static void setDefaultAwaitilityTimings() {
+ static void setDefaultAwaitilityTimings() {
Awaitility.setDefaultPollInterval(Duration.ofSeconds(5));
Awaitility.setDefaultTimeout(Duration.ofSeconds(5 * 60));
}
@@ -207,9 +200,9 @@ public static void after() throws Exception {
Log.info("Creating new K8s Client");
// create a new client bc operator has closed the old one
- createK8sClient();
+ client = createK8sClient(namespace);
} else {
- cleanGeneratedResources();
+ cleanTestResources();
}
if (cleanup) {
diff --git a/operator/controller/src/test/java/io/apicurio/registry/operator/it/IngressManager.java b/operator/controller/src/test/java/io/apicurio/registry/operator/it/IngressManager.java
index cfcecef57d..825a4e41de 100644
--- a/operator/controller/src/test/java/io/apicurio/registry/operator/it/IngressManager.java
+++ b/operator/controller/src/test/java/io/apicurio/registry/operator/it/IngressManager.java
@@ -37,7 +37,7 @@ public String getIngressHost(String prefix) {
}
private static boolean isSkipIngress() {
- return ConfigProvider.getConfig().getOptionalValue(INGRESS_SKIP_PROP, Boolean.class).orElse(false);
+ return ConfigProvider.getConfig().getValue(INGRESS_SKIP_PROP, Boolean.class);
}
private static Optional getBaseIngressHost() {
diff --git a/operator/controller/src/test/java/io/apicurio/registry/operator/it/OLMITBase.java b/operator/controller/src/test/java/io/apicurio/registry/operator/it/OLMITBase.java
new file mode 100644
index 0000000000..0a8d2be68b
--- /dev/null
+++ b/operator/controller/src/test/java/io/apicurio/registry/operator/it/OLMITBase.java
@@ -0,0 +1,116 @@
+package io.apicurio.registry.operator.it;
+
+import io.apicurio.registry.operator.Constants;
+import io.apicurio.registry.operator.OperatorException;
+import io.apicurio.registry.operator.api.v1.ApicurioRegistry3;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import io.quarkus.logging.Log;
+import org.awaitility.Awaitility;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import static io.apicurio.registry.operator.it.ITBase.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
+
+public abstract class OLMITBase {
+
+ private static final Logger log = LoggerFactory.getLogger(OLMITBase.class);
+
+ public static final String OLM_SKIP_PROP = "test.operator.olm-skip";
+ public static final String PROJECT_VERSION_PROP = "test.operator.project-version";
+ public static final String PROJECT_ROOT_PROP = "test.operator.project-root";
+ public static final String CATALOG_IMAGE_PROP = "test.operator.catalog-image";
+
+ protected static KubernetesClient client;
+ protected static String namespace;
+ protected static IngressManager ingressManager;
+ protected static boolean cleanup;
+
+ @BeforeAll
+ public static void beforeAll() throws Exception {
+ setDefaultAwaitilityTimings();
+ namespace = calculateNamespace();
+ client = createK8sClient(namespace);
+ createNamespace(client, namespace);
+ ingressManager = new IngressManager(client, namespace);
+ cleanup = ConfigProvider.getConfig().getValue(CLEANUP, Boolean.class);
+
+ if (client.apiextensions().v1().customResourceDefinitions()
+ .withName("catalogsources.operators.coreos.com").get() == null) {
+ throw new OperatorException("CatalogSource CRD is not available. Please install OLM.");
+ }
+
+ var projectVersion = ConfigProvider.getConfig().getValue(PROJECT_VERSION_PROP, String.class);
+ var projectRoot = ConfigProvider.getConfig().getValue(PROJECT_ROOT_PROP, String.class);
+ var catalogImage = ConfigProvider.getConfig().getValue(CATALOG_IMAGE_PROP, String.class);
+
+ var testDeployDir = Paths.get(projectRoot, "operator/controller/src/test/deploy");
+
+ // Catalog Source
+
+ var catalogSourceRaw = Files.readString(testDeployDir.resolve("catalog/catalog-source.yaml"));
+ catalogSourceRaw = catalogSourceRaw.replace("${PLACEHOLDER_CATALOG_NAMESPACE}", namespace);
+ catalogSourceRaw = catalogSourceRaw.replace("${PLACEHOLDER_CATALOG_IMAGE}", catalogImage);
+ var catalogSource = client.resource(catalogSourceRaw);
+ catalogSource.create();
+
+ await().ignoreExceptions().until(() -> {
+ return client.pods().inNamespace(namespace).list().getItems().stream().filter(
+ pod -> pod.getMetadata().getName().startsWith("apicurio-registry-operator-catalog"))
+ .anyMatch(pod -> pod.getStatus().getConditions().stream()
+ .anyMatch(c -> "Ready".equals(c.getType()) && "True".equals(c.getStatus())));
+ });
+
+ // Operator Group to allow deploying of the operator to the test namespace
+
+ var operatorGroupRaw = Files.readString(testDeployDir.resolve("catalog/operator-group.yaml"));
+ operatorGroupRaw = operatorGroupRaw.replace("${PLACEHOLDER_NAMESPACE}", namespace);
+ var operatorGroup = client.resource(operatorGroupRaw);
+ operatorGroup.create();
+
+ // Subscription
+
+ var subscriptionRaw = Files.readString(testDeployDir.resolve("catalog/subscription.yaml"));
+ subscriptionRaw = subscriptionRaw.replace("${PLACEHOLDER_NAMESPACE}", namespace);
+ subscriptionRaw = subscriptionRaw.replace("${PLACEHOLDER_CATALOG_NAMESPACE}", namespace);
+ subscriptionRaw = subscriptionRaw.replace("${PLACEHOLDER_PACKAGE}",
+ "apicurio-registry.v" + projectVersion.toLowerCase());
+ var subscription = client.resource(subscriptionRaw);
+ subscription.create();
+ }
+
+ @AfterEach
+ public void cleanup() {
+ if (cleanup) {
+ Log.info("Deleting CRs");
+ client.resources(ApicurioRegistry3.class).delete();
+ Awaitility.await().untilAsserted(() -> {
+ var registryDeployments = client.apps().deployments().inNamespace(namespace)
+ .withLabels(Constants.BASIC_LABELS).list().getItems();
+ assertThat(registryDeployments.size()).isZero();
+ });
+ }
+ }
+
+ @AfterAll
+ public static void afterAll() {
+ if (cleanup) {
+ Log.info("Deleting namespace : " + namespace);
+ assertThat(client.namespaces().withName(namespace).delete()).isNotNull();
+ }
+ client.close();
+ }
+
+ static boolean disabledIf() {
+ return "local".equals(ConfigProvider.getConfig().getValue(OPERATOR_DEPLOYMENT_PROP, String.class))
+ || ConfigProvider.getConfig().getValue(OLM_SKIP_PROP, Boolean.class);
+ }
+}
diff --git a/operator/controller/src/test/java/io/apicurio/registry/operator/it/SmokeITTest.java b/operator/controller/src/test/java/io/apicurio/registry/operator/it/SmokeITTest.java
index 01cd2198fd..8096dbda64 100644
--- a/operator/controller/src/test/java/io/apicurio/registry/operator/it/SmokeITTest.java
+++ b/operator/controller/src/test/java/io/apicurio/registry/operator/it/SmokeITTest.java
@@ -7,8 +7,9 @@
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.quarkus.test.junit.QuarkusTest;
import org.assertj.core.api.InstanceOfAssertFactories;
+import org.eclipse.microprofile.config.ConfigProvider;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
+import org.junit.jupiter.api.condition.DisabledIf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -25,7 +26,7 @@ public class SmokeITTest extends ITBase {
private static final Logger log = LoggerFactory.getLogger(SmokeITTest.class);
@Test
- void demoDeployment() {
+ void smoke() {
var registry = ResourceFactory.deserialize("/k8s/examples/simple.apicurioregistry3.yaml",
ApicurioRegistry3.class);
@@ -110,7 +111,7 @@ void testService() {
}
@Test
- @DisabledIfSystemProperty(named = INGRESS_SKIP_PROP, matches = "true")
+ @DisabledIf("io.apicurio.registry.operator.it.SmokeITTest#ingressDisabled")
void testIngress() {
var registry = ResourceFactory.deserialize("/k8s/examples/simple.apicurioregistry3.yaml",
@@ -162,9 +163,11 @@ void testEmptyHostDisablesIngress() {
});
// Check that REGISTRY_API_URL is set
- var uiDeployment = client.apps().deployments().inNamespace(namespace)
- .withName(registry.getMetadata().getName() + "-ui-deployment").get();
- verify_REGISTRY_API_URL_isSet(registry, uiDeployment);
+ await().ignoreExceptions().untilAsserted(() -> {
+ var uiDeployment = client.apps().deployments().inNamespace(namespace)
+ .withName(registry.getMetadata().getName() + "-ui-deployment").get();
+ verify_REGISTRY_API_URL_isSet(registry, uiDeployment);
+ });
// Disable host and therefore Ingress
registry.getSpec().getApp().setHost("");
@@ -188,7 +191,7 @@ void testEmptyHostDisablesIngress() {
.withName(registry.getMetadata().getName() + "-ui-ingress").get()).isNull();
});
- uiDeployment = client.apps().deployments().inNamespace(namespace)
+ var uiDeployment = client.apps().deployments().inNamespace(namespace)
.withName(registry.getMetadata().getName() + "-ui-deployment").get();
assertThat(uiDeployment).isNotNull();
// spotless:off
@@ -213,9 +216,11 @@ void testEmptyHostDisablesIngress() {
});
// Check that REGISTRY_API_URL is set again
- uiDeployment = client.apps().deployments().inNamespace(namespace)
- .withName(registry.getMetadata().getName() + "-ui-deployment").get();
- verify_REGISTRY_API_URL_isSet(registry, uiDeployment);
+ await().ignoreExceptions().untilAsserted(() -> {
+ var uiDeployment2 = client.apps().deployments().inNamespace(namespace)
+ .withName(registry.getMetadata().getName() + "-ui-deployment").get();
+ verify_REGISTRY_API_URL_isSet(registry, uiDeployment2);
+ });
}
private void verify_REGISTRY_API_URL_isSet(ApicurioRegistry3 registry, Deployment deployment) {
@@ -232,4 +237,8 @@ private void verify_REGISTRY_API_URL_isSet(ApicurioRegistry3 registry, Deploymen
.startsWith("http://" + registry.getSpec().getApp().getHost());
// spotless:on
}
+
+ static boolean ingressDisabled() {
+ return ConfigProvider.getConfig().getValue(INGRESS_SKIP_PROP, Boolean.class);
+ }
}
diff --git a/operator/controller/src/test/java/io/apicurio/registry/operator/it/SmokeOLMITTest.java b/operator/controller/src/test/java/io/apicurio/registry/operator/it/SmokeOLMITTest.java
new file mode 100644
index 0000000000..91bc747ac9
--- /dev/null
+++ b/operator/controller/src/test/java/io/apicurio/registry/operator/it/SmokeOLMITTest.java
@@ -0,0 +1,25 @@
+package io.apicurio.registry.operator.it;
+
+import io.quarkus.test.junit.QuarkusTest;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledIf;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
+
+@QuarkusTest
+@DisabledIf("io.apicurio.registry.operator.it.OLMITBase#disabledIf")
+public class SmokeOLMITTest extends OLMITBase {
+
+ @Test
+ void smoke() {
+ // Wait for the operator to deploy
+ var projectVersion = ConfigProvider.getConfig().getValue(PROJECT_VERSION_PROP, String.class);
+ await().ignoreExceptions().untilAsserted(() -> {
+ assertThat(client.apps().deployments()
+ .withName("apicurio-registry-operator-v" + projectVersion.toLowerCase()).get().getStatus()
+ .getReadyReplicas()).isEqualTo(1);
+ });
+ }
+}
diff --git a/operator/install/install.yaml b/operator/install/install.yaml
new file mode 100644
index 0000000000..ec6164d2a3
--- /dev/null
+++ b/operator/install/install.yaml
@@ -0,0 +1,6167 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ labels:
+ app: apicurio-registry-operator
+ app.kubernetes.io/component: operator
+ app.kubernetes.io/name: apicurio-registry-operator
+ app.kubernetes.io/part-of: apicurio-registry
+ app.kubernetes.io/version: 3.0.4-SNAPSHOT
+ name: apicurioregistries3.registry.apicur.io
+spec:
+ group: registry.apicur.io
+ names:
+ kind: ApicurioRegistry3
+ plural: apicurioregistries3
+ shortNames:
+ - registry3
+ singular: apicurioregistry3
+ scope: Namespaced
+ versions:
+ - name: v1
+ schema:
+ openAPIV3Schema:
+ properties:
+ spec:
+ properties:
+ app:
+ description: Configuration specific to Apicurio Registry backend component.
+ properties:
+ env:
+ description: List of environment variables that should be passed
+ to the App component.
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: object
+ type: array
+ host:
+ description: |-
+ Apicurio Registry backend component hostname.
+ If the value is empty, the Operator will not create an Ingress resource for the component.
+ IMPORTANT: If the Ingress already exists and the value becomes empty, the Ingress will be deleted.
+
+ Note that the UI component requires a browser-accessible URL to the Apicurio Registry backend to work properly.
+ If you create the Ingress manually, you have to manually set the REGISTRY_API_URL environment variable for the backend component.
+ type: string
+ kafkasql:
+ description: Configure KafkaSQL storage.
+ properties:
+ bootstrapServers:
+ description: Configure Kafka bootstrap servers.
+ type: string
+ type: object
+ podTemplateSpec:
+ description: |
+ This field can be used to specify a PodTemplateSpec that will be used to generate Deployment for the App component
+ This allows users to modify the apicurio-registry-app container, or adding another container to the pod.
+ Operator will apply changes on top of this PTS, so some parts might be overridden, depending on other fields in this CR.
+ Restrictions: `.spec.containers[name = apicurio-registry-app].env` must be empty.
+ properties:
+ metadata:
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ type: object
+ creationTimestamp:
+ type: string
+ deletionGracePeriodSeconds:
+ type: integer
+ deletionTimestamp:
+ type: string
+ finalizers:
+ items:
+ type: string
+ type: array
+ generateName:
+ type: string
+ generation:
+ type: integer
+ labels:
+ additionalProperties:
+ type: string
+ type: object
+ managedFields:
+ items:
+ properties:
+ apiVersion:
+ type: string
+ fieldsType:
+ type: string
+ fieldsV1:
+ type: object
+ manager:
+ type: string
+ operation:
+ type: string
+ subresource:
+ type: string
+ time:
+ type: string
+ type: object
+ type: array
+ name:
+ type: string
+ namespace:
+ type: string
+ ownerReferences:
+ items:
+ properties:
+ apiVersion:
+ type: string
+ blockOwnerDeletion:
+ type: boolean
+ controller:
+ type: boolean
+ kind:
+ type: string
+ name:
+ type: string
+ uid:
+ type: string
+ type: object
+ type: array
+ resourceVersion:
+ type: string
+ selfLink:
+ type: string
+ uid:
+ type: string
+ type: object
+ spec:
+ properties:
+ activeDeadlineSeconds:
+ type: integer
+ affinity:
+ properties:
+ nodeAffinity:
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ preference:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchFields:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ type: object
+ weight:
+ type: integer
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ properties:
+ nodeSelectorTerms:
+ items:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchFields:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ type: object
+ type: array
+ type: object
+ type: object
+ podAffinity:
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ podAffinityTerm:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ matchLabelKeys:
+ items:
+ type: string
+ type: array
+ mismatchLabelKeys:
+ items:
+ type: string
+ type: array
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ weight:
+ type: integer
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ matchLabelKeys:
+ items:
+ type: string
+ type: array
+ mismatchLabelKeys:
+ items:
+ type: string
+ type: array
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ type: array
+ type: object
+ podAntiAffinity:
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ podAffinityTerm:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ matchLabelKeys:
+ items:
+ type: string
+ type: array
+ mismatchLabelKeys:
+ items:
+ type: string
+ type: array
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ weight:
+ type: integer
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ matchLabelKeys:
+ items:
+ type: string
+ type: array
+ mismatchLabelKeys:
+ items:
+ type: string
+ type: array
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ type: array
+ type: object
+ type: object
+ automountServiceAccountToken:
+ type: boolean
+ containers:
+ items:
+ properties:
+ args:
+ items:
+ type: string
+ type: array
+ command:
+ items:
+ type: string
+ type: array
+ env:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: object
+ type: array
+ envFrom:
+ items:
+ properties:
+ configMapRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ prefix:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: array
+ image:
+ type: string
+ imagePullPolicy:
+ type: string
+ lifecycle:
+ properties:
+ postStart:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ preStop:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ type: object
+ livenessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ name:
+ type: string
+ ports:
+ items:
+ properties:
+ containerPort:
+ type: integer
+ hostIP:
+ type: string
+ hostPort:
+ type: integer
+ name:
+ type: string
+ protocol:
+ type: string
+ type: object
+ type: array
+ readinessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ resizePolicy:
+ items:
+ properties:
+ resourceName:
+ type: string
+ restartPolicy:
+ type: string
+ type: object
+ type: array
+ resources:
+ properties:
+ claims:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ restartPolicy:
+ type: string
+ securityContext:
+ properties:
+ allowPrivilegeEscalation:
+ type: boolean
+ capabilities:
+ properties:
+ add:
+ items:
+ type: string
+ type: array
+ drop:
+ items:
+ type: string
+ type: array
+ type: object
+ privileged:
+ type: boolean
+ procMount:
+ type: string
+ readOnlyRootFilesystem:
+ type: boolean
+ runAsGroup:
+ type: integer
+ runAsNonRoot:
+ type: boolean
+ runAsUser:
+ type: integer
+ seLinuxOptions:
+ properties:
+ level:
+ type: string
+ role:
+ type: string
+ type:
+ type: string
+ user:
+ type: string
+ type: object
+ seccompProfile:
+ properties:
+ localhostProfile:
+ type: string
+ type:
+ type: string
+ type: object
+ windowsOptions:
+ properties:
+ gmsaCredentialSpec:
+ type: string
+ gmsaCredentialSpecName:
+ type: string
+ hostProcess:
+ type: boolean
+ runAsUserName:
+ type: string
+ type: object
+ type: object
+ startupProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ stdin:
+ type: boolean
+ stdinOnce:
+ type: boolean
+ terminationMessagePath:
+ type: string
+ terminationMessagePolicy:
+ type: string
+ tty:
+ type: boolean
+ volumeDevices:
+ items:
+ properties:
+ devicePath:
+ type: string
+ name:
+ type: string
+ type: object
+ type: array
+ volumeMounts:
+ items:
+ properties:
+ mountPath:
+ type: string
+ mountPropagation:
+ type: string
+ name:
+ type: string
+ readOnly:
+ type: boolean
+ subPath:
+ type: string
+ subPathExpr:
+ type: string
+ type: object
+ type: array
+ workingDir:
+ type: string
+ type: object
+ type: array
+ dnsConfig:
+ properties:
+ nameservers:
+ items:
+ type: string
+ type: array
+ options:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ searches:
+ items:
+ type: string
+ type: array
+ type: object
+ dnsPolicy:
+ type: string
+ enableServiceLinks:
+ type: boolean
+ ephemeralContainers:
+ items:
+ properties:
+ args:
+ items:
+ type: string
+ type: array
+ command:
+ items:
+ type: string
+ type: array
+ env:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: object
+ type: array
+ envFrom:
+ items:
+ properties:
+ configMapRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ prefix:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: array
+ image:
+ type: string
+ imagePullPolicy:
+ type: string
+ lifecycle:
+ properties:
+ postStart:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ preStop:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ type: object
+ livenessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ name:
+ type: string
+ ports:
+ items:
+ properties:
+ containerPort:
+ type: integer
+ hostIP:
+ type: string
+ hostPort:
+ type: integer
+ name:
+ type: string
+ protocol:
+ type: string
+ type: object
+ type: array
+ readinessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ resizePolicy:
+ items:
+ properties:
+ resourceName:
+ type: string
+ restartPolicy:
+ type: string
+ type: object
+ type: array
+ resources:
+ properties:
+ claims:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ restartPolicy:
+ type: string
+ securityContext:
+ properties:
+ allowPrivilegeEscalation:
+ type: boolean
+ capabilities:
+ properties:
+ add:
+ items:
+ type: string
+ type: array
+ drop:
+ items:
+ type: string
+ type: array
+ type: object
+ privileged:
+ type: boolean
+ procMount:
+ type: string
+ readOnlyRootFilesystem:
+ type: boolean
+ runAsGroup:
+ type: integer
+ runAsNonRoot:
+ type: boolean
+ runAsUser:
+ type: integer
+ seLinuxOptions:
+ properties:
+ level:
+ type: string
+ role:
+ type: string
+ type:
+ type: string
+ user:
+ type: string
+ type: object
+ seccompProfile:
+ properties:
+ localhostProfile:
+ type: string
+ type:
+ type: string
+ type: object
+ windowsOptions:
+ properties:
+ gmsaCredentialSpec:
+ type: string
+ gmsaCredentialSpecName:
+ type: string
+ hostProcess:
+ type: boolean
+ runAsUserName:
+ type: string
+ type: object
+ type: object
+ startupProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ stdin:
+ type: boolean
+ stdinOnce:
+ type: boolean
+ targetContainerName:
+ type: string
+ terminationMessagePath:
+ type: string
+ terminationMessagePolicy:
+ type: string
+ tty:
+ type: boolean
+ volumeDevices:
+ items:
+ properties:
+ devicePath:
+ type: string
+ name:
+ type: string
+ type: object
+ type: array
+ volumeMounts:
+ items:
+ properties:
+ mountPath:
+ type: string
+ mountPropagation:
+ type: string
+ name:
+ type: string
+ readOnly:
+ type: boolean
+ subPath:
+ type: string
+ subPathExpr:
+ type: string
+ type: object
+ type: array
+ workingDir:
+ type: string
+ type: object
+ type: array
+ hostAliases:
+ items:
+ properties:
+ hostnames:
+ items:
+ type: string
+ type: array
+ ip:
+ type: string
+ type: object
+ type: array
+ hostIPC:
+ type: boolean
+ hostNetwork:
+ type: boolean
+ hostPID:
+ type: boolean
+ hostUsers:
+ type: boolean
+ hostname:
+ type: string
+ imagePullSecrets:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ initContainers:
+ items:
+ properties:
+ args:
+ items:
+ type: string
+ type: array
+ command:
+ items:
+ type: string
+ type: array
+ env:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: object
+ type: array
+ envFrom:
+ items:
+ properties:
+ configMapRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ prefix:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: array
+ image:
+ type: string
+ imagePullPolicy:
+ type: string
+ lifecycle:
+ properties:
+ postStart:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ preStop:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ type: object
+ livenessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ name:
+ type: string
+ ports:
+ items:
+ properties:
+ containerPort:
+ type: integer
+ hostIP:
+ type: string
+ hostPort:
+ type: integer
+ name:
+ type: string
+ protocol:
+ type: string
+ type: object
+ type: array
+ readinessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ resizePolicy:
+ items:
+ properties:
+ resourceName:
+ type: string
+ restartPolicy:
+ type: string
+ type: object
+ type: array
+ resources:
+ properties:
+ claims:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ restartPolicy:
+ type: string
+ securityContext:
+ properties:
+ allowPrivilegeEscalation:
+ type: boolean
+ capabilities:
+ properties:
+ add:
+ items:
+ type: string
+ type: array
+ drop:
+ items:
+ type: string
+ type: array
+ type: object
+ privileged:
+ type: boolean
+ procMount:
+ type: string
+ readOnlyRootFilesystem:
+ type: boolean
+ runAsGroup:
+ type: integer
+ runAsNonRoot:
+ type: boolean
+ runAsUser:
+ type: integer
+ seLinuxOptions:
+ properties:
+ level:
+ type: string
+ role:
+ type: string
+ type:
+ type: string
+ user:
+ type: string
+ type: object
+ seccompProfile:
+ properties:
+ localhostProfile:
+ type: string
+ type:
+ type: string
+ type: object
+ windowsOptions:
+ properties:
+ gmsaCredentialSpec:
+ type: string
+ gmsaCredentialSpecName:
+ type: string
+ hostProcess:
+ type: boolean
+ runAsUserName:
+ type: string
+ type: object
+ type: object
+ startupProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ stdin:
+ type: boolean
+ stdinOnce:
+ type: boolean
+ terminationMessagePath:
+ type: string
+ terminationMessagePolicy:
+ type: string
+ tty:
+ type: boolean
+ volumeDevices:
+ items:
+ properties:
+ devicePath:
+ type: string
+ name:
+ type: string
+ type: object
+ type: array
+ volumeMounts:
+ items:
+ properties:
+ mountPath:
+ type: string
+ mountPropagation:
+ type: string
+ name:
+ type: string
+ readOnly:
+ type: boolean
+ subPath:
+ type: string
+ subPathExpr:
+ type: string
+ type: object
+ type: array
+ workingDir:
+ type: string
+ type: object
+ type: array
+ nodeName:
+ type: string
+ nodeSelector:
+ additionalProperties:
+ type: string
+ type: object
+ os:
+ properties:
+ name:
+ type: string
+ type: object
+ overhead:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ preemptionPolicy:
+ type: string
+ priority:
+ type: integer
+ priorityClassName:
+ type: string
+ readinessGates:
+ items:
+ properties:
+ conditionType:
+ type: string
+ type: object
+ type: array
+ resourceClaims:
+ items:
+ properties:
+ name:
+ type: string
+ source:
+ properties:
+ resourceClaimName:
+ type: string
+ resourceClaimTemplateName:
+ type: string
+ type: object
+ type: object
+ type: array
+ restartPolicy:
+ type: string
+ runtimeClassName:
+ type: string
+ schedulerName:
+ type: string
+ schedulingGates:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ securityContext:
+ properties:
+ fsGroup:
+ type: integer
+ fsGroupChangePolicy:
+ type: string
+ runAsGroup:
+ type: integer
+ runAsNonRoot:
+ type: boolean
+ runAsUser:
+ type: integer
+ seLinuxOptions:
+ properties:
+ level:
+ type: string
+ role:
+ type: string
+ type:
+ type: string
+ user:
+ type: string
+ type: object
+ seccompProfile:
+ properties:
+ localhostProfile:
+ type: string
+ type:
+ type: string
+ type: object
+ supplementalGroups:
+ items:
+ type: integer
+ type: array
+ sysctls:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ windowsOptions:
+ properties:
+ gmsaCredentialSpec:
+ type: string
+ gmsaCredentialSpecName:
+ type: string
+ hostProcess:
+ type: boolean
+ runAsUserName:
+ type: string
+ type: object
+ type: object
+ serviceAccount:
+ type: string
+ serviceAccountName:
+ type: string
+ setHostnameAsFQDN:
+ type: boolean
+ shareProcessNamespace:
+ type: boolean
+ subdomain:
+ type: string
+ terminationGracePeriodSeconds:
+ type: integer
+ tolerations:
+ items:
+ properties:
+ effect:
+ type: string
+ key:
+ type: string
+ operator:
+ type: string
+ tolerationSeconds:
+ type: integer
+ value:
+ type: string
+ type: object
+ type: array
+ topologySpreadConstraints:
+ items:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ matchLabelKeys:
+ items:
+ type: string
+ type: array
+ maxSkew:
+ type: integer
+ minDomains:
+ type: integer
+ nodeAffinityPolicy:
+ type: string
+ nodeTaintsPolicy:
+ type: string
+ topologyKey:
+ type: string
+ whenUnsatisfiable:
+ type: string
+ type: object
+ type: array
+ volumes:
+ items:
+ properties:
+ awsElasticBlockStore:
+ properties:
+ fsType:
+ type: string
+ partition:
+ type: integer
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ type: object
+ azureDisk:
+ properties:
+ cachingMode:
+ type: string
+ diskName:
+ type: string
+ diskURI:
+ type: string
+ fsType:
+ type: string
+ kind:
+ type: string
+ readOnly:
+ type: boolean
+ type: object
+ azureFile:
+ properties:
+ readOnly:
+ type: boolean
+ secretName:
+ type: string
+ shareName:
+ type: string
+ type: object
+ cephfs:
+ properties:
+ monitors:
+ items:
+ type: string
+ type: array
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ secretFile:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ type: object
+ cinder:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeID:
+ type: string
+ type: object
+ configMap:
+ properties:
+ defaultMode:
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ type: integer
+ path:
+ type: string
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ csi:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ nodePublishSecretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ volumeAttributes:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ downwardAPI:
+ properties:
+ defaultMode:
+ type: integer
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ mode:
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ type: object
+ type: array
+ type: object
+ emptyDir:
+ properties:
+ medium:
+ type: string
+ sizeLimit:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ ephemeral:
+ properties:
+ volumeClaimTemplate:
+ properties:
+ metadata:
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ type: object
+ creationTimestamp:
+ type: string
+ deletionGracePeriodSeconds:
+ type: integer
+ deletionTimestamp:
+ type: string
+ finalizers:
+ items:
+ type: string
+ type: array
+ generateName:
+ type: string
+ generation:
+ type: integer
+ labels:
+ additionalProperties:
+ type: string
+ type: object
+ managedFields:
+ items:
+ properties:
+ apiVersion:
+ type: string
+ fieldsType:
+ type: string
+ fieldsV1:
+ type: object
+ manager:
+ type: string
+ operation:
+ type: string
+ subresource:
+ type: string
+ time:
+ type: string
+ type: object
+ type: array
+ name:
+ type: string
+ namespace:
+ type: string
+ ownerReferences:
+ items:
+ properties:
+ apiVersion:
+ type: string
+ blockOwnerDeletion:
+ type: boolean
+ controller:
+ type: boolean
+ kind:
+ type: string
+ name:
+ type: string
+ uid:
+ type: string
+ type: object
+ type: array
+ resourceVersion:
+ type: string
+ selfLink:
+ type: string
+ uid:
+ type: string
+ type: object
+ spec:
+ properties:
+ accessModes:
+ items:
+ type: string
+ type: array
+ dataSource:
+ properties:
+ apiGroup:
+ type: string
+ kind:
+ type: string
+ name:
+ type: string
+ type: object
+ dataSourceRef:
+ properties:
+ apiGroup:
+ type: string
+ kind:
+ type: string
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ resources:
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ selector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ storageClassName:
+ type: string
+ volumeAttributesClassName:
+ type: string
+ volumeMode:
+ type: string
+ volumeName:
+ type: string
+ type: object
+ type: object
+ type: object
+ fc:
+ properties:
+ fsType:
+ type: string
+ lun:
+ type: integer
+ readOnly:
+ type: boolean
+ targetWWNs:
+ items:
+ type: string
+ type: array
+ wwids:
+ items:
+ type: string
+ type: array
+ type: object
+ flexVolume:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ options:
+ additionalProperties:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ type: object
+ flocker:
+ properties:
+ datasetName:
+ type: string
+ datasetUUID:
+ type: string
+ type: object
+ gcePersistentDisk:
+ properties:
+ fsType:
+ type: string
+ partition:
+ type: integer
+ pdName:
+ type: string
+ readOnly:
+ type: boolean
+ type: object
+ gitRepo:
+ properties:
+ directory:
+ type: string
+ repository:
+ type: string
+ revision:
+ type: string
+ type: object
+ glusterfs:
+ properties:
+ endpoints:
+ type: string
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ type: object
+ hostPath:
+ properties:
+ path:
+ type: string
+ type:
+ type: string
+ type: object
+ iscsi:
+ properties:
+ chapAuthDiscovery:
+ type: boolean
+ chapAuthSession:
+ type: boolean
+ fsType:
+ type: string
+ initiatorName:
+ type: string
+ iqn:
+ type: string
+ iscsiInterface:
+ type: string
+ lun:
+ type: integer
+ portals:
+ items:
+ type: string
+ type: array
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ targetPortal:
+ type: string
+ type: object
+ name:
+ type: string
+ nfs:
+ properties:
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ server:
+ type: string
+ type: object
+ persistentVolumeClaim:
+ properties:
+ claimName:
+ type: string
+ readOnly:
+ type: boolean
+ type: object
+ photonPersistentDisk:
+ properties:
+ fsType:
+ type: string
+ pdID:
+ type: string
+ type: object
+ portworxVolume:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ type: object
+ projected:
+ properties:
+ defaultMode:
+ type: integer
+ sources:
+ items:
+ properties:
+ clusterTrustBundle:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ name:
+ type: string
+ optional:
+ type: boolean
+ path:
+ type: string
+ signerName:
+ type: string
+ type: object
+ configMap:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ type: integer
+ path:
+ type: string
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ downwardAPI:
+ properties:
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ mode:
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ type: object
+ type: array
+ type: object
+ secret:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ type: integer
+ path:
+ type: string
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ serviceAccountToken:
+ properties:
+ audience:
+ type: string
+ expirationSeconds:
+ type: integer
+ path:
+ type: string
+ type: object
+ type: object
+ type: array
+ type: object
+ quobyte:
+ properties:
+ group:
+ type: string
+ readOnly:
+ type: boolean
+ registry:
+ type: string
+ tenant:
+ type: string
+ user:
+ type: string
+ volume:
+ type: string
+ type: object
+ rbd:
+ properties:
+ fsType:
+ type: string
+ image:
+ type: string
+ keyring:
+ type: string
+ monitors:
+ items:
+ type: string
+ type: array
+ pool:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ type: object
+ scaleIO:
+ properties:
+ fsType:
+ type: string
+ gateway:
+ type: string
+ protectionDomain:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ sslEnabled:
+ type: boolean
+ storageMode:
+ type: string
+ storagePool:
+ type: string
+ system:
+ type: string
+ volumeName:
+ type: string
+ type: object
+ secret:
+ properties:
+ defaultMode:
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ type: integer
+ path:
+ type: string
+ type: object
+ type: array
+ optional:
+ type: boolean
+ secretName:
+ type: string
+ type: object
+ storageos:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeName:
+ type: string
+ volumeNamespace:
+ type: string
+ type: object
+ vsphereVolume:
+ properties:
+ fsType:
+ type: string
+ storagePolicyID:
+ type: string
+ storagePolicyName:
+ type: string
+ volumePath:
+ type: string
+ type: object
+ type: object
+ type: array
+ type: object
+ type: object
+ sql:
+ description: Configuration of Apicurio Registry SQL storage.
+ properties:
+ datasource:
+ description: SQL data source.
+ properties:
+ password:
+ description: Data source password.
+ type: string
+ url:
+ description: |-
+ Data source URL: \n URL of the PostgreSQL
+ database, for example: `jdbc:postgresql://..svc:5432/`.
+ type: string
+ username:
+ description: Data source username.
+ type: string
+ type: object
+ type: object
+ type: object
+ ui:
+ description: Configuration specific to Apicurio Registry UI component.
+ properties:
+ env:
+ description: List of environment variables that should be passed
+ to the UI component.
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: object
+ type: array
+ host:
+ description: |-
+ Apicurio Registry UI component hostname.
+ If the value is empty, the Operator will not create an Ingress resource for the component.
+ IMPORTANT: If the Ingress already exists and the value becomes empty, the Ingress will be deleted.
+ type: string
+ podTemplateSpec:
+ description: |-
+ This field can be used to specify a PodTemplateSpec that will be used to generate Deployment for the UI component.
+ This allows users to modify the apicurio-registry-ui container, or adding another container to the pod.
+ Operator will apply changes on top of this PTS, so some parts might be overridden, depending on other fields in this CR.
+ Restrictions: `.spec.containers[name = apicurio-registry-ui].env` must be empty.
+ properties:
+ metadata:
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ type: object
+ creationTimestamp:
+ type: string
+ deletionGracePeriodSeconds:
+ type: integer
+ deletionTimestamp:
+ type: string
+ finalizers:
+ items:
+ type: string
+ type: array
+ generateName:
+ type: string
+ generation:
+ type: integer
+ labels:
+ additionalProperties:
+ type: string
+ type: object
+ managedFields:
+ items:
+ properties:
+ apiVersion:
+ type: string
+ fieldsType:
+ type: string
+ fieldsV1:
+ type: object
+ manager:
+ type: string
+ operation:
+ type: string
+ subresource:
+ type: string
+ time:
+ type: string
+ type: object
+ type: array
+ name:
+ type: string
+ namespace:
+ type: string
+ ownerReferences:
+ items:
+ properties:
+ apiVersion:
+ type: string
+ blockOwnerDeletion:
+ type: boolean
+ controller:
+ type: boolean
+ kind:
+ type: string
+ name:
+ type: string
+ uid:
+ type: string
+ type: object
+ type: array
+ resourceVersion:
+ type: string
+ selfLink:
+ type: string
+ uid:
+ type: string
+ type: object
+ spec:
+ properties:
+ activeDeadlineSeconds:
+ type: integer
+ affinity:
+ properties:
+ nodeAffinity:
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ preference:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchFields:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ type: object
+ weight:
+ type: integer
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ properties:
+ nodeSelectorTerms:
+ items:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchFields:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ type: object
+ type: array
+ type: object
+ type: object
+ podAffinity:
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ podAffinityTerm:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ matchLabelKeys:
+ items:
+ type: string
+ type: array
+ mismatchLabelKeys:
+ items:
+ type: string
+ type: array
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ weight:
+ type: integer
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ matchLabelKeys:
+ items:
+ type: string
+ type: array
+ mismatchLabelKeys:
+ items:
+ type: string
+ type: array
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ type: array
+ type: object
+ podAntiAffinity:
+ properties:
+ preferredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ podAffinityTerm:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ matchLabelKeys:
+ items:
+ type: string
+ type: array
+ mismatchLabelKeys:
+ items:
+ type: string
+ type: array
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ weight:
+ type: integer
+ type: object
+ type: array
+ requiredDuringSchedulingIgnoredDuringExecution:
+ items:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ matchLabelKeys:
+ items:
+ type: string
+ type: array
+ mismatchLabelKeys:
+ items:
+ type: string
+ type: array
+ namespaceSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ namespaces:
+ items:
+ type: string
+ type: array
+ topologyKey:
+ type: string
+ type: object
+ type: array
+ type: object
+ type: object
+ automountServiceAccountToken:
+ type: boolean
+ containers:
+ items:
+ properties:
+ args:
+ items:
+ type: string
+ type: array
+ command:
+ items:
+ type: string
+ type: array
+ env:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: object
+ type: array
+ envFrom:
+ items:
+ properties:
+ configMapRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ prefix:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: array
+ image:
+ type: string
+ imagePullPolicy:
+ type: string
+ lifecycle:
+ properties:
+ postStart:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ preStop:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ type: object
+ livenessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ name:
+ type: string
+ ports:
+ items:
+ properties:
+ containerPort:
+ type: integer
+ hostIP:
+ type: string
+ hostPort:
+ type: integer
+ name:
+ type: string
+ protocol:
+ type: string
+ type: object
+ type: array
+ readinessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ resizePolicy:
+ items:
+ properties:
+ resourceName:
+ type: string
+ restartPolicy:
+ type: string
+ type: object
+ type: array
+ resources:
+ properties:
+ claims:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ restartPolicy:
+ type: string
+ securityContext:
+ properties:
+ allowPrivilegeEscalation:
+ type: boolean
+ capabilities:
+ properties:
+ add:
+ items:
+ type: string
+ type: array
+ drop:
+ items:
+ type: string
+ type: array
+ type: object
+ privileged:
+ type: boolean
+ procMount:
+ type: string
+ readOnlyRootFilesystem:
+ type: boolean
+ runAsGroup:
+ type: integer
+ runAsNonRoot:
+ type: boolean
+ runAsUser:
+ type: integer
+ seLinuxOptions:
+ properties:
+ level:
+ type: string
+ role:
+ type: string
+ type:
+ type: string
+ user:
+ type: string
+ type: object
+ seccompProfile:
+ properties:
+ localhostProfile:
+ type: string
+ type:
+ type: string
+ type: object
+ windowsOptions:
+ properties:
+ gmsaCredentialSpec:
+ type: string
+ gmsaCredentialSpecName:
+ type: string
+ hostProcess:
+ type: boolean
+ runAsUserName:
+ type: string
+ type: object
+ type: object
+ startupProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ stdin:
+ type: boolean
+ stdinOnce:
+ type: boolean
+ terminationMessagePath:
+ type: string
+ terminationMessagePolicy:
+ type: string
+ tty:
+ type: boolean
+ volumeDevices:
+ items:
+ properties:
+ devicePath:
+ type: string
+ name:
+ type: string
+ type: object
+ type: array
+ volumeMounts:
+ items:
+ properties:
+ mountPath:
+ type: string
+ mountPropagation:
+ type: string
+ name:
+ type: string
+ readOnly:
+ type: boolean
+ subPath:
+ type: string
+ subPathExpr:
+ type: string
+ type: object
+ type: array
+ workingDir:
+ type: string
+ type: object
+ type: array
+ dnsConfig:
+ properties:
+ nameservers:
+ items:
+ type: string
+ type: array
+ options:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ searches:
+ items:
+ type: string
+ type: array
+ type: object
+ dnsPolicy:
+ type: string
+ enableServiceLinks:
+ type: boolean
+ ephemeralContainers:
+ items:
+ properties:
+ args:
+ items:
+ type: string
+ type: array
+ command:
+ items:
+ type: string
+ type: array
+ env:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: object
+ type: array
+ envFrom:
+ items:
+ properties:
+ configMapRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ prefix:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: array
+ image:
+ type: string
+ imagePullPolicy:
+ type: string
+ lifecycle:
+ properties:
+ postStart:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ preStop:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ type: object
+ livenessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ name:
+ type: string
+ ports:
+ items:
+ properties:
+ containerPort:
+ type: integer
+ hostIP:
+ type: string
+ hostPort:
+ type: integer
+ name:
+ type: string
+ protocol:
+ type: string
+ type: object
+ type: array
+ readinessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ resizePolicy:
+ items:
+ properties:
+ resourceName:
+ type: string
+ restartPolicy:
+ type: string
+ type: object
+ type: array
+ resources:
+ properties:
+ claims:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ restartPolicy:
+ type: string
+ securityContext:
+ properties:
+ allowPrivilegeEscalation:
+ type: boolean
+ capabilities:
+ properties:
+ add:
+ items:
+ type: string
+ type: array
+ drop:
+ items:
+ type: string
+ type: array
+ type: object
+ privileged:
+ type: boolean
+ procMount:
+ type: string
+ readOnlyRootFilesystem:
+ type: boolean
+ runAsGroup:
+ type: integer
+ runAsNonRoot:
+ type: boolean
+ runAsUser:
+ type: integer
+ seLinuxOptions:
+ properties:
+ level:
+ type: string
+ role:
+ type: string
+ type:
+ type: string
+ user:
+ type: string
+ type: object
+ seccompProfile:
+ properties:
+ localhostProfile:
+ type: string
+ type:
+ type: string
+ type: object
+ windowsOptions:
+ properties:
+ gmsaCredentialSpec:
+ type: string
+ gmsaCredentialSpecName:
+ type: string
+ hostProcess:
+ type: boolean
+ runAsUserName:
+ type: string
+ type: object
+ type: object
+ startupProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ stdin:
+ type: boolean
+ stdinOnce:
+ type: boolean
+ targetContainerName:
+ type: string
+ terminationMessagePath:
+ type: string
+ terminationMessagePolicy:
+ type: string
+ tty:
+ type: boolean
+ volumeDevices:
+ items:
+ properties:
+ devicePath:
+ type: string
+ name:
+ type: string
+ type: object
+ type: array
+ volumeMounts:
+ items:
+ properties:
+ mountPath:
+ type: string
+ mountPropagation:
+ type: string
+ name:
+ type: string
+ readOnly:
+ type: boolean
+ subPath:
+ type: string
+ subPathExpr:
+ type: string
+ type: object
+ type: array
+ workingDir:
+ type: string
+ type: object
+ type: array
+ hostAliases:
+ items:
+ properties:
+ hostnames:
+ items:
+ type: string
+ type: array
+ ip:
+ type: string
+ type: object
+ type: array
+ hostIPC:
+ type: boolean
+ hostNetwork:
+ type: boolean
+ hostPID:
+ type: boolean
+ hostUsers:
+ type: boolean
+ hostname:
+ type: string
+ imagePullSecrets:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ initContainers:
+ items:
+ properties:
+ args:
+ items:
+ type: string
+ type: array
+ command:
+ items:
+ type: string
+ type: array
+ env:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ valueFrom:
+ properties:
+ configMapKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ secretKeyRef:
+ properties:
+ key:
+ type: string
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: object
+ type: array
+ envFrom:
+ items:
+ properties:
+ configMapRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ prefix:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ type: object
+ type: array
+ image:
+ type: string
+ imagePullPolicy:
+ type: string
+ lifecycle:
+ properties:
+ postStart:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ preStop:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ sleep:
+ properties:
+ seconds:
+ type: integer
+ type: object
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ type: object
+ livenessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ name:
+ type: string
+ ports:
+ items:
+ properties:
+ containerPort:
+ type: integer
+ hostIP:
+ type: string
+ hostPort:
+ type: integer
+ name:
+ type: string
+ protocol:
+ type: string
+ type: object
+ type: array
+ readinessProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ resizePolicy:
+ items:
+ properties:
+ resourceName:
+ type: string
+ restartPolicy:
+ type: string
+ type: object
+ type: array
+ resources:
+ properties:
+ claims:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ restartPolicy:
+ type: string
+ securityContext:
+ properties:
+ allowPrivilegeEscalation:
+ type: boolean
+ capabilities:
+ properties:
+ add:
+ items:
+ type: string
+ type: array
+ drop:
+ items:
+ type: string
+ type: array
+ type: object
+ privileged:
+ type: boolean
+ procMount:
+ type: string
+ readOnlyRootFilesystem:
+ type: boolean
+ runAsGroup:
+ type: integer
+ runAsNonRoot:
+ type: boolean
+ runAsUser:
+ type: integer
+ seLinuxOptions:
+ properties:
+ level:
+ type: string
+ role:
+ type: string
+ type:
+ type: string
+ user:
+ type: string
+ type: object
+ seccompProfile:
+ properties:
+ localhostProfile:
+ type: string
+ type:
+ type: string
+ type: object
+ windowsOptions:
+ properties:
+ gmsaCredentialSpec:
+ type: string
+ gmsaCredentialSpecName:
+ type: string
+ hostProcess:
+ type: boolean
+ runAsUserName:
+ type: string
+ type: object
+ type: object
+ startupProbe:
+ properties:
+ exec:
+ properties:
+ command:
+ items:
+ type: string
+ type: array
+ type: object
+ failureThreshold:
+ type: integer
+ grpc:
+ properties:
+ port:
+ type: integer
+ service:
+ type: string
+ type: object
+ httpGet:
+ properties:
+ host:
+ type: string
+ httpHeaders:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ path:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ scheme:
+ type: string
+ type: object
+ initialDelaySeconds:
+ type: integer
+ periodSeconds:
+ type: integer
+ successThreshold:
+ type: integer
+ tcpSocket:
+ properties:
+ host:
+ type: string
+ port:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ terminationGracePeriodSeconds:
+ type: integer
+ timeoutSeconds:
+ type: integer
+ type: object
+ stdin:
+ type: boolean
+ stdinOnce:
+ type: boolean
+ terminationMessagePath:
+ type: string
+ terminationMessagePolicy:
+ type: string
+ tty:
+ type: boolean
+ volumeDevices:
+ items:
+ properties:
+ devicePath:
+ type: string
+ name:
+ type: string
+ type: object
+ type: array
+ volumeMounts:
+ items:
+ properties:
+ mountPath:
+ type: string
+ mountPropagation:
+ type: string
+ name:
+ type: string
+ readOnly:
+ type: boolean
+ subPath:
+ type: string
+ subPathExpr:
+ type: string
+ type: object
+ type: array
+ workingDir:
+ type: string
+ type: object
+ type: array
+ nodeName:
+ type: string
+ nodeSelector:
+ additionalProperties:
+ type: string
+ type: object
+ os:
+ properties:
+ name:
+ type: string
+ type: object
+ overhead:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ preemptionPolicy:
+ type: string
+ priority:
+ type: integer
+ priorityClassName:
+ type: string
+ readinessGates:
+ items:
+ properties:
+ conditionType:
+ type: string
+ type: object
+ type: array
+ resourceClaims:
+ items:
+ properties:
+ name:
+ type: string
+ source:
+ properties:
+ resourceClaimName:
+ type: string
+ resourceClaimTemplateName:
+ type: string
+ type: object
+ type: object
+ type: array
+ restartPolicy:
+ type: string
+ runtimeClassName:
+ type: string
+ schedulerName:
+ type: string
+ schedulingGates:
+ items:
+ properties:
+ name:
+ type: string
+ type: object
+ type: array
+ securityContext:
+ properties:
+ fsGroup:
+ type: integer
+ fsGroupChangePolicy:
+ type: string
+ runAsGroup:
+ type: integer
+ runAsNonRoot:
+ type: boolean
+ runAsUser:
+ type: integer
+ seLinuxOptions:
+ properties:
+ level:
+ type: string
+ role:
+ type: string
+ type:
+ type: string
+ user:
+ type: string
+ type: object
+ seccompProfile:
+ properties:
+ localhostProfile:
+ type: string
+ type:
+ type: string
+ type: object
+ supplementalGroups:
+ items:
+ type: integer
+ type: array
+ sysctls:
+ items:
+ properties:
+ name:
+ type: string
+ value:
+ type: string
+ type: object
+ type: array
+ windowsOptions:
+ properties:
+ gmsaCredentialSpec:
+ type: string
+ gmsaCredentialSpecName:
+ type: string
+ hostProcess:
+ type: boolean
+ runAsUserName:
+ type: string
+ type: object
+ type: object
+ serviceAccount:
+ type: string
+ serviceAccountName:
+ type: string
+ setHostnameAsFQDN:
+ type: boolean
+ shareProcessNamespace:
+ type: boolean
+ subdomain:
+ type: string
+ terminationGracePeriodSeconds:
+ type: integer
+ tolerations:
+ items:
+ properties:
+ effect:
+ type: string
+ key:
+ type: string
+ operator:
+ type: string
+ tolerationSeconds:
+ type: integer
+ value:
+ type: string
+ type: object
+ type: array
+ topologySpreadConstraints:
+ items:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ matchLabelKeys:
+ items:
+ type: string
+ type: array
+ maxSkew:
+ type: integer
+ minDomains:
+ type: integer
+ nodeAffinityPolicy:
+ type: string
+ nodeTaintsPolicy:
+ type: string
+ topologyKey:
+ type: string
+ whenUnsatisfiable:
+ type: string
+ type: object
+ type: array
+ volumes:
+ items:
+ properties:
+ awsElasticBlockStore:
+ properties:
+ fsType:
+ type: string
+ partition:
+ type: integer
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ type: object
+ azureDisk:
+ properties:
+ cachingMode:
+ type: string
+ diskName:
+ type: string
+ diskURI:
+ type: string
+ fsType:
+ type: string
+ kind:
+ type: string
+ readOnly:
+ type: boolean
+ type: object
+ azureFile:
+ properties:
+ readOnly:
+ type: boolean
+ secretName:
+ type: string
+ shareName:
+ type: string
+ type: object
+ cephfs:
+ properties:
+ monitors:
+ items:
+ type: string
+ type: array
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ secretFile:
+ type: string
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ type: object
+ cinder:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeID:
+ type: string
+ type: object
+ configMap:
+ properties:
+ defaultMode:
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ type: integer
+ path:
+ type: string
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ csi:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ nodePublishSecretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ volumeAttributes:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ downwardAPI:
+ properties:
+ defaultMode:
+ type: integer
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ mode:
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ type: object
+ type: array
+ type: object
+ emptyDir:
+ properties:
+ medium:
+ type: string
+ sizeLimit:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ ephemeral:
+ properties:
+ volumeClaimTemplate:
+ properties:
+ metadata:
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ type: object
+ creationTimestamp:
+ type: string
+ deletionGracePeriodSeconds:
+ type: integer
+ deletionTimestamp:
+ type: string
+ finalizers:
+ items:
+ type: string
+ type: array
+ generateName:
+ type: string
+ generation:
+ type: integer
+ labels:
+ additionalProperties:
+ type: string
+ type: object
+ managedFields:
+ items:
+ properties:
+ apiVersion:
+ type: string
+ fieldsType:
+ type: string
+ fieldsV1:
+ type: object
+ manager:
+ type: string
+ operation:
+ type: string
+ subresource:
+ type: string
+ time:
+ type: string
+ type: object
+ type: array
+ name:
+ type: string
+ namespace:
+ type: string
+ ownerReferences:
+ items:
+ properties:
+ apiVersion:
+ type: string
+ blockOwnerDeletion:
+ type: boolean
+ controller:
+ type: boolean
+ kind:
+ type: string
+ name:
+ type: string
+ uid:
+ type: string
+ type: object
+ type: array
+ resourceVersion:
+ type: string
+ selfLink:
+ type: string
+ uid:
+ type: string
+ type: object
+ spec:
+ properties:
+ accessModes:
+ items:
+ type: string
+ type: array
+ dataSource:
+ properties:
+ apiGroup:
+ type: string
+ kind:
+ type: string
+ name:
+ type: string
+ type: object
+ dataSourceRef:
+ properties:
+ apiGroup:
+ type: string
+ kind:
+ type: string
+ name:
+ type: string
+ namespace:
+ type: string
+ type: object
+ resources:
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ selector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ storageClassName:
+ type: string
+ volumeAttributesClassName:
+ type: string
+ volumeMode:
+ type: string
+ volumeName:
+ type: string
+ type: object
+ type: object
+ type: object
+ fc:
+ properties:
+ fsType:
+ type: string
+ lun:
+ type: integer
+ readOnly:
+ type: boolean
+ targetWWNs:
+ items:
+ type: string
+ type: array
+ wwids:
+ items:
+ type: string
+ type: array
+ type: object
+ flexVolume:
+ properties:
+ driver:
+ type: string
+ fsType:
+ type: string
+ options:
+ additionalProperties:
+ type: string
+ type: object
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ type: object
+ flocker:
+ properties:
+ datasetName:
+ type: string
+ datasetUUID:
+ type: string
+ type: object
+ gcePersistentDisk:
+ properties:
+ fsType:
+ type: string
+ partition:
+ type: integer
+ pdName:
+ type: string
+ readOnly:
+ type: boolean
+ type: object
+ gitRepo:
+ properties:
+ directory:
+ type: string
+ repository:
+ type: string
+ revision:
+ type: string
+ type: object
+ glusterfs:
+ properties:
+ endpoints:
+ type: string
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ type: object
+ hostPath:
+ properties:
+ path:
+ type: string
+ type:
+ type: string
+ type: object
+ iscsi:
+ properties:
+ chapAuthDiscovery:
+ type: boolean
+ chapAuthSession:
+ type: boolean
+ fsType:
+ type: string
+ initiatorName:
+ type: string
+ iqn:
+ type: string
+ iscsiInterface:
+ type: string
+ lun:
+ type: integer
+ portals:
+ items:
+ type: string
+ type: array
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ targetPortal:
+ type: string
+ type: object
+ name:
+ type: string
+ nfs:
+ properties:
+ path:
+ type: string
+ readOnly:
+ type: boolean
+ server:
+ type: string
+ type: object
+ persistentVolumeClaim:
+ properties:
+ claimName:
+ type: string
+ readOnly:
+ type: boolean
+ type: object
+ photonPersistentDisk:
+ properties:
+ fsType:
+ type: string
+ pdID:
+ type: string
+ type: object
+ portworxVolume:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ volumeID:
+ type: string
+ type: object
+ projected:
+ properties:
+ defaultMode:
+ type: integer
+ sources:
+ items:
+ properties:
+ clusterTrustBundle:
+ properties:
+ labelSelector:
+ properties:
+ matchExpressions:
+ items:
+ properties:
+ key:
+ type: string
+ operator:
+ type: string
+ values:
+ items:
+ type: string
+ type: array
+ type: object
+ type: array
+ matchLabels:
+ additionalProperties:
+ type: string
+ type: object
+ type: object
+ name:
+ type: string
+ optional:
+ type: boolean
+ path:
+ type: string
+ signerName:
+ type: string
+ type: object
+ configMap:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ type: integer
+ path:
+ type: string
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ downwardAPI:
+ properties:
+ items:
+ items:
+ properties:
+ fieldRef:
+ properties:
+ apiVersion:
+ type: string
+ fieldPath:
+ type: string
+ type: object
+ mode:
+ type: integer
+ path:
+ type: string
+ resourceFieldRef:
+ properties:
+ containerName:
+ type: string
+ divisor:
+ anyOf:
+ - type: integer
+ - type: string
+ x-kubernetes-int-or-string: true
+ resource:
+ type: string
+ type: object
+ type: object
+ type: array
+ type: object
+ secret:
+ properties:
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ type: integer
+ path:
+ type: string
+ type: object
+ type: array
+ name:
+ type: string
+ optional:
+ type: boolean
+ type: object
+ serviceAccountToken:
+ properties:
+ audience:
+ type: string
+ expirationSeconds:
+ type: integer
+ path:
+ type: string
+ type: object
+ type: object
+ type: array
+ type: object
+ quobyte:
+ properties:
+ group:
+ type: string
+ readOnly:
+ type: boolean
+ registry:
+ type: string
+ tenant:
+ type: string
+ user:
+ type: string
+ volume:
+ type: string
+ type: object
+ rbd:
+ properties:
+ fsType:
+ type: string
+ image:
+ type: string
+ keyring:
+ type: string
+ monitors:
+ items:
+ type: string
+ type: array
+ pool:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ user:
+ type: string
+ type: object
+ scaleIO:
+ properties:
+ fsType:
+ type: string
+ gateway:
+ type: string
+ protectionDomain:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ sslEnabled:
+ type: boolean
+ storageMode:
+ type: string
+ storagePool:
+ type: string
+ system:
+ type: string
+ volumeName:
+ type: string
+ type: object
+ secret:
+ properties:
+ defaultMode:
+ type: integer
+ items:
+ items:
+ properties:
+ key:
+ type: string
+ mode:
+ type: integer
+ path:
+ type: string
+ type: object
+ type: array
+ optional:
+ type: boolean
+ secretName:
+ type: string
+ type: object
+ storageos:
+ properties:
+ fsType:
+ type: string
+ readOnly:
+ type: boolean
+ secretRef:
+ properties:
+ name:
+ type: string
+ type: object
+ volumeName:
+ type: string
+ volumeNamespace:
+ type: string
+ type: object
+ vsphereVolume:
+ properties:
+ fsType:
+ type: string
+ storagePolicyID:
+ type: string
+ storagePolicyName:
+ type: string
+ volumePath:
+ type: string
+ type: object
+ type: object
+ type: array
+ type: object
+ type: object
+ type: object
+ type: object
+ status:
+ properties:
+ conditions:
+ description: "Conditions: \n Apicurio Registry application and Operator
+ conditions."
+ items:
+ 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.
+ type: string
+ message:
+ description: message is a human readable message indicating
+ details about the transition. This may be an empty string.
+ 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.
+ 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.
+ 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:
+ - "False"
+ - "True"
+ - Unknown
+ type: string
+ type:
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ --- Many .condition.type values are consistent across resources
+ like Available, but because arbitrary conditions can be useful
+ (see .node.status.conditions), the ability to deconflict is
+ important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ 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
+ info:
+ description: Information about the Apicurio Registry application
+ properties:
+ appHost:
+ description: Apicurio Registry backend base URL
+ type: string
+ uiHost:
+ description: Apicurio Registry UI base URL
+ type: string
+ type: object
+ observedGeneration:
+ type: integer
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ labels:
+ app: apicurio-registry-operator
+ app.kubernetes.io/component: operator
+ app.kubernetes.io/name: apicurio-registry-operator
+ app.kubernetes.io/part-of: apicurio-registry
+ app.kubernetes.io/version: 3.0.4-SNAPSHOT
+ name: apicurio-registry-operator
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app: apicurio-registry-operator
+ app.kubernetes.io/component: operator
+ app.kubernetes.io/name: apicurio-registry-operator
+ app.kubernetes.io/part-of: apicurio-registry
+ app.kubernetes.io/version: 3.0.4-SNAPSHOT
+ name: apicurio-registry-operator-clusterrole
+rules:
+- apiGroups:
+ - registry.apicur.io
+ resources:
+ - apicurioregistries3
+ - apicurioregistries3/status
+ verbs:
+ - '*'
+- apiGroups:
+ - apps
+ resources:
+ - deployments
+ verbs:
+ - '*'
+- apiGroups:
+ - events.k8s.io
+ resources:
+ - events
+ verbs:
+ - '*'
+- apiGroups:
+ - ""
+ resources:
+ - pods
+ - services
+ verbs:
+ - '*'
+- apiGroups:
+ - apiextensions.k8s.io
+ resources:
+ - customresourcedefinitions
+ verbs:
+ - get
+- apiGroups:
+ - networking.k8s.io
+ resources:
+ - ingresses
+ verbs:
+ - '*'
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ labels:
+ app: apicurio-registry-operator
+ app.kubernetes.io/component: operator
+ app.kubernetes.io/name: apicurio-registry-operator
+ app.kubernetes.io/part-of: apicurio-registry
+ app.kubernetes.io/version: 3.0.4-SNAPSHOT
+ name: apicurio-registry-operator-clusterrolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: apicurio-registry-operator-clusterrole
+subjects:
+- kind: ServiceAccount
+ name: apicurio-registry-operator
+ namespace: PLACEHOLDER_NAMESPACE
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ app: apicurio-registry-operator
+ app.kubernetes.io/component: operator
+ app.kubernetes.io/name: apicurio-registry-operator
+ app.kubernetes.io/part-of: apicurio-registry
+ app.kubernetes.io/version: 3.0.4-SNAPSHOT
+ name: apicurio-registry-operator-v3.0.4-snapshot
+ namespace: PLACEHOLDER_NAMESPACE
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: apicurio-registry-operator
+ app.kubernetes.io/component: operator
+ app.kubernetes.io/name: apicurio-registry-operator
+ app.kubernetes.io/part-of: apicurio-registry
+ app.kubernetes.io/version: 3.0.4-SNAPSHOT
+ template:
+ metadata:
+ labels:
+ app: apicurio-registry-operator
+ app.kubernetes.io/component: operator
+ app.kubernetes.io/name: apicurio-registry-operator
+ app.kubernetes.io/part-of: apicurio-registry
+ app.kubernetes.io/version: 3.0.4-SNAPSHOT
+ spec:
+ containers:
+ - env:
+ - name: APICURIO_OPERATOR_WATCHED_NAMESPACES
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.annotations['olm.targetNamespaces']
+ - name: QUARKUS_PROFILE
+ value: prod
+ - name: REGISTRY_VERSION
+ value: 3.0.4-SNAPSHOT
+ - name: REGISTRY_APP_IMAGE
+ value: quay.io/apicurio/apicurio-registry:latest-snapshot
+ - name: REGISTRY_UI_IMAGE
+ value: quay.io/apicurio/apicurio-registry-ui:latest-snapshot
+ image: quay.io/apicurio/apicurio-registry-operator:3.0.4-snapshot
+ imagePullPolicy: Always
+ livenessProbe:
+ httpGet:
+ path: /q/health/live
+ port: 8080
+ name: apicurio-registry-operator
+ ports:
+ - containerPort: 8080
+ name: http
+ protocol: TCP
+ readinessProbe:
+ httpGet:
+ path: /q/health/ready
+ port: 8080
+ resources:
+ limits:
+ cpu: 200m
+ memory: 500Mi
+ requests:
+ cpu: 100m
+ memory: 100Mi
+ startupProbe:
+ failureThreshold: 6
+ httpGet:
+ path: /q/health/started
+ port: 8080
+ serviceAccountName: apicurio-registry-operator
diff --git a/operator/pom.xml b/operator/pom.xml
index b7dc789190..116c412148 100644
--- a/operator/pom.xml
+++ b/operator/pom.xml
@@ -27,9 +27,6 @@
17
UTF-8
UTF-8
- 3.26.3
- 1.70
- apicurio
@@ -67,6 +64,24 @@
+
+
+ org.codehaus.mojo
+ license-maven-plugin
+
+
+ aggregate-download-licenses
+
+ aggregate-download-licenses
+
+
+ system,test,provided
+ true
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 2395c5cf07..23f567ad99 100644
--- a/pom.xml
+++ b/pom.xml
@@ -223,6 +223,7 @@
7.1.0
7.0.0.202409031743-r
4.2.2
+ 3.26.3
5.4.1
@@ -252,6 +253,8 @@
3.4.0
3.1.0
2.43.0
+ 2.4.0
+ 3.5.0
8.45.1
@@ -522,6 +525,11 @@
apicurio-registry-schema-resolver
${project.version}
+
+ io.apicurio
+ apicurio-registry-operator-model
+ ${project.version}
+
@@ -841,6 +849,12 @@
awaitility
${awaitility.version}
+
+ org.assertj
+ assertj-core
+ ${assertj.core.version}
+ test
+
@@ -954,6 +968,16 @@
+
+ org.codehaus.mojo
+ license-maven-plugin
+ ${version.license-maven-plugin}
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ ${version.exec-maven-plugin}
+