From aa7f7b0baacf2cc2c32eaf600fe6753b71f04341 Mon Sep 17 00:00:00 2001 From: lwpk110 Date: Thu, 14 Nov 2024 17:53:29 +0800 Subject: [PATCH] refactor(olm): remove OLM v0 support --- .github/workflows/main.yml | 8 - .gitignore | 7 - .golangci.yml | 47 +++ Makefile | 332 +++++------------- PROJECT | 3 - api/v1alpha1/hbasecluster_types.go | 6 +- api/v1alpha1/hbasecluster_webhook.go | 4 +- api/v1alpha1/webhook_suite_test.go | 6 +- catalog-template.yaml | 121 ------- cmd/main.go | 67 +++- config/default/kustomization.yaml | 249 +++++++------ config/default/manager_auth_proxy_patch.yaml | 39 -- config/default/manager_config_patch.yaml | 10 - config/default/manager_metrics_patch.yaml | 4 + .../metrics_service.yaml} | 8 +- config/manager/manager.yaml | 1 + .../hbase-operator.clusterserviceversion.yaml | 53 --- config/manifests/kustomization.yaml | 28 -- .../network-policy/allow-metrics-traffic.yaml | 26 ++ config/network-policy/kustomization.yaml | 2 + config/prometheus/monitor.yaml | 9 + .../rbac/auth_proxy_client_clusterrole.yaml | 16 - config/rbac/auth_proxy_role.yaml | 24 -- config/rbac/auth_proxy_role_binding.yaml | 19 - config/rbac/kustomization.yaml | 22 +- config/rbac/metrics_auth_role.yaml | 17 + config/rbac/metrics_auth_role_binding.yaml | 12 + config/rbac/metrics_reader_role.yaml | 9 + config/scorecard/bases/config.yaml | 7 - config/scorecard/kustomization.yaml | 15 - config/scorecard/patches/basic.config.yaml | 10 - config/scorecard/patches/olm.config.yaml | 50 --- go.mod | 26 ++ go.sum | 57 +++ internal/controller/suite_test.go | 4 +- 35 files changed, 533 insertions(+), 785 deletions(-) create mode 100644 .golangci.yml delete mode 100644 catalog-template.yaml delete mode 100644 config/default/manager_auth_proxy_patch.yaml delete mode 100644 config/default/manager_config_patch.yaml create mode 100644 config/default/manager_metrics_patch.yaml rename config/{rbac/auth_proxy_service.yaml => default/metrics_service.yaml} (53%) delete mode 100644 config/manifests/bases/hbase-operator.clusterserviceversion.yaml delete mode 100644 config/manifests/kustomization.yaml create mode 100644 config/network-policy/allow-metrics-traffic.yaml create mode 100644 config/network-policy/kustomization.yaml delete mode 100644 config/rbac/auth_proxy_client_clusterrole.yaml delete mode 100644 config/rbac/auth_proxy_role.yaml delete mode 100644 config/rbac/auth_proxy_role_binding.yaml create mode 100644 config/rbac/metrics_auth_role.yaml create mode 100644 config/rbac/metrics_auth_role_binding.yaml create mode 100644 config/rbac/metrics_reader_role.yaml delete mode 100644 config/scorecard/bases/config.yaml delete mode 100644 config/scorecard/kustomization.yaml delete mode 100644 config/scorecard/patches/basic.config.yaml delete mode 100644 config/scorecard/patches/olm.config.yaml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f08c13f..9019a13 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -118,11 +118,3 @@ jobs: - name: Build and push operator run: | make docker-buildx - - name: Build and push operator bundle - run: | - make bundle - make bundle-buildx - - name: Build and push catalog - run: | - make catalog - make catalog-buildx diff --git a/.gitignore b/.gitignore index 15fa465..08e82c8 100644 --- a/.gitignore +++ b/.gitignore @@ -25,11 +25,4 @@ Dockerfile.cross *.swo *~ -# olm bundle -bundle.Dockerfile -bundle - **/kind-kubeconfig* - -catalog -catalog.Dockerfile diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..6b29746 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,47 @@ +run: + timeout: 5m + allow-parallel-runners: true + +issues: + # don't skip warning about doc comments + # don't exclude the default set of lint + exclude-use-default: false + # restore some of the defaults + # (fill in the rest as needed) + exclude-rules: + - path: "api/*" + linters: + - lll + - path: "internal/*" + linters: + - dupl + - lll +linters: + disable-all: true + enable: + - dupl + - errcheck + - copyloopvar + - ginkgolinter + - goconst + - gocyclo + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - lll + - misspell + - nakedret + - prealloc + - revive + - staticcheck + - typecheck + - unconvert + - unparam + - unused + +linters-settings: + revive: + rules: + - name: comment-spacings diff --git a/Makefile b/Makefile index 56f39d8..1c2ceb8 100644 --- a/Makefile +++ b/Makefile @@ -1,64 +1,13 @@ -# VERSION defines the project version for the bundle. -# Update this value when you upgrade the version of your project. -# To re-generate a bundle for another specific version without changing the standard setup, you can: -# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) -# - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.0.0-dev - -# CHANNELS define the bundle channels used in the bundle. -# Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") -# To re-generate a bundle for other specific channels without changing the standard setup, you can: -# - use the CHANNELS as arg of the bundle target (e.g make bundle CHANNELS=candidate,fast,stable) -# - use environment variables to overwrite this value (e.g export CHANNELS="candidate,fast,stable") -CHANNELS ?= "stable" -ifneq ($(origin CHANNELS), undefined) -BUNDLE_CHANNELS := --channels=$(CHANNELS) -endif -# DEFAULT_CHANNEL defines the default channel used in the bundle. -# Add a new line here if you would like to change its default config. (E.g DEFAULT_CHANNEL = "stable") -# To re-generate a bundle for any other default channel without changing the default setup, you can: -# - use the DEFAULT_CHANNEL as arg of the bundle target (e.g make bundle DEFAULT_CHANNEL=stable) -# - use environment variables to overwrite this value (e.g export DEFAULT_CHANNEL="stable") -DEFAULT_CHANNEL ?= "stable" -ifneq ($(origin DEFAULT_CHANNEL), undefined) -BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) -endif -BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) +# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. +VERSION ?= 0.0.0-dev +ENVTEST_K8S_VERSION = 1.26.1 REGISTRY ?= quay.io/zncdatadev PROJECT_NAME = hbase-operator -# IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images. -# This variable is used to construct full image tags for bundle and catalog images. -# -# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both -# zncdata.dev/hbase-operator-bundle:$VERSION and zncdata.dev/hbase-operator-catalog:$VERSION. -IMAGE_TAG_BASE ?= $(REGISTRY)/$(PROJECT_NAME) - -# BUNDLE_IMG defines the image:tag used for the bundle. -# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=/:) -BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:$(VERSION) - -# BUNDLE_GEN_FLAGS are the flags passed to the operator-sdk generate bundle command -BUNDLE_GEN_FLAGS ?= -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) - -# USE_IMAGE_DIGESTS defines if images are resolved via tags or digests -# You can enable this value if you would like to use SHA Based Digests -# To enable set flag to true -USE_IMAGE_DIGESTS ?= false -ifeq ($(USE_IMAGE_DIGESTS), true) - BUNDLE_GEN_FLAGS += --use-image-digests -endif - -# Set the Operator SDK version to use. By default, what is installed on the system is used. -# This is useful for CI or a project to utilize a specific version of the operator-sdk toolkit. -OPERATOR_SDK_VERSION ?= v1.37.0 - # Image URL to use all building/pushing image targets -IMG ?= $(IMAGE_TAG_BASE):$(VERSION) -# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.26.1 +IMG ?= $(REGISTRY)/$(PROJECT_NAME):$(VERSION) # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) @@ -85,7 +34,7 @@ all: build # The help target prints out all targets with their descriptions organized # beneath their categories. The categories are represented by '##@' and the -# target descriptions by '##'. The awk commands is responsible for reading the +# target descriptions by '##'. The awk command is responsible for reading the # entire set of makefiles included in this invocation, looking for lines of the # file as xyz: ## something, and then pretty-format the target and help. Then, # if there's a line with ##@ something, that gets pretty-printed as a category. @@ -116,64 +65,79 @@ fmt: ## Run go fmt against code. vet: ## Run go vet against code. go vet ./... -GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint -GOLANGCI_LINT_VERSION ?= v1.61.0 -golangci-lint: - @[ -f $(GOLANGCI_LINT) ] || { \ - set -e ;\ - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell dirname $(GOLANGCI_LINT)) $(GOLANGCI_LINT_VERSION) ;\ +.PHONY: test +test: manifests generate fmt vet envtest ## Run tests. + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out + +# TODO(user): To use a different vendor for e2e tests, modify the setup under 'tests/e2e'. +# The default setup assumes Kind is pre-installed and builds/loads the Manager Docker image locally. +# Prometheus and CertManager are installed by default; skip with: +# - PROMETHEUS_INSTALL_SKIP=true +# - CERT_MANAGER_INSTALL_SKIP=true +.PHONY: test-e2e +test-e2e: manifests generate fmt vet ## Run the e2e tests. Expected an isolated environment using Kind. + @command -v kind >/dev/null 2>&1 || { \ + echo "Kind is not installed. Please install Kind manually."; \ + exit 1; \ + } + @kind get clusters | grep -q 'kind' || { \ + echo "No Kind cluster is running. Please start a Kind cluster before running the e2e tests."; \ + exit 1; \ } + go test ./test/e2e/ -v -ginkgo.v .PHONY: lint -lint: golangci-lint ## Run golangci-lint linter & yamllint - $(GOLANGCI_LINT) run --timeout 5m +lint: golangci-lint ## Run golangci-lint linter + $(GOLANGCI_LINT) run .PHONY: lint-fix lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes $(GOLANGCI_LINT) run --fix -.PHONY: test -test: manifests generate fmt vet envtest ## Run tests. - KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverprofile cover.out - ##@ Build .PHONY: build -build: manifests generate fmt vet lint ## Build manager binary. +build: manifests generate fmt vet ## Build manager binary. go build -o bin/manager cmd/main.go .PHONY: run run: manifests generate fmt vet ## Run a controller from your host. go run ./cmd/main.go -# If you wish built the manager image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it. +# If you wish to build the manager image targeting other platforms you can use the --platform flag. +# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. # More info: https://docs.docker.com/develop/develop-images/build_enhancements/ .PHONY: docker-build -docker-build: test ## Build docker image with the manager. +docker-build: ## Build docker image with the manager. $(CONTAINER_TOOL) build -t ${IMG} . .PHONY: docker-push docker-push: ## Push docker image with the manager. $(CONTAINER_TOOL) push ${IMG} -# PLATFORMS defines the target platforms for the manager image be build to provide support to multiple +# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple # architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: -# - able to use docker buildx . More info: https://docs.docker.com/build/buildx/ -# - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -# - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=> then the export will fail) -# To properly provided solutions that supports more than one platform you should use this option. -PLATFORMS ?= linux/arm64,linux/amd64 +# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ +# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ +# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) +# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. +PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le .PHONY: docker-buildx -docker-buildx: test ## Build and push docker image for the manager for cross-platform support +docker-buildx: ## Build and push docker image for the manager for cross-platform support # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - - $(CONTAINER_TOOL) buildx create --name project-v3-builder - $(CONTAINER_TOOL) buildx use project-v3-builder + - $(CONTAINER_TOOL) buildx create --name $(PROJECT_NAME)-builder + $(CONTAINER_TOOL) buildx use $(PROJECT_NAME)-builder - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . - - $(CONTAINER_TOOL) buildx rm project-v3-builder + - $(CONTAINER_TOOL) buildx rm $(PROJECT_NAME)-builder rm Dockerfile.cross +.PHONY: build-installer +build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment. + mkdir -p dist + cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} + $(KUSTOMIZE) build config/default > dist/install.yaml + ##@ Deployment ifndef ignore-not-found @@ -198,10 +162,10 @@ deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in $(KUSTOMIZE) build config/default | kubectl apply --server-side=true -f - .PHONY: undeploy -undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. +undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. $(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - -##@ Build Dependencies +##@ Dependencies ## Location to install dependencies to LOCALBIN ?= $(shell pwd)/bin @@ -213,155 +177,69 @@ KUBECTL ?= kubectl KUSTOMIZE ?= $(LOCALBIN)/kustomize CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen ENVTEST ?= $(LOCALBIN)/setup-envtest +GOLANGCI_LINT = $(LOCALBIN)/golangci-lint +HELM = $(LOCALBIN)/helm +KIND = $(LOCALBIN)/kind ## Tool Versions KUSTOMIZE_VERSION ?= v5.5.0 CONTROLLER_TOOLS_VERSION ?= v0.16.5 +ENVTEST_VERSION ?= release-0.19 +GOLANGCI_LINT_VERSION ?= v1.61.0 +HELM_VERSION ?= v3.16.2 +KIND_VERSION ?= v0.24.0 .PHONY: kustomize -kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading. +kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. $(KUSTOMIZE): $(LOCALBIN) - @if test -x $(LOCALBIN)/kustomize && ! $(LOCALBIN)/kustomize version | grep -q $(KUSTOMIZE_VERSION); then \ - echo "$(LOCALBIN)/kustomize version is not expected $(KUSTOMIZE_VERSION). Removing it before installing."; \ - rm -rf $(LOCALBIN)/kustomize; \ - fi - test -s $(LOCALBIN)/kustomize || GOBIN=$(LOCALBIN) GO111MODULE=on go install sigs.k8s.io/kustomize/kustomize/v5@$(KUSTOMIZE_VERSION) + $(call go-install-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v5,$(KUSTOMIZE_VERSION)) .PHONY: controller-gen -controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. If wrong version is installed, it will be overwritten. +controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. $(CONTROLLER_GEN): $(LOCALBIN) - test -s $(LOCALBIN)/controller-gen && $(LOCALBIN)/controller-gen --version | grep -q $(CONTROLLER_TOOLS_VERSION) || \ - GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION) + $(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen,$(CONTROLLER_TOOLS_VERSION)) .PHONY: envtest -envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. +envtest: $(ENVTEST) ## Download setup-envtest locally if necessary. $(ENVTEST): $(LOCALBIN) - test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest + $(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest,$(ENVTEST_VERSION)) -.PHONY: operator-sdk -OPERATOR_SDK ?= $(LOCALBIN)/operator-sdk -operator-sdk: ## Download operator-sdk locally if necessary. -ifeq (,$(wildcard $(OPERATOR_SDK))) -ifeq (, $(shell which operator-sdk 2>/dev/null)) - @{ \ - set -e ;\ - mkdir -p $(dir $(OPERATOR_SDK)) ;\ - OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \ - curl -sSLo $(OPERATOR_SDK) https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION)/operator-sdk_$${OS}_$${ARCH} ;\ - chmod +x $(OPERATOR_SDK) ;\ - } -else -OPERATOR_SDK = $(shell which operator-sdk) -endif -endif - -.PHONY: bundle -bundle: manifests kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files. - $(OPERATOR_SDK) generate kustomize manifests -q - cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) - $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS) - $(OPERATOR_SDK) bundle validate ./bundle --select-optional suite=operatorframework --optional-values=k8s-version=1.26 - -.PHONY: bundle-build -bundle-build: ## Build the bundle image. - docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) --no-cache . - -.PHONY: bundle-push -bundle-push: ## Push the bundle image. - $(MAKE) docker-push IMG=$(BUNDLE_IMG) - - -.PHONY: bundle-buildx -bundle-buildx: ## Build the bundle image. - - $(CONTAINER_TOOL) buildx create --name project-v3-builder - $(CONTAINER_TOOL) buildx use project-v3-builder - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag $(BUNDLE_IMG) -f bundle.Dockerfile . - $(CONTAINER_TOOL) buildx rm project-v3-builder - -.PHONY: bundle-run -bundle-run: ## Run the bundle image. - $(OPERATOR_SDK) run bundle $(BUNDLE_IMG) - -.PHONY: bundle-cleanup -bundle-cleanup: ## Clean up the bundle image. - $(OPERATOR_SDK) cleanup $(PROJECT_NAME) - -OPM_VERSION ?= v1.43.0 -CATALOG_IMG ?= $(IMAGE_TAG_BASE)-catalog:latest - -.PHONY: opm -OPM = ./bin/opm -opm: ## Download opm locally if necessary. -ifeq (,$(wildcard $(OPM))) -ifeq (,$(shell which opm 2>/dev/null)) - @{ \ - 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/${OPM_VERSION}/$${OS}-$${ARCH}-opm ;\ - chmod +x $(OPM) ;\ - } -else -OPM = $(shell which opm) -endif -endif - -.PHONY: catalog -catalog: opm ## Build a catalog manifests. - mkdir -p catalog - @if ! test -f ./catalog.Dockerfile; then \ - $(OPM) generate dockerfile catalog; \ - fi - $(OPM) alpha render-template basic -o yaml catalog-template.yaml > catalog/catalog.yaml - -.PHONY: catalog-validate -catalog-validate: opm ## Validate a catalog manifests. - $(OPM) validate catalog - -.PHONY: catalog-build -catalog-build: ## Build a catalog image. - $(CONTAINER_TOOL) build -t ${CATALOG_IMG} -f catalog.Dockerfile . - -# Push the catalog image. -.PHONY: catalog-docker-push -catalog-docker-push: ## Push a catalog image. - $(MAKE) docker-push IMG=$(CATALOG_IMG) - -.PHONY: catalog-buildx -catalog-buildx: ## Build and push a catalog image for cross-platform support - - $(CONTAINER_TOOL) buildx create --name project-v3-builder - $(CONTAINER_TOOL) buildx use project-v3-builder - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) -f catalog.Dockerfile --tag ${CATALOG_IMG} . - $(CONTAINER_TOOL) buildx rm project-v3-builder - -##@ E2E - -##@ helm - -HELM_VERSION ?= v3.16.2 -HELM = $(LOCALBIN)/helm +.PHONY: golangci-lint +golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. +$(GOLANGCI_LINT): $(LOCALBIN) + $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION)) .PHONY: helm -helm: ## Download helm locally if necessary. -ifeq (,$(shell which $(HELM))) -ifeq (,$(shell which helm 2>/dev/null)) - @{ \ - set -e ;\ - mkdir -p $(dir $(HELM)) ;\ - OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \ - curl -sSL https://get.helm.sh/helm-$(HELM_VERSION)-$${OS}-$${ARCH}.tar.gz | tar -xz -C $(LOCALBIN) --strip-components=1 $${OS}-$${ARCH}/helm ;\ - chmod +x $(HELM) ;\ - } -else -HELM = $(shell which helm) -endif -endif +helm: $(HELM) ## Download helm locally if necessary. +$(HELM): $(LOCALBIN) + $(call go-install-tool,$(HELM),helm.sh/helm/v3/cmd/helm,$(HELM_VERSION)) + +.PHONY: kind +kind: $(KIND) ## Download helm locally if necessary. +$(KIND): $(LOCALBIN) + $(call go-install-tool,$(KIND),sigs.k8s.io/kind,$(KIND_VERSION)) + +# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist +# $1 - target path with name of binary +# $2 - package url which can be installed +# $3 - specific version of package +define go-install-tool +@[ -f "$(1)-$(3)" ] || { \ +set -e; \ +package=$(2)@$(3) ;\ +echo "Downloading $${package}" ;\ +rm -f $(1) || true ;\ +GOBIN=$(LOCALBIN) go install $${package} ;\ +mv $(1) $(1)-$(3) ;\ +} ;\ +ln -sf $(1)-$(3) $(1) +endef HELM_DEPENDS ?= commons-operator secret-operator listener-operator zookeeper-operator hdfs-operator TEST_NAMESPACE = kubedoop-operators .PHONY: helm-install-depends -helm-install-depends: ## Install the helm chart depends. +helm-install-depends: helm ## Install the helm chart depends. $(HELM) repo add kubedoop https://zncdatadev.github.io/kubedoop-helm-charts/ ifneq ($(strip $(HELM_DEPENDS)),) for dep in $(HELM_DEPENDS); do \ @@ -371,41 +249,26 @@ endif ## helm uninstall depends .PHONY: helm-uninstall-depends -helm-uninstall-depends: ## Uninstall the helm chart depends. +helm-uninstall-depends: helm ## Uninstall the helm chart depends. ifneq ($(strip $(HELM_DEPENDS)),) for dep in $(HELM_DEPENDS); do \ $(HELM) uninstall --namespace $(TEST_NAMESPACE) $$dep; \ done endif -# kind -KIND_VERSION ?= v0.24.0 +##@ Chainsaw-E2E +# Tool Versions KINDTEST_K8S_VERSION ?= 1.26.15 +CHAINSAW_VERSION ?= v0.2.11 KIND_IMAGE ?= kindest/node:v${KINDTEST_K8S_VERSION} - KIND_KUBECONFIG ?= ./kind-kubeconfig-$(KINDTEST_K8S_VERSION) KIND_CLUSTER_NAME ?= ${PROJECT_NAME}-$(KINDTEST_K8S_VERSION) - -.PHONY: kind -KIND = $(LOCALBIN)/kind -kind: ## Download kind locally if necessary. -ifeq (,$(shell which $(KIND))) -ifeq (,$(shell which kind 2>/dev/null)) - @{ \ - set -e ;\ - go install sigs.k8s.io/kind@$(KIND_VERSION) ;\ - } -KIND = $(GOBIN)/bin/kind -else -KIND = $(shell which kind) -endif -endif - -OLM_VERSION ?= v0.28.0 KIND_CONFIG ?= test/e2e/kind-config.yaml +CHAINSAW = $(LOCALBIN)/chainsaw + # Create a kind cluster .PHONY: kind-create kind-create: kind ## Create a kind cluster. @@ -417,9 +280,6 @@ kind-delete: kind ## Delete a kind cluster. # chainsaw -CHAINSAW_VERSION ?= v0.2.11 -CHAINSAW ?= $(LOCALBIN)/chainsaw - # Use `grep 0.2.6 > /dev/null` instead of `grep -q 0.2.6`. It will not be able to determine the version number, # although the execution in the shell is normal, but in the makefile does fail to understand the mechanism in the makefile # The operation ends by using `touch` to change the time of the file so that its timestamp is further back than the directory, diff --git a/PROJECT b/PROJECT index 9aa8384..4d07fc8 100644 --- a/PROJECT +++ b/PROJECT @@ -5,9 +5,6 @@ domain: zncdata.dev layout: - go.kubebuilder.io/v4 -plugins: - manifests.sdk.operatorframework.io/v2: {} - scorecard.sdk.operatorframework.io/v2: {} projectName: hbase-operator repo: github.com/zncdatadev/hbase-operator resources: diff --git a/api/v1alpha1/hbasecluster_types.go b/api/v1alpha1/hbasecluster_types.go index 21fd889..02db2a8 100644 --- a/api/v1alpha1/hbasecluster_types.go +++ b/api/v1alpha1/hbasecluster_types.go @@ -96,8 +96,8 @@ type HbaseClusterStatus struct { Conditions []metav1.Condition `json:"conditions,omitempty"` } -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status // HbaseCluster is the Schema for the hbaseclusters API type HbaseCluster struct { @@ -108,7 +108,7 @@ type HbaseCluster struct { Status HbaseClusterStatus `json:"status,omitempty"` } -//+kubebuilder:object:root=true +// +kubebuilder:object:root=true // HbaseClusterList contains a list of HbaseCluster type HbaseClusterList struct { diff --git a/api/v1alpha1/hbasecluster_webhook.go b/api/v1alpha1/hbasecluster_webhook.go index 7596c50..660fb58 100644 --- a/api/v1alpha1/hbasecluster_webhook.go +++ b/api/v1alpha1/hbasecluster_webhook.go @@ -35,7 +35,7 @@ func (r *HbaseCluster) SetupWebhookWithManager(mgr ctrl.Manager) error { // TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -//+kubebuilder:webhook:path=/mutate-hbase-zncdata-dev-v1alpha1-hbasecluster,mutating=true,failurePolicy=fail,sideEffects=None,groups=hbase.zncdata.dev,resources=hbaseclusters,verbs=create;update,versions=v1alpha1,name=mhbasecluster.kb.io,admissionReviewVersions=v1 +// +kubebuilder:webhook:path=/mutate-hbase-zncdata-dev-v1alpha1-hbasecluster,mutating=true,failurePolicy=fail,sideEffects=None,groups=hbase.zncdata.dev,resources=hbaseclusters,verbs=create;update,versions=v1alpha1,name=mhbasecluster.kb.io,admissionReviewVersions=v1 var _ webhook.Defaulter = &HbaseCluster{} @@ -47,7 +47,7 @@ func (r *HbaseCluster) Default() { } // TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-hbase-zncdata-dev-v1alpha1-hbasecluster,mutating=false,failurePolicy=fail,sideEffects=None,groups=hbase.zncdata.dev,resources=hbaseclusters,verbs=create;update,versions=v1alpha1,name=vhbasecluster.kb.io,admissionReviewVersions=v1 +// +kubebuilder:webhook:path=/validate-hbase-zncdata-dev-v1alpha1-hbasecluster,mutating=false,failurePolicy=fail,sideEffects=None,groups=hbase.zncdata.dev,resources=hbaseclusters,verbs=create;update,versions=v1alpha1,name=vhbasecluster.kb.io,admissionReviewVersions=v1 var _ webhook.Validator = &HbaseCluster{} diff --git a/api/v1alpha1/webhook_suite_test.go b/api/v1alpha1/webhook_suite_test.go index 5295081..e11a20c 100644 --- a/api/v1alpha1/webhook_suite_test.go +++ b/api/v1alpha1/webhook_suite_test.go @@ -29,7 +29,7 @@ import ( . "github.com/onsi/gomega" admissionv1 "k8s.io/api/admission/v1" - //+kubebuilder:scaffold:imports + // +kubebuilder:scaffold:imports "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" @@ -83,7 +83,7 @@ var _ = BeforeSuite(func() { err = admissionv1.AddToScheme(scheme) Expect(err).NotTo(HaveOccurred()) - //+kubebuilder:scaffold:scheme + // +kubebuilder:scaffold:scheme k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) Expect(err).NotTo(HaveOccurred()) @@ -107,7 +107,7 @@ var _ = BeforeSuite(func() { err = (&HbaseCluster{}).SetupWebhookWithManager(mgr) Expect(err).NotTo(HaveOccurred()) - //+kubebuilder:scaffold:webhook + // +kubebuilder:scaffold:webhook go func() { defer GinkgoRecover() diff --git a/catalog-template.yaml b/catalog-template.yaml deleted file mode 100644 index 89c9a53..0000000 --- a/catalog-template.yaml +++ /dev/null @@ -1,121 +0,0 @@ ---- -defaultChannel: stable -description: |+ - # hbase-operator - - // TODO(user): Add simple overview of use/purpose - - ## Description - - // TODO(user): An in-depth paragraph about your project and overview of use - - ## Getting Started - - You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster. - **Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows). - - ### Running on the cluster - - 1. Install Instances of Custom Resources: - - ```sh - kubectl apply -f config/samples/ - ``` - - 2. Build and push your image to the location specified by `IMG`: - - ```sh - make docker-build docker-push IMG=/hbase-operator:tag - ``` - - 3. Deploy the controller to the cluster with the image specified by `IMG`: - - ```sh - make deploy IMG=/hbase-operator:tag - ``` - - ### Uninstall CRDs - - To delete the CRDs from the cluster: - - ```sh - make uninstall - ``` - - ### Undeploy controller - - UnDeploy the controller from the cluster: - - ```sh - make undeploy - ``` - - ## Contributing - - // TODO(user): Add detailed information on how you would like others to contribute to this project - - ### How it works - - This project aims to follow the Kubernetes [Operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/). - - It uses [Controllers](https://kubernetes.io/docs/concepts/architecture/controller/), - which provide a reconcile function responsible for synchronizing resources until the desired state is reached on the cluster. - - ### Test It Out - - 1. Install the CRDs into the cluster: - - ```sh - make install - ``` - - 2. Run your controller (this will run in the foreground, so switch to a new terminal if you want to leave it running): - - ```sh - make run - ``` - - **NOTE:** You can also run this in one step by running: `make install run` - - ### Modifying the API definitions - - If you are editing the API definitions, generate the manifests such as CRs or CRDs using: - - ```sh - make manifests - ``` - - **NOTE:** Run `make --help` for more information on all potential `make` targets - - More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html) - - ## License - - Copyright 2024 zncdatadev. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -icon: - base64data: iVBORw0KGgoAAAANSUhEUgAAAdYAAAB4CAYAAABPe9NwAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAN1wAADdcBQiibeAAABCRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjkwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj45MDwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjQ3MDwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MTIwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAg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 - mediatype: image/png -name: hbase-operator -schema: olm.package ---- -schema: olm.channel -package: hbase-operator -name: stable -entries: -- name: hbase-operator.v0.0.0-dev ---- -schema: olm.bundle -image: quay.io/zncdatadev/hbase-operator-bundle:0.0.0-dev diff --git a/cmd/main.go b/cmd/main.go index e12bd69..4b72875 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -17,6 +17,7 @@ limitations under the License. package main import ( + "crypto/tls" "flag" "os" @@ -31,11 +32,13 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/controller-runtime/pkg/metrics/filters" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" hbasev1alpha1 "github.com/zncdatadev/hbase-operator/api/v1alpha1" "github.com/zncdatadev/hbase-operator/internal/controller" - //+kubebuilder:scaffold:imports + // +kubebuilder:scaffold:imports ) var ( @@ -48,18 +51,26 @@ func init() { utilruntime.Must(authv1alpha1.AddToScheme(scheme)) utilruntime.Must(hbasev1alpha1.AddToScheme(scheme)) - //+kubebuilder:scaffold:scheme + // +kubebuilder:scaffold:scheme } func main() { var metricsAddr string var enableLeaderElection bool var probeAddr string - flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") + var secureMetrics bool + var enableHTTP2 bool + var tlsOpts []func(*tls.Config) + flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+ + "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") + flag.BoolVar(&secureMetrics, "metrics-secure", true, + "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.") + flag.BoolVar(&enableHTTP2, "enable-http2", false, + "If set, HTTP/2 will be enabled for the metrics and webhook servers") opts := zap.Options{ Development: true, } @@ -68,13 +79,53 @@ func main() { ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + // 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"} + } + + if !enableHTTP2 { + tlsOpts = append(tlsOpts, disableHTTP2) + } + + webhookServer := webhook.NewServer(webhook.Options{ + TLSOpts: tlsOpts, + }) + + // 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.1/pkg/metrics/server + // - https://book.kubebuilder.io/reference/metrics.html + metricsServerOptions := metricsserver.Options{ + BindAddress: metricsAddr, + SecureServing: secureMetrics, + 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.1/pkg/metrics/filters#WithAuthenticationAndAuthorization + metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization + + // TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically + // generate self-signed certificates for the metrics server. While convenient for development and testing, + // this setup is not recommended for production. + } + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: scheme, - Metrics: metricsserver.Options{ - BindAddress: metricsAddr, - }, + Scheme: scheme, + Metrics: metricsServerOptions, HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, + WebhookServer: webhookServer, LeaderElectionID: "8a493e83.zncdata.dev", // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily // when the Manager ends. This requires the binary to immediately end when the @@ -104,7 +155,7 @@ func main() { // setupLog.Error(err, "unable to create webhook", "webhook", "HbaseCluster") // os.Exit(1) //} - //+kubebuilder:scaffold:builder + // +kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { setupLog.Error(err, "unable to set up health check") diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index cf9db44..a09e30b 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -25,120 +25,153 @@ resources: #- ../certmanager # [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 +# Uncomment the patches line if you enable Metrics, and/or are using webhooks and cert-manager patches: -# Protect the /metrics endpoint by putting it behind auth. -# If you want your controller-manager to expose the /metrics -# endpoint w/o any authn/z, please comment the following line. -- path: manager_auth_proxy_patch.yaml - - +# [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443. +# More info: https://book.kubebuilder.io/reference/metrics +- path: manager_metrics_patch.yaml + target: + kind: Deployment # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml -#- manager_webhook_patch.yaml - -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. -# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. -# 'CERTMANAGER' needs to be enabled to use ca injection -#- webhookcainjection_patch.yaml +#- path: manager_webhook_patch.yaml # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. # Uncomment the following replacements to add the cert-manager CA injection annotations #replacements: -# - source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -# fieldPath: .metadata.namespace # namespace of the certificate CR -# targets: -# - select: -# kind: ValidatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - select: -# kind: MutatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - select: -# kind: CustomResourceDefinition -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 0 -# create: true -# - source: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -# fieldPath: .metadata.name -# targets: -# - select: -# kind: ValidatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# - select: -# kind: MutatingWebhookConfiguration -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# - select: -# kind: CustomResourceDefinition -# fieldPaths: -# - .metadata.annotations.[cert-manager.io/inject-ca-from] -# options: -# delimiter: '/' -# index: 1 -# create: true -# - source: # Add cert-manager annotation to the webhook Service -# kind: Service -# version: v1 -# name: webhook-service -# fieldPath: .metadata.name # namespace of the service -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# fieldPaths: -# - .spec.dnsNames.0 -# - .spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 0 -# create: true -# - source: -# kind: Service -# version: v1 -# name: webhook-service -# fieldPath: .metadata.namespace # namespace of the service -# targets: -# - select: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# fieldPaths: -# - .spec.dnsNames.0 -# - .spec.dnsNames.1 -# options: -# delimiter: '.' -# index: 1 -# create: true +# - source: # Uncomment the following block if you have any webhook +# kind: Service +# version: v1 +# name: webhook-service +# fieldPath: .metadata.name # Name of the service +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# fieldPaths: +# - .spec.dnsNames.0 +# - .spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 0 +# create: true +# - source: +# kind: Service +# version: v1 +# name: webhook-service +# fieldPath: .metadata.namespace # Namespace of the service +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# fieldPaths: +# - .spec.dnsNames.0 +# - .spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 1 +# create: true +# +# - source: # Uncomment the following block if you have a ValidatingWebhook (--programmatic-validation) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: +# - select: +# kind: ValidatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# create: true +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.name +# targets: +# - select: +# kind: ValidatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 1 +# create: true +# +# - source: # Uncomment the following block if you have a DefaultingWebhook (--defaulting ) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: +# - select: +# kind: MutatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# create: true +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.name +# targets: +# - select: +# kind: MutatingWebhookConfiguration +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 1 +# create: true +# +# - source: # Uncomment the following block if you have a ConversionWebhook (--conversion) +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.namespace # Namespace of the certificate CR +# targets: +# - select: +# kind: CustomResourceDefinition +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 0 +# create: true +# - source: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # This name should match the one in certificate.yaml +# fieldPath: .metadata.name +# targets: +# - select: +# kind: CustomResourceDefinition +# fieldPaths: +# - .metadata.annotations.[cert-manager.io/inject-ca-from] +# options: +# delimiter: '/' +# index: 1 +# create: true diff --git a/config/default/manager_auth_proxy_patch.yaml b/config/default/manager_auth_proxy_patch.yaml deleted file mode 100644 index 73fad2a..0000000 --- a/config/default/manager_auth_proxy_patch.yaml +++ /dev/null @@ -1,39 +0,0 @@ -# This patch inject a sidecar container which is a HTTP proxy for the -# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: kube-rbac-proxy - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.14.1 - args: - - "--secure-listen-address=0.0.0.0:8443" - - "--upstream=http://127.0.0.1:8080/" - - "--logtostderr=true" - - "--v=0" - ports: - - containerPort: 8443 - protocol: TCP - name: https - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi - - name: manager - args: - - "--health-probe-bind-address=:8081" - - "--metrics-bind-address=127.0.0.1:8080" - - "--leader-elect" diff --git a/config/default/manager_config_patch.yaml b/config/default/manager_config_patch.yaml deleted file mode 100644 index f6f5891..0000000 --- a/config/default/manager_config_patch.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: manager diff --git a/config/default/manager_metrics_patch.yaml b/config/default/manager_metrics_patch.yaml new file mode 100644 index 0000000..2aaef65 --- /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/rbac/auth_proxy_service.yaml b/config/default/metrics_service.yaml similarity index 53% rename from config/rbac/auth_proxy_service.yaml rename to config/default/metrics_service.yaml index ba5159e..eb38198 100644 --- a/config/rbac/auth_proxy_service.yaml +++ b/config/default/metrics_service.yaml @@ -3,11 +3,7 @@ kind: Service metadata: labels: control-plane: controller-manager - app.kubernetes.io/name: service - app.kubernetes.io/instance: controller-manager-metrics-service - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: hbase-operator - app.kubernetes.io/part-of: hbase-operator + app.kubernetes.io/name: hbase-operator app.kubernetes.io/managed-by: kustomize name: controller-manager-metrics-service namespace: system @@ -16,6 +12,6 @@ spec: - name: https port: 8443 protocol: TCP - targetPort: https + targetPort: 8443 selector: control-plane: controller-manager diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index 8216a91..8defaab 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -72,6 +72,7 @@ spec: - /manager args: - --leader-elect + - --health-probe-bind-address=:8081 image: controller:latest name: manager securityContext: diff --git a/config/manifests/bases/hbase-operator.clusterserviceversion.yaml b/config/manifests/bases/hbase-operator.clusterserviceversion.yaml deleted file mode 100644 index c7ee15d..0000000 --- a/config/manifests/bases/hbase-operator.clusterserviceversion.yaml +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: operators.coreos.com/v1alpha1 -kind: ClusterServiceVersion -metadata: - annotations: - alm-examples: '[]' - capabilities: Basic Install - category: Big Data - name: hbase-operator.v0.0.0 - namespace: placeholder -spec: - apiservicedefinitions: {} - customresourcedefinitions: - owned: - - description: HbaseCluster is the Schema for the hbaseclusters API - displayName: Hbase Cluster - kind: HbaseCluster - name: hbaseclusters.hbase.zncdata.dev - version: v1alpha1 - description: Hbase Operator - displayName: Hbase Operator - icon: - - base64data: PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iODAwIiB3aWR0aD0iMTIwMCIgdmlld0JveD0iLTkzIC0zOS42OTUgODA2IDIzOC4xNyI+PHBhdGggZD0iTTc2LjI3NSAxMzYuMjdoLTcuMzM5Vjk4LjAxMmg3LjMzOXptLTcuMjQ5LTM4LjI2NWwtLjA5LTIzLjY5M2g3LjMzOWwtLjAzIDIzLjcyM3ptLS4wOSAzOC4yNjVoLTcuMzR2LTIzLjgySDE0LjQzOHYyMy44MkgwVjc0LjMxMmgxNC40Mzh2MjMuN2g1NC40OTl2MzguMjU4em0wLTYxLjk1OGgtNy4zNHYyMy43MjNsNy40My0uMDN6bTgzLjI1MiAzMC41NTdjNS4wNTIgMy4xMjggNy41OCA3LjkgNy41OCAxNC4zMTYgMCA0LjY1Mi0xLjQ4NCA4LjU4Mi00LjQ1MiAxMS43OS0zLjIwOCAzLjUzLTcuNTQgNS4yOTQtMTIuOTk0IDUuMjk0SDEyMS4wOXYtMTQuNDM2aDIxLjIzM2MyLjA4NiAwIDMuMTI4LTEuNTY1IDMuMTI4LTQuNjkzIDAtMy4xMjctMS4wNDItNC42OTEtMy4xMjgtNC42OTFIMTIxLjA5Vjk4LjEzMmgyMC4xNTFjMi4wODUgMCAzLjEyOC0xLjU2NCAzLjEyOC00LjY5MiAwLTMuMTI3LTEuMDQzLTQuNjkyLTMuMTI4LTQuNjkySDEyMS4wOVY3NC4zMTJoMjAuMTUxYzUuNDU0IDAgOS43ODQgMS43NjQgMTIuOTkzIDUuMjkzIDIuODg3IDMuMjA4IDQuMzMxIDcuMTM5IDQuMzMxIDExLjc5IDAgNS43NzUtMi4xMjYgMTAuMjY2LTYuMzc2IDEzLjQ3NHptLTMxLjEgMzEuNDAxSDgyLjI5Vjk4LjEzM2gzOC43OTl2MTQuMzE3SDk2LjcyN3Y5LjM4M2gyNC4zNjJ2MTQuNDM3em0wLTQ3LjUyMWgtMjQuMzZsLjAzIDkuODI3LTE0LjQzOC0uMzYxLS4wMy0yMy45MDNoMzguNzk5djE0LjQzN3oiIGZpbGw9IiNiYTE2MGMiLz48cGF0aCBkPSJNMTY2LjQxNiA1OC4yMDZWNTEuNTloMTAuNzc4di0zLjk3YzAtMS40MzMtLjQ3Ny0yLjE1LTEuNDMzLTIuMTVoLTkuMzQ2di02LjYxNWg5LjM0NmMyLjM5IDAgNC4zMjguODYzIDUuODE2IDIuNTkyIDEuNDg4IDEuNzI4IDIuMjMzIDMuNzg1IDIuMjMzIDYuMTc0djE5LjYyN2gtNi42MTZ2LTkuMDQxaC0xMC43Nzh6bTg3Ljk2NSA5LjA0MmgtMjEuOTQ0Yy0yLjU3MiAwLTQuNzU5LS44NTQtNi41Ni0yLjU2NS0xLjgwMS0xLjcwOS0yLjctMy44NS0yLjctNi40MjJ2LTEwLjQyYzAtMi41NzMuODk5LTQuNzE0IDIuNy02LjQyNCAxLjgwMS0xLjcwOSAzLjk4OC0yLjU2MyA2LjU2LTIuNTYzaDIxLjk0NHY2LjYxNWgtMjEuOTQ0Yy0xLjc2MyAwLTIuNjQ1Ljc5MS0yLjY0NSAyLjM3MnYxMC40MmMwIDEuNTguODgyIDIuMzcgMi42NDUgMi4zN2gyMS45NDR6bTY5LjYzMSAwaC02LjY3MlY1Ni4zMzJoLTE2Ljk4djEwLjkxNmgtNi42MTZWMzguODU1aDYuNjE2djEwLjg2MWgxNi45OHYtMTAuODZoNi42NzJ6bTY5LjYzMy0yMS43NzhoLTIzLjY1MXY0LjI0NkgzOTIuMXY2LjYxNmgtMjIuMTA4djQuM2gyMy41OTZ2Ni42MTVoLTMwLjIxMlYzOC44NTRoMzAuMjY3djYuNjE2em0tMjI3LjIyOS02LjYxNXY2LjYxNWgtOS40Yy0uOTE5IDAtMS4zNzguNzE3LTEuMzc4IDIuMTV2My45N2gxMC43Nzh2Ni42MTZoLTEwLjc3OHY5LjA0MWgtNi42MTZWNDcuNjJjMC0yLjM4OS43NDUtNC40NDcgMi4yMzQtNi4xNzQgMS40ODctMS43MjggMy40MDgtMi41OTIgNS43Ni0yLjU5Mmg5LjR6bS03NC41MSAxOS4xM1Y1MS4zN2g5LjcwM2MuOTU1IDAgMS40MzQtLjk3NCAxLjQzNC0yLjkyMSAwLTEuOTg1LS40NzktMi45NzgtMS40MzQtMi45NzhoLTkuNzAzdi02LjYxNWg5LjcwM2MyLjQ2MyAwIDQuNDQ3IDEuMDEgNS45NTQgMy4wMzIgMS4zOTcgMS44MzggMi4wOTYgNC4wMjMgMi4wOTYgNi41NiAwIDIuNTM2LS43IDQuNzA0LTIuMDk2IDYuNTA2LTEuNTA3IDIuMDIxLTMuNDkxIDMuMDMyLTUuOTU0IDMuMDMyem0tNTcuMTE4IDkuMjYzaC02LjYxNnYtOS4wNDFIMTcuMzk0VjUxLjU5aDEwLjc3OHYtMy45N2MwLTEuNDMzLS40NzgtMi4xNS0xLjQzMy0yLjE1aC05LjM0NXYtNi42MTVoOS4zNDVjMi4zOSAwIDQuMzI4Ljg2MyA1LjgxNiAyLjU5MSAxLjQ4OSAxLjcyOCAyLjIzMyAzLjc4NiAyLjIzMyA2LjE3NXptNTcuMTE4LTI4LjM5M3Y2LjYxNUg4MC43Njl2NS45aDExLjEzN3Y2LjYxNUg4MC43Njl2OS4yNjJoLTYuNjE2VjM4Ljg1NGgxNy43NTN6TTE3LjM5NSA1OC4yMDZINi42MTZ2OS4wNDFIMFY0Ny42MmMwLTIuMzg5Ljc0NS00LjQ0NyAyLjIzMi02LjE3NCAxLjQ4OS0xLjcyOCAzLjQxLTIuNTkyIDUuNzYyLTIuNTkyaDkuNHY2LjYxNWgtOS40Yy0uOTIgMC0xLjM3OC43MTgtMS4zNzggMi4xNXYzLjk3aDEwLjc3OXoiIGZpbGw9IiM2NjYiLz48cGF0aCBkPSJNMjQxLjQ3NiAxMzYuMjdoLTE0LjQzN3YtMTkuNzNoLTIzLjUydi0xNC40MzhoMjMuNTJWOTMuNDRjMC0zLjEyNy0xLjA0My00LjY5LTMuMTI5LTQuNjloLTIwLjM5Vjc0LjMxMWgyMC4zOTFjNS4yMTQgMCA5LjQ0NCAxLjg4NSAxMi42OTMgNS42NTQgMy4yNDggMy43NyA0Ljg3MyA4LjI2MiA0Ljg3MyAxMy40NzR6bS0zNy45NTctMTkuNzNoLTIzLjUydjE5LjczSDE2NS41NlY5My40NGMwLTUuMjEzIDEuNjI0LTkuNzA0IDQuODcyLTEzLjQ3NCAzLjI0OC0zLjc3IDcuNDQtNS42NTQgMTIuNTczLTUuNjU0aDIwLjUxMnYxNC40MzdoLTIwLjUxMmMtMi4wMDUgMC0zLjAwNyAxLjU2NC0zLjAwNyA0LjY5djguNjYzaDIzLjUyem0xMTguMDYxLjZjMCA1LjIxNS0xLjU2NCA5LjY2NS00LjY5MyAxMy4zNTUtMy4zNjggMy44NS03LjYyIDUuNzc1LTEyLjc1MiA1Ljc3NUgyNTAuNzJ2LTE0LjQzN2g1My40MTVjMi4wMDYgMCAzLjAwOC0xLjU2NCAzLjAwOC00LjY5MiAwLTMuMTI3LTEuMDAzLTQuNjkxLTMuMDA4LTQuNjkxaC0zOC44NTljLTUuMTMyIDAtOS4zODQtMS45MjYtMTIuNzUyLTUuNzc2LTMuMjA5LTMuNjA4LTQuODEzLTguMDItNC44MTMtMTMuMjM0IDAtNS4yMTIgMS42NDUtOS43MDMgNC45MzMtMTMuNDc0IDMuMjg4LTMuNzcgNy41LTUuNjU0IDEyLjYzMi01LjY1NGg1My40MTZWODguNzVoLTUzLjQxNmMtMi4wMDUgMC0zLjAwOCAxLjU2NC0zLjAwOCA0LjY5MSAwIDMuMDQ4IDEuMDAzIDQuNTcyIDMuMDA4IDQuNTcyaDM4Ljg2YzUuMTMyIDAgOS4zODMgMS45MjUgMTIuNzUxIDUuNzc2IDMuMTI5IDMuNjg5IDQuNjkzIDguMTQgNC42OTMgMTMuMzUzem03Mi4wNjUtNDIuODI4Vjg4Ljc1aC01MS42MTJ2OS4yNjNoNDguMjQzdjE0LjQzOGgtNDguMjQzdjkuMzgzaDUxLjQ5MXYxNC40MzdoLTY1LjkyOVY3NC4zMTJ6IiBmaWxsPSIjYmExNjBjIi8+PHBhdGggZD0iTTYxNSAxNTguMDA3Yy0uMTYyLS40MjUtLjI5NC0xLjE3Ni0uMjk0LTEuNjY5IDAtMS4zNC0xLjAzMi0zLjEwNy0yLjU1Ny00LjM4Mi0uNzQ3LS42MjUtMS44MjUtMS44MzktMi4zOTYtMi42OTktMS4yMTYtMS44MzEtMi41MzMtMi41NDgtNy4zOTgtNC4wMjktNS4zMzMtMS42MjItNi45NzItMy4wMTUtNy40NTQtNi4zMzNsLS4yNC0xLjY1NC0uOTcxIDEuNDA4Yy0xLjkwMSAyLjc1NC0zLjE1OSAzLjE5NC01LjczNiAyLjAwNy0xLjYzNi0uNzU1LTIuODI4LS44MjQtNC4xODYtLjI0My0uODY2LjM3LTEuMDI3LjM1NS0xLjU5My0uMTU3LS42MDUtLjU0Ny0uNjY2LS41NDktMS41MjQtLjA0Mi0uNjc2LjM5OS0xLjIyMi40NzgtMi4yNDcuMzI0LTEuNjM4LS4yNDUtMi41MTMuMjMyLTMuNjEgMS45Ny0yLjA3NSAzLjI4OC0zLjU1MyAxLjc4My0zLjU0Ni0zLjYxLjAwOC01Ljk5IDIuODI4LTkuMzg1IDEwLjk1Ny0xMy4xODggNC4xODQtMS45NTcgNi4wNzktMy4yMjUgNy4yNDUtNC44NDguODk4LTEuMjUxLjk3Ny0xLjI5NSAxLjM2OC0uNzYuODMyIDEuMTM4IDMuNjk5IDcuMDA1IDUuMDY4IDEwLjM3MiAxLjU2IDMuODM2IDIuMDMxIDQuNTQ3IDIuNjIzIDMuOTU2LjQ5OS0uNS0uNzA5LTQuMDM1LTMuMDU0LTguOTM4LTUuODItMTIuMTY4LTE0LjQxOC0yMC44NzEtMjUuMTQ5LTI1LjQ1Ni00LjkyNS0yLjEwNC03LjM0Ni0yLjU1Mi0xMy43NC0yLjU0LTQuODYxLjAxLTYuMDU0LjExMy05LjMzOC44MTItNC44MDMgMS4wMi0xMC4xNzQgMi43MzktMTcuMDIgNS40NDUtNi44OTcgMi43MjUtNi45MDMgMi43MjUtMTMuODU4LjIzNi0yLjgxNi0xLjAwOC02LjE5My0yLjEwNi03LjUwNC0yLjQ0LTIuNjc4LS42ODQtNi42MzItLjgwMy04Ljg1NS0uMjY4LTIuNTY0LjYxNy02LjE3MiAyLjU0Ni0xMC42MDIgNS42NjktNS4zMTYgMy43NDctOC4xNzYgNS4yMzItMTEuOTg2IDYuMjIyLTMuMy44NTctNC42OTUgMS42MDMtNS41MTYgMi45NS0uNjU2IDEuMDc2LS43MiAxLjk0LS4yMjMgMy4wMy4zNC43NDcgMy41OTQgMy4xMjIgNy40IDUuNDAyIDEuMDMyLjYxOCAxLjk1MyAxLjI0OCAyLjA0NiAxLjM5OS4yMjMuMzYtNC45MzMgMi45MzEtOC43IDQuMzM4LTYuNjk1IDIuNTAyLTEzLjg5MiA0LjA4NS0yNC43NDMgNS40NDItNy4yMy45MDQtOC40NjEgMS4xNTgtMTMuODU3IDIuODUxLTIuMTU0LjY3Ny01LjI3MiAxLjUxLTYuOTI5IDEuODU1LTcuMzA4IDEuNTE2LTEzLjkzMS0uMjgyLTE0LjkzNS00LjA1NC0uMTg0LS42OS0uNTExLTEuNDU2LS43MjgtMS43MDUtMS4zMzctMS41MzQtMS44MzMtNS4yMjItLjk3Mi03LjIzLjI1LS41OC43NS0yLjgxNiAxLjExNC00Ljk3IDEuMjUxLTcuNDE2IDIuNTIzLTExLjQyNyA1LjI2MS0xNi42MDIgNC43OTktOS4wNjYgMTQuMzUyLTIwLjU3NiAyNS45MjUtMzEuMjM0IDcuNjQ3LTcuMDQyIDE0LjkxMy0xMi40NTggMzEuNzEyLTIzLjYzNCAxMC4zODQtNi45MDggMTAuNDg0LTYuOTk3IDExLjY3OC0xMC4zMjguMjY1LS43NCAxLjU1My01LjUwNCAyLjg2Mi0xMC41ODggNC4wNzctMTUuODMzIDYuNjkyLTIxLjgxIDExLjU0Ny0yNi4zOTQgMi43NC0yLjU4NiA3LjEwNS00LjE5OCA5LjY0NC0zLjU2IDEuNDQ4LjM2MyAxLjUyIDEuMDc2LjUxNiA1LjEtMS42NzMgNi43MDUtMi4yMzcgMTAuOTQ0LTIuMjUzIDE2LjkyNi0uMDE1IDUuOTA0LjM1IDguMTg5IDEuNzUyIDEwLjk1NSAxLjkyMyAzLjc5NCAzLjIyIDQuNTI3IDEwLjc1MyA2LjA3IDI2LjY0MyA1LjQ2IDQ0LjQyIDEzLjY2NyA1Ny4wNSAyNi4zMzggMTEuNjk4IDExLjczNiAyMS4yMzIgMzAuMTAzIDI3LjQzNCA1Mi44NTJsMS4xODEgNC4zMyAyLjI2IDEuNzNjNS43NjQgNC40MTcgOC45OTMgOC44NjUgMTAuNzE0IDE0Ljc1OC45MSAzLjExOC43NzIgOS43NDctLjI4NSAxMy42NTctMS4xMjggNC4xNy0yLjA5IDUuOTI0LTMuMjU0IDUuOTI0LS4zMjcgMC0uNjg2LS4zMjQtLjg1Ny0uNzczem0uNDk0LTguNzQ4Yy4xMDgtLjQzMi4xMjUtMi4yOTYuMDM3LTQuMTQyLS4yOC01Ljg3Ny0yLjA5My0xMC4wNzQtNi4yNDctMTQuNDU3LTMuMTktMy4zNjYtOC45Ny03LjQyNy0xMC41Ny03LjQyNy0uNjEyIDAtLjY0OC4xMDctLjQ4OSAxLjQ0OC4wOTQuNzk2LjczMyAyLjkyNCAxLjQxOSA0LjcyNy42ODYgMS44MDQgMS4zMjMgMy45MiAxLjQxNSA0LjcwMy4xNDggMS4yNDguMDc0IDEuNTE4LS42MSAyLjItLjkzOC45NC0xLjgyMi45ODMtMy4xNzQuMTYtLjU1Ny0uMzQtMS4wNzktLjU1Mi0xLjE2LS40NzItLjA4LjA4LS4wNTMuNjk0LjA2IDEuMzYzLjQxIDIuNDMyIDEuODIgMy40MDkgNy4yMjcgNS4wMSA3LjkyNSAyLjM0NyA5LjU1NCAzLjQyNCAxMC44MDcgNy4xNDQuMjY3Ljc5MyAxLjA2Mi42MzQgMS4yODUtLjI1N3ptLTE4OC44LTExLjE0NmMxLjM4OC0uMjUgNC4xNjctLjk3NSA2LjE3Ni0xLjYxMSA0LjMxNi0xLjM2NyA3LjYyMi0yLjA1NSAxNi43NTUtMy40ODUgMTAuNzE1LTEuNjc4IDE1LjAyNi0yLjU3IDE5LjgwMi00LjA5NiAzLjAzNy0uOTcgNS44MTItMi4yMTggNS43OTMtMi42MDUtLjAwNi0uMTIyLS45MDItLjc2NC0xLjk5Mi0xLjQyNi0xLjA5LS42NjMtMy4xMjctMi4zMjQtNC41MjctMy42OS0xLjQtMS4zNjctMi42NzctMi40ODYtMi44MzgtMi40ODYtLjc1OCAwLTIuNjcgMS4wNjgtNS4wODMgMi44MzktNi45MDkgNS4wNy05LjMzIDYuMDc0LTIwLjM0MyA4LjQyMi01LjQ2NSAxLjE2NS03LjQwNCAxLjgyNi05Ljk2IDMuMzk0LTMuNTMzIDIuMTY4LTQuMjk0IDIuNTI3LTYuNjEyIDMuMTItMS4yOTQuMzMtMy4zNC42MDEtNC41NDUuNjAxLTMuMTUgMC0zLjUuOTgtLjUzOCAxLjUwMyAxLjc0Ni4zMDkgNC40NDMuMTQ1IDcuOTEyLS40OHptMTUwLjA5NC0uNjJjLjIyNy0uMjc1Ljk5NC0uNzU4IDEuNzA1LTEuMDczbDEuMjkxLS41NzMgMi43NzYuODQyYzMuNDc1IDEuMDU0IDguMDMxIDEuMjEgOS4yNjQuMzE2bDEuNzctMS4yODVjLjYyMi0uNDUgMS4yNS0uNjc4IDEuNTgyLS41NzIuMzA0LjA5Ni41NTIuMTI5LjU1Mi4wNzIgMC0uMzA3LTQuMjU2LTEwLjA0Mi00LjY1OS0xMC42NTdsLS40NzgtLjczLTEuNTE2IDEuMTk5Yy0uODM0LjY1OS0zLjY2IDIuNDg3LTYuMjggNC4wNjMtNi43MzEgNC4wNDctOC44NDMgNi4xMS04LjMzMyA4LjE0LjE0OC41OS4zODIuNzU5IDEuMDUxLjc1OS40NzQgMCAxLjA0OC0uMjI2IDEuMjc1LS41MDF6bS0xMjYuODctMTcuMzQ4Yy43My0uMzczIDEuNDU3LS44OTYgMS42MTgtMS4xNjQgMS4yNjUtMi4wOTgtMy43NzktMS44NzctNS4xMzguMjI1LS4zNTkuNTU3LS4zNS43MDkuMDcyIDEuMTMuNjc1LjY3NSAxLjg4Ni42MDggMy40NDktLjE5em05LjQ5My02LjU4NGMzLjI0My0uODcgNi40ODktMS45MzkgNy40ODEtMi40NjMgMi4wNzYtMS4wOTUgMy44NC0yLjk5NSA1LjA5NS01LjQ4OC41LS45OTQgMS40MzUtMi4yOTUgMi4wNzctMi44OS42NDItLjU5NyAxLjE2Ny0xLjMwMyAxLjE2Ny0xLjU3IDAtMi4zNDYtOC4wNi0zLjQxMi0xMy4yNTUtMS43NTQtNi4yOTYgMi4wMS0xMi4zMSA4LjQyMy0xMi40NTUgMTMuMjgyLS4wODkgMi45NzkgMS41NDMgMy4xMjUgOS44OS44ODN6bTEyMy42NjUtOS4yMDVjMC0uNTQ1LTIuMDA5LTMuMjE3LTMuNDMtNC41Ni0yLjc1Ny0yLjYwOC01LjU3My00LjIxNC0xMC45OTgtNi4yNzQtMy4yMjItMS4yMjMtNC41NS0xLjk3My00LjU1LTIuNTY5IDAtLjE0LjI3LS41MjUuNjAyLS44NTcgMS42OTEtMS42OTEgOS43OTIuMzkzIDE1LjUwNyAzLjk5IDIuMjU3IDEuNDIgNC44MzIgMy40MjYgNi45OCA1LjQzNSAxLjY0MiAxLjUzNiAxLjkxMyAxLjY5NSAxLjkxMyAxLjEyIDAtLjkwNS0xLjQ5LTMuNjM1LTMuMzA2LTYuMDU0LTQuNTQyLTYuMDUyLTExLjkzMS0xMC43NjUtMjAuMTk5LTEyLjg4My02LjY4LTEuNzExLTEyLjQ3Ny0xLjgwOS0xNy40MjItLjI5My00LjU3MSAxLjQwMi05Ljg4IDQuNzA1LTE1LjIxIDkuNDY3LTcuNSA2LjctOS43MjIgOC41NjgtMTEuNjQgOS43ODYtMS4xNTIuNzMyLTIuMDU0IDEuNDYyLTIuMDA2IDEuNjIyLjA1LjE2LjkxNC41NTUgMS45MjMuODc4bDEuODMzLjU4NiA0LjQ3MS0yLjA1NGM4Ljg0LTQuMDYxIDE2Ljk1NS02LjY3NiAyMi45OTctNy40MDkgOS4yMi0xLjExOSAxOS41MyAxLjc5NSAyOC43NyA4LjEzIDIuODE2IDEuOTMyIDMuNzY1IDIuNDIgMy43NjUgMS45NHptLTgxLjYzNyAyNS40ODdjLTkuNDgzLTEuMTcyLTE4LjQ0MS00LjQ4Ni0yNS43NTctOS41MjgtMS42NTgtMS4xNDMtMi4xMy0xLjYzNi0yLjIwNi0yLjMwNy0uMTkxLTEuNjY2IDEuMzM1LTIuNjUyIDUuNDU3LTMuNTI0IDMuNjI3LS43NjcgNi4wMjQtMS45ODMgMTEuNTEtNS44MzcgNy40MTYtNS4yMSAxMC4zNS02LjM5MyAxNS4xODMtNi4xMjYgMi4yNjMuMTI1IDMuNjc3LjUwNiAxMS4xNzYgMy4wMSAxMS4yNDEgMy43NTQgMjMuMTYzIDguMDAxIDI0LjA1OSA4LjU3MiAyLjA1NCAxLjMwNy0xLjQ5NCA2LjEzNi03LjA1NiA5LjYwMi00LjE5MyAyLjYxNC05LjczIDQuNjY3LTE1LjQxOCA1LjcxNy0zLjEzNC41NzktMTMuNTc0LjgzOC0xNi45NDguNDIxem0tNzAuMDYxLTQ2Ljc3OGMtLjExOC0uMzA1LS4xMzctMS43OTYtLjA0Mi0zLjMxNC40MTgtNi42NyA0LjA0NC0xNC4yMTMgOC45ODMtMTguNjgyIDEuODkzLTEuNzE0IDQuOTE3LTMuNTA3IDUuOTEyLTMuNTA3Ljk5IDAgMS42MDYgMS4wMzUgMi4zNDcgMy45NDUuMzkgMS41MzIgMSAzLjE4IDEuMzU2IDMuNjYxLjM1Ni40ODIuNjAyLjkxNi41NDYuOTY1LS4wNTYuMDUtMS40NTggMS4xNjYtMy4xMTQgMi40ODItNC4wNDcgMy4yMTMtOS42NSA4LjM5LTEzLjAxNyAxMi4wMjYtMi4yOTcgMi40ODItMi43OTMgMi44ODYtMi45NzEgMi40MjR6IiBmaWxsPSIjMDUwNTA1Ii8+PC9zdmc+ - mediatype: image/svg+xml - install: - spec: - deployments: null - strategy: "" - installModes: - - supported: false - type: OwnNamespace - - supported: false - type: SingleNamespace - - supported: false - type: MultiNamespace - - supported: true - type: AllNamespaces - keywords: - - hbase - - k8s - links: - - name: Hbase Operator - url: https://github.com/zncdatadev/hbase-operator - - name: hbase - url: https://hbase.apache.org/ - maintainers: - - email: zncdatadev@googlegroups.com - name: ZNCDataDev Team - maturity: stable - minKubeVersion: 1.26.1 - provider: - name: zncdatadev - url: https://github.com/zncdatadev - version: 0.0.0 diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml deleted file mode 100644 index 0569121..0000000 --- a/config/manifests/kustomization.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# These resources constitute the fully configured set of manifests -# used to generate the 'manifests/' directory in a bundle. -resources: -- bases/hbase-operator.clusterserviceversion.yaml -- ../default -- ../samples -- ../scorecard - -# [WEBHOOK] To enable webhooks, uncomment all the sections with [WEBHOOK] prefix. -# Do NOT uncomment sections with prefix [CERTMANAGER], as OLM does not support cert-manager. -# These patches remove the unnecessary "cert" volume and its manager container volumeMount. -#patches: -#- target: -# group: apps -# version: v1 -# kind: Deployment -# name: controller-manager -# namespace: system -# patch: |- -# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. -# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. -# - op: remove - -# path: /spec/template/spec/containers/0/volumeMounts/0 -# # Remove the "cert" volume, since OLM will create and mount a set of certs. -# # Update the indices in this path if adding or removing volumes in the manager's Deployment. -# - op: remove -# path: /spec/template/spec/volumes/0 diff --git a/config/network-policy/allow-metrics-traffic.yaml b/config/network-policy/allow-metrics-traffic.yaml new file mode 100644 index 0000000..54fc5b0 --- /dev/null +++ b/config/network-policy/allow-metrics-traffic.yaml @@ -0,0 +1,26 @@ +# 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: + app.kubernetes.io/name: kubebuilder-operator + app.kubernetes.io/managed-by: kustomize + 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 0000000..ec0fb5e --- /dev/null +++ b/config/network-policy/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- allow-metrics-traffic.yaml diff --git a/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml index 4538837..8ce8c56 100644 --- a/config/prometheus/monitor.yaml +++ b/config/prometheus/monitor.yaml @@ -20,6 +20,15 @@ spec: 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: diff --git a/config/rbac/auth_proxy_client_clusterrole.yaml b/config/rbac/auth_proxy_client_clusterrole.yaml deleted file mode 100644 index 111e48e..0000000 --- a/config/rbac/auth_proxy_client_clusterrole.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: metrics-reader - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: hbase-operator - app.kubernetes.io/part-of: hbase-operator - app.kubernetes.io/managed-by: kustomize - name: metrics-reader -rules: -- nonResourceURLs: - - "/metrics" - verbs: - - get diff --git a/config/rbac/auth_proxy_role.yaml b/config/rbac/auth_proxy_role.yaml deleted file mode 100644 index dc435cb..0000000 --- a/config/rbac/auth_proxy_role.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: proxy-role - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: hbase-operator - app.kubernetes.io/part-of: hbase-operator - app.kubernetes.io/managed-by: kustomize - name: proxy-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create diff --git a/config/rbac/auth_proxy_role_binding.yaml b/config/rbac/auth_proxy_role_binding.yaml deleted file mode 100644 index 66adbd2..0000000 --- a/config/rbac/auth_proxy_role_binding.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/name: clusterrolebinding - app.kubernetes.io/instance: proxy-rolebinding - app.kubernetes.io/component: kube-rbac-proxy - app.kubernetes.io/created-by: hbase-operator - app.kubernetes.io/part-of: hbase-operator - app.kubernetes.io/managed-by: kustomize - name: proxy-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: proxy-role -subjects: -- kind: ServiceAccount - name: controller-manager - namespace: system diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml index 731832a..8e40076 100644 --- a/config/rbac/kustomization.yaml +++ b/config/rbac/kustomization.yaml @@ -9,10 +9,18 @@ resources: - role_binding.yaml - leader_election_role.yaml - leader_election_role_binding.yaml -# Comment the following 4 lines if you want to disable -# the auth proxy (https://github.com/brancz/kube-rbac-proxy) -# which protects your /metrics endpoint. -- auth_proxy_service.yaml -- auth_proxy_role.yaml -- auth_proxy_role_binding.yaml -- auth_proxy_client_clusterrole.yaml +# The following RBAC configurations are used to protect +# the metrics endpoint with authn/authz. These configurations +# ensure that only authorized users and service accounts +# can access the metrics endpoint. Comment the following +# permissions if you want to disable this protection. +# More info: https://book.kubebuilder.io/reference/metrics.html +- metrics_auth_role.yaml +- metrics_auth_role_binding.yaml +- metrics_reader_role.yaml +# For each CRD, "Editor" and "Viewer" roles are scaffolded by +# default, aiding admins in cluster management. Those roles are +# not used by the Project itself. You can comment the following lines +# if you do not want those helpers be installed with your Project. +- hbasecluster_editor_role.yaml +- hbasecluster_viewer_role.yaml diff --git a/config/rbac/metrics_auth_role.yaml b/config/rbac/metrics_auth_role.yaml new file mode 100644 index 0000000..32d2e4e --- /dev/null +++ b/config/rbac/metrics_auth_role.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-auth-role +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 0000000..e775d67 --- /dev/null +++ b/config/rbac/metrics_auth_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: metrics-auth-rolebinding +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 0000000..51a75db --- /dev/null +++ b/config/rbac/metrics_reader_role.yaml @@ -0,0 +1,9 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/config/scorecard/bases/config.yaml b/config/scorecard/bases/config.yaml deleted file mode 100644 index c770478..0000000 --- a/config/scorecard/bases/config.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: scorecard.operatorframework.io/v1alpha3 -kind: Configuration -metadata: - name: config -stages: -- parallel: true - tests: [] diff --git a/config/scorecard/kustomization.yaml b/config/scorecard/kustomization.yaml deleted file mode 100644 index 7fa7113..0000000 --- a/config/scorecard/kustomization.yaml +++ /dev/null @@ -1,15 +0,0 @@ -resources: -- bases/config.yaml -patches: -- 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 diff --git a/config/scorecard/patches/basic.config.yaml b/config/scorecard/patches/basic.config.yaml deleted file mode 100644 index a2f1589..0000000 --- a/config/scorecard/patches/basic.config.yaml +++ /dev/null @@ -1,10 +0,0 @@ -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - basic-check-spec - image: quay.io/operator-framework/scorecard-test:v1.33.0 - labels: - suite: basic - test: basic-check-spec-test diff --git a/config/scorecard/patches/olm.config.yaml b/config/scorecard/patches/olm.config.yaml deleted file mode 100644 index 9b7ca41..0000000 --- a/config/scorecard/patches/olm.config.yaml +++ /dev/null @@ -1,50 +0,0 @@ -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-bundle-validation - image: quay.io/operator-framework/scorecard-test:v1.33.0 - labels: - suite: olm - test: olm-bundle-validation-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-crds-have-validation - image: quay.io/operator-framework/scorecard-test:v1.33.0 - labels: - suite: olm - test: olm-crds-have-validation-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-crds-have-resources - image: quay.io/operator-framework/scorecard-test:v1.33.0 - labels: - suite: olm - test: olm-crds-have-resources-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-spec-descriptors - image: quay.io/operator-framework/scorecard-test:v1.33.0 - labels: - suite: olm - test: olm-spec-descriptors-test -- op: add - path: /stages/0/tests/- - value: - entrypoint: - - scorecard-test - - olm-status-descriptors - image: quay.io/operator-framework/scorecard-test:v1.33.0 - labels: - suite: olm - test: olm-status-descriptors-test diff --git a/go.mod b/go.mod index 0ebe300..b411ca8 100644 --- a/go.mod +++ b/go.mod @@ -15,16 +15,22 @@ require ( require ( emperror.dev/errors v0.8.1 // 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/cisco-open/k8s-objectmatcher v1.10.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.9.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // 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.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -33,12 +39,15 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect + github.com/google/cel-go v0.20.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/imdario/mergo v0.3.6 // 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/mailru/easyjson v0.7.7 // indirect @@ -50,27 +59,44 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stoewer/go-strcase v1.2.0 // indirect github.com/x448/float16 v0.8.4 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.opentelemetry.io/otel v1.28.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.28.0 // indirect + go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/term v0.25.0 // indirect golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.26.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.31.0 // indirect + k8s.io/apiserver v0.31.0 // indirect + k8s.io/component-base v0.31.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 4fc9e1b..3b365d8 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,20 @@ emperror.dev/errors v0.8.1 h1:UavXZ5cSX/4u9iyvH6aDcuGkVjeexUGJ7Ij7G4VfQT0= emperror.dev/errors v0.8.1/go.mod h1:YcRvLPh626Ubn2xqtoprejnA5nFha+TJ+2vew48kWuE= +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/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/cisco-open/k8s-objectmatcher v1.10.0 h1:1TdhMPqVaU+NqECqytAkRF1SFU0QIMqrqbNTnTl933A= github.com/cisco-open/k8s-objectmatcher v1.10.0/go.mod h1:O/TFG3vW12jbKNQejpc8SGgSfujlaWYIOCZHcXeK514= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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= @@ -17,12 +26,17 @@ github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lSh 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/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= 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/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +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.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= @@ -40,6 +54,8 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= +github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -52,8 +68,12 @@ github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgY github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/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/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/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -95,12 +115,18 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg 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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +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/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= 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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 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.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -112,6 +138,22 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zncdatadev/operator-go v0.11.2 h1:/3ti+26D9w38gZV2eQLIz62mPe45em3Ej8iePoSj/04= github.com/zncdatadev/operator-go v0.11.2/go.mod h1:Thc0Jo5LuXnwrb73shfI63PKlxC+7cGq7SClzo3Y5qI= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +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.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= +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/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -138,6 +180,8 @@ golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbht 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.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= @@ -163,6 +207,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T 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/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -172,6 +222,7 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSP gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= @@ -184,8 +235,12 @@ k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24 k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk= k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw= k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/apiserver v0.31.0 h1:p+2dgJjy+bk+B1Csz+mc2wl5gHwvNkC9QJV+w55LVrY= +k8s.io/apiserver v0.31.0/go.mod h1:KI9ox5Yu902iBnnyMmy7ajonhKnkeZYJhTZ/YI+WEMk= k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc= k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs= +k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs= +k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo= 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-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= @@ -194,6 +249,8 @@ k8s.io/kubectl v0.31.2 h1:gTxbvRkMBwvTSAlobiTVqsH6S8Aa1aGyBcu5xYLsn8M= k8s.io/kubectl v0.31.2/go.mod h1:EyASYVU6PY+032RrTh5ahtSOMgoDRIux9V1JLKtG5xM= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.19.1 h1:Son+Q40+Be3QWb+niBXAg2vFiYWolDjjRfO8hn/cxOk= sigs.k8s.io/controller-runtime v0.19.1/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index da20cd3..fba0141 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" hbasev1alpha1 "github.com/zncdatadev/hbase-operator/api/v1alpha1" - //+kubebuilder:scaffold:imports + // +kubebuilder:scaffold:imports ) // These tests use Ginkgo (BDD-style Go testing framework). Refer to @@ -65,7 +65,7 @@ var _ = BeforeSuite(func() { err = hbasev1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - //+kubebuilder:scaffold:scheme + // +kubebuilder:scaffold:scheme k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) Expect(err).NotTo(HaveOccurred())