diff --git a/.gitignore b/.gitignore index e5ec9676e..9cc536157 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ build/ _output/ bin/ bundle/ +catalog/ temp/ # OpenShift pre-flight diff --git a/Dockerfile b/Dockerfile index 288cf2c0c..ab5278020 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,18 +14,18 @@ ARG release LABEL "com.oracle.coherence.application"="operator" LABEL "com.oracle.coherence.version"="$version" +LABEL "org.opencontainers.image.version"="$version" LABEL "org.opencontainers.image.revision"="$release" -LABEL "org.opencontainers.image.description"="The Oracle Coherece Kubernetes Operator image ($target)" LABEL "org.opencontainers.image.source"="https://github.com/oracle/coherence-operator" LABEL "org.opencontainers.image.authors"="To contact the authors use this link https://github.com/oracle/coherence-operator/discussions" LABEL "org.opencontainers.image.licenses"="UPL-1.0" -LABEL "org.opencontainers.image.description"="The Oracle Coherece Kubernetes Operator allows full lifecycle management of Oracle Coherence workloads in Kubernetes." +LABEL "org.opencontainers.image.description"="The Oracle Coherence Kubernetes Operator allows full lifecycle management of Oracle Coherence workloads in Kubernetes." LABEL "name"="Oracle Coherence Kubernetes Operator" LABEL "vendor"="Oracle" LABEL "version"="$version" LABEL "release"="$release" -LABEL "maintainer"="Oracle Coherence Engieering Team" +LABEL "maintainer"="Oracle Coherence Engineering Team" LABEL "summary"="A Kubernetes Operator for managing Oracle Coherence clusters" LABEL "description"="The Oracle Coherece Kubernetes Operator allows full lifecycle management of Oracle Coherence workloads in Kubernetes." diff --git a/Makefile b/Makefile index fe8849fa6..2a45f09bf 100644 --- a/Makefile +++ b/Makefile @@ -112,7 +112,8 @@ MAVEN_BUILD_OPTS :=$(USE_MAVEN_SETTINGS) -Drevision=$(MVN_VERSION) -Dcoherence.v # ---------------------------------------------------------------------------------------------------------------------- # Operator image names # ---------------------------------------------------------------------------------------------------------------------- -OPERATOR_IMAGE_REGISTRY ?= ghcr.io/oracle +GITHUB_REGISTRY := ghcr.io/oracle +OPERATOR_IMAGE_REGISTRY ?= $(GITHUB_REGISTRY) OPERATOR_BASE_IMAGE ?= scratch OPERATOR_IMAGE_NAME := coherence-operator OPERATOR_IMAGE_ARM := $(OPERATOR_IMAGE_REGISTRY)/$(OPERATOR_IMAGE_NAME):$(VERSION)-arm64 @@ -213,14 +214,15 @@ LOCAL_STORAGE_RESTART ?= false # This is required if building and testing in environments that need to pull or push # images to private registries. For example building and testing with k8s in OCI. # ---------------------------------------------------------------------------------------------------------------------- -DOCKER_CMD ?= docker -DOCKER_SERVER ?= -DOCKER_USERNAME ?= -DOCKER_PASSWORD ?= +DOCKER_CMD ?= docker +JIB_EXECUTABLE ?= $(shell which docker) +DOCKER_SERVER ?= +DOCKER_USERNAME ?= +DOCKER_PASSWORD ?= OCR_DOCKER_USERNAME ?= OCR_DOCKER_PASSWORD ?= -MAVEN_USER ?= -MAVEN_PASSWORD ?= +MAVEN_USER ?= +MAVEN_PASSWORD ?= ifneq ("$(MAVEN_SETTINGS)","") @@ -297,6 +299,7 @@ TOOLS_BIN = $(TOOLS_DIRECTORY)/bin TOOLS_MANIFESTS = $(TOOLS_DIRECTORY)/manifests OPERATOR_SDK_HOME = $(TOOLS_DIRECTORY)/sdk/$(UNAME_S)-$(UNAME_M) OPERATOR_SDK = $(OPERATOR_SDK_HOME)/operator-sdk +ENVTEST = $(TOOLS_BIN)/setup-envtest # ---------------------------------------------------------------------------------------------------------------------- # The ttl.sh images used in integration tests @@ -468,7 +471,9 @@ clean: ## Cleans the build -rm -rf $(BUILD_BIN) || true -rm -rf artifacts || true -rm -rf bundle || true + -rm -rf catalog || true -rm bundle.Dockerfile || true + -rm catalog.Dockerfile || true rm config/crd/bases/*.yaml || true rm -rf config/crd-small || true rm pkg/data/zz_generated_*.go || true @@ -559,23 +564,35 @@ build-operator-images: $(BUILD_TARGETS)/build-operator ## Build all operator ima # Build the Operator Test images # ---------------------------------------------------------------------------------------------------------------------- .PHONY: build-test-images -build-test-images: $(BUILD_TARGETS)/java build-client-image build-basic-test-image ## Build all of the test images +build-test-images: $(BUILD_TARGETS)/java build-client-image build-basic-test-image build-helidon-test-images build-spring-test-images ## Build all of the test images + + +.PHONY: build-helidon-test-images +build-helidon-test-images: $(BUILD_TARGETS)/java ## Build the Helidon test images # Helidon 4 ./mvnw -B -f java/operator-test-helidon package jib:dockerBuild -DskipTests \ + -Djib.dockerClient.executable=$(JIB_EXECUTABLE) \ -Dcoherence.ce.version=$(COHERENCE_CE_LATEST) \ -Djib.to.image=$(TEST_APPLICATION_IMAGE_HELIDON) \ $(MAVEN_BUILD_OPTS) # Helidon 3 ./mvnw -B -f java/operator-test-helidon-3 package jib:dockerBuild -DskipTests \ + -Djib.dockerClient.executable=$(JIB_EXECUTABLE) \ -Dcoherence.ce.version=$(COHERENCE_CE_LATEST) \ -Djib.to.image=$(TEST_APPLICATION_IMAGE_HELIDON_3) \ $(MAVEN_BUILD_OPTS) # Helidon 2 ./mvnw -B -f java/operator-test-helidon-2 package jib:dockerBuild -DskipTests \ + -Djib.dockerClient.executable=$(JIB_EXECUTABLE) \ -Djib.to.image=$(TEST_APPLICATION_IMAGE_HELIDON_2) \ $(MAVEN_BUILD_OPTS) + +.PHONY: build-spring-test-images +build-spring-test-images: $(BUILD_TARGETS)/java ## Build the Spring test images # Spring Boot 3.x JIB - ./mvnw -B -f java/operator-test-spring package jib:dockerBuild -DskipTests -Djib.to.image=$(TEST_APPLICATION_IMAGE_SPRING) $(MAVEN_BUILD_OPTS) + ./mvnw -B -f java/operator-test-spring package jib:dockerBuild -DskipTests \ + -Djib.dockerClient.executable=$(JIB_EXECUTABLE) \ + -Djib.to.image=$(TEST_APPLICATION_IMAGE_SPRING) $(MAVEN_BUILD_OPTS) # Spring Boot 3.x CNBP ./mvnw -B -f java/operator-test-spring package spring-boot:build-image -DskipTests -Dcnbp-image-name=$(TEST_APPLICATION_IMAGE_SPRING_CNBP) $(MAVEN_BUILD_OPTS) # Spring Boot 3.x fat jar @@ -586,7 +603,9 @@ build-test-images: $(BUILD_TARGETS)/java build-client-image build-basic-test-ima cd java/operator-test-spring/target/spring && jar -xvf operator-test-spring-$(MVN_VERSION).jar && rm -f operator-test-spring-$(MVN_VERSION).jar $(DOCKER_CMD) build -f java/operator-test-spring/target/Dir.Dockerfile -t $(TEST_APPLICATION_IMAGE_SPRING) --load java/operator-test-spring/target # Spring Boot 2.x JIB - ./mvnw -B -f java/operator-test-spring-2 package jib:dockerBuild -DskipTests -Djib.to.image=$(TEST_APPLICATION_IMAGE_SPRING_2) $(MAVEN_BUILD_OPTS) + ./mvnw -B -f java/operator-test-spring-2 package jib:dockerBuild -DskipTests \ + -Djib.dockerClient.executable=$(JIB_EXECUTABLE) \ + -Djib.to.image=$(TEST_APPLICATION_IMAGE_SPRING_2) $(MAVEN_BUILD_OPTS) # Spring Boot 2.x CNBP ./mvnw -B -f java/operator-test-spring-2 package spring-boot:build-image -DskipTests -Dcnbp-image-name=$(TEST_APPLICATION_IMAGE_SPRING_CNBP_2) $(MAVEN_BUILD_OPTS) # Spring Boot 2.x fat jar @@ -602,11 +621,15 @@ build-test-images: $(BUILD_TARGETS)/java build-client-image build-basic-test-ima # ---------------------------------------------------------------------------------------------------------------------- .PHONY: build-basic-test-image build-basic-test-image: $(BUILD_TARGETS)/java ## Build the basic Operator test image - ./mvnw -B -f java/operator-test clean package jib:dockerBuild -DskipTests -Djib.to.image=$(TEST_APPLICATION_IMAGE) $(MAVEN_BUILD_OPTS) -Dcoherence.version=$(COHERENCE_IMAGE_TAG) + ./mvnw -B -f java/operator-test clean package jib:dockerBuild -DskipTests \ + -Djib.dockerClient.executable=$(JIB_EXECUTABLE) \ + -Djib.to.image=$(TEST_APPLICATION_IMAGE) $(MAVEN_BUILD_OPTS) -Dcoherence.version=$(COHERENCE_IMAGE_TAG) .PHONY: build-client-image build-client-image: ## Build the test client image - ./mvnw -B -f java/operator-test-client package jib:dockerBuild -DskipTests -Djib.to.image=$(TEST_APPLICATION_IMAGE_CLIENT) $(MAVEN_BUILD_OPTS) + ./mvnw -B -f java/operator-test-client package jib:dockerBuild -DskipTests \ + -Djib.dockerClient.executable=$(JIB_EXECUTABLE) \ + -Djib.to.image=$(TEST_APPLICATION_IMAGE_CLIENT) $(MAVEN_BUILD_OPTS) # ---------------------------------------------------------------------------------------------------------------------- # Build all of the Docker images @@ -660,7 +683,7 @@ $(BUILD_HELM)/coherence-operator-$(VERSION).tgz: $(BUILD_PROPS) $(HELM_FILES) $( # Copy the Helm chart from the source location to the distribution folder -mkdir -p $(BUILD_HELM) cp -R ./helm-charts/coherence-operator $(BUILD_HELM) - $(call replaceprop,$(BUILD_HELM)/coherence-operator/Chart.yaml $(BUILD_HELM)/coherence-operator/values.yaml $(BUILD_HELM)/coherence-operator/templates/deployment.yaml) + $(call replaceprop,$(BUILD_HELM)/coherence-operator/Chart.yaml $(BUILD_HELM)/coherence-operator/values.yaml $(BUILD_HELM)/coherence-operator/templates/deployment.yaml $(BUILD_HELM)/coherence-operator/templates/rbac.yaml) # Package the chart into a .tr.gz - we don't use helm package as the version might not be SEMVER helm lint $(BUILD_HELM)/coherence-operator tar -C $(BUILD_HELM)/coherence-operator -czf $(BUILD_HELM)/coherence-operator-$(VERSION).tgz . @@ -827,6 +850,7 @@ copyright: ## Check copyright headers -X preflight.log \ -X PROJECT \ -X .sh \ + -X .svg \ -X tanzu/package/package.yml \ -X tanzu/package/values.yml \ -X temp/ \ @@ -902,13 +926,14 @@ stop: ## kill any locally running operator process bundle: $(BUILD_PROPS) ensure-sdk $(TOOLS_BIN)/kustomize $(BUILD_TARGETS)/manifests $(MANIFEST_FILES) ## Generate OLM bundle manifests and metadata, then validate generated files. $(OPERATOR_SDK) generate kustomize manifests cd config/manager && $(KUSTOMIZE) edit set image controller=$(OPERATOR_IMAGE) - $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) + $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle --verbose --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) @echo "" >> ./bundle/metadata/annotations.yaml @echo " # OpenShift annotations" >> ./bundle/metadata/annotations.yaml @echo " com.redhat.openshift.versions: $(OPENSHIFT_MIN_VERSION)" >> ./bundle/metadata/annotations.yaml @echo "" >> bundle.Dockerfile @echo "# OpenShift labels" >> bundle.Dockerfile @echo "LABEL com.redhat.openshift.versions=$(OPENSHIFT_MIN_VERSION)" >> bundle.Dockerfile + @echo "LABEL org.opencontainers.image.description=\"This is the Operator Lifecycle Manager bundle for the Coherence Kubernetes Operator\"" >> bundle.Dockerfile @echo "cert_project_id: $(OPENSHIFT_COMPONENT_PID)" > bundle/ci.yaml $(OPERATOR_SDK) bundle validate ./bundle $(OPERATOR_SDK) bundle validate ./bundle --select-optional suite=operatorframework --optional-values=k8s-version=1.26 @@ -925,53 +950,89 @@ bundle-image: bundle ## Build the OLM image $(DOCKER_CMD) build --no-cache -f bundle.Dockerfile -t $(BUNDLE_IMAGE) --load . .PHONY: bundle-push -bundle-push: ## Push the OLM bundle image. +bundle-push: bundle-image ## Push the OLM bundle image. $(DOCKER_CMD) push $(OPE) $(BUNDLE_IMAGE) +OPM = $(TOOLS_BIN)/opm + .PHONY: opm -OPM = ./bin/opm -opm: ## Download opm locally if necessary. -ifeq (,$(wildcard $(OPM))) -ifeq (,$(shell which opm 2>/dev/null)) +opm: $(TOOLS_BIN)/opm + +$(TOOLS_BIN)/opm: ## Download opm locally if necessary. @{ \ set -e ;\ - mkdir -p $(dir $(OPM)) ;\ OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \ - curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.15.1/$${OS}-$${ARCH}-opm --header $(GH_AUTH) ;\ + curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.51.0/$${OS}-$${ARCH}-opm --header $(GH_AUTH) ;\ chmod +x $(OPM) ;\ } -else -OPM = $(shell which opm) -endif -endif - -# A comma-separated list of bundle images -# These images MUST exist in a registry and be pull-able. -BUNDLE_IMAGE_LIST ?= $(BUNDLE_IMAGE) # The image tag given to the resulting catalog image -CATALOG_IMAGE := $(OPERATOR_IMAGE_REGISTRY)/$(OPERATOR_IMAGE_NAME)-catalog:$(VERSION) - -# Set CATALOG_BASE_IMG to an existing catalog image tag to add $BUNDLE_IMAGE_LIST to that image. -ifneq ($(origin CATALOG_BASE_IMG), undefined) -FROM_INDEX_OPT := --from-index $(CATALOG_BASE_IMG) -endif +CATALOG_IMAGE_NAME := $(OPERATOR_IMAGE_REGISTRY)/$(OPERATOR_IMAGE_NAME)-catalog +CATALOG_IMAGE := $(CATALOG_IMAGE_NAME):latest # Build a catalog image by adding bundle images to an empty catalog using the operator package manager tool, 'opm'. # This recipe invokes 'opm' in 'semver' bundle add mode. For more information on add modes, see: # https://github.com/operator-framework/community-operators/blob/7f1438c/docs/packaging-operator.md#updating-your-existing-operator .PHONY: catalog-build -catalog-build: opm ## Build a catalog image. - $(OPM) index add --container-tool $(DOCKER_CMD) --mode semver --tag $(CATALOG_IMAGE) --bundles $(BUNDLE_IMAGE_LIST) $(FROM_INDEX_OPT) +catalog-build: opm ## Build a catalog image (the bundle image must have been pushed first). + rm -rf catalog || true + mkdir -p catalog + rm catalog.Dockerfile || true + $(OPM) generate dockerfile catalog + $(OPM) init coherence-operator --default-channel=stable --description=./README.md --icon=./hack/logo.svg --output yaml > catalog/operator.yaml + $(OPM) render $(BUNDLE_IMAGE) --output=yaml >> catalog/operator.yaml + cat ./hack/catalog-template.yaml >> catalog/operator.yaml + @echo $(VERSION) >> catalog/operator.yaml + $(OPM) validate catalog + $(DOCKER_CMD) build --load -f catalog.Dockerfile -t $(CATALOG_IMAGE) . # Push the catalog image. .PHONY: catalog-push -catalog-push: ## Push a catalog image. +catalog-push: catalog-build ## Push a catalog image. $(DOCKER_CMD) push $(PUSH_ARGS) $(CATALOG_IMAGE) .PHONY: scorecard scorecard: $(BUILD_PROPS) ensure-sdk bundle ## Run the Operator SDK scorecard tests. - $(OPERATOR_SDK) scorecard ./bundle + $(OPERATOR_SDK) scorecard --verbose ./bundle + +.PHONY: install-olm +install-olm: ensure-sdk ## Install the Operator Lifecycle Manage into the K8s cluster + $(OPERATOR_SDK) olm install + +.PHONY: uninstall-olm +uninstall-olm: ensure-sdk ## Uninstall the Operator Lifecycle Manage from the K8s cluster + $(OPERATOR_SDK) olm uninstall || true + +# Catalog image must be pushed first +.PHONY: olm-deploy-catalog +olm-deploy-catalog: ## Deploy the Operator Catalog into OLM + mkdir -p $(BUILD_OUTPUT)/catalog || true + cp $(SCRIPTS_DIR)/operator-catalog-source.yaml $(BUILD_OUTPUT)/catalog/operator-catalog-source.yaml + $(SED) -e 's^IMAGE_NAME_PLACEHOLDER^$(CATALOG_IMAGE)^g' $(BUILD_OUTPUT)/catalog/operator-catalog-source.yaml + kubectl apply -f $(BUILD_OUTPUT)/catalog/operator-catalog-source.yaml + kubectl -n olm get catalogsource + +.PHONY: wait-for-olm-deploy +wait-for-olm-deploy: export POD=$(shell kubectl -n olm get pod -l olm.catalogSource=coherence-operator-catalog -o name) +wait-for-olm-deploy: ## Wait for the Operator Catalog to be deployed into OLM + echo "Operator Catalog Source Pods:" + kubectl -n olm get pod -l olm.catalogSource=coherence-operator-catalog + echo "Waiting for Operator Catalog Source to be ready. Pod: $(POD)" + kubectl -n olm wait --for condition=ready --timeout 480s $(POD) + +.PHONY: olm-deploy +olm-deploy: ## Deploy the Operator into the coherence namespace using OLM + kubectl create ns coherence || true + kubectl -n coherence apply -f $(SCRIPTS_DIR)/operator-group.yaml + kubectl -n coherence apply -f $(SCRIPTS_DIR)/operator-subscription.yaml + sleep 10 + kubectl -n coherence get ip + kubectl -n coherence get csv + kubectl -n coherence wait --for condition=available deployment/coherence-operator-controller-manager -timeout 480s + +.PHONY: olm-undeploy +olm-undeploy: ## Undeploy the Operator that was installed with OLM + kubectl -n coherence delete csv coherence-operator.v$(VERSION) # ====================================================================================================================== # Targets to run a local container registry @@ -1015,6 +1076,9 @@ registry-stop: # ====================================================================================================================== ##@ OpenShift related tasks +PREFLIGHT_REGISTRY_AUTH_DIR ?= $(DEPLOY_REGISTRY_CONFIG_DIR) +PREFLIGHT_REGISTRY_AUTH_JSON ?= $(DEPLOY_REGISTRY_CONFIG_JSON) + .PHONY: preflight preflight: ## Run the OpenShift preflight tests against the Operator Image in a container mkdir -p $(BUILD_PREFLIGHT) || true @@ -1028,8 +1092,8 @@ preflight: ## Run the OpenShift preflight tests against the Operator Image in a --env PFLT_LOGFILE=/artifacts/preflight.log \ -v $(BUILD_PREFLIGHT):/artifacts \ -v $(HOME)/.kube/:/kubeconfig:ro \ - -v $(SCRIPTS_DIR):/dockerconfig:ro \ - quay.io/opdev/preflight:stable check container --insecure $(OPERATOR_IMAGE) + -v $(PREFLIGHT_REGISTRY_AUTH_DIR):/dockerconfig:ro \ + quay.io/opdev/preflight:stable check container --docker-config /dockerconfig/$(PREFLIGHT_REGISTRY_AUTH_JSON) --insecure $(OPERATOR_IMAGE) .PHONY: preflight-oc preflight-oc: $(BUILD_PREFLIGHT)/preflight.yaml preflight-oc-cleanup ## Run the OpenShift preflight tests as a K8s Job against the Operator Image @@ -1047,9 +1111,6 @@ preflight-oc-cleanup: $(BUILD_PREFLIGHT)/preflight.yaml ## Clean up the OpenShif # echo -n bogus:$(oc whoami -t) | base64 PREFLIGHT_REGISTRY_CRED ?= -.PHONY: jk -jk: $(BUILD_PREFLIGHT)/preflight.yaml - # Generate the preflight job yaml $(BUILD_PREFLIGHT)/preflight.yaml: hack/preflight.yaml cp hack/preflight.yaml $(BUILD_PREFLIGHT)/preflight.yaml @@ -1157,7 +1218,7 @@ e2e-local-test: export VERSION := $(VERSION) e2e-local-test: export MVN_VERSION := $(MVN_VERSION) e2e-local-test: export OPERATOR_IMAGE := $(OPERATOR_IMAGE) e2e-local-test: export COHERENCE_IMAGE := $(COHERENCE_IMAGE) -e2e-local-test: $(BUILD_TARGETS)/build-operator reset-namespace create-ssl-secrets install-crds gotestsum undeploy ## Run the Operator end-to-end 'local' functional tests using a local Operator instance +e2e-local-test: $(BUILD_TARGETS)/build-operator undeploy reset-namespace create-ssl-secrets gotestsum install-crds ensure-pull-secret ## Run the Operator end-to-end 'local' functional tests using a local Operator instance $(GOTESTSUM) --format standard-verbose --junitfile $(TEST_LOGS_DIR)/operator-e2e-local-test.xml \ -- $(GO_TEST_FLAGS_E2E) ./test/e2e/local/... @@ -1177,7 +1238,7 @@ e2e-test: prepare-e2e-test ## Run the Operator end-to-end 'remote' functional te ; exit $$rc .PHONY: prepare-e2e-test -prepare-e2e-test: $(BUILD_TARGETS)/build-operator reset-namespace create-ssl-secrets install-crds deploy-and-wait +prepare-e2e-test: $(BUILD_TARGETS)/build-operator reset-namespace create-ssl-secrets deploy-and-wait .PHONY: run-e2e-test run-e2e-test: export CGO_ENABLED = 0 @@ -1243,7 +1304,7 @@ e2e-k3d-test: export VERSION := $(VERSION) e2e-k3d-test: export MVN_VERSION := $(MVN_VERSION) e2e-k3d-test: export OPERATOR_IMAGE := $(OPERATOR_IMAGE) e2e-k3d-test: export COHERENCE_IMAGE := $(COHERENCE_IMAGE) -e2e-k3d-test: reset-namespace create-ssl-secrets install-crds gotestsum undeploy ## Run the Operator end-to-end 'local' functional tests using a local Operator instance +e2e-k3d-test: reset-namespace create-ssl-secrets gotestsum undeploy ## Run the Operator end-to-end 'local' functional tests using a local Operator instance $(GOTESTSUM) --format standard-verbose --junitfile $(TEST_LOGS_DIR)/operator-e2e-k3d-test.xml \ -- $(GO_TEST_FLAGS_E2E) ./test/e2e/large-cluster/... @@ -1266,7 +1327,7 @@ e2e-client-test: export VERSION := $(VERSION) e2e-client-test: export MVN_VERSION := $(MVN_VERSION) e2e-client-test: export OPERATOR_IMAGE := $(OPERATOR_IMAGE) e2e-client-test: export COHERENCE_IMAGE := $(COHERENCE_IMAGE) -e2e-client-test: build-operator-images build-client-image reset-namespace create-ssl-secrets install-crds gotestsum undeploy ## Run the end-to-end Coherence client tests using a local Operator deployment +e2e-client-test: build-operator-images build-client-image reset-namespace create-ssl-secrets gotestsum undeploy ## Run the end-to-end Coherence client tests using a local Operator deployment $(GOTESTSUM) --format standard-verbose --junitfile $(TEST_LOGS_DIR)/operator-e2e-client-test.xml \ -- $(GO_TEST_FLAGS_E2E) ./test/e2e/clients/... @@ -1282,7 +1343,7 @@ e2e-helm-test: export COHERENCE_IMAGE_REGISTRY := $(COHERENCE_IMAGE_REGISTRY) e2e-helm-test: export COHERENCE_IMAGE_NAME := $(COHERENCE_IMAGE_NAME) e2e-helm-test: export COHERENCE_IMAGE_TAG := $(COHERENCE_IMAGE_TAG) e2e-helm-test: export COHERENCE_IMAGE := $(COHERENCE_IMAGE) -e2e-helm-test: $(BUILD_PROPS) $(BUILD_HELM)/coherence-operator-$(VERSION).tgz reset-namespace install-crds gotestsum ## Run the Operator Helm chart end-to-end functional tests +e2e-helm-test: $(BUILD_PROPS) $(BUILD_HELM)/coherence-operator-$(VERSION).tgz reset-namespace gotestsum ## Run the Operator Helm chart end-to-end functional tests $(GOTESTSUM) --format standard-verbose --junitfile $(TEST_LOGS_DIR)/operator-e2e-helm-test.xml \ -- $(GO_TEST_FLAGS_E2E) ./test/e2e/helm/... @@ -1299,7 +1360,7 @@ e2e-helm-test: $(BUILD_PROPS) $(BUILD_HELM)/coherence-operator-$(VERSION).tgz re # ---------------------------------------------------------------------------------------------------------------------- .PHONY: e2e-prometheus-test e2e-prometheus-test: export MF = $(MAKEFLAGS) -e2e-prometheus-test: reset-namespace install-prometheus $(BUILD_TARGETS)/build-operator create-ssl-secrets install-crds deploy-and-wait ## Run the Operator metrics/Prometheus end-to-end functional tests +e2e-prometheus-test: reset-namespace install-prometheus $(BUILD_TARGETS)/build-operator create-ssl-secrets deploy-and-wait ## Run the Operator metrics/Prometheus end-to-end functional tests $(MAKE) run-prometheus-test $${MF} \ ; rc=$$? \ ; $(MAKE) uninstall-prometheus $${MF} \ @@ -1613,8 +1674,31 @@ deploy-and-wait: deploy wait-for-deploy ## Deploy the Coherence Operator and w # The Operator is deployed HA by default OPERATOR_HA ?= true +# If this variable is set it should be the path name to the +# container registry auth file, for example with Docker +# DEPLOY_REGISTRY_CONFIG_DIR=$HOME/.docker +# DEPLOY_REGISTRY_CONFIG_JSON=config.json +# Or with Podman +# DEPLOY_REGISTRY_CONFIG_DIR=$XDG_RUNTIME_DIR/containers +# DEPLOY_REGISTRY_CONFIG_JSON=auth.json +# Or to some other file in the correct format +# +# When set, the file will be used to create a pull secret named +# coherence-operator-pull-secret in the test namespace and the +# the Kustomize deployment will be config/overlays/ci directory +# to patch the ServiceAccount to use the secret +DEPLOY_REGISTRY_CONFIG_DIR ?= +DEPLOY_REGISTRY_CONFIG_JSON ?= + +DEPLOY_REGISTRY_CONFIG_PATH := +ifneq (,$(DEPLOY_REGISTRY_CONFIG_DIR)) +ifneq (,$(DEPLOY_REGISTRY_CONFIG_JSON)) + DEPLOY_REGISTRY_CONFIG_PATH := $(DEPLOY_REGISTRY_CONFIG_DIR)/$(DEPLOY_REGISTRY_CONFIG_JSON) +endif +endif + .PHONY: deploy -deploy: prepare-deploy create-namespace $(TOOLS_BIN)/kustomize ## Deploy the Coherence Operator +deploy: prepare-deploy create-namespace $(TOOLS_BIN)/kustomize ensure-pull-secret ## Deploy the Coherence Operator ifneq (,$(WATCH_NAMESPACE)) cd $(BUILD_DEPLOY)/manager && $(KUSTOMIZE) edit add configmap env-vars --from-literal WATCH_NAMESPACE=$(WATCH_NAMESPACE) endif @@ -1622,13 +1706,34 @@ ifeq (false,$(OPERATOR_HA)) cd $(BUILD_DEPLOY)/manager && $(KUSTOMIZE) edit add patch --kind Deployment --name controller-manager --path single-replica-patch.yaml endif kubectl -n $(OPERATOR_NAMESPACE) create secret generic coherence-webhook-server-cert || true +ifeq ("$(OPERATOR_IMAGE_REGISTRY)","$(GITHUB_REGISTRY)") $(KUSTOMIZE) build $(BUILD_DEPLOY)/default | kubectl apply -f - +else + $(KUSTOMIZE) build $(BUILD_DEPLOY)/overlays/ci | kubectl apply -f - +endif sleep 5 + .PHONY: just-deploy -just-deploy: ## Deploy the Coherence Operator without rebuilding anything +just-deploy: ensure-pull-secret ## Deploy the Coherence Operator without rebuilding anything $(call prepare_deploy,$(OPERATOR_IMAGE),$(OPERATOR_NAMESPACE)) +ifeq ("$(OPERATOR_IMAGE_REGISTRY)","$(GITHUB_REGISTRY)") $(KUSTOMIZE) build $(BUILD_DEPLOY)/default | kubectl apply -f - +else + $(KUSTOMIZE) build $(BUILD_DEPLOY)/overlays/ci | kubectl apply -f - +endif + + +.PHONY: ensure-pull-secret +ensure-pull-secret: +ifneq ("$(DEPLOY_REGISTRY_CONFIG_PATH)","") + kubectl -n $(OPERATOR_NAMESPACE) delete secret coherence-operator-pull-secret || true + kubectl -n $(OPERATOR_NAMESPACE) create secret generic coherence-operator-pull-secret \ + --from-file=.dockerconfigjson=$(DEPLOY_REGISTRY_CONFIG_PATH) \ + --type=kubernetes.io/dockerconfigjson + kubectl -n $(OPERATOR_NAMESPACE) patch serviceaccount default -p '{"imagePullSecrets": [{"name": "coherence-operator-pull-secret"}]}' +endif + .PHONY: prepare-deploy prepare-deploy: $(BUILD_TARGETS)/manifests $(BUILD_TARGETS)/build-operator $(TOOLS_BIN)/kustomize @@ -1704,7 +1809,11 @@ undeploy: $(BUILD_PROPS) $(BUILD_TARGETS)/manifests $(TOOLS_BIN)/kustomize ## U kubectl -n $(OPERATOR_NAMESPACE) delete secret coherence-webhook-server-cert || true kubectl delete mutatingwebhookconfiguration coherence-operator-mutating-webhook-configuration || true kubectl delete validatingwebhookconfiguration coherence-operator-validating-webhook-configuration || true + kubectl -n $(OPERATOR_NAMESPACE) delete secret coherence-operator-pull-secret || true @echo "Undeploy Coherence Operator completed" + @echo "Uninstalling CRDs - executing deletion" + $(KUSTOMIZE) build $(BUILD_DEPLOY)/crd | kubectl delete --force -f - || true + @echo "Uninstall CRDs completed" # ---------------------------------------------------------------------------------------------------------------------- @@ -1722,17 +1831,20 @@ $(BUILD_MANIFESTS_PKG): $(TOOLS_BIN)/kustomize $(TOOLS_BIN)/yq $(MANIFEST_FILES) $(KUSTOMIZE) build config/crd > $(BUILD_MANIFESTS)/crd/temp.yaml mkdir -p $(BUILD_MANIFESTS)/crd-small $(KUSTOMIZE) build config/crd-small > $(BUILD_MANIFESTS)/crd-small/temp.yaml + cp -R config/components/ $(BUILD_MANIFESTS)/components cp -R config/default/ $(BUILD_MANIFESTS)/default cp -R config/manager/ $(BUILD_MANIFESTS)/manager + cp -R config/namespace/ $(BUILD_MANIFESTS)/namespace + cp -R config/overlays/ $(BUILD_MANIFESTS)/overlays cp -R config/rbac/ $(BUILD_MANIFESTS)/rbac - tar -C $(BUILD_OUTPUT) -czf $(BUILD_MANIFESTS_PKG) manifests/ + rm -rf $(BUILD_MANIFESTS)/overlays/ci || true $(call prepare_deploy,$(OPERATOR_IMAGE),"coherence") cp config/namespace/namespace.yaml $(BUILD_OUTPUT)/coherence-operator.yaml $(KUSTOMIZE) build $(BUILD_DEPLOY)/default >> $(BUILD_OUTPUT)/coherence-operator.yaml $(SED) -e 's/name: coherence-operator-env-vars-.*/name: coherence-operator-env-vars/g' $(BUILD_OUTPUT)/coherence-operator.yaml $(KUSTOMIZE) build $(BUILD_DEPLOY)/overlays/restricted >> $(BUILD_OUTPUT)/coherence-operator-restricted.yaml $(SED) -e 's/name: coherence-operator-env-vars-.*/name: coherence-operator-env-vars/g' $(BUILD_OUTPUT)//coherence-operator-restricted.yaml - $(SED) -e 's/ClusterRole/Role/g' $(BUILD_OUTPUT)//coherence-operator-restricted.yaml + $(SED) -e 's/ClusterRole/Role/g' $(BUILD_OUTPUT)/coherence-operator-restricted.yaml cd $(BUILD_MANIFESTS)/crd && $(TOOLS_BIN)/yq --no-doc -s '.metadata.name + ".yaml"' temp.yaml rm $(BUILD_MANIFESTS)/crd/temp.yaml mv $(BUILD_MANIFESTS)/crd/coherence.coherence.oracle.com.yaml $(BUILD_MANIFESTS)/crd/coherence.oracle.com_coherence.yaml @@ -1741,6 +1853,7 @@ $(BUILD_MANIFESTS_PKG): $(TOOLS_BIN)/kustomize $(TOOLS_BIN)/yq $(MANIFEST_FILES) rm $(BUILD_MANIFESTS)/crd-small/temp.yaml mv $(BUILD_MANIFESTS)/crd-small/coherence.coherence.oracle.com.yaml $(BUILD_MANIFESTS)/crd-small/coherence.oracle.com_coherence.yaml mv $(BUILD_MANIFESTS)/crd-small/coherencejob.coherence.oracle.com.yaml $(BUILD_MANIFESTS)/crd-small/coherencejob.oracle.com_coherence.yaml + tar -C $(BUILD_OUTPUT) -czf $(BUILD_MANIFESTS_PKG) manifests/ # ---------------------------------------------------------------------------------------------------------------------- # Delete and re-create the test namespace @@ -1767,7 +1880,7 @@ reset-namespace: export DOCKER_USERNAME := $(DOCKER_USERNAME) reset-namespace: export DOCKER_PASSWORD := $(DOCKER_PASSWORD) reset-namespace: export OCR_DOCKER_USERNAME := $(OCR_DOCKER_USERNAME) reset-namespace: export OCR_DOCKER_PASSWORD := $(OCR_DOCKER_PASSWORD) -reset-namespace: delete-namespace create-namespace ## Reset the test namespace +reset-namespace: delete-namespace create-namespace ensure-pull-secret ## Reset the test namespace ifneq ($(DOCKER_SERVER),) @echo "Creating pull secrets for $(DOCKER_SERVER)" kubectl create secret docker-registry coherence-k8s-operator-development-secret \ @@ -2293,7 +2406,9 @@ gotestsum: ## Download gotestsum locally if necessary. # ---------------------------------------------------------------------------------------------------------------------- .PHONY: build-examples build-examples: - ./mvnw -B -f ./examples package jib:dockerBuild -DskipTests $(MAVEN_BUILD_OPTS) + ./mvnw -B -f ./examples package jib:dockerBuild -DskipTests \ + -Djib.dockerClient.executable=$(JIB_EXECUTABLE) \ + $(MAVEN_BUILD_OPTS) # ---------------------------------------------------------------------------------------------------------------------- # Build and test the examples @@ -2309,13 +2424,17 @@ PUSH_ARGS ?= .PHONY: push-operator-image push-operator-image: $(BUILD_TARGETS)/build-operator - $(DOCKER_CMD) push $(PUSH_ARGS) $(OPERATOR_IMAGE_AMD) - $(DOCKER_CMD) push $(PUSH_ARGS) $(OPERATOR_IMAGE_ARM) - $(DOCKER_CMD) rmi $(OPERATOR_IMAGE) || true - $(DOCKER_CMD) manifest create $(PUSH_ARGS) $(OPERATOR_IMAGE) \ - --amend $(OPERATOR_IMAGE_AMD) \ - --amend $(OPERATOR_IMAGE_ARM) - $(DOCKER_CMD) manifest push $(PUSH_ARGS) $(OPERATOR_IMAGE) + chmod +x $(CURRDIR)/hack/run-buildah.sh + export OPERATOR_IMAGE=$(OPERATOR_IMAGE) \ + && export OPERATOR_IMAGE_AMD=$(OPERATOR_IMAGE_AMD) \ + && export OPERATOR_IMAGE_ARM=$(OPERATOR_IMAGE_ARM) \ + && export OPERATOR_IMAGE_REGISTRY=$(OPERATOR_IMAGE_REGISTRY) \ + && export VERSION=$(VERSION) \ + && export REVISION=$(GITCOMMIT) \ + && export NO_DOCKER_DAEMON=$(NO_DOCKER_DAEMON) \ + && export DOCKER_CMD=$(DOCKER_CMD) \ + && $(CURRDIR)/hack/run-buildah.sh PUSH + # ---------------------------------------------------------------------------------------------------------------------- # Push the Operator JIB Test Docker images @@ -2367,9 +2486,11 @@ push-ttl-test-images: .PHONY: build-compatibility-image build-compatibility-image: $(BUILD_TARGETS)/java ./mvnw -B -f java/operator-compatibility package -DskipTests \ + -Ddocker.command=$(DOCKER_CMD) \ -Dcoherence.compatibility.image.name=$(TEST_COMPATIBILITY_IMAGE) \ -Dcoherence.compatibility.coherence.image=$(COHERENCE_IMAGE) $(MAVEN_BUILD_OPTS) ./mvnw -B -f java/operator-compatibility exec:exec \ + -Ddocker.command=$(DOCKER_CMD) \ -Dcoherence.compatibility.image.name=$(TEST_COMPATIBILITY_IMAGE) \ -Dcoherence.compatibility.coherence.image=$(COHERENCE_IMAGE) $(MAVEN_BUILD_OPTS) @@ -2409,10 +2530,10 @@ push-ttl-operator-images: push-all-ttl-images: push-ttl-operator-images push-ttl-test-images # ---------------------------------------------------------------------------------------------------------------------- -# Push all of the Docker images that are released +# Push all of the images that are released # ---------------------------------------------------------------------------------------------------------------------- .PHONY: push-release-images -push-release-images: push-operator-image tanzu-repo +push-release-images: push-operator-image bundle-push catalog-build catalog-push tanzu-repo # ---------------------------------------------------------------------------------------------------------------------- # Install Prometheus diff --git a/PROJECT b/PROJECT index f9d815ef0..71b620bc9 100644 --- a/PROJECT +++ b/PROJECT @@ -1,17 +1,31 @@ domain: oracle.com layout: - go.kubebuilder.io/v4 +multigroup: false +plugins: + manifests.sdk.operatorframework.io/v2: {} + scorecard.sdk.operatorframework.io/v2: {} projectName: coherence-operator repo: github.com/oracle/coherence-operator resources: -- +- api: + crdVersion: v1 + namespaced: true controller: true domain: oracle.com group: coherence.oracle.com kind: Coherence path: github.com/oracle/coherence-operator/api/v1 + plural: coherence + version: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: oracle.com + group: coherence.oracle.com + kind: CoherenceJob + path: github.com/oracle/coherence-operator/api/v1 + plural: coherencejob version: v1 version: "3" -plugins: - manifests.sdk.operatorframework.io/v2: {} - scorecard.sdk.operatorframework.io/v2: {} diff --git a/api/v1/coherence_webhook.go b/api/v1/coherence_webhook.go index d94f333ce..52f51faea 100644 --- a/api/v1/coherence_webhook.go +++ b/api/v1/coherence_webhook.go @@ -7,6 +7,7 @@ package v1 import ( + "context" "fmt" "github.com/distribution/reference" "github.com/go-test/deep" @@ -31,8 +32,11 @@ var ( ) func (in *Coherence) SetupWebhookWithManager(mgr ctrl.Manager) error { + hook := &Coherence{} return ctrl.NewWebhookManagedBy(mgr). For(in). + WithDefaulter(hook). + WithValidator(hook). Complete() } @@ -44,22 +48,28 @@ const MutatingWebHookPath = "/mutate-coherence-oracle-com-v1-coherence" // An anonymous var to ensure that the Coherence struct implements webhook.Defaulter // there will be a compile time error here if this fails. -var _ webhook.Defaulter = &Coherence{} +var _ webhook.CustomDefaulter = &Coherence{} // Default implements webhook.Defaulter so a webhook will be registered for the type -func (in *Coherence) Default() { - spec, _ := in.GetStatefulSetSpec() +func (in *Coherence) Default(_ context.Context, obj runtime.Object) error { + coh, ok := obj.(*Coherence) + if !ok { + return fmt.Errorf("expected a Coherence instance but got a %T", obj) + } + + spec, _ := coh.GetStatefulSetSpec() // set the default replicas if not present if spec.Replicas == nil { spec.SetReplicas(spec.GetReplicas()) } - SetCommonDefaults(in) + SetCommonDefaults(coh) // apply a label with the hash of the spec - ths must be the last action here to make sure that // any modifications to the spec field are included in the hash - if hash, applied := EnsureCoherenceHashLabel(in); applied { + if hash, applied := EnsureCoherenceHashLabel(coh); applied { webhookLogger.Info(fmt.Sprintf("Applied %s label", LabelCoherenceHash), "hash", hash) } + return nil } // SetCommonDefaults sets defaults common to both a Job and StatefulSet @@ -135,31 +145,36 @@ const ValidatingWebHookPath = "/validate-coherence-oracle-com-v1-coherence" // An anonymous var to ensure that the Coherence struct implements webhook.Validator // there will be a compile time error here if this fails. -var _ webhook.Validator = &Coherence{} +var _ webhook.CustomValidator = &Coherence{} var commonWebHook = CommonWebHook{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type // The optional warnings will be added to the response as warning messages. // Return an error if the object is invalid. -func (in *Coherence) ValidateCreate() (admission.Warnings, error) { - logger := webhookLogger.WithValues("namespace", in.GetNamespace(), "name", in.GetName()) +func (in *Coherence) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + coh, ok := obj.(*Coherence) + if !ok { + return nil, fmt.Errorf("expected a Coherence instance but got a %T", obj) + } + + logger := webhookLogger.WithValues("namespace", coh.GetNamespace(), "name", coh.GetName()) var warnings admission.Warnings - dt := in.GetDeletionTimestamp() + dt := coh.GetDeletionTimestamp() if dt != nil { // the deletion timestamp is set so do nothing logger.Info("Skipping validation for deleted resource", "deletionTimestamp", *dt) return warnings, nil } - webhookLogger.Info("validate create", "name", in.Name) - if err := commonWebHook.validateReplicas(in); err != nil { + webhookLogger.Info("validate create", "name", coh.Name) + if err := commonWebHook.validateReplicas(coh); err != nil { return warnings, err } - if err := commonWebHook.validateImages(in); err != nil { + if err := commonWebHook.validateImages(coh); err != nil { return warnings, err } - if err := commonWebHook.validateNodePorts(in); err != nil { + if err := commonWebHook.validateNodePorts(coh); err != nil { return warnings, err } return warnings, nil @@ -168,39 +183,47 @@ func (in *Coherence) ValidateCreate() (admission.Warnings, error) { // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type // The optional warnings will be added to the response as warning messages. // Return an error if the object is invalid. -func (in *Coherence) ValidateUpdate(previous runtime.Object) (admission.Warnings, error) { - webhookLogger.Info("validate update", "name", in.Name) - logger := webhookLogger.WithValues("namespace", in.GetNamespace(), "name", in.GetName()) +func (in *Coherence) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + cohNew, ok := newObj.(*Coherence) + if !ok { + return nil, fmt.Errorf("expected a Coherence instance for new value but got a %T", newObj) + } + cohPrev, ok := oldObj.(*Coherence) + if !ok { + return nil, fmt.Errorf("expected a Coherence instance for old value but got a %T", newObj) + } + + webhookLogger.Info("validate update", "name", cohNew.Name) + logger := webhookLogger.WithValues("namespace", cohNew.GetNamespace(), "name", cohNew.GetName()) var warnings admission.Warnings - dt := in.GetDeletionTimestamp() + dt := cohNew.GetDeletionTimestamp() if dt != nil { // the deletion timestamp is set so do nothing logger.Info("Skipping validation for deleted resource", "deletionTimestamp", *dt) return warnings, nil } - if err := commonWebHook.validateReplicas(in); err != nil { + if err := commonWebHook.validateReplicas(cohNew); err != nil { return warnings, err } - if err := commonWebHook.validateImages(in); err != nil { + if err := commonWebHook.validateImages(cohNew); err != nil { return warnings, err } - prev := previous.(*Coherence) - if err := commonWebHook.validatePersistence(in, prev); err != nil { + if err := commonWebHook.validatePersistence(cohNew, cohPrev); err != nil { return warnings, err } - if err := in.validateVolumeClaimTemplates(prev); err != nil { + if err := cohNew.validateVolumeClaimTemplates(cohNew, cohPrev); err != nil { return warnings, err } - if err := commonWebHook.validateNodePorts(in); err != nil { + if err := commonWebHook.validateNodePorts(cohNew); err != nil { return warnings, err } var errorList field.ErrorList - sts := in.Spec.CreateStatefulSet(in) - stsOld := prev.Spec.CreateStatefulSet(prev) + sts := cohNew.Spec.CreateStatefulSet(cohNew) + stsOld := cohPrev.Spec.CreateStatefulSet(cohPrev) errorList = ValidateStatefulSetUpdate(&sts, &stsOld) if len(errorList) > 0 { @@ -213,27 +236,27 @@ func (in *Coherence) ValidateUpdate(previous runtime.Object) (admission.Warnings // ValidateDelete implements webhook.Validator so a webhook will be registered for the type // The optional warnings will be added to the response as warning messages. // Return an error if the object is invalid. -func (in *Coherence) ValidateDelete() (admission.Warnings, error) { +func (in *Coherence) ValidateDelete(context.Context, runtime.Object) (admission.Warnings, error) { // we do not need to validate deletions return nil, nil } -func (in *Coherence) validateVolumeClaimTemplates(previous *Coherence) error { - if in.GetReplicas() == 0 || previous.GetReplicas() == 0 { +func (in *Coherence) validateVolumeClaimTemplates(cohNew, cohPrev *Coherence) error { + if cohNew.GetReplicas() == 0 || cohPrev.GetReplicas() == 0 { // changes are allowed if current or previous replicas == 0 return nil } - if len(in.Spec.VolumeClaimTemplates) == 0 && len(previous.Spec.VolumeClaimTemplates) == 0 { + if len(cohNew.Spec.VolumeClaimTemplates) == 0 && len(cohPrev.Spec.VolumeClaimTemplates) == 0 { // no PVCs in either deployment return nil } - diff := deep.Equal(previous.Spec.VolumeClaimTemplates, in.Spec.VolumeClaimTemplates) + diff := deep.Equal(cohPrev.Spec.VolumeClaimTemplates, cohNew.Spec.VolumeClaimTemplates) if len(diff) != 0 { return fmt.Errorf("the Coherence resource \"%s\" is invalid: "+ "changes cannot be made to spec.volumeclaimtemplates unless spec.replicas == 0 or the previous"+ - " instance of the resource has spec.replicas == 0", in.Name) + " instance of the resource has spec.replicas == 0", cohNew.Name) } return nil } diff --git a/api/v1/coherence_webhook_image_test.go b/api/v1/coherence_webhook_image_test.go index acd40f027..a3f7d0cb5 100644 --- a/api/v1/coherence_webhook_image_test.go +++ b/api/v1/coherence_webhook_image_test.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -7,6 +7,7 @@ package v1_test import ( + "context" . "github.com/onsi/gomega" coh "github.com/oracle/coherence-operator/api/v1" corev1 "k8s.io/api/core/v1" @@ -19,7 +20,7 @@ func TestCoherenceWithNoImageNames(t *testing.T) { g := NewGomegaWithT(t) c := coh.Coherence{} - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).NotTo(HaveOccurred()) } @@ -33,7 +34,7 @@ func TestCoherenceCreateWithValidImageName(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).NotTo(HaveOccurred()) } @@ -47,7 +48,7 @@ func TestCoherenceCreateWithInvalidImageName(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).To(HaveOccurred()) } @@ -61,7 +62,7 @@ func TestCoherenceCreateWithImageNameWithTrailingSpace(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).To(HaveOccurred()) } @@ -77,7 +78,7 @@ func TestCoherenceCreateWithValidOperatorImageName(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).NotTo(HaveOccurred()) } @@ -93,7 +94,7 @@ func TestCoherenceCreateWithInvalidOperatorImageName(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).To(HaveOccurred()) } @@ -107,7 +108,7 @@ func TestCoherenceUpdateWithInvalidImageName(t *testing.T) { }, }, } - _, err := c.ValidateUpdate(&c) + _, err := c.ValidateUpdate(context.Background(), &c, &c) g.Expect(err).To(HaveOccurred()) } @@ -126,7 +127,7 @@ func TestCoherenceCreateWithValidInitContainerImageName(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).NotTo(HaveOccurred()) } @@ -145,7 +146,7 @@ func TestCoherenceCreateWithInvalidInitContainerImageName(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).To(HaveOccurred()) } @@ -164,7 +165,7 @@ func TestCoherenceCreateWithValidSidecarImageName(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).NotTo(HaveOccurred()) } @@ -183,7 +184,7 @@ func TestCoherenceCreateWithInvalidSidecarImageName(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).To(HaveOccurred()) } @@ -191,7 +192,7 @@ func TestJobWithNoImageNames(t *testing.T) { g := NewGomegaWithT(t) c := coh.CoherenceJob{} - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).NotTo(HaveOccurred()) } @@ -205,7 +206,7 @@ func TestJobCreateWithInvalidImageName(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).To(HaveOccurred()) } @@ -219,7 +220,7 @@ func TestJobCreateWithValidImageDigest(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).NotTo(HaveOccurred()) } @@ -233,7 +234,7 @@ func TestJobCreateWithInvalidImageDigest(t *testing.T) { }, }, } - _, err := c.ValidateCreate() + _, err := c.ValidateCreate(context.Background(), &c) g.Expect(err).To(HaveOccurred()) } @@ -247,6 +248,6 @@ func TestJobUpdateWithInvalidImageName(t *testing.T) { }, }, } - _, err := c.ValidateUpdate(&c) + _, err := c.ValidateUpdate(context.Background(), &c, &c) g.Expect(err).To(HaveOccurred()) } diff --git a/api/v1/coherence_webhook_job.go b/api/v1/coherence_webhook_job.go index 9e057bfac..4b20a2bed 100644 --- a/api/v1/coherence_webhook_job.go +++ b/api/v1/coherence_webhook_job.go @@ -7,6 +7,7 @@ package v1 import ( + "context" "fmt" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" @@ -33,11 +34,16 @@ const JobMutatingWebHookPath = "/mutate-coherence-oracle-com-v1-coherencejob" // An anonymous var to ensure that the CoherenceJob struct implements webhook.Defaulter // there will be a compile time error here if this fails. -var _ webhook.Defaulter = &CoherenceJob{} +var _ webhook.CustomDefaulter = &CoherenceJob{} // Default implements webhook.Defaulter so a webhook will be registered for the type -func (in *CoherenceJob) Default() { - spec, _ := in.GetJobResourceSpec() +func (in *CoherenceJob) Default(_ context.Context, obj runtime.Object) error { + coh, ok := obj.(*CoherenceJob) + if !ok { + return fmt.Errorf("expected a CoherenceJob instance but got a %T", obj) + } + + spec, _ := coh.GetJobResourceSpec() coherenceSpec := spec.Coherence if spec.Coherence == nil { coherenceSpec = &CoherenceSpec{} @@ -66,13 +72,14 @@ func (in *CoherenceJob) Default() { spec.SetReplicas(spec.GetReplicas()) } - SetCommonDefaults(in) + SetCommonDefaults(coh) // apply a label with the hash of the spec - ths must be the last action here to make sure that // any modifications to the spec field are included in the hash - if hash, applied := EnsureJobHashLabel(in); applied { + if hash, applied := EnsureJobHashLabel(coh); applied { webhookLogger.Info(fmt.Sprintf("Applied %s label", LabelCoherenceHash), "hash", hash) } + return nil } // The path in this annotation MUST match the const below @@ -83,49 +90,62 @@ const JobValidatingWebHookPath = "/validate-coherence-oracle-com-v1-coherencejob // An anonymous var to ensure that the Coherence struct implements webhook.Validator // there will be a compile time error here if this fails. -var _ webhook.Validator = &CoherenceJob{} +var _ webhook.CustomValidator = &CoherenceJob{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type -func (in *CoherenceJob) ValidateCreate() (admission.Warnings, error) { +func (in *CoherenceJob) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) { + coh, ok := obj.(*CoherenceJob) + if !ok { + return nil, fmt.Errorf("expected a CoherenceJob instance but got a %T", obj) + } + var err error var warnings admission.Warnings - webhookLogger.Info("validate create", "name", in.Name) - if err = commonWebHook.validateReplicas(in); err != nil { + webhookLogger.Info("validate create", "name", coh.Name) + if err = commonWebHook.validateReplicas(coh); err != nil { return warnings, err } - if err = commonWebHook.validateImages(in); err != nil { + if err = commonWebHook.validateImages(coh); err != nil { return warnings, err } - if err = commonWebHook.validateNodePorts(in); err != nil { + if err = commonWebHook.validateNodePorts(coh); err != nil { return warnings, err } return warnings, nil } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (in *CoherenceJob) ValidateUpdate(previous runtime.Object) (admission.Warnings, error) { - webhookLogger.Info("validate update", "name", in.Name) +func (in *CoherenceJob) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) { + cohNew, ok := newObj.(*CoherenceJob) + if !ok { + return nil, fmt.Errorf("expected a CoherenceJob instance for new value but got a %T", newObj) + } + cohPrev, ok := oldObj.(*CoherenceJob) + if !ok { + return nil, fmt.Errorf("expected a CoherenceJob instance for old value but got a %T", newObj) + } + + webhookLogger.Info("validate update", "name", cohNew.Name) var warnings admission.Warnings - if err := commonWebHook.validateReplicas(in); err != nil { + if err := commonWebHook.validateReplicas(cohNew); err != nil { return warnings, err } - if err := commonWebHook.validateImages(in); err != nil { + if err := commonWebHook.validateImages(cohNew); err != nil { return warnings, err } - prev := previous.(*CoherenceJob) - if err := commonWebHook.validatePersistence(in, prev); err != nil { + if err := commonWebHook.validatePersistence(cohNew, cohPrev); err != nil { return warnings, err } - if err := commonWebHook.validateNodePorts(in); err != nil { + if err := commonWebHook.validateNodePorts(cohNew); err != nil { return warnings, err } var errorList field.ErrorList - job := in.Spec.CreateJob(in) - jobOld := prev.Spec.CreateJob(prev) + job := cohNew.Spec.CreateJob(cohNew) + jobOld := cohPrev.Spec.CreateJob(cohPrev) errorList = ValidateJobUpdate(&job, &jobOld) if len(errorList) > 0 { @@ -136,7 +156,7 @@ func (in *CoherenceJob) ValidateUpdate(previous runtime.Object) (admission.Warni } // ValidateDelete implements webhook.Validator so a webhook will be registered for the type -func (in *CoherenceJob) ValidateDelete() (admission.Warnings, error) { +func (in *CoherenceJob) ValidateDelete(context.Context, runtime.Object) (admission.Warnings, error) { // we do not need to validate deletions return nil, nil } diff --git a/api/v1/coherence_webhook_job_test.go b/api/v1/coherence_webhook_job_test.go index 072200180..9eb2cf582 100644 --- a/api/v1/coherence_webhook_job_test.go +++ b/api/v1/coherence_webhook_job_test.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -7,6 +7,7 @@ package v1_test import ( + "context" . "github.com/onsi/gomega" coh "github.com/oracle/coherence-operator/api/v1" "github.com/oracle/coherence-operator/pkg/operator" @@ -22,7 +23,8 @@ func TestJobDefaultReplicasIsSet(t *testing.T) { g := NewGomegaWithT(t) c := coh.CoherenceJob{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.Replicas).NotTo(BeNil()) g.Expect(*c.Spec.Replicas).To(Equal(coh.DefaultJobReplicas)) } @@ -31,7 +33,8 @@ func TestJobAddVersionAnnotation(t *testing.T) { g := NewGomegaWithT(t) c := coh.CoherenceJob{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Annotations).NotTo(BeNil()) g.Expect(c.Annotations[coh.AnnotationOperatorVersion]).To(Equal(operator.GetVersion())) g.Expect(c.Spec).NotTo(BeNil()) @@ -42,7 +45,8 @@ func TestJobAddVersionAnnotation(t *testing.T) { func TestJobShouldAddFinalizer(t *testing.T) { g := NewGomegaWithT(t) c := coh.CoherenceJob{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) finalizers := c.GetFinalizers() g.Expect(len(finalizers)).To(Equal(0)) } @@ -55,7 +59,8 @@ func TestJobShouldNotAddFinalizerAgainIfPresent(t *testing.T) { Finalizers: []string{coh.CoherenceFinalizer}, }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) finalizers := c.GetFinalizers() g.Expect(len(finalizers)).To(Equal(1)) g.Expect(finalizers).To(ContainElement(coh.CoherenceFinalizer)) @@ -69,7 +74,8 @@ func TestJobShouldNotRemoveFinalizersAlreadyPresent(t *testing.T) { Finalizers: []string{"foo", "bar"}, }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) finalizers := c.GetFinalizers() g.Expect(len(finalizers)).To(Equal(2)) g.Expect(finalizers).To(ContainElement("foo")) @@ -87,7 +93,8 @@ func TestJobDefaultReplicasIsNotOverriddenWhenAlreadySet(t *testing.T) { }, }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.Replicas).NotTo(BeNil()) g.Expect(*c.Spec.Replicas).To(Equal(replicas)) } @@ -96,7 +103,8 @@ func TestJobCoherenceLocalPortIsSet(t *testing.T) { g := NewGomegaWithT(t) c := coh.CoherenceJob{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.Coherence).NotTo(BeNil()) g.Expect(*c.Spec.Coherence.LocalPort).To(Equal(coh.DefaultUnicastPort)) } @@ -115,7 +123,8 @@ func TestJobCoherenceLocalPortIsNotOverridden(t *testing.T) { }, }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.Coherence).NotTo(BeNil()) g.Expect(*c.Spec.Coherence.LocalPort).To(Equal(port)) } @@ -125,7 +134,8 @@ func TestJobCoherenceLocalPortIsNotSetOnUpdate(t *testing.T) { c := coh.CoherenceJob{} c.Status.Phase = coh.ConditionTypeReady - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.Coherence).NotTo(BeNil()) g.Expect(c.Spec.Coherence.LocalPort).To(BeNil()) g.Expect(c.Spec.Coherence.LocalPortAdjust).To(BeNil()) @@ -136,7 +146,8 @@ func TestJobCoherenceLocalPortAdjustIsSet(t *testing.T) { lpa := intstr.FromInt32(coh.DefaultUnicastPortAdjust) c := coh.CoherenceJob{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.Coherence).NotTo(BeNil()) g.Expect(*c.Spec.CoherenceResourceSpec.Coherence.LocalPortAdjust).To(Equal(lpa)) } @@ -154,7 +165,8 @@ func TestJobCoherenceLocalPortAdjustIsNotOverridden(t *testing.T) { }, }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.Coherence).NotTo(BeNil()) g.Expect(*c.Spec.Coherence.LocalPortAdjust).To(Equal(lpa)) } @@ -164,7 +176,8 @@ func TestJobCoherenceLocalPortAdjustIsNotSetOnUpdate(t *testing.T) { c := coh.CoherenceJob{} c.Status.Phase = coh.ConditionTypeReady - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.Coherence).NotTo(BeNil()) g.Expect(c.Spec.Coherence.LocalPortAdjust).To(BeNil()) } @@ -175,7 +188,8 @@ func TestJobCoherenceImageIsSet(t *testing.T) { viper.Set(operator.FlagCoherenceImage, "foo") c := coh.CoherenceJob{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.Image).NotTo(BeNil()) g.Expect(*c.Spec.Image).To(Equal("foo")) } @@ -193,7 +207,8 @@ func TestJobCoherenceImageIsNotOverriddenWhenAlreadySet(t *testing.T) { }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.Image).NotTo(BeNil()) g.Expect(*c.Spec.Image).To(Equal(image)) } @@ -204,7 +219,8 @@ func TestJobUtilsImageIsSet(t *testing.T) { viper.Set(operator.FlagOperatorImage, "foo") c := coh.CoherenceJob{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.CoherenceUtils).NotTo(BeNil()) g.Expect(c.Spec.CoherenceUtils.Image).NotTo(BeNil()) g.Expect(*c.Spec.CoherenceUtils.Image).To(Equal("foo")) @@ -225,7 +241,8 @@ func TestJobUtilsImageIsNotOverriddenWhenAlreadySet(t *testing.T) { }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).To(BeNil()) g.Expect(c.Spec.CoherenceUtils).NotTo(BeNil()) g.Expect(c.Spec.CoherenceUtils.Image).NotTo(BeNil()) g.Expect(*c.Spec.CoherenceUtils.Image).To(Equal(image)) @@ -270,7 +287,7 @@ func TestJobPersistenceModeChangeNotAllowed(t *testing.T) { }, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).To(HaveOccurred()) } @@ -314,7 +331,7 @@ func TestJobPersistenceModeChangeAllowedIfReplicasIsZero(t *testing.T) { }, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -358,7 +375,7 @@ func TestJobPersistenceModeChangeAllowedIfPreviousReplicasIsZero(t *testing.T) { }, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -411,7 +428,7 @@ func TestJobPersistenceVolumeChangeNotAllowed(t *testing.T) { }, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).To(HaveOccurred()) } @@ -422,7 +439,7 @@ func TestJobValidateCreateReplicasWhenReplicasIsNil(t *testing.T) { Spec: coh.CoherenceJobResourceSpec{}, } - _, err := current.ValidateCreate() + _, err := current.ValidateCreate(context.Background(), current) g.Expect(err).NotTo(HaveOccurred()) } @@ -437,7 +454,7 @@ func TestJobValidateCreateReplicasWhenReplicasIsPositive(t *testing.T) { }, } - _, err := current.ValidateCreate() + _, err := current.ValidateCreate(context.Background(), current) g.Expect(err).NotTo(HaveOccurred()) } @@ -452,7 +469,7 @@ func TestJobValidateCreateReplicasWhenReplicasIsZero(t *testing.T) { }, } - _, err := current.ValidateCreate() + _, err := current.ValidateCreate(context.Background(), current) g.Expect(err).NotTo(HaveOccurred()) } @@ -468,7 +485,7 @@ func TestJobValidateCreateReplicasWhenReplicasIsInvalid(t *testing.T) { }, } - _, err := current.ValidateCreate() + _, err := current.ValidateCreate(context.Background(), current) g.Expect(err).To(HaveOccurred()) } @@ -483,7 +500,7 @@ func TestJobValidateUpdateReplicasWhenReplicasIsNil(t *testing.T) { Spec: coh.CoherenceJobResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -502,7 +519,7 @@ func TestJobValidateUpdateReplicasWhenReplicasIsPositive(t *testing.T) { Spec: coh.CoherenceJobResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -521,7 +538,7 @@ func TestJobValidateUpdateReplicasWhenReplicasIsZero(t *testing.T) { Spec: coh.CoherenceJobResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -541,7 +558,7 @@ func TestJobValidateUpdateReplicasWhenReplicasIsInvalid(t *testing.T) { Spec: coh.CoherenceJobResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), prev, current) g.Expect(err).To(HaveOccurred()) } @@ -558,7 +575,7 @@ func TestJobValidateVolumeClaimUpdateWhenVolumeClaimsNil(t *testing.T) { Spec: coh.CoherenceJobResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -585,7 +602,7 @@ func TestJobValidateNodePortsOnCreateWithValidPorts(t *testing.T) { }, } - _, err := current.ValidateCreate() + _, err := current.ValidateCreate(context.Background(), current) g.Expect(err).NotTo(HaveOccurred()) } @@ -617,7 +634,7 @@ func TestJobValidateNodePortsOnCreateWithInvalidPort(t *testing.T) { }, } - _, err := current.ValidateCreate() + _, err := current.ValidateCreate(context.Background(), current) g.Expect(err).To(HaveOccurred()) } @@ -649,7 +666,7 @@ func TestJobValidateNodePortsOnUpdateWithValidPorts(t *testing.T) { Spec: coh.CoherenceJobResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -686,6 +703,6 @@ func TestJobValidateNodePortsOnUpdateWithInvalidPort(t *testing.T) { Spec: coh.CoherenceJobResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), prev, current) g.Expect(err).To(HaveOccurred()) } diff --git a/api/v1/coherence_webhook_test.go b/api/v1/coherence_webhook_test.go index b4a9e7854..5adb1dd7d 100644 --- a/api/v1/coherence_webhook_test.go +++ b/api/v1/coherence_webhook_test.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -7,6 +7,7 @@ package v1_test import ( + "context" . "github.com/onsi/gomega" coh "github.com/oracle/coherence-operator/api/v1" "github.com/oracle/coherence-operator/pkg/operator" @@ -23,7 +24,8 @@ func TestDefaultReplicasIsSet(t *testing.T) { g := NewGomegaWithT(t) c := coh.Coherence{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.CoherenceResourceSpec.Replicas).NotTo(BeNil()) g.Expect(*c.Spec.CoherenceResourceSpec.Replicas).To(Equal(coh.DefaultReplicas)) } @@ -32,7 +34,8 @@ func TestAddVersionAnnotation(t *testing.T) { g := NewGomegaWithT(t) c := coh.Coherence{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) an := c.GetAnnotations() g.Expect(an).NotTo(BeNil()) g.Expect(an[coh.AnnotationOperatorVersion]).To(Equal(operator.GetVersion())) @@ -42,7 +45,8 @@ func TestAddVersionAnnotation(t *testing.T) { func TestShouldAddFinalizer(t *testing.T) { g := NewGomegaWithT(t) c := coh.Coherence{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) finalizers := c.GetFinalizers() g.Expect(len(finalizers)).To(Equal(1)) g.Expect(finalizers).To(ContainElement(coh.CoherenceFinalizer)) @@ -56,7 +60,8 @@ func TestShouldNotAddFinalizerAgainIfPresent(t *testing.T) { Finalizers: []string{coh.CoherenceFinalizer}, }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) finalizers := c.GetFinalizers() g.Expect(len(finalizers)).To(Equal(1)) g.Expect(finalizers).To(ContainElement(coh.CoherenceFinalizer)) @@ -70,7 +75,8 @@ func TestShouldNotRemoveFinalizersAlreadyPresent(t *testing.T) { Finalizers: []string{"foo", "bar"}, }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) finalizers := c.GetFinalizers() g.Expect(len(finalizers)).To(Equal(3)) g.Expect(finalizers).To(ContainElement("foo")) @@ -93,7 +99,8 @@ func TestNoNotAddFinalizerToDeletedResource(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{}, } - c.Default() + err := c.Default(context.Background(), c) + g.Expect(err).NotTo(HaveOccurred()) finalizers := c.GetFinalizers() g.Expect(finalizers).To(BeNil()) } @@ -109,7 +116,8 @@ func TestDefaultReplicasIsNotOverriddenWhenAlreadySet(t *testing.T) { }, }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.Replicas).NotTo(BeNil()) g.Expect(*c.Spec.Replicas).To(Equal(replicas)) } @@ -118,7 +126,8 @@ func TestCoherenceLocalPortIsSet(t *testing.T) { g := NewGomegaWithT(t) c := coh.Coherence{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.Coherence).NotTo(BeNil()) g.Expect(*c.Spec.Coherence.LocalPort).To(Equal(coh.DefaultUnicastPort)) } @@ -137,7 +146,8 @@ func TestCoherenceLocalPortIsNotOverridden(t *testing.T) { }, }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.Coherence).NotTo(BeNil()) g.Expect(*c.Spec.Coherence.LocalPort).To(Equal(port)) } @@ -147,7 +157,8 @@ func TestCoherenceLocalPortIsNotSetOnUpdate(t *testing.T) { c := coh.Coherence{} c.Status.Phase = coh.ConditionTypeReady - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.Coherence).To(BeNil()) } @@ -156,7 +167,8 @@ func TestCoherenceLocalPortAdjustIsSet(t *testing.T) { lpa := intstr.FromInt32(coh.DefaultUnicastPortAdjust) c := coh.Coherence{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.Coherence).NotTo(BeNil()) g.Expect(*c.Spec.Coherence.LocalPortAdjust).To(Equal(lpa)) } @@ -174,7 +186,8 @@ func TestCoherenceLocalPortAdjustIsNotOverridden(t *testing.T) { }, }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.Coherence).NotTo(BeNil()) g.Expect(*c.Spec.Coherence.LocalPortAdjust).To(Equal(lpa)) } @@ -184,7 +197,8 @@ func TestCoherenceLocalPortAdjustIsNotSetOnUpdate(t *testing.T) { c := coh.Coherence{} c.Status.Phase = coh.ConditionTypeReady - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.Coherence).To(BeNil()) } @@ -194,7 +208,8 @@ func TestCoherenceImageIsSet(t *testing.T) { viper.Set(operator.FlagCoherenceImage, "foo") c := coh.Coherence{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.Image).NotTo(BeNil()) g.Expect(*c.Spec.Image).To(Equal("foo")) } @@ -212,7 +227,8 @@ func TestCoherenceImageIsNotOverriddenWhenAlreadySet(t *testing.T) { }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.Image).NotTo(BeNil()) g.Expect(*c.Spec.Image).To(Equal(image)) } @@ -223,7 +239,8 @@ func TestUtilsImageIsSet(t *testing.T) { viper.Set(operator.FlagOperatorImage, "foo") c := coh.Coherence{} - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.CoherenceUtils).NotTo(BeNil()) g.Expect(c.Spec.CoherenceUtils.Image).NotTo(BeNil()) g.Expect(*c.Spec.CoherenceUtils.Image).To(Equal("foo")) @@ -244,7 +261,8 @@ func TestUtilsImageIsNotOverriddenWhenAlreadySet(t *testing.T) { }, } - c.Default() + err := c.Default(context.Background(), &c) + g.Expect(err).NotTo(HaveOccurred()) g.Expect(c.Spec.CoherenceUtils).NotTo(BeNil()) g.Expect(c.Spec.CoherenceUtils.Image).NotTo(BeNil()) g.Expect(*c.Spec.CoherenceUtils.Image).To(Equal(image)) @@ -289,7 +307,7 @@ func TestPersistenceModeChangeNotAllowed(t *testing.T) { }, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).To(HaveOccurred()) } @@ -333,7 +351,7 @@ func TestPersistenceModeChangeAllowedIfReplicasIsZero(t *testing.T) { }, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -377,7 +395,7 @@ func TestPersistenceModeChangeAllowedIfPreviousReplicasIsZero(t *testing.T) { }, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -430,7 +448,7 @@ func TestPersistenceVolumeChangeNotAllowed(t *testing.T) { }, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).To(HaveOccurred()) } @@ -441,7 +459,7 @@ func TestValidateCreateReplicasWhenReplicasIsNil(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{}, } - _, err := current.ValidateCreate() + _, err := current.ValidateUpdate(context.Background(), current, current) g.Expect(err).NotTo(HaveOccurred()) } @@ -456,7 +474,7 @@ func TestValidateCreateReplicasWhenReplicasIsPositive(t *testing.T) { }, } - _, err := current.ValidateCreate() + _, err := current.ValidateUpdate(context.Background(), current, current) g.Expect(err).NotTo(HaveOccurred()) } @@ -471,7 +489,7 @@ func TestValidateCreateReplicasWhenReplicasIsZero(t *testing.T) { }, } - _, err := current.ValidateCreate() + _, err := current.ValidateUpdate(context.Background(), current, current) g.Expect(err).NotTo(HaveOccurred()) } @@ -487,7 +505,7 @@ func TestValidateCreateReplicasWhenReplicasIsInvalid(t *testing.T) { }, } - _, err := current.ValidateCreate() + _, err := current.ValidateUpdate(context.Background(), current, current) g.Expect(err).To(HaveOccurred()) } @@ -502,7 +520,7 @@ func TestValidateUpdateReplicasWhenReplicasIsNil(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -521,7 +539,7 @@ func TestValidateUpdateReplicasWhenReplicasIsPositive(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -540,7 +558,7 @@ func TestValidateUpdateReplicasWhenReplicasIsZero(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -560,7 +578,7 @@ func TestValidateUpdateReplicasWhenReplicasIsInvalid(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).To(HaveOccurred()) } @@ -577,7 +595,7 @@ func TestValidateVolumeClaimUpdateWhenVolumeClaimsNil(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -596,7 +614,7 @@ func TestValidateVolumeClaimUpdateWhenVolumeClaimsNilAndEmpty(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -620,7 +638,7 @@ func TestValidateVolumeClaimUpdateWhenVolumeClaimsAdded(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).To(HaveOccurred()) } @@ -644,7 +662,7 @@ func TestValidateVolumeClaimUpdateWhenVolumeClaimsRemoved(t *testing.T) { }, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).To(HaveOccurred()) } @@ -671,7 +689,7 @@ func TestValidateNodePortsOnCreateWithValidPorts(t *testing.T) { }, } - _, err := current.ValidateCreate() + _, err := current.ValidateUpdate(context.Background(), current, current) g.Expect(err).NotTo(HaveOccurred()) } @@ -703,7 +721,7 @@ func TestValidateNodePortsOnCreateWithInvalidPort(t *testing.T) { }, } - _, err := current.ValidateCreate() + _, err := current.ValidateUpdate(context.Background(), current, current) g.Expect(err).To(HaveOccurred()) } @@ -735,7 +753,7 @@ func TestValidateNodePortsOnUpdateWithValidPorts(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), current, prev) g.Expect(err).NotTo(HaveOccurred()) } @@ -772,6 +790,6 @@ func TestValidateNodePortsOnUpdateWithInvalidPort(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{}, } - _, err := current.ValidateUpdate(prev) + _, err := current.ValidateUpdate(context.Background(), prev, current) g.Expect(err).To(HaveOccurred()) } diff --git a/config/components/no-coherencejob/kustomization.yaml b/config/components/no-coherencejob/kustomization.yaml new file mode 100644 index 000000000..d7ef0d0fd --- /dev/null +++ b/config/components/no-coherencejob/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +patches: + - path: no-jobs-patch.yaml + target: + kind: Deployment + name: controller-manager diff --git a/config/manager/no-jobs-patch.yaml b/config/components/no-coherencejob/no-jobs-patch.yaml similarity index 100% rename from config/manager/no-jobs-patch.yaml rename to config/components/no-coherencejob/no-jobs-patch.yaml diff --git a/config/components/pull-secrets/kustomization.yaml b/config/components/pull-secrets/kustomization.yaml new file mode 100644 index 000000000..acff1eda0 --- /dev/null +++ b/config/components/pull-secrets/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +patches: + - path: pull-secrets-patch.yaml + target: + kind: ServiceAccount + name: service-account diff --git a/config/components/pull-secrets/pull-secrets-patch.yaml b/config/components/pull-secrets/pull-secrets-patch.yaml new file mode 100644 index 000000000..6b7689155 --- /dev/null +++ b/config/components/pull-secrets/pull-secrets-patch.yaml @@ -0,0 +1,4 @@ +- op: add + path: /imagePullSecrets/- + value: + name: coherence-operator-pull-secret diff --git a/config/overlays/restricted/cluster_role.yaml b/config/components/restricted/cluster_role.yaml similarity index 100% rename from config/overlays/restricted/cluster_role.yaml rename to config/components/restricted/cluster_role.yaml diff --git a/config/overlays/restricted/cluster_role_binding.yaml b/config/components/restricted/cluster_role_binding.yaml similarity index 100% rename from config/overlays/restricted/cluster_role_binding.yaml rename to config/components/restricted/cluster_role_binding.yaml diff --git a/config/components/restricted/kustomization.yaml b/config/components/restricted/kustomization.yaml new file mode 100644 index 000000000..999a0ece4 --- /dev/null +++ b/config/components/restricted/kustomization.yaml @@ -0,0 +1,12 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component + +patches: + - path: single-namespace-patch.yaml + target: + kind: Deployment + name: controller-manager + - path: node-viewer-role.yaml + - path: node_viewer_role_binding.yaml + - path: cluster_role.yaml + - path: cluster_role_binding.yaml diff --git a/config/overlays/restricted/node-viewer-role.yaml b/config/components/restricted/node-viewer-role.yaml similarity index 54% rename from config/overlays/restricted/node-viewer-role.yaml rename to config/components/restricted/node-viewer-role.yaml index 4dfb96767..9e842be43 100644 --- a/config/overlays/restricted/node-viewer-role.yaml +++ b/config/components/restricted/node-viewer-role.yaml @@ -1,3 +1,7 @@ +# +# This patch will remove the ClusterRole to allow the +# Operator to read Node labels. +# apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/config/overlays/restricted/node_viewer_role_binding.yaml b/config/components/restricted/node_viewer_role_binding.yaml similarity index 55% rename from config/overlays/restricted/node_viewer_role_binding.yaml rename to config/components/restricted/node_viewer_role_binding.yaml index 9e035b494..8807fb0b2 100644 --- a/config/overlays/restricted/node_viewer_role_binding.yaml +++ b/config/components/restricted/node_viewer_role_binding.yaml @@ -1,3 +1,7 @@ +# +# This patch will remove the ClusterRoleBinding to allow the +# Operator to read Node labels. +# apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: diff --git a/config/overlays/restricted/single-namespace-patch.yaml b/config/components/restricted/single-namespace-patch.yaml similarity index 79% rename from config/overlays/restricted/single-namespace-patch.yaml rename to config/components/restricted/single-namespace-patch.yaml index 9d58ad9a9..3a95dab28 100644 --- a/config/overlays/restricted/single-namespace-patch.yaml +++ b/config/components/restricted/single-namespace-patch.yaml @@ -1,3 +1,7 @@ +# +# This patch will configure the Operator to only manage the +# single namespace that it is installed into. +# - op: add path: /spec/template/spec/containers/0/env/- value: diff --git a/config/manager/single-replica-patch.yaml b/config/components/single-replica/single-replica-patch.yaml similarity index 100% rename from config/manager/single-replica-patch.yaml rename to config/components/single-replica/single-replica-patch.yaml diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 1b75c7dab..a891693f1 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -22,7 +22,7 @@ resources: configurations: - kustomizeconfig.yaml -patchesJson6902: +patches: - path: patches/coherence.oracle.com_coherence_crd_patch.json target: group: apiextensions.k8s.io @@ -36,9 +36,12 @@ patchesJson6902: name: coherencejob.coherence.oracle.com version: v1 +labels: +- pairs: + app.kubernetes.io/component: crd + app.kubernetes.io/instance: coherence-operator-crd + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/part-of: coherence-operator + commonLabels: - app.kubernetes.io/component: crd - app.kubernetes.io/instance: coherence-operator-crd - app.kubernetes.io/name: coherence-operator - app.kubernetes.io/part-of: coherence-operator app.kubernetes.io/version: 3.4.3 diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 3856433bb..3e5ae26db 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -8,27 +8,54 @@ namespace: default # e.g. a Deployment named "manager" becomes "coherence-operator-manager". namePrefix: "coherence-operator-" -configurations: - - config.yaml +resources: + - ../crd-small + - ../rbac + - ../manager +# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. +#- ../prometheus +# [METRICS] Expose the controller manager metrics service. + - metrics_service.yaml +# [NETWORK POLICY] Protect the /metrics endpoint and Webhook Server with NetworkPolicy. +# Only Pod(s) running a namespace labeled with 'metrics: enabled' will be able to gather the metrics. +# Only CR(s) which requires webhooks and are applied on namespaces labeled with 'webhooks: enabled' will +# be able to communicate with the Webhook Server. +#- ../network-policy -bases: -- ../rbac -- ../manager +labels: + - pairs: + control-plane: coherence + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator -# the following config is for teaching kustomize how to do var substitution -vars: - - name: REST_SERVICE_NAME - objref: +# Patch the SERVICE_NAME env var in the Operator Deployment +# with the name of the Operator REST service. +replacements: + - source: kind: Service - version: v1 name: rest - - name: WEBHOOK_SERVICE_NAME - objref: + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.0.env.[name=SERVICE_NAME].value + - source: kind: Service - version: v1 name: webhook - - name: WEBHOOK_SECRET_NAME - objref: + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.0.env.[name=WEBHOOK_SERVICE].value + - source: kind: Secret - version: v1 name: coherence-webhook-server-cert + targets: + - select: + kind: Deployment + name: controller-manager + fieldPaths: + - spec.template.spec.containers.0.env.[name=WEBHOOK_SECRET].value diff --git a/config/default/manager_metrics_patch.yaml b/config/default/manager_metrics_patch.yaml new file mode 100644 index 000000000..2aaef6536 --- /dev/null +++ b/config/default/manager_metrics_patch.yaml @@ -0,0 +1,4 @@ +# This patch adds the args to allow exposing the metrics endpoint using HTTPS +- op: add + path: /spec/template/spec/containers/0/args/0 + value: --metrics-bind-address=:8443 diff --git a/config/default/metrics_service.yaml b/config/default/metrics_service.yaml new file mode 100644 index 000000000..e8ffc2b81 --- /dev/null +++ b/config/default/metrics_service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + control-plane: controller-manager diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 24f912f3d..a1c9e267a 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -3,10 +3,10 @@ kind: Kustomization resources: - webhook-secret.yaml -- manager.yaml - service.yaml +- manager.yaml images: - name: controller - newName: ghcr.io/oracle/coherence-operator + newName: ghcr.io/thegridman/coherence-operator newTag: 3.4.3 diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 0e97ee782..7a931d6f1 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -4,12 +4,13 @@ metadata: name: controller-manager namespace: default labels: + app: coherence-operator control-plane: coherence + version: "3.4.3" app.kubernetes.io/name: coherence-operator - app: coherence-operator + app.kubernetes.io/managed-by: kustomize app.kubernetes.io/instance: coherence-operator-manager app.kubernetes.io/version: "3.4.3" - version: "3.4.3" app.kubernetes.io/component: manager app.kubernetes.io/part-of: coherence-operator spec: @@ -20,14 +21,16 @@ spec: template: metadata: labels: + app: coherence-operator control-plane: coherence + version: "3.4.3" app.kubernetes.io/name: coherence-operator - app: coherence-operator + app.kubernetes.io/managed-by: kustomize app.kubernetes.io/instance: coherence-operator-manager app.kubernetes.io/version: "3.4.3" - version: "3.4.3" app.kubernetes.io/component: manager app.kubernetes.io/part-of: coherence-operator + app.kubernetes.io/created-by: controller-manager annotations: alpha.image.policy.openshift.io/resolve-names: '*' spec: @@ -58,6 +61,7 @@ spec: args: - operator - --enable-leader-election + - --install-crd=false envFrom: - configMapRef: name: env-vars @@ -72,11 +76,11 @@ spec: fieldRef: fieldPath: metadata.name - name: WEBHOOK_SERVICE - value: $(WEBHOOK_SERVICE_NAME) + value: WEBHOOK_SERVICE_NAME - name: WEBHOOK_SECRET - value: $(WEBHOOK_SECRET_NAME) + value: WEBHOOK_SECRET_NAME - name: SERVICE_NAME - value: $(REST_SERVICE_NAME) + value: REST_SERVICE_NAME - name: CERT_TYPE value: "self-signed" volumeMounts: @@ -97,6 +101,13 @@ spec: initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 3 + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/config/manager/service.yaml b/config/manager/service.yaml index a06e574ea..d81c7af2a 100644 --- a/config/manager/service.yaml +++ b/config/manager/service.yaml @@ -4,8 +4,8 @@ metadata: name: webhook namespace: default labels: - control-plane: coherence app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize app.kubernetes.io/instance: coherence-operator-webhook app.kubernetes.io/version: "3.4.3" app.kubernetes.io/component: webhook @@ -16,6 +16,7 @@ spec: port: 443 targetPort: webhook-server selector: + control-plane: coherence app.kubernetes.io/name: coherence-operator app.kubernetes.io/instance: coherence-operator-manager app.kubernetes.io/version: "3.4.3" @@ -39,6 +40,7 @@ spec: port: 8000 targetPort: operator selector: + control-plane: coherence app.kubernetes.io/name: coherence-operator app.kubernetes.io/instance: coherence-operator-manager app.kubernetes.io/version: "3.4.3" diff --git a/config/manager/webhook-secret.yaml b/config/manager/webhook-secret.yaml index df6957c84..2ad9542df 100644 --- a/config/manager/webhook-secret.yaml +++ b/config/manager/webhook-secret.yaml @@ -9,3 +9,7 @@ metadata: namespace: coherence labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator diff --git a/config/manifests/bases/coherence-operator.clusterserviceversion.yaml b/config/manifests/bases/coherence-operator.clusterserviceversion.yaml index a5ed7bcfe..b1f6085fb 100644 --- a/config/manifests/bases/coherence-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/coherence-operator.clusterserviceversion.yaml @@ -31,16 +31,19 @@ spec: apiservicedefinitions: {} customresourcedefinitions: owned: - - description: Coherence is the Schema for the Coherence Cluster API. - displayName: Coherence - kind: Coherence - name: coherence.coherence.oracle.com - version: v1 - - description: CoherenceJob is the Schema for the Coherence Job API. - displayName: CoherenceJob - kind: CoherenceJob - name: coherencejob.coherence.oracle.com - version: v1 + - description: Coherence is the top level schema for the Coherence API and custom + resource definition (CRD). + displayName: Coherence + kind: Coherence + name: coherence.coherence.oracle.com + version: v1 + - description: |- + CoherenceJob is the top level schema for the CoherenceJob API and custom resource definition (CRD) + for configuring Coherence Job workloads. + displayName: Coherence Job + kind: CoherenceJob + name: coherencejob.coherence.oracle.com + version: v1 description: | The Oracle Coherence Kubernetes Operator enables easy management of Coherence clusters in a Kubernetes environment. @@ -50,29 +53,32 @@ spec: [Coherence Operator Documentation](https://oracle.github.io/coherence-operator/docs/latest/#/about/01_overview). displayName: Coherence Kubernetes Operator icon: - - base64data: iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IArs4c6QAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAIK2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICAgICAgICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjYwMDwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+NjU1MzU8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjExMjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDx4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+eG1wLmRpZDpkNDMwYzI2Yi05YTNhLTQzN2ItYWZlMy02NWRjYjgyZTY1NTc8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkhpc3Rvcnk+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMjAtMDUtMjlUMDc6NTI6MjUtMDQ6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6ZDQzMGMyNmItOWEzYS00MzdiLWFmZTMtNjVkY2I4MmU2NTU3PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNyZWF0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8eG1wTU06SW5zdGFuY2VJRD54bXAuaWlkOmQ0MzBjMjZiLTlhM2EtNDM3Yi1hZmUzLTY1ZGNiODJlNjU1NzwveG1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDpkNDMwYzI2Yi05YTNhLTQzN2ItYWZlMy02NWRjYjgyZTY1NTc8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXA6Q3JlYXRlRGF0ZT4yMDIwLTA1LTI5VDA3OjUyOjI1LTA0OjAwPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAyMC0wNi0wM1QwNDoyNzoyMC0wNDowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMjAtMDYtMDNUMDQ6Mjc6MjAtMDQ6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChNYWNpbnRvc2gpPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgoVhnKPAAAMyklEQVR4Ae1dW3LbOBa9kGRXzVerVzDyCsb5nYo78graWcHYK0i8AscrsHsFdlZg9wrMHqXmN95BNDvQfPVUJAp9DkjYlE2RIAmCTJVUZfMB4AK4h7gvAKTI7rfjwI4DOw7sOLDjQD0OqHrFui/1p0wnw0F8obScoDXjpEX6UWv1277MbrtvYb0W/HCAaJmOV7L+KEp/QJdTIF52Xj+KlvM9+RK9TOn79Q8FyEqOTtZKrtDoiSNj71d6eP43ieaO+TvP9kMA8l3+eajU8ArcmtbimFaXIxlcK4kWtcoHLNRrQCieloP4CnritClPtMgcYuyy7/qlt4B8l6OPSskFgNiiJ2pDFInWl33VL70DZClvp1qpGzRsUpvlDgW1ktt4Pbzsm37pDSA0Y0cqvgEvpw789JVlITCT9+Tfn3wRbEqnc0CMGQt/AvL9Y9PO1C1P/TKAmTyS2X1dGr7KdQoI9MQp9AStJ996oi5/Iq3j8335z2NdAk3LdQII9YQYINRh0w6wPPUBLLEJTqf4a/5Tcj2CfunCTA4KSKonOCJOmnPNUIjg+J1Zxex5xC10YiZfe2qrE5kggLiFO5zaazIVyfxMXTSZG/9Yl9L6LJSZ3DogfGohni5Q0aQxd0ScraK2R6OHvuSSaA2QRE8oPqXT3Jor3qSe2FsPz6vKde9+TcthGO+A+Ax3pJh58aw9e/7UL7DG/If5vQKylF8+FYfF3YcFZbfv2JN/n8d/mN8bIN/V0TcQm7izvCBny2KhcfT4ZdPRXl/e/uAl7brXnsDg/MUBO1dVV1RpNx2/PT07hu/y3ozEKoXz8ir9Lu92nXveAKlT+XMZDn19DCa9tz7Fc1p7ZwyV7OvZATzLS9SyaK8md8pdA0LleLanv7wJZefnsYYjEiPzDS25vPSQ97oDhOEJiKc2LJU6DOTI3F/PzjhSUT6qQ8NHmS4AYbjjYG89q+xT+OhwGQ2OVOoXjlzkDS7GggGSmLFGTxyH1BNlAGxL58jlCE71y7Zs3u+HAIThjksqzy71RB3O0dJL9csByt/XoVG1TKuAUEnyKfNlo1ftnK/8HNG0AKlfvJjJBQ1rCxBO9LyhkmzTnyjoVytJHOEc6QyboIJW9ItXQPj0JGbs7LjLWbdW0MgQhX4xFqLAUszc7tcp41iMFfWrVe23hmEYE8Nrv6pdDTsO7DgAKdjgZ2blZDVp05xNpmRXhyKDqQz0TwjJ45w/DfGYu0higcRHk0Nh+nWt/qtFz/dkeN+2gcHF4E2XEtUCZGNewWPomUwkyEOJwXx5B+ZP0cAJ73v4IW4Wt2psLNXRAwybSZM1XqOqHeUc+UrFV2AWnlA/vxSEE6X0v0TiQ0MVPfP8G2MF/QPa/bNnuhvk+ADB/7pbyhFN/8prvJwBeV5LZUXGRjtqXRggzC6o+DQhUGvAVql7zH5YEcuRvpSYi/V+BRFEFDSWlX6JqhAsyDvFA/AVE3eV1gKU+iFkGobinSj1sEVmF7QpP8kwYnB0hbW83zBJdJqfq/27K7V6SFdOTlHbCftoVsl4rJr9g0T5xjl9F7KFgJAImPbVNNaFmkMeY7eTZkdreVcymrOZVMC5D1iyBcKhJ5WyQFzKFae52f+ikoWApEN5XESgShqfPspxj4q6SvXgv1zbSLPOt9CQRSbViLrnJm0lIzwI23/OOmQ7CbeUVAfduOUuzgV9P0fn5qJg3q7V//Jy64H+O8TFxKYhpPMZcahbe60EO3btReZI2pnL4KdBADFmsorv6vTOMAgOhKzlD1hgjxsxsjyO2krW9iT/SH8BD8njK7GF9bz5JcLcDQKIsWQqbDkwIGj5LYYzZ0RMEeMb8GmkR8fpFut3IGOsrP3UyrKmOO+HcCptN4IAkvgXEDIlPwJBp2ov0MaZ1HP/BANj45eIVzOijf5cSXz1p56+sfpnI7Pni0Kl7q+u3BDHBnmCsYeVH01DDxtE61683kQ05lsj6pKrUi4QIOVNUlp9bjvWVN4Km+P1A5Q1EGyuNo6hAFmUNZ5WUVmegOn3r+rSCkZF+79QgERlXaFH69tLLqtzWzpiUJcUoZn0iG+CyFy3dhoGEMSIXHoAR/Smq9m3JUI5CBFpRmzZ1mSJKRY1YG2AWQcc6LUcQQAxATvX+WelL5bq7Vdj6big6CGPiTM9h3IYFOQ+SGG7N/weD3WVkQgCiOkcVipyWVBZg5J0KFUG+gZHN/QH3Mq450qivHhjRLoGQIky5m2GwjRzHvQ0GCDsFZcFuYMCHxp6hRFhihFfIyaJGqweCDijvQko62iD666jeaOQn4uggLDJdkHzC6VZ1pupGTEmWnr00T7ZZYWy6YyycrSthNPB1qxVh7w2IpWLrDH7iZjXOdcdZ8uGPA8OCDtnZHOy4OwMc+OPrh2Grz9hGNvML0CclYWySZf6gQBysmio4oeRjFCfrVM/JtdJm7jCkmuuXNvTRr5OALEd4YJm7g2hJZOKsoVNKzmOKc7IZIqzPHOZIo5/BJCxNNC7x7lZ6MAYFmYHj3nsjzOa9DhILKuEuWIsmbWc4Uk+B/NOEPv68CxWykpjIYSSKUDBCzHV55UMbhlz4iueaLou9dtjEzDUWGUIOclfCkJkLnr2r9MR8pIXZFTdUUNxBivggkYArTOFty+QvtEPLyvq8XWvAMnyiaOGBgBXz0PRkrlRNr3onOJMYEXRn6E4q2MEFNFvM623gNhOP4+a2TF3XkHeXLtbaOoQ4uyGRgA98TZ8GttOX8feA8Knm8qZR1pJsta/UzdgFLwHE+4dGTGG/uCCDa8+jWPdlbL1HhBjIVH8wFIiEFYncN6Em2gg0n6m7/Bsypb2f5qIM1pnxStASim1kKG3gJglM3AEMX16S4fNHHMYkIq0a2s+U6Qhm4v5DOtsmGsy51QT7FbvALEhEuMzpH4DHbbUVC1kDA0BetkYORw1LoYAHEZxcjALK/aY2CtAkpfXUDxhuScZ2yCEkZjPM+MAgl9REc8wUi6K0kOm9cIxtB3WsrpXGsEMGT7ae02PSZxKIjPylOJSpHEOzZOce53c6hUg6dyDNzCyHCUwWk8PGOGFr36YTevTea9EFgOBnLXLi035YJrRQ3rwuw9abdHoFSDo5IJ/WOY5pxNnFbyvzhugk++ObJCsMkezUbCFi56JrBlMXLk1oQ44cRAt4+/6iK/SuyY4DJW7WFuWTwTVYTfWgu+At2W6PvYKkG3MoCiDf8Ew+hx64A0/YcG8fCnm/6GkR7I+fSqr9D9wPkZ4ZaIknpj7uMj/8RNJa7z3dzbPTw9/tzkgav0rQtyR9aB9dIGjgEs3R9hQytB5shIFGwjAaM7wIcx+ynpw/nm0xXJC3q0/4DNnqB7W3HWVEbeVIBLMQyPNd5c1B4QWi5KHqlu3ijrHtHQd7ZznXBO11DH0SxzFsr+AGDL3Y2y+GUk8Zp7yH2YJlYoUVtH7XDtMUerz8xoeAElYwZA3oqonS/2L988/pE/x9RPTtRzY85U+wnsT881YboemgfA0ereKLkvN/Uj9hGAlRedJ0Wh0p5jkLKQFE5SO1ElVohQJTbYGV60vZH4aHOkWhota9WLq+OkBySFQaPYiHlTLZgfKE5iSd5zv/hHmIHL4knuLZvOS+yMxM5mbofzmwi6q2Ja1cISwEGfdGnu2iMB29fmHbR2vcp9hesS7KJ6mVcq9yuvwkoVSQMycgRre8al/VUG1G3wD6SV9imrFustN8eTtK3FKbs2atJLulALC8kZuevssEd/R2/+vcNKMRWieosnRitvKaWyVc//OlRMgtqrUsrjB9dTea3Ds5Vc4fZqxDMlU/RJcJUAs82t8AtUWfX2EXO3DVzizZuzrRla9U18K1ALENi+ZUCr6SLDNWXzU3ByT6Jfb4pz+UzNm7AdQbyyeOL/PybG6LW0ECCv1qfhALsISz8siO71uR/PK9XGkNwbEdtSbaQiClL11vqZj21J29NlW1LXxYbKyusvSvQFiK6LzhNjWBQhP7L2ax0rWiUsdPq1FilkuV/U9mr0DQsb4lMvsuI8wjE8ztk1/qhVA7NPq13IRzIlXf0ObmXXEXErjaAM7FSDi0CogFpgumNKHh8H2v8oxCCC2QdQv8H4ZE/JhXuaGYfooLm3/XY5BAWGDMgy7cGlgUR7ql1gPnz5/4dHL9m5QFPUjm1YYfs9m9HXOyabMJyCi+nT1I62c7Bt6zCIITM3Wp5mY3Pz8UVdfdAg+Ql4yq8ZTzahxoTdcU39EIZ3Sl3yw150DYhviZJZWtHJcjAmKva7CNrbv2WNvAGGjqF+2zD808oa3GhM9CWxmAenlOUMbZrsz9oeYp9xDKxOwn14wc0ex5oHsjsSOAzsO7Diw48COA73hwF/JV5eOHd1hjQAAAABJRU5ErkJggg== - mediatype: image/png + - base64data: iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAAXNSR0IArs4c6QAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAIK2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICAgICAgICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjYwMDwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+NjU1MzU8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjExMjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2UvcG5nPC9kYzpmb3JtYXQ+CiAgICAgICAgIDx4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+eG1wLmRpZDpkNDMwYzI2Yi05YTNhLTQzN2ItYWZlMy02NWRjYjgyZTY1NTc8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkhpc3Rvcnk+CiAgICAgICAgICAgIDxyZGY6U2VxPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDp3aGVuPjIwMjAtMDUtMjlUMDc6NTI6MjUtMDQ6MDA8L3N0RXZ0OndoZW4+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6ZDQzMGMyNmItOWEzYS00MzdiLWFmZTMtNjVkY2I4MmU2NTU3PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNyZWF0ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgIDwvcmRmOlNlcT4KICAgICAgICAgPC94bXBNTTpIaXN0b3J5PgogICAgICAgICA8eG1wTU06SW5zdGFuY2VJRD54bXAuaWlkOmQ0MzBjMjZiLTlhM2EtNDM3Yi1hZmUzLTY1ZGNiODJlNjU1NzwveG1wTU06SW5zdGFuY2VJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+eG1wLmRpZDpkNDMwYzI2Yi05YTNhLTQzN2ItYWZlMy02NWRjYjgyZTY1NTc8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXA6Q3JlYXRlRGF0ZT4yMDIwLTA1LTI5VDA3OjUyOjI1LTA0OjAwPC94bXA6Q3JlYXRlRGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAyMC0wNi0wM1QwNDoyNzoyMC0wNDowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHhtcDpNb2RpZnlEYXRlPjIwMjAtMDYtMDNUMDQ6Mjc6MjAtMDQ6MDA8L3htcDpNb2RpZnlEYXRlPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE1IChNYWNpbnRvc2gpPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgICAgIDxwaG90b3Nob3A6Q29sb3JNb2RlPjM8L3Bob3Rvc2hvcDpDb2xvck1vZGU+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgoVhnKPAAAMyklEQVR4Ae1dW3LbOBa9kGRXzVerVzDyCsb5nYo78graWcHYK0i8AscrsHsFdlZg9wrMHqXmN95BNDvQfPVUJAp9DkjYlE2RIAmCTJVUZfMB4AK4h7gvAKTI7rfjwI4DOw7sOLDjQD0OqHrFui/1p0wnw0F8obScoDXjpEX6UWv1277MbrtvYb0W/HCAaJmOV7L+KEp/QJdTIF52Xj+KlvM9+RK9TOn79Q8FyEqOTtZKrtDoiSNj71d6eP43ieaO+TvP9kMA8l3+eajU8ArcmtbimFaXIxlcK4kWtcoHLNRrQCieloP4CnritClPtMgcYuyy7/qlt4B8l6OPSskFgNiiJ2pDFInWl33VL70DZClvp1qpGzRsUpvlDgW1ktt4Pbzsm37pDSA0Y0cqvgEvpw789JVlITCT9+Tfn3wRbEqnc0CMGQt/AvL9Y9PO1C1P/TKAmTyS2X1dGr7KdQoI9MQp9AStJ996oi5/Iq3j8335z2NdAk3LdQII9YQYINRh0w6wPPUBLLEJTqf4a/5Tcj2CfunCTA4KSKonOCJOmnPNUIjg+J1Zxex5xC10YiZfe2qrE5kggLiFO5zaazIVyfxMXTSZG/9Yl9L6LJSZ3DogfGohni5Q0aQxd0ScraK2R6OHvuSSaA2QRE8oPqXT3Jor3qSe2FsPz6vKde9+TcthGO+A+Ax3pJh58aw9e/7UL7DG/If5vQKylF8+FYfF3YcFZbfv2JN/n8d/mN8bIN/V0TcQm7izvCBny2KhcfT4ZdPRXl/e/uAl7brXnsDg/MUBO1dVV1RpNx2/PT07hu/y3ozEKoXz8ir9Lu92nXveAKlT+XMZDn19DCa9tz7Fc1p7ZwyV7OvZATzLS9SyaK8md8pdA0LleLanv7wJZefnsYYjEiPzDS25vPSQ97oDhOEJiKc2LJU6DOTI3F/PzjhSUT6qQ8NHmS4AYbjjYG89q+xT+OhwGQ2OVOoXjlzkDS7GggGSmLFGTxyH1BNlAGxL58jlCE71y7Zs3u+HAIThjksqzy71RB3O0dJL9csByt/XoVG1TKuAUEnyKfNlo1ftnK/8HNG0AKlfvJjJBQ1rCxBO9LyhkmzTnyjoVytJHOEc6QyboIJW9ItXQPj0JGbs7LjLWbdW0MgQhX4xFqLAUszc7tcp41iMFfWrVe23hmEYE8Nrv6pdDTsO7DgAKdjgZ2blZDVp05xNpmRXhyKDqQz0TwjJ45w/DfGYu0higcRHk0Nh+nWt/qtFz/dkeN+2gcHF4E2XEtUCZGNewWPomUwkyEOJwXx5B+ZP0cAJ73v4IW4Wt2psLNXRAwybSZM1XqOqHeUc+UrFV2AWnlA/vxSEE6X0v0TiQ0MVPfP8G2MF/QPa/bNnuhvk+ADB/7pbyhFN/8prvJwBeV5LZUXGRjtqXRggzC6o+DQhUGvAVql7zH5YEcuRvpSYi/V+BRFEFDSWlX6JqhAsyDvFA/AVE3eV1gKU+iFkGobinSj1sEVmF7QpP8kwYnB0hbW83zBJdJqfq/27K7V6SFdOTlHbCftoVsl4rJr9g0T5xjl9F7KFgJAImPbVNNaFmkMeY7eTZkdreVcymrOZVMC5D1iyBcKhJ5WyQFzKFae52f+ikoWApEN5XESgShqfPspxj4q6SvXgv1zbSLPOt9CQRSbViLrnJm0lIzwI23/OOmQ7CbeUVAfduOUuzgV9P0fn5qJg3q7V//Jy64H+O8TFxKYhpPMZcahbe60EO3btReZI2pnL4KdBADFmsorv6vTOMAgOhKzlD1hgjxsxsjyO2krW9iT/SH8BD8njK7GF9bz5JcLcDQKIsWQqbDkwIGj5LYYzZ0RMEeMb8GmkR8fpFut3IGOsrP3UyrKmOO+HcCptN4IAkvgXEDIlPwJBp2ov0MaZ1HP/BANj45eIVzOijf5cSXz1p56+sfpnI7Pni0Kl7q+u3BDHBnmCsYeVH01DDxtE61683kQ05lsj6pKrUi4QIOVNUlp9bjvWVN4Km+P1A5Q1EGyuNo6hAFmUNZ5WUVmegOn3r+rSCkZF+79QgERlXaFH69tLLqtzWzpiUJcUoZn0iG+CyFy3dhoGEMSIXHoAR/Smq9m3JUI5CBFpRmzZ1mSJKRY1YG2AWQcc6LUcQQAxATvX+WelL5bq7Vdj6big6CGPiTM9h3IYFOQ+SGG7N/weD3WVkQgCiOkcVipyWVBZg5J0KFUG+gZHN/QH3Mq450qivHhjRLoGQIky5m2GwjRzHvQ0GCDsFZcFuYMCHxp6hRFhihFfIyaJGqweCDijvQko62iD666jeaOQn4uggLDJdkHzC6VZ1pupGTEmWnr00T7ZZYWy6YyycrSthNPB1qxVh7w2IpWLrDH7iZjXOdcdZ8uGPA8OCDtnZHOy4OwMc+OPrh2Grz9hGNvML0CclYWySZf6gQBysmio4oeRjFCfrVM/JtdJm7jCkmuuXNvTRr5OALEd4YJm7g2hJZOKsoVNKzmOKc7IZIqzPHOZIo5/BJCxNNC7x7lZ6MAYFmYHj3nsjzOa9DhILKuEuWIsmbWc4Uk+B/NOEPv68CxWykpjIYSSKUDBCzHV55UMbhlz4iueaLou9dtjEzDUWGUIOclfCkJkLnr2r9MR8pIXZFTdUUNxBivggkYArTOFty+QvtEPLyvq8XWvAMnyiaOGBgBXz0PRkrlRNr3onOJMYEXRn6E4q2MEFNFvM623gNhOP4+a2TF3XkHeXLtbaOoQ4uyGRgA98TZ8GttOX8feA8Knm8qZR1pJsta/UzdgFLwHE+4dGTGG/uCCDa8+jWPdlbL1HhBjIVH8wFIiEFYncN6Em2gg0n6m7/Bsypb2f5qIM1pnxStASim1kKG3gJglM3AEMX16S4fNHHMYkIq0a2s+U6Qhm4v5DOtsmGsy51QT7FbvALEhEuMzpH4DHbbUVC1kDA0BetkYORw1LoYAHEZxcjALK/aY2CtAkpfXUDxhuScZ2yCEkZjPM+MAgl9REc8wUi6K0kOm9cIxtB3WsrpXGsEMGT7ae02PSZxKIjPylOJSpHEOzZOce53c6hUg6dyDNzCyHCUwWk8PGOGFr36YTevTea9EFgOBnLXLi035YJrRQ3rwuw9abdHoFSDo5IJ/WOY5pxNnFbyvzhugk++ObJCsMkezUbCFi56JrBlMXLk1oQ44cRAt4+/6iK/SuyY4DJW7WFuWTwTVYTfWgu+At2W6PvYKkG3MoCiDf8Ew+hx64A0/YcG8fCnm/6GkR7I+fSqr9D9wPkZ4ZaIknpj7uMj/8RNJa7z3dzbPTw9/tzkgav0rQtyR9aB9dIGjgEs3R9hQytB5shIFGwjAaM7wIcx+ynpw/nm0xXJC3q0/4DNnqB7W3HWVEbeVIBLMQyPNd5c1B4QWi5KHqlu3ijrHtHQd7ZznXBO11DH0SxzFsr+AGDL3Y2y+GUk8Zp7yH2YJlYoUVtH7XDtMUerz8xoeAElYwZA3oqonS/2L988/pE/x9RPTtRzY85U+wnsT881YboemgfA0ereKLkvN/Uj9hGAlRedJ0Wh0p5jkLKQFE5SO1ElVohQJTbYGV60vZH4aHOkWhota9WLq+OkBySFQaPYiHlTLZgfKE5iSd5zv/hHmIHL4knuLZvOS+yMxM5mbofzmwi6q2Ja1cISwEGfdGnu2iMB29fmHbR2vcp9hesS7KJ6mVcq9yuvwkoVSQMycgRre8al/VUG1G3wD6SV9imrFustN8eTtK3FKbs2atJLulALC8kZuevssEd/R2/+vcNKMRWieosnRitvKaWyVc//OlRMgtqrUsrjB9dTea3Ds5Vc4fZqxDMlU/RJcJUAs82t8AtUWfX2EXO3DVzizZuzrRla9U18K1ALENi+ZUCr6SLDNWXzU3ByT6Jfb4pz+UzNm7AdQbyyeOL/PybG6LW0ECCv1qfhALsISz8siO71uR/PK9XGkNwbEdtSbaQiClL11vqZj21J29NlW1LXxYbKyusvSvQFiK6LzhNjWBQhP7L2ax0rWiUsdPq1FilkuV/U9mr0DQsb4lMvsuI8wjE8ztk1/qhVA7NPq13IRzIlXf0ObmXXEXErjaAM7FSDi0CogFpgumNKHh8H2v8oxCCC2QdQv8H4ZE/JhXuaGYfooLm3/XY5BAWGDMgy7cGlgUR7ql1gPnz5/4dHL9m5QFPUjm1YYfs9m9HXOyabMJyCi+nT1I62c7Bt6zCIITM3Wp5mY3Pz8UVdfdAg+Ql4yq8ZTzahxoTdcU39EIZ3Sl3yw150DYhviZJZWtHJcjAmKva7CNrbv2WNvAGGjqF+2zD808oa3GhM9CWxmAenlOUMbZrsz9oeYp9xDKxOwn14wc0ex5oHsjsSOAzsO7Diw48COA73hwF/JV5eOHd1hjQAAAABJRU5ErkJggg== + mediatype: image/png install: spec: deployments: null strategy: "" installModes: - - supported: true - type: OwnNamespace - - supported: true - type: SingleNamespace - - supported: true - type: MultiNamespace - - supported: true - type: AllNamespaces + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: true + type: MultiNamespace + - supported: true + type: AllNamespaces keywords: - - coherence + - Coherence + - Oracle + - In Memory Data + - Caching links: - - name: Coherence Kubernetes Operator - url: https://oracle.github.io/coherence-operator/docs/latest - - name: Oracle Coherence - url: https://coherence.community - maturity: alpha + - name: Coherence Kubernetes Operator + url: https://oracle.github.io/coherence-operator/docs/latest + - name: Oracle Coherence + url: https://coherence.community + maturity: mature minKubeVersion: 1.26.0 provider: name: Oracle Corporation diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml index 8363fc558..bb9b2e826 100644 --- a/config/manifests/kustomization.yaml +++ b/config/manifests/kustomization.yaml @@ -1,7 +1,7 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -bases: -- ../default -- ../samples -- ../scorecard +# These resources constitute the fully configured set of manifests +# used to generate the 'manifests/' directory in a bundle. +resources: + - bases/coherence-operator.clusterserviceversion.yaml + - ../default + - ../samples + - ../scorecard diff --git a/config/network-policy/allow-metrics-traffic.yaml b/config/network-policy/allow-metrics-traffic.yaml new file mode 100644 index 000000000..8fb51a8d2 --- /dev/null +++ b/config/network-policy/allow-metrics-traffic.yaml @@ -0,0 +1,29 @@ +# This NetworkPolicy allows ingress traffic +# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those +# namespaces are able to gathering data from the metrics endpoint. +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator + name: allow-metrics-traffic + namespace: system +spec: + podSelector: + matchLabels: + control-plane: controller-manager + policyTypes: + - Ingress + ingress: + # This allows ingress traffic from any namespace with the label metrics: enabled + - from: + - namespaceSelector: + matchLabels: + metrics: enabled # Only from namespaces with this label + ports: + - port: 8443 + protocol: TCP diff --git a/config/network-policy/kustomization.yaml b/config/network-policy/kustomization.yaml new file mode 100644 index 000000000..ec0fb5e57 --- /dev/null +++ b/config/network-policy/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- allow-metrics-traffic.yaml diff --git a/config/overlays/ci/always-pull-patch.yaml b/config/overlays/ci/always-pull-patch.yaml new file mode 100644 index 000000000..7f943c67c --- /dev/null +++ b/config/overlays/ci/always-pull-patch.yaml @@ -0,0 +1,4 @@ +- op: add + path: /spec/template/spec/containers/0/imagePullPolicy + value: + Always diff --git a/config/overlays/ci/kustomization.yaml b/config/overlays/ci/kustomization.yaml new file mode 100644 index 000000000..2978d5408 --- /dev/null +++ b/config/overlays/ci/kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - ../../default + +components: + - ../../components/pull-secrets + +patches: + - path: always-pull-patch.yaml + target: + kind: Deployment + name: controller-manager diff --git a/config/overlays/restricted/kustomization.yaml b/config/overlays/restricted/kustomization.yaml index 6317684a4..ba2d99641 100644 --- a/config/overlays/restricted/kustomization.yaml +++ b/config/overlays/restricted/kustomization.yaml @@ -4,12 +4,5 @@ kind: Kustomization resources: - ../../default -patches: - - path: single-namespace-patch.yaml - target: - kind: Deployment - name: controller-manager - - path: node-viewer-role.yaml - - path: node_viewer_role_binding.yaml - - path: cluster_role.yaml - - path: cluster_role_binding.yaml +components: + - ../../components/restricted diff --git a/config/prometheus/kustomization.yaml b/config/prometheus/kustomization.yaml new file mode 100644 index 000000000..ed137168a --- /dev/null +++ b/config/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml new file mode 100644 index 000000000..a59ea74a2 --- /dev/null +++ b/config/prometheus/monitor.yaml @@ -0,0 +1,32 @@ +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - path: /metrics + port: https # Ensure this is the name of the port that exposes HTTPS metrics + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + # TODO(user): The option insecureSkipVerify: true is not recommended for production since it disables + # certificate verification. This poses a significant security risk by making the system vulnerable to + # man-in-the-middle attacks, where an attacker could intercept and manipulate the communication between + # Prometheus and the monitored services. This could lead to unauthorized access to sensitive metrics data, + # compromising the integrity and confidentiality of the information. + # Please use the following options for secure configurations: + # caFile: /etc/metrics-certs/ca.crt + # certFile: /etc/metrics-certs/tls.crt + # keyFile: /etc/metrics-certs/tls.key + insecureSkipVerify: true + selector: + matchLabels: + control-plane: controller-manager diff --git a/config/rbac/cluster_role.yaml b/config/rbac/cluster_role.yaml index 19f957257..99a0e9604 100644 --- a/config/rbac/cluster_role.yaml +++ b/config/rbac/cluster_role.yaml @@ -8,6 +8,10 @@ metadata: name: crd-webhook-install-role labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator rules: - apiGroups: - apiextensions.k8s.io diff --git a/config/rbac/cluster_role_binding.yaml b/config/rbac/cluster_role_binding.yaml index 297e5dbd0..94380d86d 100644 --- a/config/rbac/cluster_role_binding.yaml +++ b/config/rbac/cluster_role_binding.yaml @@ -8,6 +8,10 @@ metadata: name: crd-webhook-install-rolebinding labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole diff --git a/config/rbac/coherence_editor_role.yaml b/config/rbac/coherence_editor_role.yaml index 90f8db744..f0437ab48 100644 --- a/config/rbac/coherence_editor_role.yaml +++ b/config/rbac/coherence_editor_role.yaml @@ -2,25 +2,29 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: coherence-editor-role labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator + name: coherence-editor-role rules: -- apiGroups: - - coherence.oracle.com - resources: - - coherence - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - coherence.oracle.com - resources: - - coherence/status - verbs: - - get + - apiGroups: + - coherence.oracle.com + resources: + - coherence + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - coherence.oracle.com + resources: + - coherence/status + verbs: + - get diff --git a/config/rbac/coherence_viewer_role.yaml b/config/rbac/coherence_viewer_role.yaml index c79edc238..6dff64058 100644 --- a/config/rbac/coherence_viewer_role.yaml +++ b/config/rbac/coherence_viewer_role.yaml @@ -2,21 +2,25 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: coherence-viewer-role labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator + name: coherence-viewer-role rules: -- apiGroups: - - coherence.oracle.com - resources: - - coherence - verbs: - - get - - list - - watch -- apiGroups: - - coherence.oracle.com - resources: - - coherence/status - verbs: - - get + - apiGroups: + - coherence.oracle.com + resources: + - coherence + verbs: + - get + - list + - watch + - apiGroups: + - coherence.oracle.com + resources: + - coherence/status + verbs: + - get diff --git a/config/rbac/coherencejob_editor_role.yaml b/config/rbac/coherencejob_editor_role.yaml new file mode 100644 index 000000000..c691e5040 --- /dev/null +++ b/config/rbac/coherencejob_editor_role.yaml @@ -0,0 +1,30 @@ +# permissions for end users to edit coherencejob. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator + name: coherencejob-editor-role +rules: +- apiGroups: + - coherence.oracle.com + resources: + - coherencejob + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - coherence.oracle.com + resources: + - coherencejob/status + verbs: + - get diff --git a/config/rbac/coherencejob_viewer_role.yaml b/config/rbac/coherencejob_viewer_role.yaml new file mode 100644 index 000000000..09c2e1adb --- /dev/null +++ b/config/rbac/coherencejob_viewer_role.yaml @@ -0,0 +1,26 @@ +# permissions for end users to view coherencejob. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator + name: coherencejob-viewer-role +rules: +- apiGroups: + - coherence.oracle.com + resources: + - coherencejob + verbs: + - get + - list + - watch +- apiGroups: + - coherence.oracle.com + resources: + - coherencejob/status + verbs: + - get diff --git a/config/rbac/leader_election_role.yaml b/config/rbac/leader_election_role.yaml index 36bfb341e..7e70f935b 100644 --- a/config/rbac/leader_election_role.yaml +++ b/config/rbac/leader_election_role.yaml @@ -5,35 +5,39 @@ metadata: name: leader-election-role labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator rules: -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/config/rbac/leader_election_role_binding.yaml b/config/rbac/leader_election_role_binding.yaml index b9958d300..8a55d939e 100644 --- a/config/rbac/leader_election_role_binding.yaml +++ b/config/rbac/leader_election_role_binding.yaml @@ -4,6 +4,10 @@ metadata: name: leader-election-rolebinding labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator roleRef: apiGroup: rbac.authorization.k8s.io kind: Role diff --git a/config/rbac/metrics_auth_role.yaml b/config/rbac/metrics_auth_role.yaml new file mode 100644 index 000000000..ff6831a3f --- /dev/null +++ b/config/rbac/metrics_auth_role.yaml @@ -0,0 +1,23 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-auth-role + labels: + control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/config/rbac/metrics_auth_role_binding.yaml b/config/rbac/metrics_auth_role_binding.yaml new file mode 100644 index 000000000..3ad273798 --- /dev/null +++ b/config/rbac/metrics_auth_role_binding.yaml @@ -0,0 +1,18 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: metrics-auth-rolebinding + labels: + control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: metrics-auth-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/config/rbac/metrics_reader_role.yaml b/config/rbac/metrics_reader_role.yaml new file mode 100644 index 000000000..13503ca72 --- /dev/null +++ b/config/rbac/metrics_reader_role.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader + labels: + control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/config/rbac/node_viewer_role.yaml b/config/rbac/node_viewer_role.yaml index 2435625b0..6443dc857 100644 --- a/config/rbac/node_viewer_role.yaml +++ b/config/rbac/node_viewer_role.yaml @@ -10,6 +10,10 @@ metadata: name: node-viewer-role labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator rules: - apiGroups: - "" diff --git a/config/rbac/node_viewer_role_binding.yaml b/config/rbac/node_viewer_role_binding.yaml index 85c70339a..594369e78 100644 --- a/config/rbac/node_viewer_role_binding.yaml +++ b/config/rbac/node_viewer_role_binding.yaml @@ -10,6 +10,10 @@ metadata: name: node-viewer-rolebinding labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole diff --git a/config/rbac/role_binding.yaml b/config/rbac/role_binding.yaml index 9b70d7e81..79c62fa76 100644 --- a/config/rbac/role_binding.yaml +++ b/config/rbac/role_binding.yaml @@ -8,6 +8,10 @@ metadata: name: manager-rolebinding labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole diff --git a/config/rbac/service_account.yaml b/config/rbac/service_account.yaml index 81444013f..e53891eee 100644 --- a/config/rbac/service_account.yaml +++ b/config/rbac/service_account.yaml @@ -7,3 +7,8 @@ metadata: name: service-account labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/version: "3.4.3" + app.kubernetes.io/part-of: coherence-operator +imagePullSecrets: [] \ No newline at end of file diff --git a/config/samples/coherence.oracle.com_v1_coherence.yaml b/config/samples/coherence_v1_coherence.yaml similarity index 100% rename from config/samples/coherence.oracle.com_v1_coherence.yaml rename to config/samples/coherence_v1_coherence.yaml diff --git a/config/samples/coherence_v1_coherencejob.yaml b/config/samples/coherence_v1_coherencejob.yaml new file mode 100644 index 000000000..46e478ad3 --- /dev/null +++ b/config/samples/coherence_v1_coherencejob.yaml @@ -0,0 +1,6 @@ +apiVersion: coherence.oracle.com/v1 +kind: CoherenceJob +metadata: + name: coherence-job-sample +spec: + replicas: 1 diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index ac0962f5c..ea51f5618 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -1,3 +1,5 @@ -## This file is auto-generated, do not modify ## +## Append samples of your project ## resources: -- coherence.oracle.com_v1_coherence.yaml + - coherence_v1_coherence.yaml + - coherence_v1_coherencejob.yaml +# +kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/scorecard/kustomization.yaml b/config/scorecard/kustomization.yaml index 50cd2d084..f4ef4d647 100644 --- a/config/scorecard/kustomization.yaml +++ b/config/scorecard/kustomization.yaml @@ -1,16 +1,18 @@ resources: -- bases/config.yaml -patchesJson6902: -- path: patches/basic.config.yaml - target: - group: scorecard.operatorframework.io - version: v1alpha3 - kind: Configuration - name: config -- path: patches/olm.config.yaml - target: - group: scorecard.operatorframework.io - version: v1alpha3 - kind: Configuration - name: config -#+kubebuilder:scaffold:patchesJson6902 + - bases/config.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +patches: + - path: patches/basic.config.yaml + target: + group: scorecard.operatorframework.io + kind: Configuration + name: config + version: v1alpha3 + - path: patches/olm.config.yaml + target: + group: scorecard.operatorframework.io + kind: Configuration + name: config + version: v1alpha3 +# +kubebuilder:scaffold:patches diff --git a/config/scorecard/patches/basic.config.yaml b/config/scorecard/patches/basic.config.yaml index d070a0e52..6ca7d78b6 100644 --- a/config/scorecard/patches/basic.config.yaml +++ b/config/scorecard/patches/basic.config.yaml @@ -2,9 +2,9 @@ path: /stages/0/tests/- value: entrypoint: - - scorecard-test - - basic-check-spec - image: quay.io/operator-framework/scorecard-test:v1.4.2 + - scorecard-test + - basic-check-spec + image: quay.io/operator-framework/scorecard-test:v1.39.1 labels: suite: basic test: basic-check-spec-test diff --git a/config/scorecard/patches/olm.config.yaml b/config/scorecard/patches/olm.config.yaml index c0dc15345..a15b6ff34 100644 --- a/config/scorecard/patches/olm.config.yaml +++ b/config/scorecard/patches/olm.config.yaml @@ -2,9 +2,9 @@ path: /stages/0/tests/- value: entrypoint: - - scorecard-test - - olm-bundle-validation - image: quay.io/operator-framework/scorecard-test:v1.4.2 + - scorecard-test + - olm-bundle-validation + image: quay.io/operator-framework/scorecard-test:v1.39.1 labels: suite: olm test: olm-bundle-validation-test @@ -12,9 +12,9 @@ path: /stages/0/tests/- value: entrypoint: - - scorecard-test - - olm-crds-have-validation - image: quay.io/operator-framework/scorecard-test:v1.4.2 + - scorecard-test + - olm-crds-have-validation + image: quay.io/operator-framework/scorecard-test:v1.39.1 labels: suite: olm test: olm-crds-have-validation-test @@ -22,9 +22,9 @@ path: /stages/0/tests/- value: entrypoint: - - scorecard-test - - olm-crds-have-resources - image: quay.io/operator-framework/scorecard-test:v1.4.2 + - scorecard-test + - olm-crds-have-resources + image: quay.io/operator-framework/scorecard-test:v1.39.1 labels: suite: olm test: olm-crds-have-resources-test @@ -32,9 +32,9 @@ path: /stages/0/tests/- value: entrypoint: - - scorecard-test - - olm-spec-descriptors - image: quay.io/operator-framework/scorecard-test:v1.4.2 + - scorecard-test + - olm-spec-descriptors + image: quay.io/operator-framework/scorecard-test:v1.39.1 labels: suite: olm test: olm-spec-descriptors-test @@ -42,9 +42,9 @@ path: /stages/0/tests/- value: entrypoint: - - scorecard-test - - olm-status-descriptors - image: quay.io/operator-framework/scorecard-test:v1.4.2 + - scorecard-test + - olm-status-descriptors + image: quay.io/operator-framework/scorecard-test:v1.39.1 labels: suite: olm test: olm-status-descriptors-test diff --git a/controllers/coherence_controller.go b/controllers/coherence_controller.go index 37ceb69ab..487088c40 100644 --- a/controllers/coherence_controller.go +++ b/controllers/coherence_controller.go @@ -17,6 +17,7 @@ import ( "github.com/oracle/coherence-operator/controllers/servicemonitor" "github.com/oracle/coherence-operator/controllers/statefulset" "github.com/oracle/coherence-operator/pkg/clients" + "github.com/oracle/coherence-operator/pkg/events" "github.com/oracle/coherence-operator/pkg/operator" "github.com/oracle/coherence-operator/pkg/probe" "github.com/oracle/coherence-operator/pkg/rest" @@ -108,7 +109,10 @@ func (in *CoherenceReconciler) Reconcile(ctx context.Context, request ctrl.Reque log.Info("Coherence resource not found. Ignoring request since object must be deleted.") return ctrl.Result{}, nil } - // Error reading the current deployment state from k8s. + // else... error reading the current deployment state from k8s. + msg := fmt.Sprintf("failed to find Coherence resource, %s", err.Error()) + in.GetEventRecorder().Event(deployment, coreV1.EventTypeWarning, reconciler.EventReasonFailed, msg) + // returning an error will requeue the event so we will try again ToDo: probably need som backoff here return reconcile.Result{}, errors.Wrap(err, "getting Coherence resource") } @@ -121,7 +125,10 @@ func (in *CoherenceReconciler) Reconcile(ctx context.Context, request ctrl.Reque // Run finalization logic. // If the finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. + in.GetEventRecorder().Event(deployment, coreV1.EventTypeNormal, reconciler.EventReasonDeleted, "running finalizers") if err := in.finalizeDeployment(ctx, deployment); err != nil { + msg := fmt.Sprintf("failed to finalize Coherence resource, %s", err.Error()) + in.GetEventRecorder().Event(deployment, coreV1.EventTypeWarning, reconciler.EventReasonDeleted, msg) log.Error(err, "Failed to remove finalizer") return ctrl.Result{Requeue: true}, nil } @@ -134,12 +141,14 @@ func (in *CoherenceReconciler) Reconcile(ctx context.Context, request ctrl.Reque log.Info("Failed to remove the finalizer from the Coherence resource, it looks like it had already been deleted") return ctrl.Result{}, nil } + msg := fmt.Sprintf("failed to remove finalizers from Coherence resource, %s", err.Error()) + in.GetEventRecorder().Event(deployment, coreV1.EventTypeWarning, reconciler.EventReasonDeleted, msg) return ctrl.Result{}, errors.Wrap(err, "trying to remove finalizer from Coherence resource") } } else { log.Info("Coherence resource deleted at " + deleteTime.String() + ", finalizer already removed") } - + // nothing else to do return ctrl.Result{}, nil } @@ -165,6 +174,14 @@ func (in *CoherenceReconciler) Reconcile(ctx context.Context, request ctrl.Reque // Add finalizer for this CR if required (it should have been added by the web-hook but may not have been if the // Coherence resource was added when the Operator was uninstalled) if finalizerApplied, err := in.ensureFinalizerApplied(ctx, deployment); finalizerApplied || err != nil { + var msg string + if err != nil { + msg = fmt.Sprintf("failed to add finalizers to Coherence resource, %s", err.Error()) + in.GetEventRecorder().Event(deployment, coreV1.EventTypeWarning, reconciler.EventReasonFailed, msg) + } else { + in.GetEventRecorder().Event(deployment, coreV1.EventTypeNormal, reconciler.EventReasonUpdated, "added finalizer") + } + // we need to requeue as we have updated the Coherence resource return ctrl.Result{Requeue: true}, err } } @@ -173,6 +190,7 @@ func (in *CoherenceReconciler) Reconcile(ctx context.Context, request ctrl.Reque if deployment.Status.Phase == "" { err := in.UpdateCoherenceStatusPhase(ctx, request.NamespacedName, coh.ConditionTypeInitialized) if err != nil { + // failed to set the status return reconcile.Result{}, err } } @@ -189,9 +207,14 @@ func (in *CoherenceReconciler) Reconcile(ctx context.Context, request ctrl.Reque patch.Spec.Replicas = &replicas _, err = in.ThreeWayPatch(ctx, deployment.Name, deployment, deployment, patch) if err != nil { - log.Info("Added default replicas to Coherence resource, re-queuing request", "Replicas", strconv.Itoa(int(replicas))) - return reconcile.Result{}, err + in.GetEventRecorder().Event(deployment, coreV1.EventTypeWarning, reconciler.EventReasonFailed, + fmt.Sprintf("failed to add default replicas to Coherence resource, %s", err.Error())) + return reconcile.Result{}, errors.Wrap(err, "failed to add default replicas to Coherence resource") } + msg := "Added default replicas to Coherence resource, re-queuing request" + log.Info(msg, "Replicas", strconv.Itoa(int(replicas))) + in.GetEventRecorder().Event(deployment, coreV1.EventTypeNormal, reconciler.EventReasonUpdated, msg) + return reconcile.Result{}, err } // ensure that the Operator configuration Secret exists @@ -204,6 +227,8 @@ func (in *CoherenceReconciler) Reconcile(ctx context.Context, request ctrl.Reque storage, err := utils.NewStorage(request.NamespacedName, in.GetManager()) if err != nil { err = errors.Wrap(err, "obtaining desired state store") + in.GetEventRecorder().Event(deployment, coreV1.EventTypeWarning, reconciler.EventReasonFailed, + fmt.Sprintf("failed to obtain state store: %s", err.Error())) return in.HandleErrAndRequeue(ctx, err, nil, fmt.Sprintf(reconcileFailedMessage, request.Name, request.Namespace, err), in.Log) } @@ -211,7 +236,7 @@ func (in *CoherenceReconciler) Reconcile(ctx context.Context, request ctrl.Reque storeHash, _ := storage.GetHash() var desiredResources coh.Resources - desiredResources, err = checkCoherenceHash(deployment, storage, log) + desiredResources, err = getDesiredResources(deployment, storage, log) if err != nil { return in.HandleErrAndRequeue(ctx, err, nil, fmt.Sprintf(createResourcesFailedMessage, request.Name, request.Namespace, err), in.Log) } @@ -237,8 +262,18 @@ func (in *CoherenceReconciler) Reconcile(ctx context.Context, request ctrl.Reque // Ensure the version annotation is present (it should have been added by the web-hook, so this should be a no-op). // The hash may not have been added if the Coherence resource was added/modified when the Operator was uninstalled. - if applied, err := in.ensureVersionAnnotationApplied(ctx, deployment); applied || err != nil { - return ctrl.Result{Requeue: true}, err + applied, err := in.ensureVersionAnnotationApplied(ctx, deployment) + if err != nil { + // We failed to update the Coherence resource + in.GetEventRecorder().Eventf(deployment, coreV1.EventTypeWarning, reconciler.EventReasonFailed, + fmt.Sprintf("failed to ensure version annotation applied: %s", err.Error())) + return ctrl.Result{}, err + } + if applied { + // We updated the Coherence resource, so requeue the event + in.GetEventRecorder().Eventf(deployment, coreV1.EventTypeNormal, reconciler.EventReasonUpdated, + "applied version annotation") + return ctrl.Result{Requeue: true}, nil } // process the secondary resources in the order they should be created @@ -305,6 +340,7 @@ func (in *CoherenceReconciler) SetupWithManager(mgr ctrl.Manager, cs clients.Cli return ctrl.NewControllerManagedBy(mgr). For(template). Named("coherence"). + WithOptions(controller.Options{MaxConcurrentReconciles: 1}). Complete(in) } @@ -438,8 +474,9 @@ func (in *CoherenceReconciler) finalizeDeployment(ctx context.Context, c *coh.Co } else { // Do service suspension... p := probe.CoherenceProbe{ - Client: in.GetClient(), - Config: in.GetManager().GetConfig(), + Client: in.GetClient(), + Config: in.GetManager().GetConfig(), + EventRecorder: events.NewOwnedEventRecorder(c, in.GetEventRecorder()), } if p.SuspendServices(ctx, c, sts) == probe.ServiceSuspendFailed { return fmt.Errorf("failed to suspend services") diff --git a/controllers/coherencejob_controller.go b/controllers/coherencejob_controller.go index 175802f91..b84f4d503 100644 --- a/controllers/coherencejob_controller.go +++ b/controllers/coherencejob_controller.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" "strconv" @@ -163,7 +164,7 @@ func (in *CoherenceJobReconciler) ReconcileDeployment(ctx context.Context, reque storeHash, _ := storage.GetHash() var desiredResources coh.Resources - desiredResources, err = checkJobHash(deployment, storage, log) + desiredResources, err = getDesiredJobResources(deployment, storage, log) if err != nil { return in.HandleErrAndRequeue(ctx, err, nil, fmt.Sprintf(createResourcesFailedMessage, request.Name, request.Namespace, err), in.Log) } @@ -258,6 +259,7 @@ func (in *CoherenceJobReconciler) SetupWithManager(mgr ctrl.Manager, cs clients. return ctrl.NewControllerManagedBy(mgr). For(template). Named("coherencejob"). + WithOptions(controller.Options{MaxConcurrentReconciles: 1}). Complete(in) } diff --git a/controllers/common.go b/controllers/common.go index 1a90f240b..7264634c7 100644 --- a/controllers/common.go +++ b/controllers/common.go @@ -12,11 +12,11 @@ import ( "github.com/oracle/coherence-operator/pkg/utils" ) -func checkCoherenceHash(deployment *coh.Coherence, storage utils.Storage, log logr.Logger) (coh.Resources, error) { +func getDesiredResources(deployment *coh.Coherence, storage utils.Storage, log logr.Logger) (coh.Resources, error) { return checkHash(deployment, deployment.Status.Phase, storage, log) } -func checkJobHash(deployment *coh.CoherenceJob, storage utils.Storage, log logr.Logger) (coh.Resources, error) { +func getDesiredJobResources(deployment *coh.CoherenceJob, storage utils.Storage, log logr.Logger) (coh.Resources, error) { return checkHash(deployment, deployment.Status.Phase, storage, log) } diff --git a/controllers/job/job_controller.go b/controllers/job/job_controller.go index c6b128063..69c50018c 100644 --- a/controllers/job/job_controller.go +++ b/controllers/job/job_controller.go @@ -249,7 +249,7 @@ func (in *ReconcileJob) patchJob(ctx context.Context, deployment coh.CoherenceRe errorList := coh.ValidateJobUpdate(desired, original) if len(errorList) > 0 { - msg := fmt.Sprintf("upddates to the statefuleset would have been invalid, the update will not be re-queued: %v", errorList) + msg := fmt.Sprintf("upddates to the job would have been invalid, the update will not be re-queued: %v", errorList) events := in.GetEventRecorder() events.Event(deployment, corev1.EventTypeWarning, reconciler.EventReasonUpdated, msg) return reconcile.Result{Requeue: false}, errors.New(msg) diff --git a/controllers/reconciler/base_controller.go b/controllers/reconciler/base_controller.go index 8f19663f2..0664f2d80 100644 --- a/controllers/reconciler/base_controller.go +++ b/controllers/reconciler/base_controller.go @@ -48,6 +48,10 @@ const ( EventReasonFailed string = "Failed" // EventReasonDeleted is the reason description for a deleted event. EventReasonDeleted string = "Deleted" + // EventReasonReconciling is the reason description for an reconciling event. + EventReasonReconciling string = "Reconciling" + // EventReasonScaling is the reason description for an scaling event. + EventReasonScaling string = "Scaling" ) var ( diff --git a/controllers/servicemonitor/servicemonitor_controller.go b/controllers/servicemonitor/servicemonitor_controller.go index 0c03c466e..c6a9d95b5 100644 --- a/controllers/servicemonitor/servicemonitor_controller.go +++ b/controllers/servicemonitor/servicemonitor_controller.go @@ -257,14 +257,7 @@ func (in *ReconcileServiceMonitor) UpdateServiceMonitor(ctx context.Context, nam } } - if err == nil { - if hashMatches { - logger.Info("Update applied to ServiceMonitor even though hashes matched (possible external update)") - } else { - logger.Info("Update applied to ServiceMonitor") - } - } - + logger.Info("Update applied to ServiceMonitor") return nil } @@ -273,7 +266,7 @@ func (in *ReconcileServiceMonitor) hasServiceMonitor() bool { dc := discovery.NewDiscoveryClientForConfigOrDie(in.GetManager().GetConfig()) apiVersion := coh.ServiceMonitorGroupVersion kind := coh.ServiceMonitorKind - ok, err := ResourceExists(dc, apiVersion, kind) + ok, err := resourceExists(dc, apiVersion, kind) if err != nil { in.GetLog().Error(err, "error checking for Prometheus ServiceMonitor CRD") return false @@ -283,7 +276,7 @@ func (in *ReconcileServiceMonitor) hasServiceMonitor() bool { // ResourceExists returns true if the given resource kind exists // in the given api group/version -func ResourceExists(dc discovery.DiscoveryInterface, apiGroupVersion, kind string) (bool, error) { +func resourceExists(dc discovery.DiscoveryInterface, apiGroupVersion, kind string) (bool, error) { _, apiLists, err := dc.ServerGroupsAndResources() if err != nil { diff --git a/controllers/statefulset/statefulset_controller.go b/controllers/statefulset/statefulset_controller.go index b0212f792..edfdb3ae0 100644 --- a/controllers/statefulset/statefulset_controller.go +++ b/controllers/statefulset/statefulset_controller.go @@ -13,6 +13,7 @@ import ( coh "github.com/oracle/coherence-operator/api/v1" "github.com/oracle/coherence-operator/controllers/reconciler" "github.com/oracle/coherence-operator/pkg/clients" + "github.com/oracle/coherence-operator/pkg/events" "github.com/oracle/coherence-operator/pkg/probe" "github.com/oracle/coherence-operator/pkg/utils" "github.com/pkg/errors" @@ -119,6 +120,8 @@ func (in *ReconcileStatefulSet) ReconcileAllResourceOfKind(ctx context.Context, stsCurrent, stsExists, err := in.MaybeFindStatefulSet(ctx, request.Namespace, request.Name) if err != nil { logger.Info("Finished reconciling StatefulSet for deployment. Error getting StatefulSet", "error", err.Error()) + in.GetEventRecorder().Eventf(deployment, corev1.EventTypeWarning, reconciler.EventReasonReconciling, + "error getting statefulset for deployment %s, %s", request.Name, err.Error()) return result, errors.Wrapf(err, "getting StatefulSet %s/%s", request.Namespace, request.Name) } @@ -132,6 +135,8 @@ func (in *ReconcileStatefulSet) ReconcileAllResourceOfKind(ctx context.Context, // find the owning Coherence resource if deployment, err = in.FindOwningCoherenceResource(ctx, stsCurrent); err != nil { logger.Info("Finished reconciling StatefulSet. Error finding parent Coherence resource", "error", err.Error()) + in.GetEventRecorder().Eventf(deployment, corev1.EventTypeWarning, reconciler.EventReasonReconciling, + "finding parent Coherence resource %s, %s", request.Name, err.Error()) return reconcile.Result{}, err } } @@ -146,6 +151,8 @@ func (in *ReconcileStatefulSet) ReconcileAllResourceOfKind(ctx context.Context, // If the Coherence resource did not exist then service suspension already happened // when the Coherence resource was deleted. logger.Info("Scaling down to zero") + in.GetEventRecorder().Eventf(deployment, corev1.EventTypeNormal, reconciler.EventReasonScaling, + "scaling statefuleset %s down to zero", request.Name) err = in.UpdateDeploymentStatusActionsState(ctx, request.NamespacedName, false) // TODO: what to do with error? if err != nil { @@ -153,14 +160,22 @@ func (in *ReconcileStatefulSet) ReconcileAllResourceOfKind(ctx context.Context, } stsSpec, _ := deployment.GetStatefulSetSpec() if stsSpec.IsSuspendServicesOnShutdown() { + in.GetEventRecorder().Eventf(deployment, corev1.EventTypeNormal, reconciler.EventReasonScaling, + "suspending Coherence services in statefuleset %s", request.Name) // we are scaling down to zero and suspend services flag is true, so suspend services suspended := in.suspendServices(ctx, deployment, stsCurrent) switch suspended { case probe.ServiceSuspendFailed: + in.GetEventRecorder().Eventf(deployment, corev1.EventTypeWarning, reconciler.EventReasonScaling, + "failed suspending Coherence services in statefuleset %s", request.Name) return reconcile.Result{Requeue: true, RequeueAfter: time.Minute}, fmt.Errorf("failed to suspend services prior to scaling down to zero") case probe.ServiceSuspendSkipped: - logger.Info("Skipping suspension of Coherence services prior to deletion of StatefulSet") + logger.Info("skipping suspension of Coherence services prior to deletion of StatefulSet") + in.GetEventRecorder().Eventf(deployment, corev1.EventTypeNormal, reconciler.EventReasonScaling, + "skipped suspended Coherence services in statefuleset %s", request.Name) case probe.ServiceSuspendSuccessful: + in.GetEventRecorder().Eventf(deployment, corev1.EventTypeNormal, reconciler.EventReasonScaling, + "suspended Coherence services in statefuleset %s", request.Name) } } } @@ -523,8 +538,9 @@ func (in *ReconcileStatefulSet) patchStatefulSet(ctx context.Context, deployment // suspendServices suspends Coherence services in the target deployment. func (in *ReconcileStatefulSet) suspendServices(ctx context.Context, deployment coh.CoherenceResource, current *appsv1.StatefulSet) probe.ServiceSuspendStatus { probe := probe.CoherenceProbe{ - Client: in.GetClient(), - Config: in.GetManager().GetConfig(), + Client: in.GetClient(), + Config: in.GetManager().GetConfig(), + EventRecorder: events.NewOwnedEventRecorder(deployment, in.GetEventRecorder()), } return probe.SuspendServices(ctx, deployment, current) } diff --git a/docs/applications/020_build_application.adoc b/docs/applications/020_build_application.adoc index 104d582ce..8bbdd7844 100644 --- a/docs/applications/020_build_application.adoc +++ b/docs/applications/020_build_application.adoc @@ -55,13 +55,13 @@ for the Coherence container and from these constructs a Java command line that i The default command might look something like this: [source,bash] ---- -java -cp `/app/resources:/app/classes:/app/libs/*` \ +java --class-path `/app/resources:/app/classes:/app/libs/*` \ \ \ - com.tangosol.net.DefaultCacheServer + com.tangosol.net.Coherence ---- The `runner` will work out the JVM's classpath, args and system properties to add to the command line -and execute the main class `com.tangosol.net.DefaultCacheServer`. +and execute the main class `com.tangosol.net.Coherence`. All these are configurable in the `Coherence` resource spec. === Optional `CLASSPATH` Environment Variable diff --git a/docs/applications/070_spring.adoc b/docs/applications/070_spring.adoc index 1323e736d..9719882dd 100644 --- a/docs/applications/070_spring.adoc +++ b/docs/applications/070_spring.adoc @@ -158,13 +158,13 @@ When the Operator starts the application it will then run a command equivalent t *Spring Boot 2.x* [source,bash] ---- -java -cp /app/libs/catalogue-1.0.0.jar org.springframework.boot.loader.PropertiesLauncher +java --class-path /app/libs/catalogue-1.0.0.jar org.springframework.boot.loader.PropertiesLauncher ---- *Spring Boot 3.x* [source,bash] ---- -java -cp /app/libs/catalogue-1.0.0.jar org.springframework.boot.loader.launch.PropertiesLauncher +java --class-path /app/libs/catalogue-1.0.0.jar org.springframework.boot.loader.launch.PropertiesLauncher ---- NOTE: The Operator does not run the fat jar using the `java -jar` command because it needs to add various other diff --git a/docs/installation/01_installation.adoc b/docs/installation/01_installation.adoc index 96eab5e3d..4e5cababa 100644 --- a/docs/installation/01_installation.adoc +++ b/docs/installation/01_installation.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2020, 2024, Oracle and/or its affiliates. + Copyright (c) 2020, 2025, Oracle and/or its affiliates. Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. @@ -41,14 +41,10 @@ easily be installed into a Kubernetes cluster. The prerequisites apply to all installation methods. * Access to Oracle Coherence Operator images. -* Access to a Kubernetes v1.19.0+ cluster. The Operator test pipeline is run using Kubernetes versions v1.19 upto v1.26 +* Access to a Kubernetes cluster. The Operator test pipeline is run using against all the currently supported Kubernetes versions. * A Coherence application image using Coherence version 12.2.1.3 or later. Note that some functionality (e.g. metrics) is only available in Coherence 12.2.1.4 and later. -[NOTE] -==== -ARM Support: As of version 3.2.0, the Coherence Operator is build as a multi-architecture image that supports running in Kubernetes on both Linux/amd64 and Linux/arm64. The prerequisite is that the Coherence application image used has been built to support ARM. -==== [NOTE] ==== @@ -148,16 +144,39 @@ Operators trying to remove finalizers and delete a Coherence cluster. [#manifest] == Default Install with Kubectl -If you want the default Coherence Operator installation then the simplest solution is use `kubectl` to apply the manifests from the Operator release. +If you want the default Coherence Operator installation then the simplest solution is use `kubectl` to +apply the manifests from the Operator release. + +[NOTE] +==== +As of v3.4.3 of the Operator the manifest yaml also installs the two CRDs that the Operator uses. +In previous releases the Operator would install the CRDs when it started but this behaviour is disabled by default +when installing with the manifest yaml. +==== + +The following command will install the Operator. This assumes that the Kubernetes account being used to perform +the installation has all the RBAC permissions required to install all the resource types in the yaml file. [source,bash] ---- kubectl apply -f https://github.com/oracle/coherence-operator/releases/download/v3.4.3/coherence-operator.yaml ---- -This will create a namespace called `coherence` and install the Operator into it along with all the required `ClusterRole` and `RoleBinding` resources. The `coherence` namespace can be changed by downloading and editing the yaml file. +This will create a namespace called `coherence` and install the CRDs and the Operator into the namespace, +along with all the required `ClusterRole` and `RoleBinding` resources. The `coherence` namespace can be changed by +downloading and editing the yaml file. + +In some restricted environments, a Kubernetes user might not have RBAC permissions to install CRDs. +In this case the `coherence-operator.yaml` file will need to be edited to remove the two CRDs from the +beginning of the file. The CRDs *_must be manually installed before the Operator is installed_*, as described +below in <>. -NOTE: Because the `coherence-operator.yaml` manifest also creates the namespace, the corresponding `kubectl delete` command will _remove the namespace and everything deployed to it_! If you do not want this behaviour you should edit the `coherence-operator.yaml` to remove the namespace section from the start of the file. +[NOTE] +==== +Because the `coherence-operator.yaml` manifest also creates the namespace, the corresponding `kubectl delete` +command will _remove the namespace and everything deployed to it_! If you do not want this behaviour you should edit +the `coherence-operator.yaml` to remove the namespace section from the start of the file. +==== Instead of using a hard coded version in the command above you can find the latest Operator version using `curl`: @@ -190,9 +209,18 @@ the Operator into a single namespace without any cluster roles. The Operator installed with this yaml -* will not install the CRDs * will not use WebHooks -* wil not look-up Node labels for Coherence site and rack configurations +* will not look-up Node labels for Coherence site and rack configurations + +[NOTE] +==== +As of v3.4.3 of the Operator the `coherence-operator-restricted.yaml` also installs the two CRDs that the Operator uses. +In previous releases the Operator would install the CRDs when it started but this behaviour is disabled by default +when installing with the manifest yaml. +==== + +The following command will install the Operator. This assumes that the Kubernetes account being used to perform +the installation has all the RBAC permissions required to install all the resource types in the yaml file. [source,bash] ---- @@ -201,8 +229,10 @@ kubectl apply -f https://github.com/oracle/coherence-operator/releases/download/ [IMPORTANT] ==== -When installing the Operator in a restricted mode, the CRDs must have already been manually installed into -the Kubernetes cluster. +In some restricted environments, a Kubernetes user might not have RBAC permissions to install CRDs. +In this case the `coherence-operator.yaml` file will need to be edited to remove the two CRDs from the +beginning of the file. The CRDs *_must be manually installed before the Operator is installed_*, as described +below in <>. ==== [#manual-crd] @@ -243,7 +273,7 @@ sed -i '' -e 's/replicas: 3/replicas: 1/g' coherence-operator.yaml [#helm] == Installing With Helm -For more flexibility but the simplest way to install the Coherence Operator is to use the Helm chart. +For more flexibility the simplest way to install the Coherence Operator is to use the Helm chart. This ensures that all the correct resources will be created in Kubernetes. === Add the Coherence Helm Repository @@ -257,7 +287,14 @@ helm repo add coherence https://oracle.github.io/coherence-operator/charts helm repo update ---- -NOTE: To avoid confusion, the URL `https://oracle.github.io/coherence-operator/charts` is a Helm repo, it is not a website you open in a browser. You may think we shouldn't have to say this, but you'd be surprised. +NOTE: To avoid confusion, the URL `https://oracle.github.io/coherence-operator/charts` is a Helm repo, it is not +a website you open in a browser. You may think we shouldn't have to say this, but you'd be surprised. + +Unlike the manifest files described above, the Helm chart does not install the CRDs the Operator requires. +By default, the Operator will install the CRDs when it starts. +Whilst it would have been more consistent to make the Helm chart also install the CRDs the same as the manifest yaml files, +this would break Helm upgrades from a previous Operator version. Helm would refuse to perform the upgrade because the +existing CRDs were not installed by Helm. === Install the Coherence Operator Helm chart @@ -720,13 +757,20 @@ helm delete coherence-operator --namespace If you want to use yaml directly to install the operator, with something like `kubectl`, you can use the manifest files published with the GitHub release at this link: -https://github.com/oracle/coherence-operator/releases/download/v3.3.5/coherence-operator-manifests.tar.gz[3.3.5 Manifests] +https://github.com/oracle/coherence-operator/releases/download/v3.4.3/coherence-operator-manifests.tar.gz[3.4.3 Manifests] These manifest files are for use with a tool called Kustomize, which is built into `kubectl` see the documentation here: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/ +[NOTE] +==== +As of v3.4.3 of the Operator the manifest yaml also installs the two CRDs that the Operator uses. +In previous releases the Operator would install the CRDs when it started but this behaviour is disabled by default +when installing with the manifest yaml. +==== + Download the -https://github.com/oracle/coherence-operator/releases/download/v3.3.5/coherence-operator-manifests.tar.gz[3.3.5 Manifests] +https://github.com/oracle/coherence-operator/releases/download/v3.4.3/coherence-operator-manifests.tar.gz[3.4.3 Manifests] from the release page and unpack the file, which should produce a directory called `manifests` with a structure like this: [source] @@ -779,14 +823,14 @@ Change the name of the Operator image by running the command below, changing the that you are using for the Operator, for example if you have the images in a custom registry [source,bash] ---- -cd ./manager && kustomize edit set image controller=myregistry/coherence-operator:3.3.5 +cd ./manager && kustomize edit set image controller=myregistry/coherence-operator:3.4.3 ---- Change the name of the Operator image by running the command below, changing the image name to the registry and image name that you are using for the Operator utilities image [source,bash] ---- -cd ./manager && kustomize edit add configmap env-vars --from-literal OPERATOR_IMAGE=myregistry/coherence-operator:3.3.5 +cd ./manager && kustomize edit add configmap env-vars --from-literal OPERATOR_IMAGE=myregistry/coherence-operator:3.4.3 ---- Change the name of the default Coherence image. If you are always going to be deploying your own application images then this @@ -864,7 +908,7 @@ This can be done using the Tanzu CLI. [source,bash] ---- tanzu package repository add coherence-repo \ - --url ghcr.io/oracle/coherence-operator-repo:3.3.5 \ + --url ghcr.io/oracle/coherence-operator-repo:3.4.3 \ --namespace coherence \ --create-namespace ---- @@ -894,7 +938,7 @@ which should include the Operator package, `coherence-operator.oracle.github.com [source,bash] ---- NAME DISPLAY-NAME SHORT-DESCRIPTION LATEST-VERSION -coherence-operator.oracle.github.com Oracle Coherence Operator A Kubernetes operator for managing Oracle Coherence clusters 3.3.5 +coherence-operator.oracle.github.com Oracle Coherence Operator A Kubernetes operator for managing Oracle Coherence clusters 3.4.3 ---- === Install the Coherence Operator Package @@ -905,7 +949,7 @@ Once the Coherence Operator repository has been installed, the `coherence-operat ---- tanzu package install coherence \ --package-name coherence-operator.oracle.github.com \ - --version 3.3.5 \ + --version 3.4.3 \ --namespace coherence ---- @@ -921,7 +965,7 @@ which should display the Coherence Operator package. [source,bash] ---- NAME PACKAGE-NAME PACKAGE-VERSION STATUS -coherence coherence-operator.oracle.github.com 3.3.5 Reconcile succeeded +coherence coherence-operator.oracle.github.com 3.4.3 Reconcile succeeded ---- The Operator is now installed and ready to mage Coherence clusters. \ No newline at end of file diff --git a/docs/management/026_queryplus.adoc b/docs/management/026_queryplus.adoc new file mode 100644 index 000000000..039504d42 --- /dev/null +++ b/docs/management/026_queryplus.adoc @@ -0,0 +1,118 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2023, Oracle and/or its affiliates. + Licensed under the Universal Permissive License v 1.0 as shown at + http://oss.oracle.com/licenses/upl. + +/////////////////////////////////////////////////////////////////////////////// + += The Coherence Query Plus + +== The Coherence Query Plus + +The Coherence Query Plus utility is a console application that allows simple SQL like queries +to be made against caches, see the +https://{commercial-docs-base-url}/develop-applications/using-coherence-query-language.html[Using Coherence Query Language] +section of the Coherence documentation. + +=== Using Query Plus in Pods + +Most official Coherence images are distroless images, so they do not have a shell that can be used to +create a command line session and execute commands. +The Operator works around this to support a few selected commands by injecting its `runner` utility. +The Operator installs the `runner` at the location `/coherence-operator/utils/runner`. + +The `runner` utility is a simple CLI that executes commands, one of those is `queryplus` which will +start a Java process running Query Plus. + +[CAUTION] +==== +The Query Plus JVM will join the cluster as a storage disabled member alongside the JVM running in the +Coherence container in the Pod. +The Query Plus session will have all the same configuration parameters as the Coherence container. + +For this reason, great care must be taken with the commands that are executed so that the cluster does not become unstable. +==== + +=== Start a Query Plus Session + +The yaml below will create a simple three member cluster. + +[source] +.minimal.yaml +---- +apiVersion: coherence.oracle.com/v1 +kind: Coherence +metadata: + name: storage +spec: + replicas: 3 +---- + +The cluster name is `storage` and there will be three Pods created, `storage-0`, `storage-1` and `storage-2`. + +A Query Plus session can be run by exec'ing into one of the Pods to execute the runner with the argument `queryplus`. + +[source,bash] +---- +kubectl exec -it storage-0 -c coherence -- /coherence-operator/runner queryplus +---- + +[NOTE] +==== +The `kubectl exec` command must include the `-it` options so that `kubectl` creates an interactive terminal session. +==== + +After executing the above command, the `CohQL>` prompt will be displayed ready to accept input. +Using the Query Plus utility is documented in the +https://{commercial-docs-base-url}/develop-applications/using-coherence-query-language.html#GUID-1CBE48A8-1009-4656-868D-663AA85CB021[Using the CohQL Command-Line Tool] +section of the Coherence documentation + + +=== Run Query Plus With Command Line Arguments + +Instead of running an interactive Query Plus session, arguments can be passed into Query Plus as part of the exec command. +Query Plus will execute the commands and exit. + +The command line for this is slightly complicated because there are two CLI programs involved in the full command line, +first `kubectl` and second the Operator's runner. +In each case the `--` command line separator needs to be used so that each CLI knows the everything after a `--` +is to be passed to the next process. + +For example a simple string key and value could be inserted into a cache named "test" with the following +CohQL statement `insert into "test" key "one" value "value-one"`. +This statement can be executed in a Pod with the following command + +[source,bash] +---- +kubectl exec storage-0 -c coherence -- /coherence-operator/runner queryplus -- -c -l 'insert into test key "one" value "value-one"' +---- + +In the above example the first `--` tels `kubectl` that all the remaining arguments are to be passed +as arguments to the exec session. The second `--` tells the Operator runner that all the remaining arguments +are to be passed to Query Plus. + +After running the above command the cache `test` will contain an entry with the key `"one"` and value `"value-one"`. +If the statement `select * from test` is executed the value in the cache will be displayed. + +[source,bash] +---- +kubectl exec storage-0 -c coherence -- /coherence-operator/runner queryplus -- -c -l 'select * from test' +---- + +The last few lines of the console output will display the results of executing the statement: +[source] +---- +Results +"value-one" +---- + + + + + + + + + + diff --git a/docs/management/027_jshell.adoc b/docs/management/027_jshell.adoc new file mode 100644 index 000000000..6155e1420 --- /dev/null +++ b/docs/management/027_jshell.adoc @@ -0,0 +1,97 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2023, Oracle and/or its affiliates. + Licensed under the Universal Permissive License v 1.0 as shown at + http://oss.oracle.com/licenses/upl. + +/////////////////////////////////////////////////////////////////////////////// + += Using JShell + +== Using JShell + +JShell is a Java utility that allows Java code to be executed in a console. +Whilst it is simple to exec into a Pod and run JShell, the Coherence Operator will run JShell +configured with the same class path and system properties as the running Coherence container. +This makes it simpler to invoke JShell commands knowing that everything required to +access the running Coherence JVM is present. + +=== Using JShell in Pods + +The Operator installs a simple CLI named `runner` at the location `/coherence-operator/utils/runner`. +One of the commands the runner can execute is `jshell` which will start a JShell process. + +[CAUTION] +==== +JShell can be a useful debugging tool, but running JShell in a production cluster is not recommended. + +The JShell JVM will join the cluster as a storage disabled member alongside the JVM running in the +Coherence container in the Pod. +The JShell session will have all the same configuration parameters as the Coherence container. + +For this reason, great care must be taken with the commands that are executed so that the cluster does not become unstable. +==== + +=== Start a JShell Session + +The `kubectl exec` command can be used to create an interactive session in a Pod using the Coherence Operator runner +to start a JShell session. + +*Example* + +The yaml below will create a simple three member cluster. + +[source] +.minimal.yaml +---- +apiVersion: coherence.oracle.com/v1 +kind: Coherence +metadata: + name: storage +spec: + replicas: 3 +---- + +The cluster name is `storage` and there will be three Pods created, `storage-0`, `storage-1` and `storage-2`. + +A Query Plus session can be run by exec'ing into one of the Pods to execute the runner with the argument `jshell`. + +[source,bash] +---- +kubectl exec -it storage-0 -c coherence -- /coherence-operator/runner jshell +---- + +After executing the above command, the `jshell>` prompt will be displayed ready to accept input. + +[NOTE] +==== +The `kubectl exec` command must include the `-it` options so that `kubectl` creates an interactive terminal session. +==== + +=== Starting Coherence + +The JShell session only starts the JShell REPL and Coherence is not started in the JShell process. +As the JShell process has all the same configuration except it is configured to be storage disabled. +As the Coherence container in the Pod any of the normal ways to bootstrap Coherence can be used. +Any configuration changes, for example setting system properties, can be done before Coherence is started. + +For example: + +[source,java] +---- +jshell> import com.tangosol.net.*; + +jshell> Coherence c = Coherence.clusterMember().start().join(); + +jshell> Session s = c.getSession(); +s ==> com.tangosol.internal.net.ConfigurableCacheFactorySession@3d0f8e03 + +jshell> NamedCache cache = s.getCache("test"); +cache ==> com.tangosol.internal.net.SessionNamedCache@91213130 + +jshell> cache.size(); +$5 ==> 0 + +jshell> +---- + diff --git a/docs/sitegen.yaml b/docs/sitegen.yaml index 4f731b45f..2f77024b5 100644 --- a/docs/sitegen.yaml +++ b/docs/sitegen.yaml @@ -16,7 +16,7 @@ engine: coherence-image: "${coherence.image}" k8s-doc-link: "kubernetes.io/docs/reference/generated/kubernetes-api/${k8s-doc-version}" guides-dir: "${project.basedir}/../examples/guides" - commercial-docs-base-url: "docs.oracle.com/en/middleware/standalone/coherence/14.1.1.2206" + commercial-docs-base-url: "docs.oracle.com/en/middleware/fusion-middleware/coherence/14.1.2" examples-source: "github.com/oracle/coherence-operator/tree/main/examples/" assets: - target: "/" diff --git a/examples/016_simple_docker_image/README.adoc b/examples/016_simple_docker_image/README.adoc index d752efe87..31d79e80c 100644 --- a/examples/016_simple_docker_image/README.adoc +++ b/examples/016_simple_docker_image/README.adoc @@ -37,7 +37,7 @@ FROM gcr.io/distroless/java11-debian11 # Health checks will only work with Coherence 22.06 and later HEALTHCHECK --start-period=10s --interval=30s \ CMD ["java", \ - "-cp", "/app/libs/coherence.jar", \ + "--class-path", "/app/libs/coherence.jar", \ "com.tangosol.util.HealthCheckClient", \ "http://127.0.0.1:6676/ready", \ "||", "exit", "1"] @@ -53,7 +53,7 @@ EXPOSE 9612 EXPOSE 6676 # Set the entry point to be the Java command to run -ENTRYPOINT ["java", "-cp", "/app/classes:/app/libs/*", "com.tangosol.net.Coherence"] +ENTRYPOINT ["java", "--class-path", "/app/classes:/app/libs/*", "com.tangosol.net.Coherence"] # Set any environment variables # Set the health check port to a fixed value (corresponding to the command above) diff --git a/examples/no-operator/01_simple_server/coherence.yaml b/examples/no-operator/01_simple_server/coherence.yaml index 9c8e65def..56f1c8102 100644 --- a/examples/no-operator/01_simple_server/coherence.yaml +++ b/examples/no-operator/01_simple_server/coherence.yaml @@ -86,7 +86,7 @@ spec: command: - java args: - - -cp + - --class-path - "@/app/jib-classpath-file" - -Xms1800m - -Xmx1800m diff --git a/examples/no-operator/02_metrics/README.adoc b/examples/no-operator/02_metrics/README.adoc index 9b265df9e..feab8f441 100644 --- a/examples/no-operator/02_metrics/README.adoc +++ b/examples/no-operator/02_metrics/README.adoc @@ -61,7 +61,7 @@ spec: command: - java args: - - -cp + - "--class-path" - "@/app/jib-classpath-file" - -Xms1800m - -Xmx1800m diff --git a/examples/no-operator/02_metrics/coherence-metrics.yaml b/examples/no-operator/02_metrics/coherence-metrics.yaml index e2a7d4193..09ec2ccbf 100644 --- a/examples/no-operator/02_metrics/coherence-metrics.yaml +++ b/examples/no-operator/02_metrics/coherence-metrics.yaml @@ -86,7 +86,7 @@ spec: command: - java args: - - -cp + - --class-path - "@/app/jib-classpath-file" - -Xms1800m - -Xmx1800m diff --git a/examples/no-operator/03_extend_tls/README.adoc b/examples/no-operator/03_extend_tls/README.adoc index b4a96ed29..4ba5a7629 100644 --- a/examples/no-operator/03_extend_tls/README.adoc +++ b/examples/no-operator/03_extend_tls/README.adoc @@ -225,7 +225,7 @@ spec: command: - java args: - - -cp + - "--class-path" - "@/app/jib-classpath-file" - -Xms1800m - -Xmx1800m diff --git a/examples/no-operator/03_extend_tls/coherence-tls.yaml b/examples/no-operator/03_extend_tls/coherence-tls.yaml index 2d3ed2ba0..29a2285f1 100644 --- a/examples/no-operator/03_extend_tls/coherence-tls.yaml +++ b/examples/no-operator/03_extend_tls/coherence-tls.yaml @@ -93,7 +93,7 @@ spec: command: - java args: - - -cp + - "--class-path" - "@/app/jib-classpath-file" - -Xms1800m - -Xmx1800m diff --git a/examples/no-operator/04_istio/README.adoc b/examples/no-operator/04_istio/README.adoc index 8a72281c8..66660d99f 100644 --- a/examples/no-operator/04_istio/README.adoc +++ b/examples/no-operator/04_istio/README.adoc @@ -310,7 +310,7 @@ using the Bootstrap API introduced in 22.06. Start Coherence using `com.tangosol.net.Coherence` as the main class. [source,bash] ---- -java -cp coherence.jar com.tangosol.net.Coherence +java --class-path coherence.jar com.tangosol.net.Coherence ---- Start Coherence in code: diff --git a/go.mod b/go.mod index 12c328493..c1cda6e83 100644 --- a/go.mod +++ b/go.mod @@ -11,84 +11,113 @@ require ( github.com/go-test/deep v1.1.1 github.com/onsi/gomega v1.36.2 github.com/pkg/errors v0.9.1 - github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.79.2 - github.com/prometheus-operator/prometheus-operator/pkg/client v0.79.2 - github.com/spf13/cobra v1.8.1 - github.com/spf13/pflag v1.0.5 + github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.1 + github.com/prometheus-operator/prometheus-operator/pkg/client v0.80.1 + github.com/spf13/cobra v1.9.1 + github.com/spf13/pflag v1.0.6 github.com/spf13/viper v1.19.0 - golang.org/x/mod v0.22.0 - golang.org/x/net v0.33.0 - k8s.io/api v0.32.0 - k8s.io/apiextensions-apiserver v0.32.0 - k8s.io/apimachinery v0.32.0 - k8s.io/client-go v0.32.0 + golang.org/x/mod v0.23.0 + golang.org/x/net v0.35.0 + k8s.io/api v0.32.2 + k8s.io/apiextensions-apiserver v0.32.2 + k8s.io/apimachinery v0.32.2 + k8s.io/client-go v0.32.2 k8s.io/utils v0.0.0-20241210054802-24370beab758 - sigs.k8s.io/controller-runtime v0.19.3 + sigs.k8s.io/controller-runtime v0.20.2 sigs.k8s.io/testing_frameworks v0.1.2 ) require ( + cel.dev/expr v0.18.0 // indirect + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.12.1 // indirect - github.com/evanphx/json-patch v5.9.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/cel-go v0.22.0 // indirect github.com/google/gnostic-models v0.6.9 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20250208200701-d0013a598941 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/magiconair/properties v1.8.9 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/spdystream v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/onsi/ginkgo/v2 v2.22.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/prometheus/client_golang v1.21.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/afero v1.12.0 // indirect + github.com/spf13/cast v1.7.1 // indirect + github.com/stoewer/go-strcase v1.3.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/x448/float16 v0.8.4 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect + go.opentelemetry.io/otel v1.29.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.29.0 // indirect + go.opentelemetry.io/otel/sdk v1.29.0 // indirect + go.opentelemetry.io/otel/trace v1.29.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/term v0.27.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/time v0.8.0 // indirect + golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect + golang.org/x/time v0.10.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/protobuf v1.36.1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 // indirect + google.golang.org/grpc v1.67.3 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apiserver v0.32.2 // indirect + k8s.io/component-base v0.32.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20241212045625-5ad02ce6640f // indirect + k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 25323de97..78dc0c8db 100644 --- a/go.sum +++ b/go.sum @@ -1,32 +1,47 @@ +cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo= +cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= -github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= -github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= -github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= @@ -44,20 +59,26 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g= +github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20250208200701-d0013a598941 h1:43XjGa6toxLpeksjcxs1jIoIyr+vUfOqY2c6HB4bpoc= +github.com/google/pprof v0.0.0-20250208200701-d0013a598941/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -68,6 +89,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -75,10 +98,12 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= +github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= @@ -94,67 +119,84 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/onsi/ginkgo v1.4.0 h1:n60/4GZK0Sr9O2iuGKq876Aoa0ER2ydgpMOBwzJ8e2c= github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo/v2 v2.22.1 h1:QW7tbJAUDyVDVOM5dFa7qaybo+CRfR7bemlQUN6Z8aM= -github.com/onsi/ginkgo/v2 v2.22.1/go.mod h1:S6aTpoRsSq2cZOd+pssHAlKW/Q/jZt6cPrPlnj4a1xM= +github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= +github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.79.2 h1:DGv150w4UyxnjNHlkCw85R3+lspOxegtdnbpP2vKRrk= -github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.79.2/go.mod h1:AVMP4QEW8xuGWnxaWSpI3kKjP9fDA31nO68zsyREJZA= -github.com/prometheus-operator/prometheus-operator/pkg/client v0.79.2 h1:wUMuHTC069Ayy+0/srqD5OrLVP/QRhSCUR/7SJ8tSqQ= -github.com/prometheus-operator/prometheus-operator/pkg/client v0.79.2/go.mod h1:671/KciyzKiTmvIYTpp7CzWD1/TNXVPgeDLJcGFWrOM= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.1 h1:DP+PUNVOc+Bkft8a4QunLzaZ0RspWuD3tBbcPHr2PeE= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.1/go.mod h1:6x4x0t9BP35g4XcjkHE9EB3RxhyfxpdpmZKd/Qyk8+M= +github.com/prometheus-operator/prometheus-operator/pkg/client v0.80.1 h1:7/TPlTy7tkMXC1KwS2WdUdU8J220DszlSQ1+KHjXwHc= +github.com/prometheus-operator/prometheus-operator/pkg/client v0.80.1/go.mod h1:0lW4yp2XE7AKohpGB2UGdomjP08rbr4f8JwAN6sUDWU= +github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA= +github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= +github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= +github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= +go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= +go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= +go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= +go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= +go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= +go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= +go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= +go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -164,53 +206,61 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= +golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= +golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= -golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= -golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= +golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= +golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8 h1:TqExAhdPaB60Ux47Cn0oLV07rGnxZzIsaRhQaqS666A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA= +google.golang.org/grpc v1.67.3 h1:OgPcDAFKHnH8X3O4WcO4XUc8GRDeKsKReqbQtiCj7N8= +google.golang.org/grpc v1.67.3/go.mod h1:YGaHCc6Oap+FzBJTZLBzkGSYt/cvGPFTPxkn7QfSU8s= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -228,22 +278,28 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= -k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= -k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0= -k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw= -k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= -k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= -k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= -k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= +k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw= +k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y= +k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4= +k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA= +k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ= +k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/apiserver v0.32.2 h1:WzyxAu4mvLkQxwD9hGa4ZfExo3yZZaYzoYvvVDlM6vw= +k8s.io/apiserver v0.32.2/go.mod h1:PEwREHiHNU2oFdte7BjzA1ZyjWjuckORLIK/wLV5goM= +k8s.io/client-go v0.32.2 h1:4dYCD4Nz+9RApM2b/3BtVvBHw54QjMFUl1OLcJG5yOA= +k8s.io/client-go v0.32.2/go.mod h1:fpZ4oJXclZ3r2nDOv+Ux3XcJutfrwjKTCHz2H3sww94= +k8s.io/component-base v0.32.2 h1:1aUL5Vdmu7qNo4ZsE+569PV5zFatM9hl+lb3dEea2zU= +k8s.io/component-base v0.32.2/go.mod h1:PXJ61Vx9Lg+P5mS8TLd7bCIr+eMJRQTyXe8KvkrvJq0= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20241212045625-5ad02ce6640f h1:jyijczch0N1N0Uk0p4P0hfgTP+2Rkt4m6pVX8l3R6q4= -k8s.io/kube-openapi v0.0.0-20241212045625-5ad02ce6640f/go.mod h1:iZjdMQzunI7O/sUrf/5WRX1gvaAIam32lKx9+paoLbU= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas= k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.19.3 h1:XO2GvC9OPftRst6xWCpTgBZO04S2cbp0Qqkj8bX1sPw= -sigs.k8s.io/controller-runtime v0.19.3/go.mod h1:j4j87DqtsThvwTv5/Tc5NFRyyF/RF0ip4+62tbTSIUM= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 h1:CPT0ExVicCzcpeN4baWEV2ko2Z/AsiZgEdwgcfwLgMo= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/controller-runtime v0.20.2 h1:/439OZVxoEc02psi1h4QO3bHzTgu49bb347Xp4gW1pc= +sigs.k8s.io/controller-runtime v0.20.2/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk= diff --git a/hack/catalog-template.yaml b/hack/catalog-template.yaml new file mode 100644 index 000000000..3c5d4b1f1 --- /dev/null +++ b/hack/catalog-template.yaml @@ -0,0 +1,6 @@ +--- +schema: olm.channel +package: coherence-operator +name: stable +entries: + - name: coherence-operator.v \ No newline at end of file diff --git a/hack/ensure-sdk.sh b/hack/ensure-sdk.sh index f8418fc51..c28336666 100755 --- a/hack/ensure-sdk.sh +++ b/hack/ensure-sdk.sh @@ -27,16 +27,16 @@ if [ ${OK} != 0 ]; then echo "Operator SDK not found or not correct version" if [ "${UNAME_S}" = "Darwin" ]; then - if [ "${UNAME_S}" = "x86_64" ]; then + if [ "${UNAME_M}" = "x86_64" ]; then URL="https://github.com/operator-framework/operator-sdk/releases/download/${REQUIRED_VERSION}/operator-sdk_darwin_amd64" else URL="https://github.com/operator-framework/operator-sdk/releases/download/${REQUIRED_VERSION}/operator-sdk_darwin_arm64" fi else - if [ "${UNAME_S}" = "x86_64" ]; then - URL="https://github.com/operator-framework/operator-sdk/releases/download/${REQUIRED_VERSION}/operator-sdk-linux-amd64" + if [ "${UNAME_M}" = "x86_64" ]; then + URL="https://github.com/operator-framework/operator-sdk/releases/download/${REQUIRED_VERSION}/operator-sdk_linux_amd64" else - URL="https://github.com/operator-framework/operator-sdk/releases/download/${REQUIRED_VERSION}/operator-sdk-linux-arm64" + URL="https://github.com/operator-framework/operator-sdk/releases/download/${REQUIRED_VERSION}/operator-sdk_linux_arm64" fi fi diff --git a/hack/k8s-certification.sh b/hack/k8s-certification.sh index d496aba8c..bab20b3d0 100755 --- a/hack/k8s-certification.sh +++ b/hack/k8s-certification.sh @@ -1,5 +1,11 @@ #!/usr/bin/env bash +# +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# + # -------------------------------------------------------------------------------- # This script will build the Operator and run the K8s certification test suite. # @@ -25,7 +31,19 @@ export OPERATOR_NAMESPACE=coherence echo "Building Operator" -if ! make build-all-images; +if ! make build-operator; +then + exit 1 +fi + +echo "Building Test imager" +if ! make build-basic-test-image; +then + exit 1 +fi + +echo "Building Compatibility Test imager" +if ! make build-compatibility-image; then exit 1 fi diff --git a/hack/logo.svg b/hack/logo.svg new file mode 100644 index 000000000..aeb176b89 --- /dev/null +++ b/hack/logo.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hack/operator-catalog-source.yaml b/hack/operator-catalog-source.yaml new file mode 100644 index 000000000..0333dde60 --- /dev/null +++ b/hack/operator-catalog-source.yaml @@ -0,0 +1,13 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: CatalogSource +metadata: + name: coherence-operator-catalog + namespace: olm +spec: + displayName: Oracle Coherence Operators + image: IMAGE_NAME_PLACEHOLDER + publisher: Oracle Corporation + sourceType: grpc + updateStrategy: + registryPoll: + interval: 60m diff --git a/hack/operator-group.yaml b/hack/operator-group.yaml new file mode 100644 index 000000000..59c532e26 --- /dev/null +++ b/hack/operator-group.yaml @@ -0,0 +1,5 @@ +apiVersion: operators.coreos.com/v1 +kind: OperatorGroup +metadata: + name: coherence-operator-group + namespace: coherence diff --git a/hack/operator-subscription.yaml b/hack/operator-subscription.yaml new file mode 100644 index 000000000..ec1d1e47e --- /dev/null +++ b/hack/operator-subscription.yaml @@ -0,0 +1,11 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: coherence-operator + namespace: coherence +spec: + channel: stable + name: coherence-operator + source: coherence-operator-catalog + sourceNamespace: olm + installPlanApproval: Automatic diff --git a/hack/push-images.sh b/hack/push-images.sh new file mode 100755 index 000000000..2949f3e95 --- /dev/null +++ b/hack/push-images.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# +set -x -e + +buildah version + +if [ "${OPERATOR_IMAGE_REGISTRY}" != "" ] && [ "${REGISTRY_USERNAME}" != "" ] && [ "${REGISTRY_PASSWORD}" != "" ] +then + buildah login -u "${REGISTRY_USERNAME}" -p "${REGISTRY_PASSWORD}" "${OPERATOR_IMAGE_REGISTRY}" +fi + +if [ "${NO_DOCKER_DAEMON}" != "true" ] +then + buildah pull "docker-daemon:${OPERATOR_IMAGE_AMD}" + buildah pull "docker-daemon:${OPERATOR_IMAGE_ARM}" +fi + +DESCR='The Oracle Coherence Kubernetes Operator allows full lifecycle management of Oracle Coherence workloads in Kubernetes.' + +buildah rmi "${OPERATOR_IMAGE}" || true +buildah manifest rm "${OPERATOR_IMAGE}" || true +buildah manifest create \ + --annotation org.opencontainers.image.source=https://github.com/oracle/coherence-operator \ + --annotation org.opencontainers.image.description="${DESCR}" \ + --annotation org.opencontainers.image.licenses="UPL-1.0" \ + --annotation org.opencontainers.image.version="${VERSION}" \ + --annotation org.opencontainers.image.revision="${REVISION}" \ + "${OPERATOR_IMAGE}" +buildah manifest add --arch amd64 --os linux \ + --annotation org.opencontainers.image.source=https://github.com/oracle/coherence-operator \ + --annotation org.opencontainers.image.description="${DESCR}" \ + --annotation org.opencontainers.image.licenses="UPL-1.0" \ + --annotation org.opencontainers.image.version="${VERSION}" \ + --annotation org.opencontainers.image.revision="${REVISION}" \ + "${OPERATOR_IMAGE}" "${OPERATOR_IMAGE_AMD}" +buildah manifest add --arch arm64 --os linux \ + --annotation org.opencontainers.image.source=https://github.com/oracle/coherence-operator \ + --annotation org.opencontainers.image.description="${DESCR}" \ + --annotation "org.opencontainers.image.licenses"="UPL-1.0" \ + --annotation org.opencontainers.image.version="${VERSION}" \ + --annotation org.opencontainers.image.revision="${REVISION}" \ + "${OPERATOR_IMAGE}" "${OPERATOR_IMAGE_ARM}" +buildah manifest inspect "${OPERATOR_IMAGE}" + +buildah manifest push --all -f v2s2 "${OPERATOR_IMAGE}" "docker://${OPERATOR_IMAGE}" diff --git a/hack/run-buildah.sh b/hack/run-buildah.sh new file mode 100755 index 000000000..e8765f4ea --- /dev/null +++ b/hack/run-buildah.sh @@ -0,0 +1,121 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# + +# --------------------------------------------------------------------------- +# This script determines whether Buildah is available locally and if it is +# runs the Coherence image builder script otherwise it starts Buildah inside +# a container and exports the images to the local Docker daemon. +# --------------------------------------------------------------------------- +set -x -e + +BASEDIR=$(dirname "$0") + +# Ensure the OPERATOR_IMAGE has been set - this is the name of the image to build +if [ "${OPERATOR_IMAGE}" == "" ] +then + echo "ERROR: No OPERATOR_IMAGE environment variable has been set" + exit 1 +fi + +if [ "${OPERATOR_IMAGE_AMD}" == "" ] +then + OPERATOR_IMAGE_AMD="${OPERATOR_IMAGE}-amd64" +fi + +if [ "${OPERATOR_IMAGE_ARM}" == "" ] +then + OPERATOR_IMAGE_AMD="${OPERATOR_IMAGE}-arm64" +fi + +ARGS= + +if [ "$1" == "PUSH" ] +then + SCRIPT_NAME="${BASEDIR}/push-images.sh" +elif [ "$1" == "EXEC" ] +then + SCRIPT_NAME= + ARGS=-it +fi + +if [ "${SCRIPT_NAME}" != "" ] +then + chmod +x "${SCRIPT_NAME}" +fi + +BUILDAH="" +if [ "${LOCAL_BUILDAH}" == "true" ] +then + BUILDAH=$(which buildah || true) +fi + +if [ "${BUILDAH}" != "" ] +then + echo "Running Buildah locally" + if [ "${NO_DOCKER_DAEMON}" == "" ] + then + export NO_DOCKER_DAEMON=true + fi +# we must run the script with Buildah unshare + buildah unshare "${SCRIPT_NAME}" +else + echo "Buildah not found locally - running in container" + if [ "${NO_DOCKER_DAEMON}" == "" ] + then + NO_DOCKER_DAEMON=false + fi + + $DOCKER_CMD rm -f buildah || true + + if [ "${BUILDAH_VOLUME}" == "" ] + then + export BUILDAH_VOLUME=buildah-containers-volume + fi + + if ! $DOCKER_CMD volume inspect "${BUILDAH_VOLUME}"; + then + $DOCKER_CMD volume create "${BUILDAH_VOLUME}" + fi + if [ "${MY_DOCKER_HOST}" == "" ] + then + DOCKER_HOST="${MY_DOCKER_HOST}" + fi + + if [ "${DOCKER_HOST}" == "" ] + then + PDM=$(which podman || true) + if [ "${USE_PODMAN}" != "false" && "${PDM}" != "" ] + then +# we're using Podman + MY_UID=$(id -u) + DOCKER_HOST=/run/user/${MY_UID}/podman/podman.sock + else +# we're using Docker + DOCKER_HOST=/var/run/docker.sock + fi + fi + + $DOCKER_CMD run --rm ${ARGS} -v "${BASEDIR}:${BASEDIR}" \ + -v ${DOCKER_HOST}:${DOCKER_HOST} \ + --privileged --network host \ + -e VERSION="${VERSION}" \ + -e REVISION="${REVISION}" \ + -e OPERATOR_IMAGE="${OPERATOR_IMAGE}" \ + -e OPERATOR_IMAGE_AMD="${OPERATOR_IMAGE_AMD}" \ + -e OPERATOR_IMAGE_ARM="${OPERATOR_IMAGE_ARM}" \ + -e PODMAN_IMPORT="${PODMAN_IMPORT}" \ + -e DOCKER_HOST="${DOCKER_HOST}" \ + -e NO_DOCKER_DAEMON="${NO_DOCKER_DAEMON}" \ + -e OPERATOR_IMAGE_REGISTRY="${OPERATOR_IMAGE_REGISTRY}" \ + -e REGISTRY_USERNAME="${REGISTRY_USERNAME}" \ + -e REGISTRY_PASSWORD="${REGISTRY_PASSWORD}" \ + -e HTTP_PROXY="${HTTP_PROXY}" -e HTTPS_PROXY="${HTTPS_PROXY}" -e NO_PROXY="${NO_PROXY}" \ + -e http_proxy="${http_proxy}" -e https_proxy="${https_proxy}" -e no_proxy="${no_proxy}" \ + --name buildah \ + quay.io/buildah/stable:v1.37.1 "${SCRIPT_NAME}" +fi + diff --git a/hack/setup-crc.sh b/hack/setup-crc.sh new file mode 100644 index 000000000..4b0733605 --- /dev/null +++ b/hack/setup-crc.sh @@ -0,0 +1,26 @@ +# +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# + +#!/usr/bin/env bash + +# -------------------------------------------------------------------- +# This script exports various environment variables so that +# Make targets will be executed using Podman and OpenShift CRC. +# -------------------------------------------------------------------- + +export DOCKER_CMD=podman +export PUSH_ARGS=--tls-verify=false +export REGISTRY=$(oc get route/default-route -n openshift-image-registry -o=jsonpath='{.spec.host}') +export OPERATOR_IMAGE_REGISTRY=${REGISTRY}/oracle +export PREFLIGHT_REGISTRY_CRED=$(echo -n bogus:$(oc whoami -t) | base64) + +podman login -u bogus -p $(oc whoami -t) --tls-verify=false ${REGISTRY} +podman login -u bogus -p $(oc whoami -t) --tls-verify=false ${OPERATOR_IMAGE_REGISTRY} + +#oc new-project oracle || true +#oc -n oracle create is coherence-operator || true +# Allow anyone to pull oracle images +#oc adm policy add-role-to-group system:image-puller system:authenticated --namespace=oracle diff --git a/hack/setup-iad-env.sh b/hack/setup-iad-env.sh new file mode 100644 index 000000000..ab74cad18 --- /dev/null +++ b/hack/setup-iad-env.sh @@ -0,0 +1,9 @@ +# +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# + +#!/usr/bin/env bash + +export OPERATOR_IMAGE_REGISTRY=iad.ocir.io/odx-stateservice/test diff --git a/hack/setup-openshift.sh b/hack/setup-openshift.sh new file mode 100644 index 000000000..05be5a544 --- /dev/null +++ b/hack/setup-openshift.sh @@ -0,0 +1,20 @@ +# +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# + +#!/usr/bin/env bash + +export OPERATOR_IMAGE_REGISTRY=iad.ocir.io/odx-stateservice/test +export DOCKER_CMD=podman +export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock +export MY_DOCKER_HOST=${DOCKER_HOST} +export JIB_EXECUTABLE=$(which podman) +export USE_PODMAN=true +export LOCAL_BUILDAH=true +export DEPLOY_REGISTRY_CONFIG_DIR=$XDG_RUNTIME_DIR/containers +export DEPLOY_REGISTRY_CONFIG_JSON=auth.json + +echo "OpenShift setup done" +echo "Run podman login iad.ocir.io" diff --git a/hack/setup-podman.sh b/hack/setup-podman.sh index d37cca460..29a8df8eb 100644 --- a/hack/setup-podman.sh +++ b/hack/setup-podman.sh @@ -8,19 +8,10 @@ # -------------------------------------------------------------------- # This script exports various environment variables so that -# Make targets will be executed using Podman and OpenShift. +# Make targets will be executed using Podman. # -------------------------------------------------------------------- export DOCKER_CMD=podman -export PUSH_ARGS=--tls-verify=false -export REGISTRY=$(oc get route/default-route -n openshift-image-registry -o=jsonpath='{.spec.host}') -export OPERATOR_IMAGE_REGISTRY=${REGISTRY}/oracle -export PREFLIGHT_REGISTRY_CRED=$(echo -n bogus:$(oc whoami -t) | base64) - -podman login -u bogus -p $(oc whoami -t) --tls-verify=false ${REGISTRY} -podman login -u bogus -p $(oc whoami -t) --tls-verify=false ${OPERATOR_IMAGE_REGISTRY} - -#oc new-project oracle || true -#oc -n oracle create is coherence-operator || true -# Allow anyone to pull oracle images -#oc adm policy add-role-to-group system:image-puller system:authenticated --namespace=oracle +export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock +export JIB_EXECUTABLE=$(which podman) +export MY_DOCKER_HOST=${DOCKER_HOST} diff --git a/helm-charts/coherence-operator/templates/deployment.yaml b/helm-charts/coherence-operator/templates/deployment.yaml index 04dec6ff4..c19d40ad0 100644 --- a/helm-charts/coherence-operator/templates/deployment.yaml +++ b/helm-charts/coherence-operator/templates/deployment.yaml @@ -11,6 +11,9 @@ metadata: {{- end }} {{- if (.Values.globalAnnotations) }} annotations: + control-plane: coherence + app.kubernetes.io/version: "${VERSION}" + app.kubernetes.io/part-of: coherence-operator {{ toYaml .Values.globalAnnotations | indent 4 }} {{- end }} {{- end }} @@ -83,14 +86,14 @@ metadata: name: coherence-operator namespace: {{ .Release.Namespace }} labels: + app: coherence-operator control-plane: coherence + version: "${VERSION}" app.kubernetes.io/name: coherence-operator app.kubernetes.io/instance: coherence-operator-manager app.kubernetes.io/version: "${VERSION}" app.kubernetes.io/component: manager app.kubernetes.io/part-of: coherence-operator - app.kubernetes.io/managed-by: helm - app.kubernetes.io/created-by: controller-manager {{- if (.Values.globalLabels) }} {{ toYaml .Values.globalLabels | indent 4 }} {{- end }} @@ -114,13 +117,15 @@ spec: template: metadata: labels: + app: coherence-operator control-plane: coherence + version: "${VERSION}" app.kubernetes.io/name: coherence-operator + app.kubernetes.io/managed-by: helm app.kubernetes.io/instance: coherence-operator-manager app.kubernetes.io/version: "${VERSION}" app.kubernetes.io/component: manager app.kubernetes.io/part-of: coherence-operator - app.kubernetes.io/managed-by: helm app.kubernetes.io/created-by: controller-manager {{- if (.Values.globalLabels) }} {{ toYaml .Values.globalLabels | indent 8 }} diff --git a/helm-charts/coherence-operator/templates/rbac.yaml b/helm-charts/coherence-operator/templates/rbac.yaml index 16a3d3707..720f1e28f 100644 --- a/helm-charts/coherence-operator/templates/rbac.yaml +++ b/helm-charts/coherence-operator/templates/rbac.yaml @@ -8,6 +8,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/version: "${VERSION}" + app.kubernetes.io/part-of: coherence-operator {{- if (.Values.globalLabels) }} {{ toYaml .Values.globalLabels | indent 4 }} {{- end }} @@ -28,6 +31,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/version: "${VERSION}" + app.kubernetes.io/part-of: coherence-operator {{- if (.Values.globalLabels) }} {{ toYaml .Values.globalLabels | indent 4 }} {{- end }} @@ -68,6 +74,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/version: "${VERSION}" + app.kubernetes.io/part-of: coherence-operator {{- if (.Values.globalLabels) }} {{ toYaml .Values.globalLabels | indent 4 }} {{- end }} @@ -99,6 +108,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/version: "${VERSION}" + app.kubernetes.io/part-of: coherence-operator {{- if (.Values.globalLabels) }} {{ toYaml .Values.globalLabels | indent 4 }} {{- end }} @@ -127,6 +139,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/version: "${VERSION}" + app.kubernetes.io/part-of: coherence-operator {{- if (.Values.globalLabels) }} {{ toYaml .Values.globalLabels | indent 4 }} {{- end }} @@ -159,6 +174,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/version: "${VERSION}" + app.kubernetes.io/part-of: coherence-operator {{- if (.Values.globalLabels) }} {{ toYaml .Values.globalLabels | indent 4 }} {{- end }} @@ -267,6 +285,9 @@ metadata: namespace: {{ .Release.Namespace }} labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/version: "${VERSION}" + app.kubernetes.io/part-of: coherence-operator {{- if (.Values.globalLabels) }} {{ toYaml .Values.globalLabels | indent 4 }} {{- end }} @@ -297,6 +318,9 @@ metadata: name: leader-election-role labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/version: "${VERSION}" + app.kubernetes.io/part-of: coherence-operator {{- if (.Values.globalLabels) }} {{ toYaml .Values.globalLabels | indent 4 }} {{- end }} @@ -347,6 +371,9 @@ metadata: name: leader-election-rolebinding labels: control-plane: coherence + app.kubernetes.io/name: coherence-operator + app.kubernetes.io/version: "${VERSION}" + app.kubernetes.io/part-of: coherence-operator {{- if (.Values.globalLabels) }} {{ toYaml .Values.globalLabels | indent 4 }} {{- end }} diff --git a/helm-charts/coherence-operator/values.yaml b/helm-charts/coherence-operator/values.yaml index 6c159a117..e59484d13 100644 --- a/helm-charts/coherence-operator/values.yaml +++ b/helm-charts/coherence-operator/values.yaml @@ -15,7 +15,7 @@ defaultCoherenceImage: name: "${COHERENCE_IMAGE_NAME}" tag: "${COHERENCE_IMAGE_TAG}" -# watchNamespaces is the comma delimited list of namespaces that the operator should +# watchNamespaces is the comma-delimited list of namespaces that the operator should # manage Coherence resources in. The default is to manage all namespaces. watchNamespaces: "" diff --git a/java/operator-compatibility/image-build.sh b/java/operator-compatibility/image-build.sh deleted file mode 100644 index ba641d5e2..000000000 --- a/java/operator-compatibility/image-build.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e - -docker build --load -t jk/coherence:1.0.0 -f operator-compatibility/target/classes/Dockerfile ./operator-compatibility \ No newline at end of file diff --git a/java/operator-compatibility/pom.xml b/java/operator-compatibility/pom.xml index e79184668..362028840 100644 --- a/java/operator-compatibility/pom.xml +++ b/java/operator-compatibility/pom.xml @@ -57,7 +57,7 @@ exec-maven-plugin ${version.plugin.maven.exec} - docker + ${docker.command} build --load diff --git a/java/operator-test-spring-2/pom.xml b/java/operator-test-spring-2/pom.xml index 1cf551e4c..194781fdf 100644 --- a/java/operator-test-spring-2/pom.xml +++ b/java/operator-test-spring-2/pom.xml @@ -1,11 +1,9 @@ + ~ Copyright (c) 2020, 2025, Oracle and/or its affiliates. + ~ Licensed under the Universal Permissive License v 1.0 as shown at + ~ http://oss.oracle.com/licenses/upl. + --> 17.* + + ${env.DOCKER_HOST} + true + diff --git a/java/operator-test-spring/pom.xml b/java/operator-test-spring/pom.xml index 01b25a566..fd9ca7071 100644 --- a/java/operator-test-spring/pom.xml +++ b/java/operator-test-spring/pom.xml @@ -1,11 +1,9 @@ + ~ Copyright (c) 2020, 2025, Oracle and/or its affiliates. + ~ Licensed under the Universal Permissive License v 1.0 as shown at + ~ http://oss.oracle.com/licenses/upl. + --> ${cnbp-image-name} + + ${env.DOCKER_HOST} + true + diff --git a/java/pom.xml b/java/pom.xml index 1227ac408..00bc9fa9c 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -56,6 +56,8 @@ ghcr.io/oracle/${project.artifactId}:${project.version} + docker + ../build/_output/certs diff --git a/pkg/events/events.go b/pkg/events/events.go new file mode 100644 index 000000000..4e28fe76e --- /dev/null +++ b/pkg/events/events.go @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. + * Licensed under the Universal Permissive License v 1.0 as shown at + * http://oss.oracle.com/licenses/upl. + */ + +package events + +import ( + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/record" +) + +// OwnedEventRecorder is a wrapper around an EventRecorder that +// keeps a reference to the object associated with the events +type OwnedEventRecorder struct { + owner runtime.Object + recorder record.EventRecorder +} + +// NewOwnedEventRecorder creates a new OwnedEventRecorder +func NewOwnedEventRecorder(owner runtime.Object, recorder record.EventRecorder) OwnedEventRecorder { + return OwnedEventRecorder{ + owner: owner, + recorder: recorder, + } +} + +// Event constructs an event from the given information and puts it in the queue for sending. +// 'eventType' of this event, and can be one of Normal, Warning. New types could be added in future +// 'reason' is the reason this event is generated. 'reason' should be short and unique; it +// should be in UpperCamelCase format (starting with a capital letter). "reason" will be used +// to automate handling of events, so imagine people writing switch statements to handle them. +// You want to make that easy. +// 'message' is intended to be human-readable. +// +// The resulting event will be created in the same namespace as the reference object. +func (in *OwnedEventRecorder) Event(eventType, reason, message string) { + if in != nil && in.owner != nil && in.recorder != nil { + in.recorder.Event(in.owner, eventType, reason, message) + } +} + +// Warn is just like Event, and sends a Warning event. +func (in *OwnedEventRecorder) Warn(reason, message string) { + in.Event(corev1.EventTypeWarning, reason, message) +} + +// Info is just like Event, and sends a Normal event. +func (in *OwnedEventRecorder) Info(reason, message string) { + in.Event(corev1.EventTypeNormal, reason, message) +} + +// Eventf is just like Event, but with Sprintf for the message field. +func (in *OwnedEventRecorder) Eventf(eventType, reason, messageFmt string, args ...interface{}) { + if in != nil && in.owner != nil && in.recorder != nil { + in.recorder.Eventf(in.owner, eventType, reason, messageFmt, args...) + } +} + +// Warnf is just like Eventf, and sends a Warning event. +func (in *OwnedEventRecorder) Warnf(reason, messageFmt string, args ...interface{}) { + in.Eventf(corev1.EventTypeWarning, reason, messageFmt, args...) +} + +// Infof is just like Eventf, and sends a Normal event. +func (in *OwnedEventRecorder) Infof(reason, messageFmt string, args ...interface{}) { + in.Eventf(corev1.EventTypeNormal, reason, messageFmt, args...) +} + +// AnnotatedEventf is just like eventf, but with annotations attached +func (in *OwnedEventRecorder) AnnotatedEventf(annotations map[string]string, eventType, reason, messageFmt string, args ...interface{}) { + if in != nil && in.owner != nil && in.recorder != nil { + in.recorder.AnnotatedEventf(in.owner, annotations, eventType, reason, messageFmt, args...) + } +} + +// AnnotatedWarnf is just like AnnotatedEventf, and sends a Warning event. +func (in *OwnedEventRecorder) AnnotatedWarnf(annotations map[string]string, reason, messageFmt string, args ...interface{}) { + in.AnnotatedEventf(annotations, corev1.EventTypeWarning, reason, messageFmt, args...) +} + +// AnnotatedInfof is just like AnnotatedEventf, and sends a Normal event. +func (in *OwnedEventRecorder) AnnotatedInfof(annotations map[string]string, reason, messageFmt string, args ...interface{}) { + in.AnnotatedEventf(annotations, corev1.EventTypeNormal, reason, messageFmt, args...) +} diff --git a/pkg/operator/operator.go b/pkg/operator/operator.go index 3b693074b..b6e045ba0 100644 --- a/pkg/operator/operator.go +++ b/pkg/operator/operator.go @@ -57,6 +57,7 @@ const ( FlagDevMode = "coherence-dev-mode" FlagDryRun = "dry-run" FlagEnableWebhook = "enable-webhook" + FlagEnableHttp2 = "enable-http2" FlagGlobalAnnotation = "global-annotation" FlagGlobalLabel = "global-label" FlagHealthAddress = "health-addr" @@ -68,6 +69,7 @@ const ( FlagRackLabel = "rack-label" FlagRestHost = "rest-host" FlagRestPort = "rest-port" + FlagSecureMetrics = "metrics-secure" FlagServiceName = "service-name" FlagServicePort = "service-port" FlagSiteLabel = "site-label" @@ -182,6 +184,11 @@ func SetupFlags(cmd *cobra.Command, v *viper.Viper) { true, "Enables automatic installation/update of CoherenceJob CRD", ) + cmd.Flags().Bool( + FlagEnableHttp2, + false, + "If set, HTTP/2 will be enabled for the metrics and webhook servers", + ) cmd.Flags().Bool( FlagEnableWebhook, true, @@ -217,6 +224,11 @@ func SetupFlags(cmd *cobra.Command, v *viper.Viper) { DefaultRestPort, "The port that the REST server will bind to", ) + cmd.Flags().Bool( + FlagSecureMetrics, + true, + "FlagSecureMetrics", + ) cmd.Flags().String( FlagServiceName, "", diff --git a/pkg/probe/probe.go b/pkg/probe/probe.go index 852c85ba0..f9993580b 100644 --- a/pkg/probe/probe.go +++ b/pkg/probe/probe.go @@ -10,6 +10,7 @@ import ( "context" "fmt" coh "github.com/oracle/coherence-operator/api/v1" + "github.com/oracle/coherence-operator/pkg/events" mgmt "github.com/oracle/coherence-operator/pkg/management" "github.com/oracle/coherence-operator/pkg/operator" "github.com/spf13/viper" @@ -25,7 +26,7 @@ import ( "strings" ) -// Result is a string used to handle the results for probing container readiness/livenss +// Result is a string used to handle the results for probing container readiness/liveness type Result string const ( @@ -42,6 +43,7 @@ var log = logf.Log.WithName("Probe") type CoherenceProbe struct { Client client.Client Config *rest.Config + EventRecorder events.OwnedEventRecorder getPodHostName func(pod corev1.Pod) string translatePort func(name string, port int) int } @@ -133,32 +135,26 @@ func (in *CoherenceProbe) SuspendServices(ctx context.Context, deployment coh.Co stsSpec, _ := c.GetStatefulSetSpec() if viper.GetBool(operator.FlagSkipServiceSuspend) { - log.Info("Skipping suspension of Coherence services in StatefulSet "+sts.Name+ - operator.FlagSkipServiceSuspend+" is set to true", - "Namespace", ns, "Name", name) - return ServiceSuspendSkipped - } - - // check whether the Coherence deployment supports service suspension - ann := deployment.GetAnnotations() - if ann[coh.AnnotationFeatureSuspend] != "true" { - log.Info("Skipping suspension of Coherence services in StatefulSet "+sts.Name+ - coh.AnnotationFeatureSuspend+" annotation is missing or not set to true", - "Namespace", ns, "Name", name) + msg := fmt.Sprintf("Skipping suspension of Coherence services in StatefulSet %s, flag %s is set to true", + sts.Name, operator.FlagSkipServiceSuspend) + log.Info(msg, "Namespace", ns, "Name", name) + in.EventRecorder.Warn("ServiceSuspendSkipped", msg) return ServiceSuspendSkipped } if !stsSpec.IsSuspendServicesOnShutdown() { - log.Info("Skipping suspension of Coherence services in StatefulSet "+sts.Name+ - " spec.SuspendServicesOnShutdown is set to false", - "Namespace", ns, "Name", name) + msg := fmt.Sprintf("Skipping suspension of Coherence services in StatefulSet %s, spec.SuspendServicesOnShutdown is set to false", sts.Name) + log.Info(msg, "Namespace", ns, "Name", name) + in.EventRecorder.Warn("ServiceSuspendSkipped", msg) return ServiceSuspendSkipped } log.Info("Suspending Coherence services in StatefulSet "+sts.Name, "Namespace", ns, "Name", name) if in.ExecuteProbe(ctx, sts, deployment.GetWkaServiceName(), stsSpec.GetSuspendProbe()) { + in.EventRecorder.Warnf("ServiceSuspendFailed", "failed to suspend Coherence services in StatefulSet %s", sts.Name) return ServiceSuspendSuccessful } + in.EventRecorder.Infof("ServiceSuspended", "suspended Coherence services in StatefulSet %s", sts.Name) return ServiceSuspendFailed } @@ -176,6 +172,7 @@ func (in *CoherenceProbe) ExecuteProbe(ctx context.Context, sts *appsv1.Stateful pods, err := in.GetPodsForStatefulSet(ctx, sts) if err != nil { log.Error(err, "Error getting list of Pods for StatefulSet "+sts.Name) + in.EventRecorder.Infof("CheckStatusHA", "Failed to get pods for StatefulSet %s: %s", sts.Name, err.Error()) return false } return in.ExecuteProbeForSubSetOfPods(ctx, sts, svc, probe, pods, pods) @@ -187,7 +184,9 @@ func (in *CoherenceProbe) ExecuteProbeForSubSetOfPods(ctx context.Context, sts * // All Pods must be in the Running Phase for _, pod := range stsPods.Items { if ready, phase := in.IsPodReady(pod); !ready { - logger.Info(fmt.Sprintf("Cannot execute probe, one or more Pods is not in a ready state - %s (%v) ", pod.Name, phase)) + msg := fmt.Sprintf("Cannot execute probe, one or more Pods is not in a ready state - %s (%v) ", pod.Name, phase) + logger.Info(msg) + in.EventRecorder.Warn("CheckStatusHA", msg) return false } } @@ -195,13 +194,19 @@ func (in *CoherenceProbe) ExecuteProbeForSubSetOfPods(ctx context.Context, sts * count := int32(len(stsPods.Items)) switch { case count == 0: - logger.Info("Cannot find any Pods for StatefulSet " + sts.Name) + msg := fmt.Sprintf("Skipping StatusHA check, no Pods found in StatefulSet %s", sts.Name) + logger.Info(msg) + in.EventRecorder.Info("CheckStatusHA", msg) return true case sts.Spec.Replicas == nil && count != 1: - logger.Info(fmt.Sprintf("Pod count of %d does not yet match StatefulSet replica count: 1", count)) + msg := fmt.Sprintf("Pod count of %d does not yet match StatefulSet replica count: 1", count) + logger.Info(msg) + in.EventRecorder.Info("CheckStatusHA", msg) return false case sts.Spec.Replicas != nil && count != *sts.Spec.Replicas: - logger.Info(fmt.Sprintf("Pod count of %d does not yet match StatefulSet replica count: %d", count, *sts.Spec.Replicas)) + msg := fmt.Sprintf("Pod count of %d does not yet match StatefulSet replica count: %d", count, *sts.Spec.Replicas) + in.EventRecorder.Info("CheckStatusHA", msg) + logger.Info(msg) return false } @@ -213,12 +218,18 @@ func (in *CoherenceProbe) ExecuteProbeForSubSetOfPods(ctx context.Context, sts * ha, err := in.RunProbe(ctx, pod, svc, probe) if err == nil { - log.Info(fmt.Sprintf("Executed probe using pod %s result=%t", pod.Name, ha)) + msg := fmt.Sprintf("Executed probe using pod %s result=%t", pod.Name, ha) + log.Info(msg) + in.EventRecorder.Info("CheckStatusHA", msg) return ha } - log.Info(fmt.Sprintf("Execute probe using pod %s (%t) error %s", pod.Name, ha, err.Error())) + msg := fmt.Sprintf("Execute probe using pod %s (%t) error %s", pod.Name, ha, err.Error()) + in.EventRecorder.Warn("CheckStatusHA", msg) + log.Info(msg) } else { - log.Info("Skipping execute probe for pod " + pod.Name + " as Pod status not in running phase") + msg := fmt.Sprintf("Skipping execute probe for pod %s as Pod status not in running phase", pod.Name) + log.Info(msg) + in.EventRecorder.Warn("CheckStatusHA", msg) } } diff --git a/pkg/runner/cmd_console.go b/pkg/runner/cmd_console.go index 390e6be28..3d5128356 100644 --- a/pkg/runner/cmd_console.go +++ b/pkg/runner/cmd_console.go @@ -50,8 +50,15 @@ func console(details *RunDetails, args []string, v *viper.Viper) { details.Command = CommandConsole details.addArg("-Dcoherence.distributed.localstorage=false") details.addArg("-Dcoherence.localport.adjust=true") - details.addArg("-Dcoherence.management.http.enabled=false") + details.addArg("-Dcoherence.management.http=none") + details.addArg("-Dcoherence.management.http.port=0") details.addArg("-Dcoherence.metrics.http.enabled=false") + details.addArg("-Dcoherence.metrics.http.port=0") + details.addArg("-Dcoherence.k8s.operator.health.enabled=false") + details.addArg("-Dcoherence.health.http.port=0") + details.addArg("-Dcoherence.grpc.enabled=false") + details.setenv(v1.EnvVarJvmMemoryNativeTracking, "off") details.setenv(v1.EnvVarCohRole, "console") + details.setenv(v1.EnvVarCohHealthPort, "0") details.MainArgs = args } diff --git a/pkg/runner/cmd_jshell.go b/pkg/runner/cmd_jshell.go index 83f6e5483..9875e56c3 100644 --- a/pkg/runner/cmd_jshell.go +++ b/pkg/runner/cmd_jshell.go @@ -10,7 +10,6 @@ import ( v1 "github.com/oracle/coherence-operator/api/v1" "github.com/spf13/cobra" "github.com/spf13/viper" - "os" ) const ( @@ -26,7 +25,9 @@ func jShellCommand(v *viper.Viper) *cobra.Command { Long: "Starts a Coherence interactive JShell console", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { - return run(cmd, jShell) + return run(cmd, func(details *RunDetails, cmd *cobra.Command) { + jShell(details, args, v) + }) }, } addEnvVarFlag(cmd) @@ -36,16 +37,21 @@ func jShellCommand(v *viper.Viper) *cobra.Command { } // Configure the runner to run a Coherence JShell console -func jShell(details *RunDetails, _ *cobra.Command) { - details.Command = CommandQueryPlus - details.AppType = AppTypeJava - details.MainClass = "jdk.internal.jshell.tool.JShellToolProvider" - if len(os.Args) > 2 { - details.MainArgs = os.Args[2:] - } +func jShell(details *RunDetails, args []string, v *viper.Viper) { + details.AppType = AppTypeJShell + details.Command = CommandJShell details.addArg("-Dcoherence.distributed.localstorage=false") details.addArg("-Dcoherence.localport.adjust=true") - details.addArg("-Dcoherence.management.http.enabled=false") + details.addArg("-Dcoherence.management.http=none") + details.addArg("-Dcoherence.management.http.port=0") details.addArg("-Dcoherence.metrics.http.enabled=false") + details.addArg("-Dcoherence.metrics.http.port=0") + details.setenv(v1.EnvVarJvmMemoryNativeTracking, "off") + details.setenv(v1.EnvVarJvmUseContainerLimits, "false") + details.addArg("-Dcoherence.k8s.operator.health.enabled=false") + details.addArg("-Dcoherence.health.http.port=0") + details.addArg("-Dcoherence.grpc.enabled=false") details.setenv(v1.EnvVarCohRole, "jshell") + details.setenv(v1.EnvVarCohHealthPort, "0") + details.MainArgs = args } diff --git a/pkg/runner/cmd_operator.go b/pkg/runner/cmd_operator.go index 1b7759314..7b78e02f9 100644 --- a/pkg/runner/cmd_operator.go +++ b/pkg/runner/cmd_operator.go @@ -8,6 +8,7 @@ package runner import ( "context" + "crypto/tls" "fmt" coh "github.com/oracle/coherence-operator/api/v1" "github.com/oracle/coherence-operator/controllers" @@ -33,7 +34,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/metrics/filters" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + hooks "sigs.k8s.io/controller-runtime/pkg/webhook" // +kubebuilder:scaffold:imports ) @@ -80,6 +83,25 @@ func execute() error { setupLog.Info(fmt.Sprintf("Operator Coherence Image: %s", operator.GetDefaultCoherenceImage())) setupLog.Info(fmt.Sprintf("Operator Image: %s", operator.GetDefaultOperatorImage())) + // if the enable-http2 flag is false (the default), http/2 should be disabled + // due to its vulnerabilities. More specifically, disabling http/2 will + // prevent from being vulnerable to the HTTP/2 Stream Cancellation and + // Rapid Reset CVEs. For more information see: + // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3 + // - https://github.com/advisories/GHSA-4374-p667-p6c8 + disableHTTP2 := func(c *tls.Config) { + setupLog.Info("disabling http/2") + c.NextProtos = []string{"http/1.1"} + } + + vpr := operator.GetViper() + + var tlsOpts []func(*tls.Config) + enableHTTP2 := vpr.GetBool(operator.FlagEnableHttp2) + if !enableHTTP2 { + tlsOpts = append(tlsOpts, disableHTTP2) + } + cfg := ctrl.GetConfigOrDie() cs, err := clients.NewForConfig(cfg) if err != nil { @@ -93,19 +115,46 @@ func execute() error { return errors.Wrap(err, "unable to create client") } - vpr := operator.GetViper() - f := vpr.GetBool(operator.FlagDryRun) + dryRun := operator.IsDryRun() + secureMetrics := vpr.GetBool(operator.FlagSecureMetrics) + + // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server. + // More info: + // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/metrics/server + // - https://book.kubebuilder.io/reference/metrics.html + metricsServerOptions := metricsserver.Options{ + BindAddress: viper.GetString(operator.FlagMetricsAddress), + SecureServing: secureMetrics, + // TODO(user): TLSOpts is used to allow configuring the TLS config used for the server. If certificates are + // not provided, self-signed certificates will be generated by default. This option is not recommended for + // production environments as self-signed certificates do not offer the same level of trust and security + // as certificates issued by a trusted Certificate Authority (CA). The primary risk is potentially allowing + // unauthorized access to sensitive metrics data. Consider replacing with CertDir, CertName, and KeyName + // to provide certificates, ensuring the server communicates using trusted and secure certificates. + TLSOpts: tlsOpts, + } + + if secureMetrics { + // FilterProvider is used to protect the metrics endpoint with authn/authz. + // These configurations ensure that only authorized users and service accounts + // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info: + // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.0/pkg/metrics/filters#WithAuthenticationAndAuthorization + metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization + } + + webhookServer := hooks.NewServer(hooks.Options{ + TLSOpts: tlsOpts, + }) options := ctrl.Options{ Scheme: scheme, HealthProbeBindAddress: viper.GetString(operator.FlagHealthAddress), - Metrics: metricsserver.Options{ - BindAddress: viper.GetString(operator.FlagMetricsAddress), - }, - LeaderElection: viper.GetBool(operator.FlagLeaderElection), - LeaderElectionID: lockName, + Metrics: metricsServerOptions, + WebhookServer: webhookServer, + LeaderElection: viper.GetBool(operator.FlagLeaderElection), + LeaderElectionID: lockName, Controller: config.Controller{ - SkipNameValidation: ptr.To(f), + SkipNameValidation: ptr.To(dryRun), }, } @@ -172,7 +221,6 @@ func execute() error { } } - dryRun := operator.IsDryRun() if !dryRun { // We intercept the signal handler here so that we can do clean-up before the Manager stops handler := ctrl.SetupSignalHandler() diff --git a/pkg/runner/cmd_query_plus.go b/pkg/runner/cmd_query_plus.go index e989326e1..5b2313504 100644 --- a/pkg/runner/cmd_query_plus.go +++ b/pkg/runner/cmd_query_plus.go @@ -10,7 +10,7 @@ import ( v1 "github.com/oracle/coherence-operator/api/v1" "github.com/spf13/cobra" "github.com/spf13/viper" - "os" + "strings" ) const ( @@ -26,7 +26,9 @@ func queryPlusCommand(v *viper.Viper) *cobra.Command { Long: "Starts a Coherence interactive QueryPlus console", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { - return run(cmd, queryPlus) + return run(cmd, func(details *RunDetails, cmd *cobra.Command) { + queryPlus(details, args, v) + }) }, } addEnvVarFlag(cmd) @@ -36,16 +38,28 @@ func queryPlusCommand(v *viper.Viper) *cobra.Command { } // Configure the runner to run a Coherence Query Plus console -func queryPlus(details *RunDetails, _ *cobra.Command) { - details.Command = CommandQueryPlus - details.AppType = AppTypeJava - details.MainClass = "com.tangosol.coherence.dslquery.QueryPlus" - if len(os.Args) > 2 { - details.MainArgs = os.Args[2:] +func queryPlus(details *RunDetails, args []string, v *viper.Viper) { + app := strings.ToLower(v.GetString(v1.EnvVarAppType)) + if app == AppTypeSpring2 { + details.AppType = AppTypeSpring2 + details.MainClass = SpringBootMain2 + details.addArg("-Dloader.main=" + QueryPlusMain) + } else { + details.AppType = AppTypeJava + details.MainClass = QueryPlusMain } + details.Command = CommandQueryPlus details.addArg("-Dcoherence.distributed.localstorage=false") details.addArg("-Dcoherence.localport.adjust=true") - details.addArg("-Dcoherence.management.http.enabled=false") + details.addArg("-Dcoherence.management.http=none") + details.addArg("-Dcoherence.management.http.port=0") details.addArg("-Dcoherence.metrics.http.enabled=false") + details.addArg("-Dcoherence.metrics.http.port=0") + details.addArg("-Dcoherence.k8s.operator.health.enabled=false") + details.addArg("-Dcoherence.health.http.port=0") + details.addArg("-Dcoherence.grpc.enabled=false") + details.setenv(v1.EnvVarJvmMemoryNativeTracking, "off") details.setenv(v1.EnvVarCohRole, "queryPlus") + details.setenv(v1.EnvVarCohHealthPort, "0") + details.MainArgs = args } diff --git a/pkg/runner/cmd_sleep.go b/pkg/runner/cmd_sleep.go index 32f6ca259..72527eb0c 100644 --- a/pkg/runner/cmd_sleep.go +++ b/pkg/runner/cmd_sleep.go @@ -10,6 +10,7 @@ import ( v1 "github.com/oracle/coherence-operator/api/v1" "github.com/spf13/cobra" "github.com/spf13/viper" + "strings" ) const ( @@ -25,8 +26,8 @@ func sleepCommand(v *viper.Viper) *cobra.Command { Long: "Sleep for a number of seconds", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { - return run(cmd, func(details *RunDetails, _ *cobra.Command) { - sleep(details, args) + return run(cmd, func(details *RunDetails, cmd *cobra.Command) { + sleep(details, args, v) }) }, } @@ -36,15 +37,29 @@ func sleepCommand(v *viper.Viper) *cobra.Command { return cmd } -func sleep(details *RunDetails, args []string) { +func sleep(details *RunDetails, args []string, v *viper.Viper) { + app := strings.ToLower(v.GetString(v1.EnvVarAppType)) + if app == AppTypeSpring2 { + details.AppType = AppTypeSpring2 + details.MainClass = SpringBootMain2 + details.addArg("-Dloader.main=com.oracle.coherence.k8s.Sleep") + } else { + details.AppType = AppTypeJava + details.MainClass = "com.oracle.coherence.k8s.Sleep" + } details.Command = CommandSleep - details.AppType = AppTypeJava - details.MainClass = "com.oracle.coherence.k8s.Sleep" details.MainArgs = args details.UseOperatorHealth = true details.addArg("-Dcoherence.distributed.localstorage=false") details.addArg("-Dcoherence.localport.adjust=true") - details.addArg("-Dcoherence.management.http.enabled=false") + details.addArg("-Dcoherence.management.http=none") + details.addArg("-Dcoherence.management.http.port=0") details.addArg("-Dcoherence.metrics.http.enabled=false") + details.addArg("-Dcoherence.metrics.http.port=0") + details.addArg("-Dcoherence.k8s.operator.health.enabled=false") + details.addArg("-Dcoherence.grpc.enabled=false") + details.setenv(v1.EnvVarJvmMemoryNativeTracking, "off") details.setenv(v1.EnvVarCohRole, "sleep") + details.setenv(v1.EnvVarCohHealthPort, "0") + details.MainArgs = args } diff --git a/pkg/runner/run_details.go b/pkg/runner/run_details.go index 97c14b44d..e46fc06bb 100644 --- a/pkg/runner/run_details.go +++ b/pkg/runner/run_details.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -210,12 +210,26 @@ func (in *RunDetails) isEnvTrueOrBlank(name string) bool { } func (in *RunDetails) getCommand() []string { + return in.getCommandWithPrefix("", "") +} + +func (in *RunDetails) getCommandWithPrefix(propPrefix, jvmPrefix string) []string { var cmd []string cp := in.getClasspath() if cp != "" { - cmd = append(cmd, "-cp", cp) + cmd = append(cmd, "--class-path", cp) + } + if propPrefix == "" && jvmPrefix == "" { + cmd = append(cmd, in.Args...) + } else { + for _, arg := range in.Args { + if strings.HasPrefix(arg, "-D") && propPrefix != "" { + cmd = append(cmd, propPrefix+arg) + } else if jvmPrefix != "" { + cmd = append(cmd, jvmPrefix+arg) + } + } } - cmd = append(cmd, in.Args...) return cmd } @@ -232,7 +246,7 @@ func (in *RunDetails) getSpringBootArgs() []string { // Are we using a Spring Boot fat jar if jar, _ := in.lookupEnv(v1.EnvVarSpringBootFatJar); jar != "" { - cmd = append(cmd, "-cp", jar) + cmd = append(cmd, "--class-path", jar) } cmd = append(cmd, in.Args...) @@ -363,6 +377,13 @@ func (in *RunDetails) getJavaExecutable() string { return "java" } +func (in *RunDetails) getJShellExecutable() string { + if in.JavaHome != "" { + return in.JavaHome + "/bin/jshell" + } + return "jshell" +} + // isBuildPacks determines whether to run the application with the Cloud Native Buildpack launcher func (in *RunDetails) isBuildPacks() bool { if in.BuildPacks == nil { diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 24947be1e..fda98ed68 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -46,6 +46,10 @@ const ( SpringBootMain3 = "org.springframework.boot.loader.launch.PropertiesLauncher" // ConsoleMain is the Coherence console main class ConsoleMain = "com.tangosol.net.CacheFactory" + // QueryPlusMain is the main class to run Coherence Query Plus + QueryPlusMain = "com.tangosol.coherence.dslquery.QueryPlus" + // JShellMain is the main class to run a JShell console + JShellMain = "jdk.internal.jshell.tool.JShellToolProvider" // AppTypeNone is the argument to specify no application type. AppTypeNone = "" @@ -61,6 +65,8 @@ const ( AppTypeSpring3 = "spring3" // AppTypeOperator is the argument to specify running an Operator command. AppTypeOperator = "operator" + // AppTypeJShell is the argument to specify a JShell application. + AppTypeJShell = "jshell" // defaultConfig is the root name of the default configuration file defaultConfig = ".coherence-runner" @@ -345,7 +351,7 @@ func createCommand(details *RunDetails) (string, *exec.Cmd, error) { // Add the Operator Utils jar to the classpath details.addClasspath(details.UtilsDir + "/lib/coherence-operator.jar") - details.addClasspath(details.UtilsDir + "/config") + details.addClasspathIfExists(details.UtilsDir + "/config") // Configure Coherence persistence mode := details.getenvOrDefault(v1.EnvVarCohPersistenceMode, "on-demand") @@ -620,6 +626,9 @@ func createCommand(details *RunDetails) (string, *exec.Cmd, error) { case details.AppType == AppTypeCoherence: app = "Java" cmd, err = createJavaCommand(details.getJavaExecutable(), details) + case details.AppType == AppTypeJShell: + app = "JShell" + cmd, err = createJShellCommand(details.getJShellExecutable(), details) case details.AppType == AppTypeOperator: app = "Operator" cmd, err = createOperatorCommand(details) @@ -642,6 +651,11 @@ func createJavaCommand(javaCmd string, details *RunDetails) (*exec.Cmd, error) { return _createJavaCommand(javaCmd, details, args) } +func createJShellCommand(jshellCmd string, details *RunDetails) (*exec.Cmd, error) { + args := details.getCommandWithPrefix("-R", "-J") + return _createJavaCommand(jshellCmd, details, args) +} + func readFirstLineFromFile(path string) (string, error) { file, err := os.Open(maybeStripFileScheme(path)) if err != nil { @@ -992,7 +1006,7 @@ func checkCoherenceVersion(v string, details *RunDetails) bool { if jar, _ := details.lookupEnv(v1.EnvVarSpringBootFatJar); jar != "" { // This is a fat jar Spring boot app so put the fat jar on the classpath - args = append(args, "-cp", jar) + args = append(args, "--class-path", jar) } if details.AppType == AppTypeSpring2 { @@ -1004,7 +1018,7 @@ func checkCoherenceVersion(v string, details *RunDetails) bool { } } else { // We can use normal Java - args = append(args, "-cp", cp, + args = append(args, "--class-path", cp, "-Dcoherence.operator.springboot.listener=false", "com.oracle.coherence.k8s.CoherenceVersion", v) } diff --git a/pkg/runner/runner_jvm_jibclasspath_test.go b/pkg/runner/runner_jvm_jibclasspath_test.go index 6c08011b5..32e524298 100644 --- a/pkg/runner/runner_jvm_jibclasspath_test.go +++ b/pkg/runner/runner_jvm_jibclasspath_test.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -190,12 +190,13 @@ func createJibMainClassFile() *os.File { func GetMinimalExpectedArgsWithAppClasspathFile() []string { fileName := fmt.Sprintf("%s/jib-classpath-file", TestAppDir) cp := readFirstLine(fileName) - args := []string{ - GetJavaArg(), - "-cp", - cp + ":/coherence-operator/utils/lib/coherence-operator.jar:/coherence-operator/utils/config", + cp = cp + ":/coherence-operator/utils/lib/coherence-operator.jar" + if _, err := os.Stat("/coherence-operator/utils/config"); err == nil { + cp = cp + ":/coherence-operator/utils/config" } + args := []string{GetJavaArg(), "--class-path", cp} + return append(AppendCommonExpectedArgs(args), "com.oracle.coherence.k8s.Main", "$DEFAULT$") @@ -205,12 +206,13 @@ func GetMinimalExpectedArgsWithAppMainClassFile() []string { cp := fmt.Sprintf("%s/resources:%s/classes:%s/classpath/bar2.JAR:%s/classpath/foo2.jar:%s/libs/bar1.JAR:%s/libs/foo1.jar", TestAppDir, TestAppDir, TestAppDir, TestAppDir, TestAppDir, TestAppDir) - args := []string{ - GetJavaArg(), - "-cp", - cp + ":/coherence-operator/utils/lib/coherence-operator.jar:/coherence-operator/utils/config", + cp = cp + ":/coherence-operator/utils/lib/coherence-operator.jar" + if _, err := os.Stat("/coherence-operator/utils/config"); err == nil { + cp = cp + ":/coherence-operator/utils/config" } + args := []string{GetJavaArg(), "--class-path", cp} + fileName := fmt.Sprintf("%s/jib-main-class-file", TestAppDir) mainCls := readFirstLine(fileName) return append(AppendCommonExpectedArgs(args), @@ -221,13 +223,13 @@ func GetMinimalExpectedArgsWithAppMainClassFile() []string { func GetMinimalExpectedArgsWithAppClasspathFileAndMainClassFile() []string { fileName := fmt.Sprintf("%s/jib-classpath-file", TestAppDir) cp := readFirstLine(fileName) - - args := []string{ - GetJavaArg(), - "-cp", - cp + ":/coherence-operator/utils/lib/coherence-operator.jar:/coherence-operator/utils/config", + cp = cp + ":/coherence-operator/utils/lib/coherence-operator.jar" + if _, err := os.Stat("/coherence-operator/utils/config"); err == nil { + cp = cp + ":/coherence-operator/utils/config" } + args := []string{GetJavaArg(), "--class-path", cp} + fileName = fmt.Sprintf("%s/jib-main-class-file", TestAppDir) mainCls := readFirstLine(fileName) return append(AppendCommonExpectedArgs(args), diff --git a/pkg/runner/runner_spring_test.go b/pkg/runner/runner_spring_test.go index e03c0f6c3..fdb5358a6 100644 --- a/pkg/runner/runner_spring_test.go +++ b/pkg/runner/runner_spring_test.go @@ -161,8 +161,18 @@ func TestSpringBootFatJarConsole(t *testing.T) { expectedCommand := GetJavaCommand() expectedArgs := GetMinimalExpectedSpringBootFatJarArgsForRole(jar, ConsoleMain, "") + expectedArgs = ReplaceArg(expectedArgs, "-XX:NativeMemoryTracking=summary", "-XX:NativeMemoryTracking=off") + expectedArgs = ReplaceArg(expectedArgs, "-Dcoherence.health.http.port=6676", "-Dcoherence.health.http.port=0") + expectedArgs = RemoveArg(expectedArgs, "-Dcoherence.k8s.operator.health.port=6676") expectedArgs = append(expectedArgs, "-Dcoherence.localport.adjust=true", - "-Dcoherence.management.http.enabled=false", "-Dcoherence.metrics.http.enabled=false") + "-Dcoherence.metrics.http.enabled=false", + "-Dcoherence.management.http=none", + "-Dcoherence.management.http.port=0", + "-Dcoherence.metrics.http.port=0", + "-Dcoherence.k8s.operator.health.enabled=false", + "-Dcoherence.health.http.port=0", + "-Dcoherence.grpc.enabled=false", + "-Dcoherence.k8s.operator.health.port=0") e, err := ExecuteWithArgsAndNewViper(env, args) g.Expect(err).NotTo(HaveOccurred()) @@ -195,8 +205,18 @@ func TestSpringBootFatJarConsoleWithArgs(t *testing.T) { expectedCommand := GetJavaCommand() expectedArgs := GetMinimalExpectedSpringBootFatJarArgsForRole(jar, ConsoleMain, "") + expectedArgs = ReplaceArg(expectedArgs, "-XX:NativeMemoryTracking=summary", "-XX:NativeMemoryTracking=off") + expectedArgs = ReplaceArg(expectedArgs, "-Dcoherence.health.http.port=6676", "-Dcoherence.health.http.port=0") + expectedArgs = RemoveArg(expectedArgs, "-Dcoherence.k8s.operator.health.port=6676") expectedArgs = append(expectedArgs, "-Dcoherence.localport.adjust=true", - "-Dcoherence.management.http.enabled=false", "-Dcoherence.metrics.http.enabled=false", + "-Dcoherence.metrics.http.enabled=false", + "-Dcoherence.management.http=none", + "-Dcoherence.management.http.port=0", + "-Dcoherence.metrics.http.port=0", + "-Dcoherence.k8s.operator.health.enabled=false", + "-Dcoherence.grpc.enabled=false", + "-Dcoherence.k8s.operator.health.port=0", + "-Dcoherence.health.http.port=0", "foo", "bar") e, err := ExecuteWithArgsAndNewViper(env, args) @@ -282,15 +302,24 @@ func TestSpringBootBuildpacks(t *testing.T) { data, err := os.ReadFile(fileName) g.Expect(err).NotTo(HaveOccurred()) + cp := "/coherence-operator/utils/lib/coherence-operator.jar" + if _, err := os.Stat("/coherence-operator/utils/config"); err == nil { + cp = cp + ":/coherence-operator/utils/config" + } + actualOpts := strings.Split(string(data), "\n") - expectedOpts := AppendCommonExpectedArgs([]string{"-Dloader.path=/coherence-operator/utils/lib/coherence-operator.jar,/coherence-operator/utils/config"}) + expectedOpts := AppendCommonExpectedArgs([]string{"-Dloader.path=" + cp}) g.Expect(actualOpts).To(ConsistOf(expectedOpts)) } func GetMinimalExpectedSpringBootArgs(main string) []string { + cp := "/coherence-operator/utils/lib/coherence-operator.jar" + if _, err := os.Stat("/coherence-operator/utils/config"); err == nil { + cp = cp + ",/coherence-operator/utils/config" + } args := []string{ GetJavaArg(), - "-Dloader.path=/coherence-operator/utils/lib/coherence-operator.jar,/coherence-operator/utils/config", + "-Dloader.path=" + cp, } args = append(AppendCommonExpectedArgs(args), main) return args @@ -301,11 +330,15 @@ func GetMinimalExpectedSpringBootFatJarArgs(jar, main string) []string { } func GetMinimalExpectedSpringBootFatJarArgsWithMain(jar, springMain, main string) []string { + cp := "/coherence-operator/utils/lib/coherence-operator.jar" + if _, err := os.Stat("/coherence-operator/utils/config"); err == nil { + cp = cp + ",/coherence-operator/utils/config" + } args := []string{ GetJavaArg(), - "-cp", + "--class-path", jar, - "-Dloader.path=/coherence-operator/utils/lib/coherence-operator.jar,/coherence-operator/utils/config", + "-Dloader.path=" + cp, } if main != "" { @@ -316,11 +349,15 @@ func GetMinimalExpectedSpringBootFatJarArgsWithMain(jar, springMain, main string } func GetMinimalExpectedSpringBootFatJarArgsForRole(jar, main, role string) []string { + cp := "/coherence-operator/utils/lib/coherence-operator.jar" + if _, err := os.Stat("/coherence-operator/utils/config"); err == nil { + cp = cp + ",/coherence-operator/utils/config" + } args := []string{ GetJavaArg(), - "-cp", + "--class-path", jar, - "-Dloader.path=/coherence-operator/utils/lib/coherence-operator.jar,/coherence-operator/utils/config", + "-Dloader.path=" + cp, "-Dcoherence.distributed.localstorage=false", } diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go index 9f50fa727..bb294748a 100644 --- a/pkg/runner/runner_test.go +++ b/pkg/runner/runner_test.go @@ -111,12 +111,13 @@ func GetMinimalExpectedArgs() []string { cp := fmt.Sprintf("%s/resources:%s/classes:%s/classpath/bar2.JAR:%s/classpath/foo2.jar:%s/libs/bar1.JAR:%s/libs/foo1.jar", TestAppDir, TestAppDir, TestAppDir, TestAppDir, TestAppDir, TestAppDir) - args := []string{ - GetJavaArg(), - "-cp", - cp + ":/coherence-operator/utils/lib/coherence-operator.jar:/coherence-operator/utils/config", + cp = cp + ":/coherence-operator/utils/lib/coherence-operator.jar" + if _, err := os.Stat("/coherence-operator/utils/config"); err == nil { + cp = cp + ":/coherence-operator/utils/config" } + args := []string{GetJavaArg(), "--class-path", cp} + return append(AppendCommonExpectedArgs(args), "com.oracle.coherence.k8s.Main", "$DEFAULT$") @@ -131,11 +132,11 @@ func GetMinimalExpectedArgsWithoutCP() []string { } func GetMinimalExpectedArgsWithoutAppClasspath() []string { - args := []string{ - GetJavaArg(), - "-cp", - "/coherence-operator/utils/lib/coherence-operator.jar:/coherence-operator/utils/config", + cp := "/coherence-operator/utils/lib/coherence-operator.jar" + if _, err := os.Stat("/coherence-operator/utils/config"); err == nil { + cp = cp + ":/coherence-operator/utils/config" } + args := []string{GetJavaArg(), "--class-path", cp} return append(AppendCommonExpectedArgs(args), "com.oracle.coherence.k8s.Main",