diff --git a/.github/workflows/lint-sample.yml b/.github/workflows/lint-sample.yml new file mode 100644 index 00000000000..8196d232a8c --- /dev/null +++ b/.github/workflows/lint-sample.yml @@ -0,0 +1,54 @@ +# Copyright 2023 The Caramello-io Authors. + +name: Sample Testdata Tests + +on: + push: + pull_request: + +jobs: + test: + name: "Sample Testdata - Make Test" + runs-on: ubuntu-latest + if: (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) + steps: + - name: Clone the code + uses: actions/checkout@v3 + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: '~1.20' + - name: Remove pre-installed kustomize + run: sudo rm -f /usr/local/bin/kustomize + - name: Run make test for project-v4-with-deploy-image + run: cd testdata/project-v4-with-deploy-image && go mod tidy && make all && make test + - name: Run make test for project-v4-multigroup-with-deploy-image + run: cd testdata/project-v4-multigroup-with-deploy-image && go mod tidy && make all && make test + + lint: + name: "Sample Testdata - Lint" + runs-on: ubuntu-latest + # Pull requests from the same repository won't trigger this checks as they were already triggered by the push + if: (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) + steps: + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: '~1.20' + - name: Clone the code + uses: actions/checkout@v4 + - name: Run linter + uses: golangci/golangci-lint-action@v3 + with: + version: v1.54 + working-directory: testdata/project-v4-with-deploy-image + args: --config ../.golangci.yml ./... + skip-cache: true # first lint action will handle + - name: Run linter + uses: golangci/golangci-lint-action@v3 + with: + version: v1.54 + working-directory: testdata/project-v4-multigroup-with-deploy-image + args: --config ../.golangci.yml ./... + skip-cache: true # first lint action will handle + diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6c8d0ddd8bb..b60db866861 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -22,7 +22,6 @@ jobs: uses: golangci/golangci-lint-action@v3 with: version: v1.54 - only-new-issues: true # Show only new issues if it's a pull request yamllint: runs-on: ubuntu-latest diff --git a/test/testdata/generate.sh b/test/testdata/generate.sh index f37c007b63a..1e10928d9c1 100755 --- a/test/testdata/generate.sh +++ b/test/testdata/generate.sh @@ -98,21 +98,11 @@ function scaffold_test_project { $kb create api --group foo --version v1 --kind Bar --controller=true --resource=true --make=false $kb create api --group fiz --version v1 --kind Bar --controller=true --resource=true --make=false - if [ $project == "project-v3-multigroup" ] || [ $project == "project-v4-multigroup" ]; then + if [ $project == "project-v4-multigroup" ] || [ $project == "project-v4-multigroup-with-deploy-image" ] ; then $kb create api --version v1 --kind Lakers --controller=true --resource=true --make=false $kb create webhook --version v1 --kind Lakers --defaulting --programmatic-validation fi - # Call ALL optional plugins within multigroup layout to ensure that they can work within - header_text 'Creating Memcached API with deploy-image plugin ...' - $kb create api --group example.com --version v1alpha1 --kind Memcached --image=memcached:1.4.36-alpine --image-container-command="memcached,-m=64,-o,modern,-v" --image-container-port="11211" --run-as-user="1001" --plugins="deploy-image/v1-alpha" --make=false - $kb create api --group example.com --version v1alpha1 --kind Busybox --image=busybox:1.28 --plugins="deploy-image/v1-alpha" --make=false - header_text 'Creating Memcached webhook ...' - $kb create webhook --group example.com --version v1alpha1 --kind Memcached --programmatic-validation - - header_text 'Editing project with Grafana plugin ...' - $kb edit --plugins=grafana.kubebuilder.io/v1-alpha - elif [[ $project =~ deploy-image ]]; then header_text 'Creating Memcached API with deploy-image plugin ...' $kb create api --group example.com --version v1alpha1 --kind Memcached --image=memcached:1.4.36-alpine --image-container-command="memcached,-m=64,-o,modern,-v" --image-container-port="11211" --run-as-user="1001" --plugins="deploy-image/v1-alpha" --make=false @@ -141,5 +131,6 @@ scaffold_test_project project-v3 --plugins="go/v3" # [Currently, default CLI plugin] - [Next version, alpha] Project version v4-alpha scaffold_test_project project-v4 --plugins="go/v4" scaffold_test_project project-v4-multigroup --plugins="go/v4" +scaffold_test_project project-v4-multigroup-with-deploy-image --plugins="go/v4" scaffold_test_project project-v4-with-deploy-image --plugins="go/v4" scaffold_test_project project-v4-with-grafana --plugins="go/v4" diff --git a/test/testdata/test.sh b/test/testdata/test.sh index 162a66419a1..abf7ffb5f04 100755 --- a/test/testdata/test.sh +++ b/test/testdata/test.sh @@ -33,5 +33,6 @@ build_kb # Project version v4-alpha test_project project-v4 test_project project-v4-multigroup +test_project project-v4-multigroup-with-deploy-image test_project project-v4-with-deploy-image test_project project-v4-with-grafana diff --git a/testdata/project-v4-multigroup-with-deploy-image/.dockerignore b/testdata/project-v4-multigroup-with-deploy-image/.dockerignore new file mode 100644 index 00000000000..a3aab7af70c --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/.dockerignore @@ -0,0 +1,3 @@ +# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Ignore build and test binaries. +bin/ diff --git a/testdata/project-v4-multigroup-with-deploy-image/.gitignore b/testdata/project-v4-multigroup-with-deploy-image/.gitignore new file mode 100644 index 00000000000..7f02333db7a --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/.gitignore @@ -0,0 +1,26 @@ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin/* +Dockerfile.cross + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Kubernetes Generated files - skip generated files, except for vendored files + +!vendor/**/zz_generated.* + +# editor and IDE paraphernalia +.idea +.vscode +*.swp +*.swo +*~ diff --git a/testdata/project-v4-multigroup-with-deploy-image/.golangci.yml b/testdata/project-v4-multigroup-with-deploy-image/.golangci.yml new file mode 100644 index 00000000000..aed8644d11e --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/.golangci.yml @@ -0,0 +1,40 @@ +run: + deadline: 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 + - exportloopref + - goconst + - gocyclo + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - lll + - misspell + - nakedret + - prealloc + - staticcheck + - typecheck + - unconvert + - unparam + - unused diff --git a/testdata/project-v4-multigroup-with-deploy-image/Dockerfile b/testdata/project-v4-multigroup-with-deploy-image/Dockerfile new file mode 100644 index 00000000000..c389c0981af --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/Dockerfile @@ -0,0 +1,33 @@ +# Build the manager binary +FROM golang:1.20 as builder +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY cmd/main.go cmd/main.go +COPY api/ api/ +COPY internal/controller/ internal/controller/ + +# Build +# the GOARCH has not a default value to allow the binary be built according to the host where the command +# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO +# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, +# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM gcr.io/distroless/static:nonroot +WORKDIR / +COPY --from=builder /workspace/manager . +USER 65532:65532 + +ENTRYPOINT ["/manager"] diff --git a/testdata/project-v4-multigroup-with-deploy-image/Makefile b/testdata/project-v4-multigroup-with-deploy-image/Makefile new file mode 100644 index 00000000000..fc949b7f470 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/Makefile @@ -0,0 +1,178 @@ + +# Image URL to use all building/pushing image targets +IMG ?= controller:latest +# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. +ENVTEST_K8S_VERSION = 1.28.0 + +# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) +ifeq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin +else +GOBIN=$(shell go env GOBIN) +endif + +# CONTAINER_TOOL defines the container tool to be used for building images. +# Be aware that the target commands are only tested with Docker which is +# scaffolded by default. However, you might want to replace it to use other +# tools. (i.e. podman) +CONTAINER_TOOL ?= docker + +# Setting SHELL to bash allows bash commands to be executed by recipes. +# Options are set to exit when a recipe line exits non-zero or a piped command fails. +SHELL = /usr/bin/env bash -o pipefail +.SHELLFLAGS = -ec + +.PHONY: all +all: build + +##@ General + +# 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 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. +# More info on the usage of ANSI control characters for terminal formatting: +# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters +# More info on the awk command: +# http://linuxcommand.org/lc3_adv_awk.php + +.PHONY: help +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +##@ Development + +.PHONY: manifests +manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. + $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases + +.PHONY: generate +generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. + $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." + +.PHONY: fmt +fmt: ## Run go fmt against code. + go fmt ./... + +.PHONY: vet +vet: ## Run go vet against code. + go vet ./... + +.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 + +GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint +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)) v1.54.2 ;\ + } + +.PHONY: lint +lint: golangci-lint ## Run golangci-lint linter & yamllint + $(GOLANGCI_LINT) run + +.PHONY: lint-fix +lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes + $(GOLANGCI_LINT) run --fix + +##@ Build + +.PHONY: build +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 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: ## 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 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: +# - 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: ## 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 build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . + - $(CONTAINER_TOOL) buildx rm project-v3-builder + rm Dockerfile.cross + +##@ Deployment + +ifndef ignore-not-found + ignore-not-found = false +endif + +.PHONY: install +install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. + $(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f - + +.PHONY: uninstall +uninstall: manifests kustomize ## Uninstall CRDs 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/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - + +.PHONY: deploy +deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. + cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} + $(KUSTOMIZE) build config/default | $(KUBECTL) apply -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. + $(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - + +##@ Build Dependencies + +## Location to install dependencies to +LOCALBIN ?= $(shell pwd)/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + +## Tool Binaries +KUBECTL ?= kubectl +KUSTOMIZE ?= $(LOCALBIN)/kustomize +CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen +ENVTEST ?= $(LOCALBIN)/setup-envtest + +## Tool Versions +KUSTOMIZE_VERSION ?= v5.1.1 +CONTROLLER_TOOLS_VERSION ?= v0.13.0 + +.PHONY: kustomize +kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading. +$(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) + +.PHONY: controller-gen +controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. If wrong version is installed, it will be overwritten. +$(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) + +.PHONY: envtest +envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. +$(ENVTEST): $(LOCALBIN) + test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest diff --git a/testdata/project-v4-multigroup-with-deploy-image/PROJECT b/testdata/project-v4-multigroup-with-deploy-image/PROJECT new file mode 100644 index 00000000000..c225adc3d9e --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/PROJECT @@ -0,0 +1,121 @@ +# Code generated by tool. DO NOT EDIT. +# This file is used to track the info used to scaffold your project +# and allow the plugins properly work. +# More info: https://book.kubebuilder.io/reference/project-config.html +domain: testproject.org +layout: +- go.kubebuilder.io/v4 +multigroup: true +projectName: project-v4-multigroup-with-deploy-image +repo: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image +resources: +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: crew + kind: Captain + path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1 + version: v1 + webhooks: + defaulting: true + validation: true + webhookVersion: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: ship + kind: Frigate + path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1 + version: v1beta1 + webhooks: + conversion: true + webhookVersion: v1 +- api: + crdVersion: v1 + controller: true + domain: testproject.org + group: ship + kind: Destroyer + path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1 + version: v1 + webhooks: + defaulting: true + webhookVersion: v1 +- api: + crdVersion: v1 + controller: true + domain: testproject.org + group: ship + kind: Cruiser + path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1 + version: v2alpha1 + webhooks: + validation: true + webhookVersion: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: sea-creatures + kind: Kraken + path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1 + version: v1beta1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: sea-creatures + kind: Leviathan + path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2 + version: v1beta2 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: foo.policy + kind: HealthCheckPolicy + path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1 + version: v1 +- controller: true + group: apps + kind: Deployment + path: k8s.io/api/apps/v1 + version: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: foo + kind: Bar + path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1 + version: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: fiz + kind: Bar + path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1 + version: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + kind: Lakers + path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/v1 + version: v1 + webhooks: + defaulting: true + validation: true + webhookVersion: v1 +version: "3" diff --git a/testdata/project-v4-multigroup-with-deploy-image/README.md b/testdata/project-v4-multigroup-with-deploy-image/README.md new file mode 100644 index 00000000000..ab49c609017 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/README.md @@ -0,0 +1,94 @@ +# project-v4-multigroup-with-deploy-image +// 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 -k config/samples/ +``` + +2. Build and push your image to the location specified by `IMG`: + +```sh +make docker-build docker-push IMG=/project-v4-multigroup-with-deploy-image:tag +``` + +3. Deploy the controller to the cluster with the image specified by `IMG`: + +```sh +make deploy IMG=/project-v4-multigroup-with-deploy-image: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 2023 The Kubernetes authors. + +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. + diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/captain_types.go b/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/captain_types.go new file mode 100644 index 00000000000..6eafa937b54 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/captain_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// CaptainSpec defines the desired state of Captain +type CaptainSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Captain. Edit captain_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// CaptainStatus defines the observed state of Captain +type CaptainStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// Captain is the Schema for the captains API +type Captain struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CaptainSpec `json:"spec,omitempty"` + Status CaptainStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// CaptainList contains a list of Captain +type CaptainList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Captain `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Captain{}, &CaptainList{}) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/captain_webhook.go b/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/captain_webhook.go new file mode 100644 index 00000000000..ed99f7f0e55 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/captain_webhook.go @@ -0,0 +1,77 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// log is for logging in this package. +var captainlog = logf.Log.WithName("captain-resource") + +// SetupWebhookWithManager will setup the manager to manage the webhooks +func (r *Captain) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +//+kubebuilder:webhook:path=/mutate-crew-testproject-org-v1-captain,mutating=true,failurePolicy=fail,sideEffects=None,groups=crew.testproject.org,resources=captains,verbs=create;update,versions=v1,name=mcaptain.kb.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &Captain{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *Captain) Default() { + captainlog.Info("default", "name", r.Name) + + // TODO(user): fill in your defaulting logic. +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-crew-testproject-org-v1-captain,mutating=false,failurePolicy=fail,sideEffects=None,groups=crew.testproject.org,resources=captains,verbs=create;update,versions=v1,name=vcaptain.kb.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &Captain{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *Captain) ValidateCreate() (admission.Warnings, error) { + captainlog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil, nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Captain) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { + captainlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil, nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Captain) ValidateDelete() (admission.Warnings, error) { + captainlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil, nil +} diff --git a/testdata/project-v4-multigroup/api/example.com/v1alpha1/groupversion_info.go b/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/groupversion_info.go similarity index 80% rename from testdata/project-v4-multigroup/api/example.com/v1alpha1/groupversion_info.go rename to testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/groupversion_info.go index 9541616caff..fe267f232c5 100644 --- a/testdata/project-v4-multigroup/api/example.com/v1alpha1/groupversion_info.go +++ b/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/groupversion_info.go @@ -14,10 +14,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package v1alpha1 contains API Schema definitions for the example.com v1alpha1 API group +// Package v1 contains API Schema definitions for the crew v1 API group // +kubebuilder:object:generate=true -// +groupName=example.com.testproject.org -package v1alpha1 +// +groupName=crew.testproject.org +package v1 import ( "k8s.io/apimachinery/pkg/runtime/schema" @@ -26,7 +26,7 @@ import ( var ( // GroupVersion is group version used to register these objects - GroupVersion = schema.GroupVersion{Group: "example.com.testproject.org", Version: "v1alpha1"} + GroupVersion = schema.GroupVersion{Group: "crew.testproject.org", Version: "v1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} diff --git a/testdata/project-v4-multigroup/api/example.com/v1alpha1/webhook_suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/webhook_suite_test.go similarity index 98% rename from testdata/project-v4-multigroup/api/example.com/v1alpha1/webhook_suite_test.go rename to testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/webhook_suite_test.go index 17d019e74f8..d58a13812d1 100644 --- a/testdata/project-v4-multigroup/api/example.com/v1alpha1/webhook_suite_test.go +++ b/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/webhook_suite_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1alpha1 +package v1 import ( "context" @@ -113,7 +113,7 @@ var _ = BeforeSuite(func() { }) Expect(err).NotTo(HaveOccurred()) - err = (&Memcached{}).SetupWebhookWithManager(mgr) + err = (&Captain{}).SetupWebhookWithManager(mgr) Expect(err).NotTo(HaveOccurred()) //+kubebuilder:scaffold:webhook diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..83b88d335a7 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Captain) DeepCopyInto(out *Captain) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Captain. +func (in *Captain) DeepCopy() *Captain { + if in == nil { + return nil + } + out := new(Captain) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Captain) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CaptainList) DeepCopyInto(out *CaptainList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Captain, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CaptainList. +func (in *CaptainList) DeepCopy() *CaptainList { + if in == nil { + return nil + } + out := new(CaptainList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CaptainList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CaptainSpec) DeepCopyInto(out *CaptainSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CaptainSpec. +func (in *CaptainSpec) DeepCopy() *CaptainSpec { + if in == nil { + return nil + } + out := new(CaptainSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CaptainStatus) DeepCopyInto(out *CaptainStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CaptainStatus. +func (in *CaptainStatus) DeepCopy() *CaptainStatus { + if in == nil { + return nil + } + out := new(CaptainStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1/bar_types.go b/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1/bar_types.go new file mode 100644 index 00000000000..7cc002b4610 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1/bar_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// BarSpec defines the desired state of Bar +type BarSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Bar. Edit bar_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// BarStatus defines the observed state of Bar +type BarStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// Bar is the Schema for the bars API +type Bar struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec BarSpec `json:"spec,omitempty"` + Status BarStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// BarList contains a list of Bar +type BarList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Bar `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Bar{}, &BarList{}) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1/groupversion_info.go b/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1/groupversion_info.go new file mode 100644 index 00000000000..15af8f01654 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Package v1 contains API Schema definitions for the fiz v1 API group +// +kubebuilder:object:generate=true +// +groupName=fiz.testproject.org +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "fiz.testproject.org", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..76023cf206f --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Bar) DeepCopyInto(out *Bar) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Bar. +func (in *Bar) DeepCopy() *Bar { + if in == nil { + return nil + } + out := new(Bar) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Bar) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BarList) DeepCopyInto(out *BarList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Bar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarList. +func (in *BarList) DeepCopy() *BarList { + if in == nil { + return nil + } + out := new(BarList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BarList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BarSpec) DeepCopyInto(out *BarSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarSpec. +func (in *BarSpec) DeepCopy() *BarSpec { + if in == nil { + return nil + } + out := new(BarSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BarStatus) DeepCopyInto(out *BarStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarStatus. +func (in *BarStatus) DeepCopy() *BarStatus { + if in == nil { + return nil + } + out := new(BarStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1/groupversion_info.go b/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1/groupversion_info.go new file mode 100644 index 00000000000..33bf52ac801 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Package v1 contains API Schema definitions for the foo.policy v1 API group +// +kubebuilder:object:generate=true +// +groupName=foo.policy.testproject.org +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "foo.policy.testproject.org", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1/healthcheckpolicy_types.go b/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1/healthcheckpolicy_types.go new file mode 100644 index 00000000000..01e8d1765a6 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1/healthcheckpolicy_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// HealthCheckPolicySpec defines the desired state of HealthCheckPolicy +type HealthCheckPolicySpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of HealthCheckPolicy. Edit healthcheckpolicy_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// HealthCheckPolicyStatus defines the observed state of HealthCheckPolicy +type HealthCheckPolicyStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// HealthCheckPolicy is the Schema for the healthcheckpolicies API +type HealthCheckPolicy struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec HealthCheckPolicySpec `json:"spec,omitempty"` + Status HealthCheckPolicyStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// HealthCheckPolicyList contains a list of HealthCheckPolicy +type HealthCheckPolicyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []HealthCheckPolicy `json:"items"` +} + +func init() { + SchemeBuilder.Register(&HealthCheckPolicy{}, &HealthCheckPolicyList{}) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..66bf028e3ba --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HealthCheckPolicy) DeepCopyInto(out *HealthCheckPolicy) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheckPolicy. +func (in *HealthCheckPolicy) DeepCopy() *HealthCheckPolicy { + if in == nil { + return nil + } + out := new(HealthCheckPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *HealthCheckPolicy) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HealthCheckPolicyList) DeepCopyInto(out *HealthCheckPolicyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]HealthCheckPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheckPolicyList. +func (in *HealthCheckPolicyList) DeepCopy() *HealthCheckPolicyList { + if in == nil { + return nil + } + out := new(HealthCheckPolicyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *HealthCheckPolicyList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HealthCheckPolicySpec) DeepCopyInto(out *HealthCheckPolicySpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheckPolicySpec. +func (in *HealthCheckPolicySpec) DeepCopy() *HealthCheckPolicySpec { + if in == nil { + return nil + } + out := new(HealthCheckPolicySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HealthCheckPolicyStatus) DeepCopyInto(out *HealthCheckPolicyStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheckPolicyStatus. +func (in *HealthCheckPolicyStatus) DeepCopy() *HealthCheckPolicyStatus { + if in == nil { + return nil + } + out := new(HealthCheckPolicyStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1/bar_types.go b/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1/bar_types.go new file mode 100644 index 00000000000..7cc002b4610 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1/bar_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// BarSpec defines the desired state of Bar +type BarSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Bar. Edit bar_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// BarStatus defines the observed state of Bar +type BarStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// Bar is the Schema for the bars API +type Bar struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec BarSpec `json:"spec,omitempty"` + Status BarStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// BarList contains a list of Bar +type BarList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Bar `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Bar{}, &BarList{}) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1/groupversion_info.go b/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1/groupversion_info.go new file mode 100644 index 00000000000..d0d26e62293 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Package v1 contains API Schema definitions for the foo v1 API group +// +kubebuilder:object:generate=true +// +groupName=foo.testproject.org +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "foo.testproject.org", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..76023cf206f --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Bar) DeepCopyInto(out *Bar) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Bar. +func (in *Bar) DeepCopy() *Bar { + if in == nil { + return nil + } + out := new(Bar) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Bar) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BarList) DeepCopyInto(out *BarList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Bar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarList. +func (in *BarList) DeepCopy() *BarList { + if in == nil { + return nil + } + out := new(BarList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *BarList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BarSpec) DeepCopyInto(out *BarSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarSpec. +func (in *BarSpec) DeepCopy() *BarSpec { + if in == nil { + return nil + } + out := new(BarSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BarStatus) DeepCopyInto(out *BarStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarStatus. +func (in *BarStatus) DeepCopy() *BarStatus { + if in == nil { + return nil + } + out := new(BarStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1/groupversion_info.go b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1/groupversion_info.go new file mode 100644 index 00000000000..9200968a3a5 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Package v1beta1 contains API Schema definitions for the sea-creatures v1beta1 API group +// +kubebuilder:object:generate=true +// +groupName=sea-creatures.testproject.org +package v1beta1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "sea-creatures.testproject.org", Version: "v1beta1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1/kraken_types.go b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1/kraken_types.go new file mode 100644 index 00000000000..4c4d33ef844 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1/kraken_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// KrakenSpec defines the desired state of Kraken +type KrakenSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Kraken. Edit kraken_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// KrakenStatus defines the observed state of Kraken +type KrakenStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// Kraken is the Schema for the krakens API +type Kraken struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec KrakenSpec `json:"spec,omitempty"` + Status KrakenStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// KrakenList contains a list of Kraken +type KrakenList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Kraken `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Kraken{}, &KrakenList{}) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..64ce14510af --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1beta1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Kraken) DeepCopyInto(out *Kraken) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Kraken. +func (in *Kraken) DeepCopy() *Kraken { + if in == nil { + return nil + } + out := new(Kraken) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Kraken) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KrakenList) DeepCopyInto(out *KrakenList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Kraken, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KrakenList. +func (in *KrakenList) DeepCopy() *KrakenList { + if in == nil { + return nil + } + out := new(KrakenList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KrakenList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KrakenSpec) DeepCopyInto(out *KrakenSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KrakenSpec. +func (in *KrakenSpec) DeepCopy() *KrakenSpec { + if in == nil { + return nil + } + out := new(KrakenSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KrakenStatus) DeepCopyInto(out *KrakenStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KrakenStatus. +func (in *KrakenStatus) DeepCopy() *KrakenStatus { + if in == nil { + return nil + } + out := new(KrakenStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2/groupversion_info.go b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2/groupversion_info.go new file mode 100644 index 00000000000..c6059651fad --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Package v1beta2 contains API Schema definitions for the sea-creatures v1beta2 API group +// +kubebuilder:object:generate=true +// +groupName=sea-creatures.testproject.org +package v1beta2 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "sea-creatures.testproject.org", Version: "v1beta2"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2/leviathan_types.go b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2/leviathan_types.go new file mode 100644 index 00000000000..470019dc160 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2/leviathan_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1beta2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// LeviathanSpec defines the desired state of Leviathan +type LeviathanSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Leviathan. Edit leviathan_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// LeviathanStatus defines the observed state of Leviathan +type LeviathanStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// Leviathan is the Schema for the leviathans API +type Leviathan struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec LeviathanSpec `json:"spec,omitempty"` + Status LeviathanStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// LeviathanList contains a list of Leviathan +type LeviathanList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Leviathan `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Leviathan{}, &LeviathanList{}) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2/zz_generated.deepcopy.go b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2/zz_generated.deepcopy.go new file mode 100644 index 00000000000..6777d3b537d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1beta2 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Leviathan) DeepCopyInto(out *Leviathan) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Leviathan. +func (in *Leviathan) DeepCopy() *Leviathan { + if in == nil { + return nil + } + out := new(Leviathan) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Leviathan) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeviathanList) DeepCopyInto(out *LeviathanList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Leviathan, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeviathanList. +func (in *LeviathanList) DeepCopy() *LeviathanList { + if in == nil { + return nil + } + out := new(LeviathanList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LeviathanList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeviathanSpec) DeepCopyInto(out *LeviathanSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeviathanSpec. +func (in *LeviathanSpec) DeepCopy() *LeviathanSpec { + if in == nil { + return nil + } + out := new(LeviathanSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LeviathanStatus) DeepCopyInto(out *LeviathanStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeviathanStatus. +func (in *LeviathanStatus) DeepCopy() *LeviathanStatus { + if in == nil { + return nil + } + out := new(LeviathanStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/destroyer_types.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/destroyer_types.go new file mode 100644 index 00000000000..f8cc80eefb5 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/destroyer_types.go @@ -0,0 +1,65 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// DestroyerSpec defines the desired state of Destroyer +type DestroyerSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Destroyer. Edit destroyer_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// DestroyerStatus defines the observed state of Destroyer +type DestroyerStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:scope=Cluster + +// Destroyer is the Schema for the destroyers API +type Destroyer struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec DestroyerSpec `json:"spec,omitempty"` + Status DestroyerStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// DestroyerList contains a list of Destroyer +type DestroyerList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Destroyer `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Destroyer{}, &DestroyerList{}) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/destroyer_webhook.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/destroyer_webhook.go new file mode 100644 index 00000000000..4b0fb739d55 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/destroyer_webhook.go @@ -0,0 +1,46 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1 + +import ( + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +// log is for logging in this package. +var destroyerlog = logf.Log.WithName("destroyer-resource") + +// SetupWebhookWithManager will setup the manager to manage the webhooks +func (r *Destroyer) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +//+kubebuilder:webhook:path=/mutate-ship-testproject-org-v1-destroyer,mutating=true,failurePolicy=fail,sideEffects=None,groups=ship.testproject.org,resources=destroyers,verbs=create;update,versions=v1,name=mdestroyer.kb.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &Destroyer{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *Destroyer) Default() { + destroyerlog.Info("default", "name", r.Name) + + // TODO(user): fill in your defaulting logic. +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/groupversion_info.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/groupversion_info.go new file mode 100644 index 00000000000..7ca96e4ea8c --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Package v1 contains API Schema definitions for the ship v1 API group +// +kubebuilder:object:generate=true +// +groupName=ship.testproject.org +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "ship.testproject.org", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/webhook_suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/webhook_suite_test.go new file mode 100644 index 00000000000..1c6bb164c54 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/webhook_suite_test.go @@ -0,0 +1,145 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1 + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "path/filepath" + "runtime" + "testing" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + admissionv1 "k8s.io/api/admission/v1" + //+kubebuilder:scaffold:imports + apimachineryruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var ctx context.Context +var cancel context.CancelFunc + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Webhook Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + ctx, cancel = context.WithCancel(context.TODO()) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: false, + + // The BinaryAssetsDirectory is only required if you want to run the tests directly + // without call the makefile target test. If not informed it will look for the + // default path defined in controller-runtime which is /usr/local/kubebuilder/. + // Note that you must have the required binaries setup under the bin directory to perform + // the tests directly. When we run make test it will be setup and used automatically. + BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", + fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), + + WebhookInstallOptions: envtest.WebhookInstallOptions{ + Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")}, + }, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + scheme := apimachineryruntime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1.AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + + // start webhook server using Manager + webhookInstallOptions := &testEnv.WebhookInstallOptions + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme, + WebhookServer: webhook.NewServer(webhook.Options{ + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + }), + LeaderElection: false, + Metrics: metricsserver.Options{BindAddress: "0"}, + }) + Expect(err).NotTo(HaveOccurred()) + + err = (&Destroyer{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:webhook + + go func() { + defer GinkgoRecover() + err = mgr.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() + + // wait for the webhook server to get ready + dialer := &net.Dialer{Timeout: time.Second} + addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) + Eventually(func() error { + conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) + if err != nil { + return err + } + return conn.Close() + }).Should(Succeed()) + +}) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..f33c86fef82 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Destroyer) DeepCopyInto(out *Destroyer) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Destroyer. +func (in *Destroyer) DeepCopy() *Destroyer { + if in == nil { + return nil + } + out := new(Destroyer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Destroyer) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DestroyerList) DeepCopyInto(out *DestroyerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Destroyer, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestroyerList. +func (in *DestroyerList) DeepCopy() *DestroyerList { + if in == nil { + return nil + } + out := new(DestroyerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DestroyerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DestroyerSpec) DeepCopyInto(out *DestroyerSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestroyerSpec. +func (in *DestroyerSpec) DeepCopy() *DestroyerSpec { + if in == nil { + return nil + } + out := new(DestroyerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DestroyerStatus) DeepCopyInto(out *DestroyerStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestroyerStatus. +func (in *DestroyerStatus) DeepCopy() *DestroyerStatus { + if in == nil { + return nil + } + out := new(DestroyerStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/frigate_types.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/frigate_types.go new file mode 100644 index 00000000000..bd62ed8ed7d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/frigate_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// FrigateSpec defines the desired state of Frigate +type FrigateSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Frigate. Edit frigate_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// FrigateStatus defines the observed state of Frigate +type FrigateStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// Frigate is the Schema for the frigates API +type Frigate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec FrigateSpec `json:"spec,omitempty"` + Status FrigateStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// FrigateList contains a list of Frigate +type FrigateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Frigate `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Frigate{}, &FrigateList{}) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/frigate_webhook.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/frigate_webhook.go new file mode 100644 index 00000000000..e03bafd22b2 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/frigate_webhook.go @@ -0,0 +1,34 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1beta1 + +import ( + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" +) + +// log is for logging in this package. +var frigatelog = logf.Log.WithName("frigate-resource") + +// SetupWebhookWithManager will setup the manager to manage the webhooks +func (r *Frigate) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/groupversion_info.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/groupversion_info.go new file mode 100644 index 00000000000..a27e3ab1af0 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Package v1beta1 contains API Schema definitions for the ship v1beta1 API group +// +kubebuilder:object:generate=true +// +groupName=ship.testproject.org +package v1beta1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "ship.testproject.org", Version: "v1beta1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..b72247060db --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1beta1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Frigate) DeepCopyInto(out *Frigate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Frigate. +func (in *Frigate) DeepCopy() *Frigate { + if in == nil { + return nil + } + out := new(Frigate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Frigate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FrigateList) DeepCopyInto(out *FrigateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Frigate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FrigateList. +func (in *FrigateList) DeepCopy() *FrigateList { + if in == nil { + return nil + } + out := new(FrigateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FrigateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FrigateSpec) DeepCopyInto(out *FrigateSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FrigateSpec. +func (in *FrigateSpec) DeepCopy() *FrigateSpec { + if in == nil { + return nil + } + out := new(FrigateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FrigateStatus) DeepCopyInto(out *FrigateStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FrigateStatus. +func (in *FrigateStatus) DeepCopy() *FrigateStatus { + if in == nil { + return nil + } + out := new(FrigateStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/cruiser_types.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/cruiser_types.go new file mode 100644 index 00000000000..b79187f2766 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/cruiser_types.go @@ -0,0 +1,65 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v2alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// CruiserSpec defines the desired state of Cruiser +type CruiserSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Cruiser. Edit cruiser_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// CruiserStatus defines the observed state of Cruiser +type CruiserStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:scope=Cluster + +// Cruiser is the Schema for the cruisers API +type Cruiser struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CruiserSpec `json:"spec,omitempty"` + Status CruiserStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// CruiserList contains a list of Cruiser +type CruiserList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Cruiser `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Cruiser{}, &CruiserList{}) +} diff --git a/testdata/project-v4-multigroup/api/example.com/v1alpha1/memcached_webhook.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/cruiser_webhook.go similarity index 66% rename from testdata/project-v4-multigroup/api/example.com/v1alpha1/memcached_webhook.go rename to testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/cruiser_webhook.go index 77993bc8d50..14d5710a831 100644 --- a/testdata/project-v4-multigroup/api/example.com/v1alpha1/memcached_webhook.go +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/cruiser_webhook.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package v1alpha1 +package v2alpha1 import ( "k8s.io/apimachinery/pkg/runtime" @@ -25,10 +25,10 @@ import ( ) // log is for logging in this package. -var memcachedlog = logf.Log.WithName("memcached-resource") +var cruiserlog = logf.Log.WithName("cruiser-resource") // SetupWebhookWithManager will setup the manager to manage the webhooks -func (r *Memcached) SetupWebhookWithManager(mgr ctrl.Manager) error { +func (r *Cruiser) SetupWebhookWithManager(mgr ctrl.Manager) error { return ctrl.NewWebhookManagedBy(mgr). For(r). Complete() @@ -37,29 +37,29 @@ func (r *Memcached) SetupWebhookWithManager(mgr ctrl.Manager) error { // TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! // TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. -//+kubebuilder:webhook:path=/validate-example-com-testproject-org-v1alpha1-memcached,mutating=false,failurePolicy=fail,sideEffects=None,groups=example.com.testproject.org,resources=memcacheds,verbs=create;update,versions=v1alpha1,name=vmemcached.kb.io,admissionReviewVersions=v1 +//+kubebuilder:webhook:path=/validate-ship-testproject-org-v2alpha1-cruiser,mutating=false,failurePolicy=fail,sideEffects=None,groups=ship.testproject.org,resources=cruisers,verbs=create;update,versions=v2alpha1,name=vcruiser.kb.io,admissionReviewVersions=v1 -var _ webhook.Validator = &Memcached{} +var _ webhook.Validator = &Cruiser{} // ValidateCreate implements webhook.Validator so a webhook will be registered for the type -func (r *Memcached) ValidateCreate() (admission.Warnings, error) { - memcachedlog.Info("validate create", "name", r.Name) +func (r *Cruiser) ValidateCreate() (admission.Warnings, error) { + cruiserlog.Info("validate create", "name", r.Name) // TODO(user): fill in your validation logic upon object creation. return nil, nil } // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type -func (r *Memcached) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { - memcachedlog.Info("validate update", "name", r.Name) +func (r *Cruiser) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { + cruiserlog.Info("validate update", "name", r.Name) // TODO(user): fill in your validation logic upon object update. return nil, nil } // ValidateDelete implements webhook.Validator so a webhook will be registered for the type -func (r *Memcached) ValidateDelete() (admission.Warnings, error) { - memcachedlog.Info("validate delete", "name", r.Name) +func (r *Cruiser) ValidateDelete() (admission.Warnings, error) { + cruiserlog.Info("validate delete", "name", r.Name) // TODO(user): fill in your validation logic upon object deletion. return nil, nil diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/groupversion_info.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/groupversion_info.go new file mode 100644 index 00000000000..1b291530c6b --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Package v2alpha1 contains API Schema definitions for the ship v2alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=ship.testproject.org +package v2alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "ship.testproject.org", Version: "v2alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/webhook_suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/webhook_suite_test.go new file mode 100644 index 00000000000..38482d55ee7 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/webhook_suite_test.go @@ -0,0 +1,145 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v2alpha1 + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "path/filepath" + "runtime" + "testing" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + admissionv1 "k8s.io/api/admission/v1" + //+kubebuilder:scaffold:imports + apimachineryruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var ctx context.Context +var cancel context.CancelFunc + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Webhook Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + ctx, cancel = context.WithCancel(context.TODO()) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: false, + + // The BinaryAssetsDirectory is only required if you want to run the tests directly + // without call the makefile target test. If not informed it will look for the + // default path defined in controller-runtime which is /usr/local/kubebuilder/. + // Note that you must have the required binaries setup under the bin directory to perform + // the tests directly. When we run make test it will be setup and used automatically. + BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", + fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), + + WebhookInstallOptions: envtest.WebhookInstallOptions{ + Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")}, + }, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + scheme := apimachineryruntime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1.AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + + // start webhook server using Manager + webhookInstallOptions := &testEnv.WebhookInstallOptions + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme, + WebhookServer: webhook.NewServer(webhook.Options{ + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + }), + LeaderElection: false, + Metrics: metricsserver.Options{BindAddress: "0"}, + }) + Expect(err).NotTo(HaveOccurred()) + + err = (&Cruiser{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:webhook + + go func() { + defer GinkgoRecover() + err = mgr.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() + + // wait for the webhook server to get ready + dialer := &net.Dialer{Timeout: time.Second} + addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) + Eventually(func() error { + conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) + if err != nil { + return err + } + return conn.Close() + }).Should(Succeed()) + +}) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..1a54bea8d43 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v2alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Cruiser) DeepCopyInto(out *Cruiser) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cruiser. +func (in *Cruiser) DeepCopy() *Cruiser { + if in == nil { + return nil + } + out := new(Cruiser) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Cruiser) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CruiserList) DeepCopyInto(out *CruiserList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Cruiser, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CruiserList. +func (in *CruiserList) DeepCopy() *CruiserList { + if in == nil { + return nil + } + out := new(CruiserList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CruiserList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CruiserSpec) DeepCopyInto(out *CruiserSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CruiserSpec. +func (in *CruiserSpec) DeepCopy() *CruiserSpec { + if in == nil { + return nil + } + out := new(CruiserSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CruiserStatus) DeepCopyInto(out *CruiserStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CruiserStatus. +func (in *CruiserStatus) DeepCopy() *CruiserStatus { + if in == nil { + return nil + } + out := new(CruiserStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/v1/groupversion_info.go b/testdata/project-v4-multigroup-with-deploy-image/api/v1/groupversion_info.go new file mode 100644 index 00000000000..49502eee2c5 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Package v1 contains API Schema definitions for the v1 API group +// +kubebuilder:object:generate=true +// +groupName=testproject.org +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "testproject.org", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/v1/lakers_types.go b/testdata/project-v4-multigroup-with-deploy-image/api/v1/lakers_types.go new file mode 100644 index 00000000000..415b5bc3924 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/v1/lakers_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// LakersSpec defines the desired state of Lakers +type LakersSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of Lakers. Edit lakers_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// LakersStatus defines the observed state of Lakers +type LakersStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// Lakers is the Schema for the lakers API +type Lakers struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec LakersSpec `json:"spec,omitempty"` + Status LakersStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// LakersList contains a list of Lakers +type LakersList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Lakers `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Lakers{}, &LakersList{}) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/v1/lakers_webhook.go b/testdata/project-v4-multigroup-with-deploy-image/api/v1/lakers_webhook.go new file mode 100644 index 00000000000..26041fdfc75 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/v1/lakers_webhook.go @@ -0,0 +1,77 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/webhook" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" +) + +// log is for logging in this package. +var lakerslog = logf.Log.WithName("lakers-resource") + +// SetupWebhookWithManager will setup the manager to manage the webhooks +func (r *Lakers) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// TODO(user): EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! + +//+kubebuilder:webhook:path=/mutate-testproject-org-v1-lakers,mutating=true,failurePolicy=fail,sideEffects=None,groups=testproject.org,resources=lakers,verbs=create;update,versions=v1,name=mlakers.kb.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &Lakers{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *Lakers) Default() { + lakerslog.Info("default", "name", r.Name) + + // TODO(user): fill in your defaulting logic. +} + +// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation. +//+kubebuilder:webhook:path=/validate-testproject-org-v1-lakers,mutating=false,failurePolicy=fail,sideEffects=None,groups=testproject.org,resources=lakers,verbs=create;update,versions=v1,name=vlakers.kb.io,admissionReviewVersions=v1 + +var _ webhook.Validator = &Lakers{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *Lakers) ValidateCreate() (admission.Warnings, error) { + lakerslog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil, nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Lakers) ValidateUpdate(old runtime.Object) (admission.Warnings, error) { + lakerslog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil, nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Lakers) ValidateDelete() (admission.Warnings, error) { + lakerslog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil, nil +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/v1/webhook_suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/api/v1/webhook_suite_test.go new file mode 100644 index 00000000000..250b42b87b3 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/v1/webhook_suite_test.go @@ -0,0 +1,145 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package v1 + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "path/filepath" + "runtime" + "testing" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + admissionv1 "k8s.io/api/admission/v1" + //+kubebuilder:scaffold:imports + apimachineryruntime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment +var ctx context.Context +var cancel context.CancelFunc + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Webhook Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + ctx, cancel = context.WithCancel(context.TODO()) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: false, + + // The BinaryAssetsDirectory is only required if you want to run the tests directly + // without call the makefile target test. If not informed it will look for the + // default path defined in controller-runtime which is /usr/local/kubebuilder/. + // Note that you must have the required binaries setup under the bin directory to perform + // the tests directly. When we run make test it will be setup and used automatically. + BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s", + fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), + + WebhookInstallOptions: envtest.WebhookInstallOptions{ + Paths: []string{filepath.Join("..", "..", "config", "webhook")}, + }, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + scheme := apimachineryruntime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1.AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + + // start webhook server using Manager + webhookInstallOptions := &testEnv.WebhookInstallOptions + mgr, err := ctrl.NewManager(cfg, ctrl.Options{ + Scheme: scheme, + WebhookServer: webhook.NewServer(webhook.Options{ + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + }), + LeaderElection: false, + Metrics: metricsserver.Options{BindAddress: "0"}, + }) + Expect(err).NotTo(HaveOccurred()) + + err = (&Lakers{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:webhook + + go func() { + defer GinkgoRecover() + err = mgr.Start(ctx) + Expect(err).NotTo(HaveOccurred()) + }() + + // wait for the webhook server to get ready + dialer := &net.Dialer{Timeout: time.Second} + addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) + Eventually(func() error { + conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) + if err != nil { + return err + } + return conn.Close() + }).Should(Succeed()) + +}) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup-with-deploy-image/api/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup-with-deploy-image/api/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..904f7ad869a --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/api/v1/zz_generated.deepcopy.go @@ -0,0 +1,114 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Lakers) DeepCopyInto(out *Lakers) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Lakers. +func (in *Lakers) DeepCopy() *Lakers { + if in == nil { + return nil + } + out := new(Lakers) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Lakers) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LakersList) DeepCopyInto(out *LakersList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Lakers, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LakersList. +func (in *LakersList) DeepCopy() *LakersList { + if in == nil { + return nil + } + out := new(LakersList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *LakersList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LakersSpec) DeepCopyInto(out *LakersSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LakersSpec. +func (in *LakersSpec) DeepCopy() *LakersSpec { + if in == nil { + return nil + } + out := new(LakersSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LakersStatus) DeepCopyInto(out *LakersStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LakersStatus. +func (in *LakersStatus) DeepCopy() *LakersStatus { + if in == nil { + return nil + } + out := new(LakersStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/cmd/main.go b/testdata/project-v4-multigroup-with-deploy-image/cmd/main.go new file mode 100644 index 00000000000..69b93d3824b --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/cmd/main.go @@ -0,0 +1,240 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package main + +import ( + "flag" + "os" + + // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) + // to ensure that exec-entrypoint and run can make use of them. + _ "k8s.io/client-go/plugin/pkg/client/auth" + + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1" + fizv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1" + foopolicyv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1" + foov1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1" + seacreaturesv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1" + seacreaturesv1beta2 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2" + shipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1" + shipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1" + shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1" + testprojectorgv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/v1" + "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/internal/controller" + appscontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/internal/controller/apps" + crewcontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/internal/controller/crew" + fizcontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/internal/controller/fiz" + foocontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo" + foopolicycontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo.policy" + seacreaturescontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/internal/controller/sea-creatures" + shipcontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship" + //+kubebuilder:scaffold:imports +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + + utilruntime.Must(crewv1.AddToScheme(scheme)) + utilruntime.Must(shipv1beta1.AddToScheme(scheme)) + utilruntime.Must(shipv1.AddToScheme(scheme)) + utilruntime.Must(shipv2alpha1.AddToScheme(scheme)) + utilruntime.Must(seacreaturesv1beta1.AddToScheme(scheme)) + utilruntime.Must(seacreaturesv1beta2.AddToScheme(scheme)) + utilruntime.Must(foopolicyv1.AddToScheme(scheme)) + utilruntime.Must(foov1.AddToScheme(scheme)) + utilruntime.Must(fizv1.AddToScheme(scheme)) + utilruntime.Must(testprojectorgv1.AddToScheme(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.") + 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.") + opts := zap.Options{ + Development: true, + } + opts.BindFlags(flag.CommandLine) + flag.Parse() + + ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + Scheme: scheme, + Metrics: metricsserver.Options{BindAddress: metricsAddr}, + HealthProbeBindAddress: probeAddr, + LeaderElection: enableLeaderElection, + LeaderElectionID: "65c8a5ec.testproject.org", + // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily + // when the Manager ends. This requires the binary to immediately end when the + // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly + // speeds up voluntary leader transitions as the new leader don't have to wait + // LeaseDuration time first. + // + // In the default scaffold provided, the program ends immediately after + // the manager stops, so would be fine to enable this option. However, + // if you are doing or is intended to do any operation such as perform cleanups + // after the manager stops then its usage might be unsafe. + // LeaderElectionReleaseOnCancel: true, + }) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + if err = (&crewcontroller.CaptainReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Captain") + os.Exit(1) + } + if os.Getenv("ENABLE_WEBHOOKS") != "false" { + if err = (&crewv1.Captain{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Captain") + os.Exit(1) + } + } + if err = (&shipcontroller.FrigateReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Frigate") + os.Exit(1) + } + if os.Getenv("ENABLE_WEBHOOKS") != "false" { + if err = (&shipv1beta1.Frigate{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Frigate") + os.Exit(1) + } + } + if err = (&shipcontroller.DestroyerReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Destroyer") + os.Exit(1) + } + if os.Getenv("ENABLE_WEBHOOKS") != "false" { + if err = (&shipv1.Destroyer{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Destroyer") + os.Exit(1) + } + } + if err = (&shipcontroller.CruiserReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Cruiser") + os.Exit(1) + } + if os.Getenv("ENABLE_WEBHOOKS") != "false" { + if err = (&shipv2alpha1.Cruiser{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Cruiser") + os.Exit(1) + } + } + if err = (&seacreaturescontroller.KrakenReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Kraken") + os.Exit(1) + } + if err = (&seacreaturescontroller.LeviathanReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Leviathan") + os.Exit(1) + } + if err = (&foopolicycontroller.HealthCheckPolicyReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "HealthCheckPolicy") + os.Exit(1) + } + if err = (&appscontroller.DeploymentReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Deployment") + os.Exit(1) + } + if err = (&foocontroller.BarReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Bar") + os.Exit(1) + } + if err = (&fizcontroller.BarReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Bar") + os.Exit(1) + } + if err = (&controller.LakersReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Lakers") + os.Exit(1) + } + if os.Getenv("ENABLE_WEBHOOKS") != "false" { + if err = (&testprojectorgv1.Lakers{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Lakers") + os.Exit(1) + } + } + //+kubebuilder:scaffold:builder + + if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up health check") + os.Exit(1) + } + if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up ready check") + os.Exit(1) + } + + setupLog.Info("starting manager") + if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/certmanager/certificate.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/certmanager/certificate.yaml new file mode 100644 index 00000000000..67a1128b1cd --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/certmanager/certificate.yaml @@ -0,0 +1,39 @@ +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/name: certificate + app.kubernetes.io/instance: serving-cert + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/name: certificate + app.kubernetes.io/instance: serving-cert + app.kubernetes.io/component: certificate + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + namespace: system +spec: + # SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize + dnsNames: + - SERVICE_NAME.SERVICE_NAMESPACE.svc + - SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/certmanager/kustomization.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/certmanager/kustomization.yaml new file mode 100644 index 00000000000..bebea5a595e --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- certificate.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/certmanager/kustomizeconfig.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 00000000000..cf6f89e8892 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/certmanager/kustomizeconfig.yaml @@ -0,0 +1,8 @@ +# This configuration is for teaching kustomize how to update name ref substitution +nameReference: +- kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/crew.testproject.org_captains.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/crew.testproject.org_captains.yaml new file mode 100644 index 00000000000..fb3c3619819 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/crew.testproject.org_captains.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: captains.crew.testproject.org +spec: + group: crew.testproject.org + names: + kind: Captain + listKind: CaptainList + plural: captains + singular: captain + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Captain is the Schema for the captains API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CaptainSpec defines the desired state of Captain + properties: + foo: + description: Foo is an example field of Captain. Edit captain_types.go + to remove/update + type: string + type: object + status: + description: CaptainStatus defines the observed state of Captain + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/fiz.testproject.org_bars.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/fiz.testproject.org_bars.yaml new file mode 100644 index 00000000000..f82ce349aa7 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/fiz.testproject.org_bars.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: bars.fiz.testproject.org +spec: + group: fiz.testproject.org + names: + kind: Bar + listKind: BarList + plural: bars + singular: bar + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Bar is the Schema for the bars API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BarSpec defines the desired state of Bar + properties: + foo: + description: Foo is an example field of Bar. Edit bar_types.go to + remove/update + type: string + type: object + status: + description: BarStatus defines the observed state of Bar + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/foo.policy.testproject.org_healthcheckpolicies.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/foo.policy.testproject.org_healthcheckpolicies.yaml new file mode 100644 index 00000000000..fccaf45ebcf --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/foo.policy.testproject.org_healthcheckpolicies.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: healthcheckpolicies.foo.policy.testproject.org +spec: + group: foo.policy.testproject.org + names: + kind: HealthCheckPolicy + listKind: HealthCheckPolicyList + plural: healthcheckpolicies + singular: healthcheckpolicy + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: HealthCheckPolicy is the Schema for the healthcheckpolicies API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: HealthCheckPolicySpec defines the desired state of HealthCheckPolicy + properties: + foo: + description: Foo is an example field of HealthCheckPolicy. Edit healthcheckpolicy_types.go + to remove/update + type: string + type: object + status: + description: HealthCheckPolicyStatus defines the observed state of HealthCheckPolicy + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/foo.testproject.org_bars.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/foo.testproject.org_bars.yaml new file mode 100644 index 00000000000..2ac74780e21 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/foo.testproject.org_bars.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: bars.foo.testproject.org +spec: + group: foo.testproject.org + names: + kind: Bar + listKind: BarList + plural: bars + singular: bar + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Bar is the Schema for the bars API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: BarSpec defines the desired state of Bar + properties: + foo: + description: Foo is an example field of Bar. Edit bar_types.go to + remove/update + type: string + type: object + status: + description: BarStatus defines the observed state of Bar + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/sea-creatures.testproject.org_krakens.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/sea-creatures.testproject.org_krakens.yaml new file mode 100644 index 00000000000..893171cd25c --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/sea-creatures.testproject.org_krakens.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: krakens.sea-creatures.testproject.org +spec: + group: sea-creatures.testproject.org + names: + kind: Kraken + listKind: KrakenList + plural: krakens + singular: kraken + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Kraken is the Schema for the krakens API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: KrakenSpec defines the desired state of Kraken + properties: + foo: + description: Foo is an example field of Kraken. Edit kraken_types.go + to remove/update + type: string + type: object + status: + description: KrakenStatus defines the observed state of Kraken + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/sea-creatures.testproject.org_leviathans.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/sea-creatures.testproject.org_leviathans.yaml new file mode 100644 index 00000000000..23354ee849b --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/sea-creatures.testproject.org_leviathans.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: leviathans.sea-creatures.testproject.org +spec: + group: sea-creatures.testproject.org + names: + kind: Leviathan + listKind: LeviathanList + plural: leviathans + singular: leviathan + scope: Namespaced + versions: + - name: v1beta2 + schema: + openAPIV3Schema: + description: Leviathan is the Schema for the leviathans API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: LeviathanSpec defines the desired state of Leviathan + properties: + foo: + description: Foo is an example field of Leviathan. Edit leviathan_types.go + to remove/update + type: string + type: object + status: + description: LeviathanStatus defines the observed state of Leviathan + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/ship.testproject.org_cruisers.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/ship.testproject.org_cruisers.yaml new file mode 100644 index 00000000000..822b7ddcd07 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/ship.testproject.org_cruisers.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: cruisers.ship.testproject.org +spec: + group: ship.testproject.org + names: + kind: Cruiser + listKind: CruiserList + plural: cruisers + singular: cruiser + scope: Cluster + versions: + - name: v2alpha1 + schema: + openAPIV3Schema: + description: Cruiser is the Schema for the cruisers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CruiserSpec defines the desired state of Cruiser + properties: + foo: + description: Foo is an example field of Cruiser. Edit cruiser_types.go + to remove/update + type: string + type: object + status: + description: CruiserStatus defines the observed state of Cruiser + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/ship.testproject.org_destroyers.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/ship.testproject.org_destroyers.yaml new file mode 100644 index 00000000000..1d16092fb0e --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/ship.testproject.org_destroyers.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: destroyers.ship.testproject.org +spec: + group: ship.testproject.org + names: + kind: Destroyer + listKind: DestroyerList + plural: destroyers + singular: destroyer + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Destroyer is the Schema for the destroyers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: DestroyerSpec defines the desired state of Destroyer + properties: + foo: + description: Foo is an example field of Destroyer. Edit destroyer_types.go + to remove/update + type: string + type: object + status: + description: DestroyerStatus defines the observed state of Destroyer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/ship.testproject.org_frigates.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/ship.testproject.org_frigates.yaml new file mode 100644 index 00000000000..a39aaa5e962 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/ship.testproject.org_frigates.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: frigates.ship.testproject.org +spec: + group: ship.testproject.org + names: + kind: Frigate + listKind: FrigateList + plural: frigates + singular: frigate + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Frigate is the Schema for the frigates API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: FrigateSpec defines the desired state of Frigate + properties: + foo: + description: Foo is an example field of Frigate. Edit frigate_types.go + to remove/update + type: string + type: object + status: + description: FrigateStatus defines the observed state of Frigate + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/testproject.org_lakers.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/testproject.org_lakers.yaml new file mode 100644 index 00000000000..1677f648fab --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/bases/testproject.org_lakers.yaml @@ -0,0 +1,49 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: lakers.testproject.org +spec: + group: testproject.org + names: + kind: Lakers + listKind: LakersList + plural: lakers + singular: lakers + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Lakers is the Schema for the lakers API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: LakersSpec defines the desired state of Lakers + properties: + foo: + description: Foo is an example field of Lakers. Edit lakers_types.go + to remove/update + type: string + type: object + status: + description: LakersStatus defines the observed state of Lakers + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/kustomization.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/kustomization.yaml new file mode 100644 index 00000000000..9b25692779d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/kustomization.yaml @@ -0,0 +1,48 @@ +# This kustomization.yaml is not intended to be run by itself, +# since it depends on service name and namespace that are out of this kustomize package. +# It should be run by config/default +resources: +- bases/crew.testproject.org_captains.yaml +- bases/ship.testproject.org_frigates.yaml +- bases/ship.testproject.org_destroyers.yaml +- bases/ship.testproject.org_cruisers.yaml +- bases/sea-creatures.testproject.org_krakens.yaml +- bases/sea-creatures.testproject.org_leviathans.yaml +- bases/foo.policy.testproject.org_healthcheckpolicies.yaml +- bases/foo.testproject.org_bars.yaml +- bases/fiz.testproject.org_bars.yaml +- bases/testproject.org_lakers.yaml +#+kubebuilder:scaffold:crdkustomizeresource + +patches: +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. +# patches here are for enabling the conversion webhook for each CRD +#- path: patches/webhook_in_crew_captains.yaml +#- path: patches/webhook_in_ship_frigates.yaml +#- path: patches/webhook_in_ship_destroyers.yaml +#- path: patches/webhook_in_ship_cruisers.yaml +#- path: patches/webhook_in_sea-creatures_krakens.yaml +#- path: patches/webhook_in_sea-creatures_leviathans.yaml +#- path: patches/webhook_in_foo.policy_healthcheckpolicies.yaml +#- path: patches/webhook_in_foo_bars.yaml +#- path: patches/webhook_in_fiz_bars.yaml +#- path: patches/webhook_in__lakers.yaml +#+kubebuilder:scaffold:crdkustomizewebhookpatch + +# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. +# patches here are for enabling the CA injection for each CRD +#- path: patches/cainjection_in_crew_captains.yaml +#- path: patches/cainjection_in_ship_frigates.yaml +#- path: patches/cainjection_in_ship_destroyers.yaml +#- path: patches/cainjection_in_ship_cruisers.yaml +#- path: patches/cainjection_in_sea-creatures_krakens.yaml +#- path: patches/cainjection_in_sea-creatures_leviathans.yaml +#- path: patches/cainjection_in_foo.policy_healthcheckpolicies.yaml +#- path: patches/cainjection_in_foo_bars.yaml +#- path: patches/cainjection_in_fiz_bars.yaml +#- path: patches/cainjection_in__lakers.yaml +#+kubebuilder:scaffold:crdkustomizecainjectionpatch + +# the following config is for teaching kustomize how to do kustomization for CRDs. +configurations: +- kustomizeconfig.yaml diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/kustomizeconfig.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/kustomizeconfig.yaml new file mode 100644 index 00000000000..ec5c150a9df --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/kustomizeconfig.yaml @@ -0,0 +1,19 @@ +# This file is for teaching kustomize how to substitute name and namespace reference in CRD +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: CustomResourceDefinition + version: v1 + group: apiextensions.k8s.io + path: spec/conversion/webhook/clientConfig/service/name + +namespace: +- kind: CustomResourceDefinition + version: v1 + group: apiextensions.k8s.io + path: spec/conversion/webhook/clientConfig/service/namespace + create: false + +varReference: +- path: metadata/annotations diff --git a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_example.com_busyboxes.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in__lakers.yaml similarity index 84% rename from testdata/project-v4-multigroup/config/crd/patches/cainjection_in_example.com_busyboxes.yaml rename to testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in__lakers.yaml index 5f6b0384f48..90be9dfc598 100644 --- a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_example.com_busyboxes.yaml +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in__lakers.yaml @@ -4,4 +4,4 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME - name: busyboxes.example.com.testproject.org + name: lakers.testproject.org diff --git a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_example.com_memcacheds.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_crew_captains.yaml similarity index 84% rename from testdata/project-v4-multigroup/config/crd/patches/cainjection_in_example.com_memcacheds.yaml rename to testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_crew_captains.yaml index 5b9e839364d..fba0c3ed6fd 100644 --- a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_example.com_memcacheds.yaml +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_crew_captains.yaml @@ -4,4 +4,4 @@ kind: CustomResourceDefinition metadata: annotations: cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME - name: memcacheds.example.com.testproject.org + name: captains.crew.testproject.org diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_fiz_bars.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_fiz_bars.yaml new file mode 100644 index 00000000000..c6dfcc97f3e --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_fiz_bars.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME + name: bars.fiz.testproject.org diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_foo.policy_healthcheckpolicies.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_foo.policy_healthcheckpolicies.yaml new file mode 100644 index 00000000000..887d632ef1d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_foo.policy_healthcheckpolicies.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME + name: healthcheckpolicies.foo.policy.testproject.org diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_foo_bars.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_foo_bars.yaml new file mode 100644 index 00000000000..7cacea184db --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_foo_bars.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME + name: bars.foo.testproject.org diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_sea-creatures_krakens.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_sea-creatures_krakens.yaml new file mode 100644 index 00000000000..b16c174c7b2 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_sea-creatures_krakens.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME + name: krakens.sea-creatures.testproject.org diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_sea-creatures_leviathans.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_sea-creatures_leviathans.yaml new file mode 100644 index 00000000000..35b16d717cb --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_sea-creatures_leviathans.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME + name: leviathans.sea-creatures.testproject.org diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_ship_cruisers.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_ship_cruisers.yaml new file mode 100644 index 00000000000..0d31cb0b8af --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_ship_cruisers.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME + name: cruisers.ship.testproject.org diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_ship_destroyers.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_ship_destroyers.yaml new file mode 100644 index 00000000000..865395574ff --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_ship_destroyers.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME + name: destroyers.ship.testproject.org diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_ship_frigates.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_ship_frigates.yaml new file mode 100644 index 00000000000..d4acb9d24c1 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/cainjection_in_ship_frigates.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME + name: frigates.ship.testproject.org diff --git a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_example.com_busyboxes.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in__lakers.yaml similarity index 88% rename from testdata/project-v4-multigroup/config/crd/patches/webhook_in_example.com_busyboxes.yaml rename to testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in__lakers.yaml index 5dbd9da7176..58df2264dde 100644 --- a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_example.com_busyboxes.yaml +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in__lakers.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - name: busyboxes.example.com.testproject.org + name: lakers.testproject.org spec: conversion: strategy: Webhook diff --git a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_example.com_memcacheds.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_crew_captains.yaml similarity index 88% rename from testdata/project-v4-multigroup/config/crd/patches/webhook_in_example.com_memcacheds.yaml rename to testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_crew_captains.yaml index 4a56b0f4c69..f73ae2e8abc 100644 --- a/testdata/project-v4-multigroup/config/crd/patches/webhook_in_example.com_memcacheds.yaml +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_crew_captains.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: - name: memcacheds.example.com.testproject.org + name: captains.crew.testproject.org spec: conversion: strategy: Webhook diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_fiz_bars.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_fiz_bars.yaml new file mode 100644 index 00000000000..eddaa868fdd --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_fiz_bars.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: bars.fiz.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_foo.policy_healthcheckpolicies.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_foo.policy_healthcheckpolicies.yaml new file mode 100644 index 00000000000..61381b747c5 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_foo.policy_healthcheckpolicies.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: healthcheckpolicies.foo.policy.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_foo_bars.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_foo_bars.yaml new file mode 100644 index 00000000000..831ad1b8164 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_foo_bars.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: bars.foo.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_sea-creatures_krakens.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_sea-creatures_krakens.yaml new file mode 100644 index 00000000000..620a12faaee --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_sea-creatures_krakens.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: krakens.sea-creatures.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_sea-creatures_leviathans.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_sea-creatures_leviathans.yaml new file mode 100644 index 00000000000..5cb95bc7b38 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_sea-creatures_leviathans.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: leviathans.sea-creatures.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_ship_cruisers.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_ship_cruisers.yaml new file mode 100644 index 00000000000..99b6b6741b6 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_ship_cruisers.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: cruisers.ship.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_ship_destroyers.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_ship_destroyers.yaml new file mode 100644 index 00000000000..0e0095cb3a6 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_ship_destroyers.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: destroyers.ship.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_ship_frigates.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_ship_frigates.yaml new file mode 100644 index 00000000000..cdc5078ae71 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/crd/patches/webhook_in_ship_frigates.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: frigates.ship.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/default/kustomization.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/default/kustomization.yaml new file mode 100644 index 00000000000..c6c6da56c46 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/default/kustomization.yaml @@ -0,0 +1,144 @@ +# Adds namespace to all resources. +namespace: project-v4-multigroup-with-deploy-image-system + +# Value of this field is prepended to the +# names of all resources, e.g. a deployment named +# "wordpress" becomes "alices-wordpress". +# Note that it should also match with the prefix (text before '-') of the namespace +# field above. +namePrefix: project-v4-multigroup-with-deploy-image- + +# Labels to add to all resources and selectors. +#labels: +#- includeSelectors: true +# pairs: +# someName: someValue + +resources: +- ../crd +- ../rbac +- ../manager +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +#- ../webhook +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. +#- ../certmanager +# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. +#- ../prometheus + +patchesStrategicMerge: +# 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. +- manager_auth_proxy_patch.yaml + + + +# [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 + +# [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 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/default/manager_auth_proxy_patch.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/default/manager_auth_proxy_patch.yaml new file mode 100644 index 00000000000..73fad2a6754 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,39 @@ +# 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/testdata/project-v4-multigroup-with-deploy-image/config/default/manager_config_patch.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/default/manager_config_patch.yaml new file mode 100644 index 00000000000..f6f58916922 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/default/manager_config_patch.yaml @@ -0,0 +1,10 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/default/manager_webhook_patch.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/default/manager_webhook_patch.yaml new file mode 100644 index 00000000000..738de350b71 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/default/manager_webhook_patch.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/default/webhookcainjection_patch.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/default/webhookcainjection_patch.yaml new file mode 100644 index 00000000000..f5129665598 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/default/webhookcainjection_patch.yaml @@ -0,0 +1,29 @@ +# This patch add annotation to admission webhook config and +# CERTIFICATE_NAMESPACE and CERTIFICATE_NAME will be substituted by kustomize +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/name: mutatingwebhookconfiguration + app.kubernetes.io/instance: mutating-webhook-configuration + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/name: validatingwebhookconfiguration + app.kubernetes.io/instance: validating-webhook-configuration + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/manager/kustomization.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/manager/kustomization.yaml new file mode 100644 index 00000000000..5c5f0b84cba --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/manager/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- manager.yaml diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/manager/manager.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/manager/manager.yaml new file mode 100644 index 00000000000..e6ec6dfc06d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/manager/manager.yaml @@ -0,0 +1,102 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + app.kubernetes.io/name: namespace + app.kubernetes.io/instance: system + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager + app.kubernetes.io/name: deployment + app.kubernetes.io/instance: controller-manager + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize +spec: + selector: + matchLabels: + control-plane: controller-manager + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + # TODO(user): Uncomment the following code to configure the nodeAffinity expression + # according to the platforms which are supported by your solution. + # It is considered best practice to support multiple architectures. You can + # build your manager image using the makefile target docker-buildx. + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: kubernetes.io/arch + # operator: In + # values: + # - amd64 + # - arm64 + # - ppc64le + # - s390x + # - key: kubernetes.io/os + # operator: In + # values: + # - linux + securityContext: + runAsNonRoot: true + # TODO(user): For common cases that do not require escalating privileges + # it is recommended to ensure that all your Pods/Containers are restrictive. + # More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted + # Please uncomment the following code if your project does NOT have to work on old Kubernetes + # versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ). + # seccompProfile: + # type: RuntimeDefault + containers: + - command: + - /manager + args: + - --leader-elect + image: controller:latest + name: manager + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + # TODO(user): Configure the resources accordingly based on the project requirements. + # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + serviceAccountName: controller-manager + terminationGracePeriodSeconds: 10 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/prometheus/kustomization.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/prometheus/kustomization.yaml new file mode 100644 index 00000000000..ed137168a1d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/prometheus/monitor.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/prometheus/monitor.yaml new file mode 100644 index 00000000000..3a4f61fb0e9 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/prometheus/monitor.yaml @@ -0,0 +1,26 @@ + +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: controller-manager + app.kubernetes.io/name: servicemonitor + app.kubernetes.io/instance: controller-manager-metrics-monitor + app.kubernetes.io/component: metrics + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - path: /metrics + port: https + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + insecureSkipVerify: true + selector: + matchLabels: + control-plane: controller-manager diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_memcached_editor_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/_lakers_editor_role.yaml similarity index 51% rename from testdata/project-v4-multigroup/config/rbac/example.com_memcached_editor_role.yaml rename to testdata/project-v4-multigroup-with-deploy-image/config/rbac/_lakers_editor_role.yaml index aacaa6ffb8a..a714b834cec 100644 --- a/testdata/project-v4-multigroup/config/rbac/example.com_memcached_editor_role.yaml +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/_lakers_editor_role.yaml @@ -1,20 +1,20 @@ -# permissions for end users to edit memcacheds. +# permissions for end users to edit lakers. apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: memcached-editor-role + app.kubernetes.io/instance: lakers-editor-role app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: project-v4-multigroup - app.kubernetes.io/part-of: project-v4-multigroup + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image app.kubernetes.io/managed-by: kustomize - name: memcached-editor-role + name: lakers-editor-role rules: - apiGroups: - - example.com.testproject.org + - testproject.org resources: - - memcacheds + - lakers verbs: - create - delete @@ -24,8 +24,8 @@ rules: - update - watch - apiGroups: - - example.com.testproject.org + - testproject.org resources: - - memcacheds/status + - lakers/status verbs: - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/_lakers_viewer_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/_lakers_viewer_role.yaml new file mode 100644 index 00000000000..5aa120091d9 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/_lakers_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view lakers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: lakers-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: lakers-viewer-role +rules: +- apiGroups: + - testproject.org + resources: + - lakers + verbs: + - get + - list + - watch +- apiGroups: + - testproject.org + resources: + - lakers/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_client_clusterrole.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 00000000000..3c9ad11fc52 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_client_clusterrole.yaml @@ -0,0 +1,16 @@ +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: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_role.yaml new file mode 100644 index 00000000000..0050db22e36 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_role.yaml @@ -0,0 +1,24 @@ +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: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + 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/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_role_binding.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 00000000000..2865bf6007b --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_role_binding.yaml @@ -0,0 +1,19 @@ +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: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + 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/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_service.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_service.yaml new file mode 100644 index 00000000000..eaa3581887a --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/auth_proxy_service.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +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: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: controller-manager-metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + selector: + control-plane: controller-manager diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/crew_captain_editor_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/crew_captain_editor_role.yaml new file mode 100644 index 00000000000..bd5635e807a --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/crew_captain_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: captain-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: captain-editor-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - captains + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - captains/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/crew_captain_viewer_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/crew_captain_viewer_role.yaml new file mode 100644 index 00000000000..4b2d5239891 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/crew_captain_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: captain-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: captain-viewer-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - captains + verbs: + - get + - list + - watch +- apiGroups: + - crew.testproject.org + resources: + - captains/status + verbs: + - get diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_busybox_editor_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/fiz_bar_editor_role.yaml similarity index 51% rename from testdata/project-v4-multigroup/config/rbac/example.com_busybox_editor_role.yaml rename to testdata/project-v4-multigroup-with-deploy-image/config/rbac/fiz_bar_editor_role.yaml index ceae6910a0e..b78e82144a5 100644 --- a/testdata/project-v4-multigroup/config/rbac/example.com_busybox_editor_role.yaml +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/fiz_bar_editor_role.yaml @@ -1,20 +1,20 @@ -# permissions for end users to edit busyboxes. +# permissions for end users to edit bars. apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: busybox-editor-role + app.kubernetes.io/instance: bar-editor-role app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: project-v4-multigroup - app.kubernetes.io/part-of: project-v4-multigroup + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image app.kubernetes.io/managed-by: kustomize - name: busybox-editor-role + name: bar-editor-role rules: - apiGroups: - - example.com.testproject.org + - fiz.testproject.org resources: - - busyboxes + - bars verbs: - create - delete @@ -24,8 +24,8 @@ rules: - update - watch - apiGroups: - - example.com.testproject.org + - fiz.testproject.org resources: - - busyboxes/status + - bars/status verbs: - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/fiz_bar_viewer_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/fiz_bar_viewer_role.yaml new file mode 100644 index 00000000000..08c01ae9813 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/fiz_bar_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view bars. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: bar-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: bar-viewer-role +rules: +- apiGroups: + - fiz.testproject.org + resources: + - bars + verbs: + - get + - list + - watch +- apiGroups: + - fiz.testproject.org + resources: + - bars/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo.policy_healthcheckpolicy_editor_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo.policy_healthcheckpolicy_editor_role.yaml new file mode 100644 index 00000000000..40c5d23d3ba --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo.policy_healthcheckpolicy_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit healthcheckpolicies. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: healthcheckpolicy-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: healthcheckpolicy-editor-role +rules: +- apiGroups: + - foo.policy.testproject.org + resources: + - healthcheckpolicies + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - foo.policy.testproject.org + resources: + - healthcheckpolicies/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml new file mode 100644 index 00000000000..8ea5332cc09 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view healthcheckpolicies. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: healthcheckpolicy-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: healthcheckpolicy-viewer-role +rules: +- apiGroups: + - foo.policy.testproject.org + resources: + - healthcheckpolicies + verbs: + - get + - list + - watch +- apiGroups: + - foo.policy.testproject.org + resources: + - healthcheckpolicies/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo_bar_editor_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo_bar_editor_role.yaml new file mode 100644 index 00000000000..9e7821cf8c4 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo_bar_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit bars. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: bar-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: bar-editor-role +rules: +- apiGroups: + - foo.testproject.org + resources: + - bars + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - foo.testproject.org + resources: + - bars/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo_bar_viewer_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo_bar_viewer_role.yaml new file mode 100644 index 00000000000..fdcc0f8cf60 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/foo_bar_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view bars. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: bar-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: bar-viewer-role +rules: +- apiGroups: + - foo.testproject.org + resources: + - bars + verbs: + - get + - list + - watch +- apiGroups: + - foo.testproject.org + resources: + - bars/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/kustomization.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/kustomization.yaml new file mode 100644 index 00000000000..731832a6ac3 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/kustomization.yaml @@ -0,0 +1,18 @@ +resources: +# All RBAC will be applied under this service account in +# the deployment namespace. You may comment out this resource +# if your manager will use a service account that exists at +# runtime. Be sure to update RoleBinding and ClusterRoleBinding +# subjects if changing service account names. +- service_account.yaml +- role.yaml +- role_binding.yaml +- leader_election_role.yaml +- leader_election_role_binding.yaml +# 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 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/leader_election_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/leader_election_role.yaml new file mode 100644 index 00000000000..71eb53be354 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/leader_election_role.yaml @@ -0,0 +1,44 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: role + app.kubernetes.io/instance: leader-election-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: leader-election-role +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 diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/leader_election_role_binding.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/leader_election_role_binding.yaml new file mode 100644 index 00000000000..46b200947c6 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/leader_election_role_binding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: rolebinding + app.kubernetes.io/instance: leader-election-rolebinding + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: leader-election-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/role.yaml new file mode 100644 index 00000000000..e2d30b23205 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/role.yaml @@ -0,0 +1,292 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: manager-role +rules: +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - deployments/finalizers + verbs: + - update +- apiGroups: + - apps + resources: + - deployments/status + verbs: + - get + - patch + - update +- apiGroups: + - crew.testproject.org + resources: + - captains + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - captains/finalizers + verbs: + - update +- apiGroups: + - crew.testproject.org + resources: + - captains/status + verbs: + - get + - patch + - update +- apiGroups: + - fiz.testproject.org + resources: + - bars + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - fiz.testproject.org + resources: + - bars/finalizers + verbs: + - update +- apiGroups: + - fiz.testproject.org + resources: + - bars/status + verbs: + - get + - patch + - update +- apiGroups: + - foo.policy.testproject.org + resources: + - healthcheckpolicies + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - foo.policy.testproject.org + resources: + - healthcheckpolicies/finalizers + verbs: + - update +- apiGroups: + - foo.policy.testproject.org + resources: + - healthcheckpolicies/status + verbs: + - get + - patch + - update +- apiGroups: + - foo.testproject.org + resources: + - bars + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - foo.testproject.org + resources: + - bars/finalizers + verbs: + - update +- apiGroups: + - foo.testproject.org + resources: + - bars/status + verbs: + - get + - patch + - update +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens/finalizers + verbs: + - update +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens/status + verbs: + - get + - patch + - update +- apiGroups: + - sea-creatures.testproject.org + resources: + - leviathans + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - sea-creatures.testproject.org + resources: + - leviathans/finalizers + verbs: + - update +- apiGroups: + - sea-creatures.testproject.org + resources: + - leviathans/status + verbs: + - get + - patch + - update +- apiGroups: + - ship.testproject.org + resources: + - cruisers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - ship.testproject.org + resources: + - cruisers/finalizers + verbs: + - update +- apiGroups: + - ship.testproject.org + resources: + - cruisers/status + verbs: + - get + - patch + - update +- apiGroups: + - ship.testproject.org + resources: + - destroyers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - ship.testproject.org + resources: + - destroyers/finalizers + verbs: + - update +- apiGroups: + - ship.testproject.org + resources: + - destroyers/status + verbs: + - get + - patch + - update +- apiGroups: + - ship.testproject.org + resources: + - frigates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - ship.testproject.org + resources: + - frigates/finalizers + verbs: + - update +- apiGroups: + - ship.testproject.org + resources: + - frigates/status + verbs: + - get + - patch + - update +- apiGroups: + - testproject.org + resources: + - lakers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - testproject.org + resources: + - lakers/finalizers + verbs: + - update +- apiGroups: + - testproject.org + resources: + - lakers/status + verbs: + - get + - patch + - update diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/role_binding.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/role_binding.yaml new file mode 100644 index 00000000000..a21e269bbeb --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/role_binding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: clusterrolebinding + app.kubernetes.io/instance: manager-rolebinding + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: manager-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_kraken_editor_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_kraken_editor_role.yaml new file mode 100644 index 00000000000..12a22f31ef8 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_kraken_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit krakens. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: kraken-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: kraken-editor-role +rules: +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_kraken_viewer_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_kraken_viewer_role.yaml new file mode 100644 index 00000000000..de8052ce7a4 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_kraken_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view krakens. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: kraken-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: kraken-viewer-role +rules: +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens + verbs: + - get + - list + - watch +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_leviathan_editor_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_leviathan_editor_role.yaml new file mode 100644 index 00000000000..9915768283d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_leviathan_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit leviathans. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: leviathan-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: leviathan-editor-role +rules: +- apiGroups: + - sea-creatures.testproject.org + resources: + - leviathans + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - sea-creatures.testproject.org + resources: + - leviathans/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_leviathan_viewer_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_leviathan_viewer_role.yaml new file mode 100644 index 00000000000..d07705c5eb3 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/sea-creatures_leviathan_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view leviathans. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: leviathan-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: leviathan-viewer-role +rules: +- apiGroups: + - sea-creatures.testproject.org + resources: + - leviathans + verbs: + - get + - list + - watch +- apiGroups: + - sea-creatures.testproject.org + resources: + - leviathans/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/service_account.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/service_account.yaml new file mode 100644 index 00000000000..e14982021a9 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/service_account.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: serviceaccount + app.kubernetes.io/instance: controller-manager-sa + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: controller-manager + namespace: system diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_cruiser_editor_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_cruiser_editor_role.yaml new file mode 100644 index 00000000000..52a5c228354 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_cruiser_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit cruisers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: cruiser-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: cruiser-editor-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - cruisers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - ship.testproject.org + resources: + - cruisers/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_cruiser_viewer_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_cruiser_viewer_role.yaml new file mode 100644 index 00000000000..e4c28e54811 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_cruiser_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view cruisers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: cruiser-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: cruiser-viewer-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - cruisers + verbs: + - get + - list + - watch +- apiGroups: + - ship.testproject.org + resources: + - cruisers/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_destroyer_editor_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_destroyer_editor_role.yaml new file mode 100644 index 00000000000..540cd60f0d0 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_destroyer_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit destroyers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: destroyer-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: destroyer-editor-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - destroyers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - ship.testproject.org + resources: + - destroyers/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_destroyer_viewer_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_destroyer_viewer_role.yaml new file mode 100644 index 00000000000..0a3fb441bfd --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_destroyer_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view destroyers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: destroyer-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: destroyer-viewer-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - destroyers + verbs: + - get + - list + - watch +- apiGroups: + - ship.testproject.org + resources: + - destroyers/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_frigate_editor_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_frigate_editor_role.yaml new file mode 100644 index 00000000000..a7fe83c260d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_frigate_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit frigates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: frigate-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: frigate-editor-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - frigates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - ship.testproject.org + resources: + - frigates/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_frigate_viewer_role.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_frigate_viewer_role.yaml new file mode 100644 index 00000000000..e3dc1d4b033 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/rbac/ship_frigate_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view frigates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: frigate-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: frigate-viewer-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - frigates + verbs: + - get + - list + - watch +- apiGroups: + - ship.testproject.org + resources: + - frigates/status + verbs: + - get diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/samples/_v1_lakers.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/samples/_v1_lakers.yaml new file mode 100644 index 00000000000..212abd9cb63 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/samples/_v1_lakers.yaml @@ -0,0 +1,12 @@ +apiVersion: testproject.org/v1 +kind: Lakers +metadata: + labels: + app.kubernetes.io/name: lakers + app.kubernetes.io/instance: lakers-sample + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + name: lakers-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/samples/crew_v1_captain.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/samples/crew_v1_captain.yaml new file mode 100644 index 00000000000..f673b14f595 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/samples/crew_v1_captain.yaml @@ -0,0 +1,12 @@ +apiVersion: crew.testproject.org/v1 +kind: Captain +metadata: + labels: + app.kubernetes.io/name: captain + app.kubernetes.io/instance: captain-sample + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + name: captain-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/samples/fiz_v1_bar.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/samples/fiz_v1_bar.yaml new file mode 100644 index 00000000000..8e8bbe548a7 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/samples/fiz_v1_bar.yaml @@ -0,0 +1,12 @@ +apiVersion: fiz.testproject.org/v1 +kind: Bar +metadata: + labels: + app.kubernetes.io/name: bar + app.kubernetes.io/instance: bar-sample + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + name: bar-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/samples/foo.policy_v1_healthcheckpolicy.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/samples/foo.policy_v1_healthcheckpolicy.yaml new file mode 100644 index 00000000000..2e186a61163 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/samples/foo.policy_v1_healthcheckpolicy.yaml @@ -0,0 +1,12 @@ +apiVersion: foo.policy.testproject.org/v1 +kind: HealthCheckPolicy +metadata: + labels: + app.kubernetes.io/name: healthcheckpolicy + app.kubernetes.io/instance: healthcheckpolicy-sample + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + name: healthcheckpolicy-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/samples/foo_v1_bar.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/samples/foo_v1_bar.yaml new file mode 100644 index 00000000000..b53b7541890 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/samples/foo_v1_bar.yaml @@ -0,0 +1,12 @@ +apiVersion: foo.testproject.org/v1 +kind: Bar +metadata: + labels: + app.kubernetes.io/name: bar + app.kubernetes.io/instance: bar-sample + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + name: bar-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/samples/kustomization.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/samples/kustomization.yaml new file mode 100644 index 00000000000..a74ed904341 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/samples/kustomization.yaml @@ -0,0 +1,13 @@ +## Append samples of your project ## +resources: +- crew_v1_captain.yaml +- ship_v1beta1_frigate.yaml +- ship_v1_destroyer.yaml +- ship_v2alpha1_cruiser.yaml +- sea-creatures_v1beta1_kraken.yaml +- sea-creatures_v1beta2_leviathan.yaml +- foo.policy_v1_healthcheckpolicy.yaml +- foo_v1_bar.yaml +- fiz_v1_bar.yaml +- _v1_lakers.yaml +#+kubebuilder:scaffold:manifestskustomizesamples diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/samples/sea-creatures_v1beta1_kraken.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/samples/sea-creatures_v1beta1_kraken.yaml new file mode 100644 index 00000000000..0df2e7f9614 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/samples/sea-creatures_v1beta1_kraken.yaml @@ -0,0 +1,12 @@ +apiVersion: sea-creatures.testproject.org/v1beta1 +kind: Kraken +metadata: + labels: + app.kubernetes.io/name: kraken + app.kubernetes.io/instance: kraken-sample + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + name: kraken-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/samples/sea-creatures_v1beta2_leviathan.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/samples/sea-creatures_v1beta2_leviathan.yaml new file mode 100644 index 00000000000..0e5fff34936 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/samples/sea-creatures_v1beta2_leviathan.yaml @@ -0,0 +1,12 @@ +apiVersion: sea-creatures.testproject.org/v1beta2 +kind: Leviathan +metadata: + labels: + app.kubernetes.io/name: leviathan + app.kubernetes.io/instance: leviathan-sample + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + name: leviathan-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/samples/ship_v1_destroyer.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/samples/ship_v1_destroyer.yaml new file mode 100644 index 00000000000..1a22738bd1d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/samples/ship_v1_destroyer.yaml @@ -0,0 +1,12 @@ +apiVersion: ship.testproject.org/v1 +kind: Destroyer +metadata: + labels: + app.kubernetes.io/name: destroyer + app.kubernetes.io/instance: destroyer-sample + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + name: destroyer-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/samples/ship_v1beta1_frigate.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/samples/ship_v1beta1_frigate.yaml new file mode 100644 index 00000000000..b7361d362d0 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/samples/ship_v1beta1_frigate.yaml @@ -0,0 +1,12 @@ +apiVersion: ship.testproject.org/v1beta1 +kind: Frigate +metadata: + labels: + app.kubernetes.io/name: frigate + app.kubernetes.io/instance: frigate-sample + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + name: frigate-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/samples/ship_v2alpha1_cruiser.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/samples/ship_v2alpha1_cruiser.yaml new file mode 100644 index 00000000000..c55fc456ae7 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/samples/ship_v2alpha1_cruiser.yaml @@ -0,0 +1,12 @@ +apiVersion: ship.testproject.org/v2alpha1 +kind: Cruiser +metadata: + labels: + app.kubernetes.io/name: cruiser + app.kubernetes.io/instance: cruiser-sample + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + name: cruiser-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/webhook/kustomization.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/webhook/kustomization.yaml new file mode 100644 index 00000000000..9cf26134e4d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/webhook/kustomizeconfig.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/webhook/kustomizeconfig.yaml new file mode 100644 index 00000000000..206316e54ff --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,22 @@ +# the following config is for teaching kustomize where to look at when substituting nameReference. +# It requires kustomize v2.1.0 or newer to work properly. +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + - kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name + +namespace: +- kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true +- kind: ValidatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/webhook/manifests.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/webhook/manifests.yaml new file mode 100644 index 00000000000..62374002227 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/webhook/manifests.yaml @@ -0,0 +1,132 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-crew-testproject-org-v1-captain + failurePolicy: Fail + name: mcaptain.kb.io + rules: + - apiGroups: + - crew.testproject.org + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - captains + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-ship-testproject-org-v1-destroyer + failurePolicy: Fail + name: mdestroyer.kb.io + rules: + - apiGroups: + - ship.testproject.org + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - destroyers + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-testproject-org-v1-lakers + failurePolicy: Fail + name: mlakers.kb.io + rules: + - apiGroups: + - testproject.org + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - lakers + sideEffects: None +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-crew-testproject-org-v1-captain + failurePolicy: Fail + name: vcaptain.kb.io + rules: + - apiGroups: + - crew.testproject.org + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - captains + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-ship-testproject-org-v2alpha1-cruiser + failurePolicy: Fail + name: vcruiser.kb.io + rules: + - apiGroups: + - ship.testproject.org + apiVersions: + - v2alpha1 + operations: + - CREATE + - UPDATE + resources: + - cruisers + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /validate-testproject-org-v1-lakers + failurePolicy: Fail + name: vlakers.kb.io + rules: + - apiGroups: + - testproject.org + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - lakers + sideEffects: None diff --git a/testdata/project-v4-multigroup-with-deploy-image/config/webhook/service.yaml b/testdata/project-v4-multigroup-with-deploy-image/config/webhook/service.yaml new file mode 100644 index 00000000000..beb16dfbee1 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/config/webhook/service.yaml @@ -0,0 +1,20 @@ + +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: service + app.kubernetes.io/instance: webhook-service + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: project-v4-multigroup-with-deploy-image + app.kubernetes.io/part-of: project-v4-multigroup-with-deploy-image + app.kubernetes.io/managed-by: kustomize + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager diff --git a/testdata/project-v4-multigroup-with-deploy-image/go.mod b/testdata/project-v4-multigroup-with-deploy-image/go.mod new file mode 100644 index 00000000000..cffc8973d3d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/go.mod @@ -0,0 +1,73 @@ +module sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image + +go 1.20 + +require ( + github.com/onsi/ginkgo/v2 v2.11.0 + github.com/onsi/gomega v1.27.10 + k8s.io/api v0.28.1 + k8s.io/apimachinery v0.28.1 + k8s.io/client-go v0.28.1 + sigs.k8s.io/controller-runtime v0.16.1 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/zapr v1.2.4 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/imdario/mergo v0.3.6 // 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 + github.com/matttproud/golang_protobuf_extensions v1.0.4 // 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/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.16.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.10.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.25.0 // indirect + golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect + golang.org/x/net v0.13.0 // indirect + golang.org/x/oauth2 v0.8.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.9.3 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.30.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.28.0 // indirect + k8s.io/component-base v0.28.1 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/testdata/project-v4-multigroup-with-deploy-image/hack/boilerplate.go.txt b/testdata/project-v4-multigroup-with-deploy-image/hack/boilerplate.go.txt new file mode 100644 index 00000000000..8c36d12450d --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ \ No newline at end of file diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/apps/deployment_controller.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/apps/deployment_controller.go new file mode 100644 index 00000000000..24f8f5c4ef1 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/apps/deployment_controller.go @@ -0,0 +1,61 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package apps + +import ( + "context" + + appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" +) + +// DeploymentReconciler reconciles a Deployment object +type DeploymentReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=apps,resources=deployments/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the Deployment object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile +func (r *DeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *DeploymentReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&appsv1.Deployment{}). + Complete(r) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/apps/suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/apps/suite_test.go new file mode 100644 index 00000000000..78f8abdf282 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/apps/suite_test.go @@ -0,0 +1,89 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package apps + +import ( + "fmt" + "path/filepath" + "runtime" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + appsv1 "k8s.io/api/apps/v1" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + //+kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment + +func TestControllers(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Controller Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: false, + + // The BinaryAssetsDirectory is only required if you want to run the tests directly + // without call the makefile target test. If not informed it will look for the + // default path defined in controller-runtime which is /usr/local/kubebuilder/. + // Note that you must have the required binaries setup under the bin directory to perform + // the tests directly. When we run make test it will be setup and used automatically. + BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", + fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = appsv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/crew/captain_controller.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/crew/captain_controller.go new file mode 100644 index 00000000000..f1fb4ca5c21 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/crew/captain_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package crew + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1" +) + +// CaptainReconciler reconciles a Captain object +type CaptainReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=crew.testproject.org,resources=captains,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=crew.testproject.org,resources=captains/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=crew.testproject.org,resources=captains/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the Captain object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile +func (r *CaptainReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *CaptainReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&crewv1.Captain{}). + Complete(r) +} diff --git a/testdata/project-v4-multigroup/internal/controller/example.com/suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/crew/suite_test.go similarity index 93% rename from testdata/project-v4-multigroup/internal/controller/example.com/suite_test.go rename to testdata/project-v4-multigroup-with-deploy-image/internal/controller/crew/suite_test.go index b298e0a96d8..92de83f12c0 100644 --- a/testdata/project-v4-multigroup/internal/controller/example.com/suite_test.go +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/crew/suite_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package examplecom +package crew import ( "fmt" @@ -32,7 +32,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/crew/v1" //+kubebuilder:scaffold:imports ) @@ -72,7 +72,7 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = examplecomv1alpha1.AddToScheme(scheme.Scheme) + err = crewv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) //+kubebuilder:scaffold:scheme diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/fiz/bar_controller.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/fiz/bar_controller.go new file mode 100644 index 00000000000..f9fbb9af76c --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/fiz/bar_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package fiz + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + fizv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1" +) + +// BarReconciler reconciles a Bar object +type BarReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=fiz.testproject.org,resources=bars,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=fiz.testproject.org,resources=bars/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=fiz.testproject.org,resources=bars/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the Bar object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile +func (r *BarReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *BarReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&fizv1.Bar{}). + Complete(r) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/fiz/suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/fiz/suite_test.go new file mode 100644 index 00000000000..08507362144 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/fiz/suite_test.go @@ -0,0 +1,90 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package fiz + +import ( + "fmt" + "path/filepath" + "runtime" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + fizv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/fiz/v1" + //+kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment + +func TestControllers(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Controller Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: true, + + // The BinaryAssetsDirectory is only required if you want to run the tests directly + // without call the makefile target test. If not informed it will look for the + // default path defined in controller-runtime which is /usr/local/kubebuilder/. + // Note that you must have the required binaries setup under the bin directory to perform + // the tests directly. When we run make test it will be setup and used automatically. + BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", + fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = fizv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo.policy/healthcheckpolicy_controller.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo.policy/healthcheckpolicy_controller.go new file mode 100644 index 00000000000..aba21bcd561 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo.policy/healthcheckpolicy_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package foopolicy + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + foopolicyv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1" +) + +// HealthCheckPolicyReconciler reconciles a HealthCheckPolicy object +type HealthCheckPolicyReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=foo.policy.testproject.org,resources=healthcheckpolicies,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=foo.policy.testproject.org,resources=healthcheckpolicies/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=foo.policy.testproject.org,resources=healthcheckpolicies/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the HealthCheckPolicy object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile +func (r *HealthCheckPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *HealthCheckPolicyReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&foopolicyv1.HealthCheckPolicy{}). + Complete(r) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo.policy/suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo.policy/suite_test.go new file mode 100644 index 00000000000..4b54814270f --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo.policy/suite_test.go @@ -0,0 +1,90 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package foopolicy + +import ( + "fmt" + "path/filepath" + "runtime" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + foopolicyv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/foo.policy/v1" + //+kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment + +func TestControllers(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Controller Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: true, + + // The BinaryAssetsDirectory is only required if you want to run the tests directly + // without call the makefile target test. If not informed it will look for the + // default path defined in controller-runtime which is /usr/local/kubebuilder/. + // Note that you must have the required binaries setup under the bin directory to perform + // the tests directly. When we run make test it will be setup and used automatically. + BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", + fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = foopolicyv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo/bar_controller.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo/bar_controller.go new file mode 100644 index 00000000000..ee446c317f4 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo/bar_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package foo + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + foov1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1" +) + +// BarReconciler reconciles a Bar object +type BarReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=foo.testproject.org,resources=bars,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=foo.testproject.org,resources=bars/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=foo.testproject.org,resources=bars/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the Bar object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile +func (r *BarReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *BarReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&foov1.Bar{}). + Complete(r) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo/suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo/suite_test.go new file mode 100644 index 00000000000..0b8a1f7de20 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/foo/suite_test.go @@ -0,0 +1,90 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package foo + +import ( + "fmt" + "path/filepath" + "runtime" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + foov1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/foo/v1" + //+kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment + +func TestControllers(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Controller Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: true, + + // The BinaryAssetsDirectory is only required if you want to run the tests directly + // without call the makefile target test. If not informed it will look for the + // default path defined in controller-runtime which is /usr/local/kubebuilder/. + // Note that you must have the required binaries setup under the bin directory to perform + // the tests directly. When we run make test it will be setup and used automatically. + BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", + fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = foov1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/lakers_controller.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/lakers_controller.go new file mode 100644 index 00000000000..d513d64f66b --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/lakers_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package controller + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + testprojectorgv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/v1" +) + +// LakersReconciler reconciles a Lakers object +type LakersReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=testproject.org,resources=lakers,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=testproject.org,resources=lakers/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=testproject.org,resources=lakers/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the Lakers object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile +func (r *LakersReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *LakersReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&testprojectorgv1.Lakers{}). + Complete(r) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/sea-creatures/kraken_controller.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/sea-creatures/kraken_controller.go new file mode 100644 index 00000000000..34436e16426 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/sea-creatures/kraken_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package seacreatures + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + seacreaturesv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1" +) + +// KrakenReconciler reconciles a Kraken object +type KrakenReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=krakens,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=krakens/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=krakens/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the Kraken object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile +func (r *KrakenReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *KrakenReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&seacreaturesv1beta1.Kraken{}). + Complete(r) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/sea-creatures/leviathan_controller.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/sea-creatures/leviathan_controller.go new file mode 100644 index 00000000000..cbc66c0cf3c --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/sea-creatures/leviathan_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package seacreatures + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + seacreaturesv1beta2 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2" +) + +// LeviathanReconciler reconciles a Leviathan object +type LeviathanReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=leviathans,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=leviathans/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=sea-creatures.testproject.org,resources=leviathans/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the Leviathan object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile +func (r *LeviathanReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *LeviathanReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&seacreaturesv1beta2.Leviathan{}). + Complete(r) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/sea-creatures/suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/sea-creatures/suite_test.go new file mode 100644 index 00000000000..9035668a10a --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/sea-creatures/suite_test.go @@ -0,0 +1,94 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package seacreatures + +import ( + "fmt" + "path/filepath" + "runtime" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + seacreaturesv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta1" + seacreaturesv1beta2 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/sea-creatures/v1beta2" + //+kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment + +func TestControllers(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Controller Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: true, + + // The BinaryAssetsDirectory is only required if you want to run the tests directly + // without call the makefile target test. If not informed it will look for the + // default path defined in controller-runtime which is /usr/local/kubebuilder/. + // Note that you must have the required binaries setup under the bin directory to perform + // the tests directly. When we run make test it will be setup and used automatically. + BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", + fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = seacreaturesv1beta1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + err = seacreaturesv1beta2.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/cruiser_controller.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/cruiser_controller.go new file mode 100644 index 00000000000..74f8f7c19c5 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/cruiser_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package ship + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1" +) + +// CruiserReconciler reconciles a Cruiser object +type CruiserReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=ship.testproject.org,resources=cruisers,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=ship.testproject.org,resources=cruisers/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=ship.testproject.org,resources=cruisers/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the Cruiser object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile +func (r *CruiserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *CruiserReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&shipv2alpha1.Cruiser{}). + Complete(r) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/destroyer_controller.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/destroyer_controller.go new file mode 100644 index 00000000000..b133421d850 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/destroyer_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package ship + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + shipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1" +) + +// DestroyerReconciler reconciles a Destroyer object +type DestroyerReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=ship.testproject.org,resources=destroyers,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=ship.testproject.org,resources=destroyers/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=ship.testproject.org,resources=destroyers/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the Destroyer object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile +func (r *DestroyerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *DestroyerReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&shipv1.Destroyer{}). + Complete(r) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/frigate_controller.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/frigate_controller.go new file mode 100644 index 00000000000..4046ae09437 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/frigate_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package ship + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + shipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1" +) + +// FrigateReconciler reconciles a Frigate object +type FrigateReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=ship.testproject.org,resources=frigates,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=ship.testproject.org,resources=frigates/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=ship.testproject.org,resources=frigates/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the Frigate object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile +func (r *FrigateReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *FrigateReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&shipv1beta1.Frigate{}). + Complete(r) +} diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/suite_test.go new file mode 100644 index 00000000000..dfd58b12897 --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/ship/suite_test.go @@ -0,0 +1,98 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package ship + +import ( + "fmt" + "path/filepath" + "runtime" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + shipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1" + shipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v1beta1" + shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/ship/v2alpha1" + //+kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment + +func TestControllers(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Controller Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: true, + + // The BinaryAssetsDirectory is only required if you want to run the tests directly + // without call the makefile target test. If not informed it will look for the + // default path defined in controller-runtime which is /usr/local/kubebuilder/. + // Note that you must have the required binaries setup under the bin directory to perform + // the tests directly. When we run make test it will be setup and used automatically. + BinaryAssetsDirectory: filepath.Join("..", "..", "..", "bin", "k8s", + fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = shipv1beta1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + err = shipv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + err = shipv2alpha1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup-with-deploy-image/internal/controller/suite_test.go b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/suite_test.go new file mode 100644 index 00000000000..4d8c3984d6f --- /dev/null +++ b/testdata/project-v4-multigroup-with-deploy-image/internal/controller/suite_test.go @@ -0,0 +1,90 @@ +/* +Copyright 2023 The Kubernetes authors. + +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. +*/ + +package controller + +import ( + "fmt" + "path/filepath" + "runtime" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + testprojectorgv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup-with-deploy-image/api/v1" + //+kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment + +func TestControllers(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Controller Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: true, + + // The BinaryAssetsDirectory is only required if you want to run the tests directly + // without call the makefile target test. If not informed it will look for the + // default path defined in controller-runtime which is /usr/local/kubebuilder/. + // Note that you must have the required binaries setup under the bin directory to perform + // the tests directly. When we run make test it will be setup and used automatically. + BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s", + fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = testprojectorgv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/PROJECT b/testdata/project-v4-multigroup/PROJECT index 12d9db3cd58..92f8bcfd7a5 100644 --- a/testdata/project-v4-multigroup/PROJECT +++ b/testdata/project-v4-multigroup/PROJECT @@ -6,25 +6,6 @@ domain: testproject.org layout: - go.kubebuilder.io/v4 multigroup: true -plugins: - deploy-image.go.kubebuilder.io/v1-alpha: - resources: - - domain: testproject.org - group: example.com - kind: Memcached - options: - containerCommand: memcached,-m=64,-o,modern,-v - containerPort: "11211" - image: memcached:1.4.36-alpine - runAsUser: "1001" - version: v1alpha1 - - domain: testproject.org - group: example.com - kind: Busybox - options: - image: busybox:1.28 - version: v1alpha1 - grafana.kubebuilder.io/v1-alpha: {} projectName: project-v4-multigroup repo: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup resources: @@ -137,25 +118,4 @@ resources: defaulting: true validation: true webhookVersion: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: example.com - kind: Memcached - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1 - version: v1alpha1 - webhooks: - validation: true - webhookVersion: v1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: testproject.org - group: example.com - kind: Busybox - path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1 - version: v1alpha1 version: "3" diff --git a/testdata/project-v4-multigroup/api/example.com/v1alpha1/busybox_types.go b/testdata/project-v4-multigroup/api/example.com/v1alpha1/busybox_types.go deleted file mode 100644 index 440dd96baef..00000000000 --- a/testdata/project-v4-multigroup/api/example.com/v1alpha1/busybox_types.go +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright 2023 The Kubernetes authors. - -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. -*/ - -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -// BusyboxSpec defines the desired state of Busybox -type BusyboxSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // Size defines the number of Busybox instances - // The following markers will use OpenAPI v3 schema to validate the value - // More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - // +kubebuilder:validation:Minimum=1 - // +kubebuilder:validation:Maximum=3 - // +kubebuilder:validation:ExclusiveMaximum=false - Size int32 `json:"size,omitempty"` -} - -// BusyboxStatus defines the observed state of Busybox -type BusyboxStatus struct { - // Represents the observations of a Busybox's current state. - // Busybox.status.conditions.type are: "Available", "Progressing", and "Degraded" - // Busybox.status.conditions.status are one of True, False, Unknown. - // Busybox.status.conditions.reason the value should be a CamelCase string and producers of specific - // condition types may define expected values and meanings for this field, and whether the values - // are considered a guaranteed API. - // Busybox.status.conditions.Message is a human readable message indicating details about the transition. - // For further information see: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties - - Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` -} - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status - -// Busybox is the Schema for the busyboxes API -type Busybox struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec BusyboxSpec `json:"spec,omitempty"` - Status BusyboxStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// BusyboxList contains a list of Busybox -type BusyboxList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Busybox `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Busybox{}, &BusyboxList{}) -} diff --git a/testdata/project-v4-multigroup/api/example.com/v1alpha1/memcached_types.go b/testdata/project-v4-multigroup/api/example.com/v1alpha1/memcached_types.go deleted file mode 100644 index aa82a833c00..00000000000 --- a/testdata/project-v4-multigroup/api/example.com/v1alpha1/memcached_types.go +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright 2023 The Kubernetes authors. - -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. -*/ - -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -// MemcachedSpec defines the desired state of Memcached -type MemcachedSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // Size defines the number of Memcached instances - // The following markers will use OpenAPI v3 schema to validate the value - // More info: https://book.kubebuilder.io/reference/markers/crd-validation.html - // +kubebuilder:validation:Minimum=1 - // +kubebuilder:validation:Maximum=3 - // +kubebuilder:validation:ExclusiveMaximum=false - Size int32 `json:"size,omitempty"` - - // Port defines the port that will be used to init the container with the image - ContainerPort int32 `json:"containerPort,omitempty"` -} - -// MemcachedStatus defines the observed state of Memcached -type MemcachedStatus struct { - // Represents the observations of a Memcached's current state. - // Memcached.status.conditions.type are: "Available", "Progressing", and "Degraded" - // Memcached.status.conditions.status are one of True, False, Unknown. - // Memcached.status.conditions.reason the value should be a CamelCase string and producers of specific - // condition types may define expected values and meanings for this field, and whether the values - // are considered a guaranteed API. - // Memcached.status.conditions.Message is a human readable message indicating details about the transition. - // For further information see: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties - - Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` -} - -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status - -// Memcached is the Schema for the memcacheds API -type Memcached struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec MemcachedSpec `json:"spec,omitempty"` - Status MemcachedStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// MemcachedList contains a list of Memcached -type MemcachedList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []Memcached `json:"items"` -} - -func init() { - SchemeBuilder.Register(&Memcached{}, &MemcachedList{}) -} diff --git a/testdata/project-v4-multigroup/api/example.com/v1alpha1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/api/example.com/v1alpha1/zz_generated.deepcopy.go deleted file mode 100644 index fa209b7c2b2..00000000000 --- a/testdata/project-v4-multigroup/api/example.com/v1alpha1/zz_generated.deepcopy.go +++ /dev/null @@ -1,218 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2023 The Kubernetes authors. - -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. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Busybox) DeepCopyInto(out *Busybox) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Busybox. -func (in *Busybox) DeepCopy() *Busybox { - if in == nil { - return nil - } - out := new(Busybox) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Busybox) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BusyboxList) DeepCopyInto(out *BusyboxList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Busybox, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusyboxList. -func (in *BusyboxList) DeepCopy() *BusyboxList { - if in == nil { - return nil - } - out := new(BusyboxList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BusyboxList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BusyboxSpec) DeepCopyInto(out *BusyboxSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusyboxSpec. -func (in *BusyboxSpec) DeepCopy() *BusyboxSpec { - if in == nil { - return nil - } - out := new(BusyboxSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BusyboxStatus) DeepCopyInto(out *BusyboxStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusyboxStatus. -func (in *BusyboxStatus) DeepCopy() *BusyboxStatus { - if in == nil { - return nil - } - out := new(BusyboxStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Memcached) DeepCopyInto(out *Memcached) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Memcached. -func (in *Memcached) DeepCopy() *Memcached { - if in == nil { - return nil - } - out := new(Memcached) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Memcached) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MemcachedList) DeepCopyInto(out *MemcachedList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Memcached, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemcachedList. -func (in *MemcachedList) DeepCopy() *MemcachedList { - if in == nil { - return nil - } - out := new(MemcachedList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *MemcachedList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MemcachedSpec) DeepCopyInto(out *MemcachedSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemcachedSpec. -func (in *MemcachedSpec) DeepCopy() *MemcachedSpec { - if in == nil { - return nil - } - out := new(MemcachedSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MemcachedStatus) DeepCopyInto(out *MemcachedStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemcachedStatus. -func (in *MemcachedStatus) DeepCopy() *MemcachedStatus { - if in == nil { - return nil - } - out := new(MemcachedStatus) - in.DeepCopyInto(out) - return out -} diff --git a/testdata/project-v4-multigroup/cmd/main.go b/testdata/project-v4-multigroup/cmd/main.go index c9bebd9afbc..d6453cef006 100644 --- a/testdata/project-v4-multigroup/cmd/main.go +++ b/testdata/project-v4-multigroup/cmd/main.go @@ -33,7 +33,6 @@ import ( metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/crew/v1" - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" fizv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/fiz/v1" foopolicyv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo.policy/v1" foov1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/foo/v1" @@ -46,7 +45,6 @@ import ( "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller" appscontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/apps" crewcontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/crew" - examplecomcontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/example.com" fizcontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/fiz" foocontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/foo" foopolicycontroller "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/internal/controller/foo.policy" @@ -73,7 +71,6 @@ func init() { utilruntime.Must(foov1.AddToScheme(scheme)) utilruntime.Must(fizv1.AddToScheme(scheme)) utilruntime.Must(testprojectorgv1.AddToScheme(scheme)) - utilruntime.Must(examplecomv1alpha1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } @@ -224,28 +221,6 @@ func main() { os.Exit(1) } } - if err = (&examplecomcontroller.MemcachedReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Recorder: mgr.GetEventRecorderFor("memcached-controller"), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Memcached") - os.Exit(1) - } - if err = (&examplecomcontroller.BusyboxReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Recorder: mgr.GetEventRecorderFor("busybox-controller"), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "Busybox") - os.Exit(1) - } - if os.Getenv("ENABLE_WEBHOOKS") != "false" { - if err = (&examplecomv1alpha1.Memcached{}).SetupWebhookWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create webhook", "webhook", "Memcached") - os.Exit(1) - } - } //+kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { diff --git a/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_busyboxes.yaml b/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_busyboxes.yaml deleted file mode 100644 index 5f6cac569ec..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_busyboxes.yaml +++ /dev/null @@ -1,122 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.13.0 - name: busyboxes.example.com.testproject.org -spec: - group: example.com.testproject.org - names: - kind: Busybox - listKind: BusyboxList - plural: busyboxes - singular: busybox - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Busybox is the Schema for the busyboxes API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: BusyboxSpec defines the desired state of Busybox - properties: - size: - description: 'Size defines the number of Busybox instances The following - markers will use OpenAPI v3 schema to validate the value More info: - https://book.kubebuilder.io/reference/markers/crd-validation.html' - format: int32 - maximum: 3 - minimum: 1 - type: integer - type: object - status: - description: BusyboxStatus defines the observed state of Busybox - properties: - conditions: - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_memcacheds.yaml b/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_memcacheds.yaml deleted file mode 100644 index 8d09426d3a8..00000000000 --- a/testdata/project-v4-multigroup/config/crd/bases/example.com.testproject.org_memcacheds.yaml +++ /dev/null @@ -1,127 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.13.0 - name: memcacheds.example.com.testproject.org -spec: - group: example.com.testproject.org - names: - kind: Memcached - listKind: MemcachedList - plural: memcacheds - singular: memcached - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Memcached is the Schema for the memcacheds API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: MemcachedSpec defines the desired state of Memcached - properties: - containerPort: - description: Port defines the port that will be used to init the container - with the image - format: int32 - type: integer - size: - description: 'Size defines the number of Memcached instances The following - markers will use OpenAPI v3 schema to validate the value More info: - https://book.kubebuilder.io/reference/markers/crd-validation.html' - format: int32 - maximum: 3 - minimum: 1 - type: integer - type: object - status: - description: MemcachedStatus defines the observed state of Memcached - properties: - conditions: - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/testdata/project-v4-multigroup/config/crd/kustomization.yaml b/testdata/project-v4-multigroup/config/crd/kustomization.yaml index e3729c3f731..9b25692779d 100644 --- a/testdata/project-v4-multigroup/config/crd/kustomization.yaml +++ b/testdata/project-v4-multigroup/config/crd/kustomization.yaml @@ -12,8 +12,6 @@ resources: - bases/foo.testproject.org_bars.yaml - bases/fiz.testproject.org_bars.yaml - bases/testproject.org_lakers.yaml -- bases/example.com.testproject.org_memcacheds.yaml -- bases/example.com.testproject.org_busyboxes.yaml #+kubebuilder:scaffold:crdkustomizeresource patches: @@ -29,8 +27,6 @@ patches: #- path: patches/webhook_in_foo_bars.yaml #- path: patches/webhook_in_fiz_bars.yaml #- path: patches/webhook_in__lakers.yaml -#- path: patches/webhook_in_example.com_memcacheds.yaml -#- path: patches/webhook_in_example.com_busyboxes.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. @@ -45,8 +41,6 @@ patches: #- path: patches/cainjection_in_foo_bars.yaml #- path: patches/cainjection_in_fiz_bars.yaml #- path: patches/cainjection_in__lakers.yaml -#- path: patches/cainjection_in_example.com_memcacheds.yaml -#- path: patches/cainjection_in_example.com_busyboxes.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/testdata/project-v4-multigroup/config/manager/manager.yaml b/testdata/project-v4-multigroup/config/manager/manager.yaml index e36823baac8..b9d340945db 100644 --- a/testdata/project-v4-multigroup/config/manager/manager.yaml +++ b/testdata/project-v4-multigroup/config/manager/manager.yaml @@ -72,11 +72,6 @@ spec: - --leader-elect image: controller:latest name: manager - env: - - name: BUSYBOX_IMAGE - value: busybox:1.28 - - name: MEMCACHED_IMAGE - value: memcached:1.4.36-alpine securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_busybox_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/example.com_busybox_viewer_role.yaml deleted file mode 100644 index b3f6d566507..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/example.com_busybox_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view busyboxes. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: busybox-viewer-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: project-v4-multigroup - app.kubernetes.io/part-of: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: busybox-viewer-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - verbs: - - get - - list - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/example.com_memcached_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/example.com_memcached_viewer_role.yaml deleted file mode 100644 index 251117ddb78..00000000000 --- a/testdata/project-v4-multigroup/config/rbac/example.com_memcached_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view memcacheds. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: memcached-viewer-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: project-v4-multigroup - app.kubernetes.io/part-of: project-v4-multigroup - app.kubernetes.io/managed-by: kustomize - name: memcached-viewer-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds - verbs: - - get - - list - - watch -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/status - verbs: - - get diff --git a/testdata/project-v4-multigroup/config/rbac/role.yaml b/testdata/project-v4-multigroup/config/rbac/role.yaml index 0744d29613d..e2d30b23205 100644 --- a/testdata/project-v4-multigroup/config/rbac/role.yaml +++ b/testdata/project-v4-multigroup/config/rbac/role.yaml @@ -30,21 +30,6 @@ rules: - get - patch - update -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch -- apiGroups: - - "" - resources: - - pods - verbs: - - get - - list - - watch - apiGroups: - crew.testproject.org resources: @@ -71,58 +56,6 @@ rules: - get - patch - update -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/finalizers - verbs: - - update -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - verbs: - - get - - patch - - update -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/finalizers - verbs: - - update -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/status - verbs: - - get - - patch - - update - apiGroups: - fiz.testproject.org resources: diff --git a/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_busybox.yaml b/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_busybox.yaml deleted file mode 100644 index e5ba7642dd1..00000000000 --- a/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_busybox.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: example.com.testproject.org/v1alpha1 -kind: Busybox -metadata: - name: busybox-sample -spec: - # TODO(user): edit the following value to ensure the number - # of Pods/Instances your Operand must have on cluster - size: 1 - diff --git a/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_memcached.yaml b/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_memcached.yaml deleted file mode 100644 index 153d1db36c8..00000000000 --- a/testdata/project-v4-multigroup/config/samples/example.com_v1alpha1_memcached.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: example.com.testproject.org/v1alpha1 -kind: Memcached -metadata: - name: memcached-sample -spec: - # TODO(user): edit the following value to ensure the number - # of Pods/Instances your Operand must have on cluster - size: 1 -# TODO(user): edit the following value to ensure the container has the right port to be initialized - containerPort: 11211 diff --git a/testdata/project-v4-multigroup/config/samples/kustomization.yaml b/testdata/project-v4-multigroup/config/samples/kustomization.yaml index 7018e7905d0..a74ed904341 100644 --- a/testdata/project-v4-multigroup/config/samples/kustomization.yaml +++ b/testdata/project-v4-multigroup/config/samples/kustomization.yaml @@ -10,6 +10,4 @@ resources: - foo_v1_bar.yaml - fiz_v1_bar.yaml - _v1_lakers.yaml -- example.com_v1alpha1_memcached.yaml -- example.com_v1alpha1_busybox.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/testdata/project-v4-multigroup/config/webhook/manifests.yaml b/testdata/project-v4-multigroup/config/webhook/manifests.yaml index 8537370eb6e..62374002227 100644 --- a/testdata/project-v4-multigroup/config/webhook/manifests.yaml +++ b/testdata/project-v4-multigroup/config/webhook/manifests.yaml @@ -90,26 +90,6 @@ webhooks: resources: - captains sideEffects: None -- admissionReviewVersions: - - v1 - clientConfig: - service: - name: webhook-service - namespace: system - path: /validate-example-com-testproject-org-v1alpha1-memcached - failurePolicy: Fail - name: vmemcached.kb.io - rules: - - apiGroups: - - example.com.testproject.org - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - memcacheds - sideEffects: None - admissionReviewVersions: - v1 clientConfig: diff --git a/testdata/project-v4-multigroup/grafana/controller-resources-metrics.json b/testdata/project-v4-multigroup/grafana/controller-resources-metrics.json deleted file mode 100644 index 629e0d3c9b1..00000000000 --- a/testdata/project-v4-multigroup/grafana/controller-resources-metrics.json +++ /dev/null @@ -1,306 +0,0 @@ -{ - "__inputs": [ - { - "name": "DS_PROMETHEUS", - "label": "Prometheus", - "description": "", - "type": "datasource", - "pluginId": "prometheus", - "pluginName": "Prometheus" - } - ], - "__requires": [ - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "1.0.0" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": "-- Grafana --", - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "links": [], - "liveNow": false, - "panels": [ - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "percent" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 0 - }, - "id": 2, - "interval": "1m", - "links": [], - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.4.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "rate(process_cpu_seconds_total{job=\"$job\", namespace=\"$namespace\", pod=\"$pod\"}[5m]) * 100", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "Pod: {{pod}} | Container: {{container}}", - "refId": "A", - "step": 10 - } - ], - "title": "Controller CPU Usage", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "bytes" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 0 - }, - "id": 4, - "interval": "1m", - "links": [], - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.4.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "process_resident_memory_bytes{job=\"$job\", namespace=\"$namespace\", pod=\"$pod\"}", - "format": "time_series", - "interval": "", - "intervalFactor": 2, - "legendFormat": "Pod: {{pod}} | Container: {{container}}", - "refId": "A", - "step": 10 - } - ], - "title": "Controller Memory Usage", - "type": "timeseries" - } - ], - "refresh": "", - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "job", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "current": { - "selected": false, - "text": "observability", - "value": "observability" - }, - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total, namespace)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "namespace", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total, namespace)", - "refId": "StandardVariableQuery" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "current": { - "selected": false, - "text": "All", - "value": "$__all" - }, - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "hide": 2, - "includeAll": true, - "label": "pod", - "multi": true, - "name": "pod", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Controller-Resources-Metrics", - "weekStart": "" -} diff --git a/testdata/project-v4-multigroup/grafana/controller-runtime-metrics.json b/testdata/project-v4-multigroup/grafana/controller-runtime-metrics.json deleted file mode 100644 index 70023a42d82..00000000000 --- a/testdata/project-v4-multigroup/grafana/controller-runtime-metrics.json +++ /dev/null @@ -1,710 +0,0 @@ -{ - "__inputs": [ - { - "name": "DS_PROMETHEUS", - "label": "Prometheus", - "description": "", - "type": "datasource", - "pluginId": "prometheus", - "pluginName": "Prometheus" - } - ], - "__requires": [ - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "1.0.0" - } - ], - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "target": { - "limit": 100, - "matchAny": false, - "tags": [], - "type": "dashboard" - }, - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "links": [], - "liveNow": false, - "panels": [ - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 9, - "panels": [], - "title": "Reconciliation Metrics", - "type": "row" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "Total number of reconciliations per controller", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "cpm" - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 1 - }, - "id": 7, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "editorMode": "code", - "exemplar": true, - "expr": "sum(rate(controller_runtime_reconcile_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, pod)", - "interval": "", - "legendFormat": "{{instance}} {{pod}}", - "range": true, - "refId": "A" - } - ], - "title": "Total Reconciliation Count Per Controller", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "Total number of reconciliation errors per controller", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "cpm" - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 1 - }, - "id": 6, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "editorMode": "code", - "exemplar": true, - "expr": "sum(rate(controller_runtime_reconcile_errors_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, pod)", - "interval": "", - "legendFormat": "{{instance}} {{pod}}", - "range": true, - "refId": "A" - } - ], - "title": "Reconciliation Error Count Per Controller", - "type": "timeseries" - }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 8 - }, - "id": 11, - "panels": [], - "title": "Work Queue Metrics", - "type": "row" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "How long in seconds an item stays in workqueue before being requested", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "normal" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 9 - }, - "id": 13, - "options": { - "legend": { - "calcs": [ - "max", - "mean" - ], - "displayMode": "list", - "placement": "right" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.50, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "interval": "", - "legendFormat": "P50 {{name}} {{instance}} ", - "refId": "A" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.90, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P90 {{name}} {{instance}} ", - "refId": "B" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.99, sum(rate(workqueue_queue_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P99 {{name}} {{instance}} ", - "refId": "C" - } - ], - "title": "Seconds For Items Stay In Queue (before being requested) (P50, P90, P99)", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "ops" - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 9 - }, - "id": 15, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "8.4.3", - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "sum(rate(workqueue_adds_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name)", - "interval": "", - "legendFormat": "{{name}} {{instance}}", - "refId": "A" - } - ], - "title": "Work Queue Add Rate", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "How long in seconds processing an item from workqueue takes.", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "s" - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 0, - "y": 16 - }, - "id": 19, - "options": { - "legend": { - "calcs": [ - "max", - "mean" - ], - "displayMode": "table", - "placement": "right" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.50, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "interval": "", - "legendFormat": "P50 {{name}} {{instance}} ", - "refId": "A" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.90, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P90 {{name}} {{instance}} ", - "refId": "B" - }, - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "histogram_quantile(0.99, sum(rate(workqueue_work_duration_seconds_bucket{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name, le))", - "hide": false, - "interval": "", - "legendFormat": "P99 {{name}} {{instance}} ", - "refId": "C" - } - ], - "title": "Seconds Processing Items From WorkQueue (P50, P90, P99)", - "type": "timeseries" - }, - { - "datasource": "${DS_PROMETHEUS}", - "description": "Total number of retries handled by workqueue", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 20, - "gradientMode": "scheme", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "smooth", - "lineWidth": 3, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "ops" - }, - "overrides": [] - }, - "gridPos": { - "h": 7, - "w": 12, - "x": 12, - "y": 16 - }, - "id": 17, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom" - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": "${DS_PROMETHEUS}", - "exemplar": true, - "expr": "sum(rate(workqueue_retries_total{job=\"$job\", namespace=\"$namespace\"}[5m])) by (instance, name)", - "interval": "", - "legendFormat": "{{name}} {{instance}} ", - "refId": "A" - } - ], - "title": "Work Queue Retries Rate", - "type": "timeseries" - } - ], - "refresh": "", - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "job", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\"}, job)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total, namespace)", - "hide": 0, - "includeAll": false, - "multi": false, - "name": "namespace", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total, namespace)", - "refId": "StandardVariableQuery" - }, - "refresh": 1, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - }, - { - "current": { - "selected": true, - "text": [ - "All" - ], - "value": [ - "$__all" - ] - }, - "datasource": "${DS_PROMETHEUS}", - "definition": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "hide": 2, - "includeAll": true, - "label": "pod", - "multi": true, - "name": "pod", - "options": [], - "query": { - "query": "label_values(controller_runtime_reconcile_total{namespace=~\"$namespace\", job=~\"$job\"}, pod)", - "refId": "StandardVariableQuery" - }, - "refresh": 2, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "type": "query" - } - ] - }, - "time": { - "from": "now-15m", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "Controller-Runtime-Metrics", - "weekStart": "" -} diff --git a/testdata/project-v4-multigroup/grafana/custom-metrics/config.yaml b/testdata/project-v4-multigroup/grafana/custom-metrics/config.yaml deleted file mode 100644 index 3ee1bebdf24..00000000000 --- a/testdata/project-v4-multigroup/grafana/custom-metrics/config.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -customMetrics: -# - metric: # Raw custom metric (required) -# type: # Metric type: counter/gauge/histogram (required) -# expr: # Prom_ql for the metric (optional) -# unit: # Unit of measurement, examples: s,none,bytes,percent,etc. (optional) -# -# -# Example: -# --- -# customMetrics: -# - metric: foo_bar -# unit: none -# type: histogram -# expr: histogram_quantile(0.90, sum by(instance, le) (rate(foo_bar{job=\"$job\", namespace=\"$namespace\"}[5m]))) diff --git a/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller.go b/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller.go deleted file mode 100644 index 639ca1ee0ad..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller.go +++ /dev/null @@ -1,433 +0,0 @@ -/* -Copyright 2023 The Kubernetes authors. - -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. -*/ - -package examplecom - -import ( - "context" - "fmt" - "os" - "strings" - "time" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/log" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" -) - -const busyboxFinalizer = "example.com.testproject.org/finalizer" - -// Definitions to manage status conditions -const ( - // typeAvailableBusybox represents the status of the Deployment reconciliation - typeAvailableBusybox = "Available" - // typeDegradedBusybox represents the status used when the custom resource is deleted and the finalizer operations are must to occur. - typeDegradedBusybox = "Degraded" -) - -// BusyboxReconciler reconciles a Busybox object -type BusyboxReconciler struct { - client.Client - Scheme *runtime.Scheme - Recorder record.EventRecorder -} - -// The following markers are used to generate the rules permissions (RBAC) on config/rbac using controller-gen -// when the command is executed. -// To know more about markers see: https://book.kubebuilder.io/reference/markers.html - -//+kubebuilder:rbac:groups=example.com.testproject.org,resources=busyboxes,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=example.com.testproject.org,resources=busyboxes/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=example.com.testproject.org,resources=busyboxes/finalizers,verbs=update -//+kubebuilder:rbac:groups=core,resources=events,verbs=create;patch -//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// It is essential for the controller's reconciliation loop to be idempotent. By following the Operator -// pattern you will create Controllers which provide a reconcile function -// responsible for synchronizing resources until the desired state is reached on the cluster. -// Breaking this recommendation goes against the design principles of controller-runtime. -// and may lead to unforeseen consequences such as resources becoming stuck and requiring manual intervention. -// For further info: -// - About Operator Pattern: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/ -// - About Controllers: https://kubernetes.io/docs/concepts/architecture/controller/ -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile -func (r *BusyboxReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - log := log.FromContext(ctx) - - // Fetch the Busybox instance - // The purpose is check if the Custom Resource for the Kind Busybox - // is applied on the cluster if not we return nil to stop the reconciliation - busybox := &examplecomv1alpha1.Busybox{} - err := r.Get(ctx, req.NamespacedName, busybox) - if err != nil { - if apierrors.IsNotFound(err) { - // If the custom resource is not found then, it usually means that it was deleted or not created - // In this way, we will stop the reconciliation - log.Info("busybox resource not found. Ignoring since object must be deleted") - return ctrl.Result{}, nil - } - // Error reading the object - requeue the request. - log.Error(err, "Failed to get busybox") - return ctrl.Result{}, err - } - - // Let's just set the status as Unknown when no status are available - if busybox.Status.Conditions == nil || len(busybox.Status.Conditions) == 0 { - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, Status: metav1.ConditionUnknown, Reason: "Reconciling", Message: "Starting reconciliation"}) - if err = r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - // Let's re-fetch the busybox Custom Resource after update the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raise the issue "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - // if we try to update it again in the following operations - if err := r.Get(ctx, req.NamespacedName, busybox); err != nil { - log.Error(err, "Failed to re-fetch busybox") - return ctrl.Result{}, err - } - } - - // Let's add a finalizer. Then, we can define some operations which should - // occurs before the custom resource to be deleted. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers - if !controllerutil.ContainsFinalizer(busybox, busyboxFinalizer) { - log.Info("Adding Finalizer for Busybox") - if ok := controllerutil.AddFinalizer(busybox, busyboxFinalizer); !ok { - log.Error(err, "Failed to add finalizer into the custom resource") - return ctrl.Result{Requeue: true}, nil - } - - if err = r.Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update custom resource to add finalizer") - return ctrl.Result{}, err - } - } - - // Check if the Busybox instance is marked to be deleted, which is - // indicated by the deletion timestamp being set. - isBusyboxMarkedToBeDeleted := busybox.GetDeletionTimestamp() != nil - if isBusyboxMarkedToBeDeleted { - if controllerutil.ContainsFinalizer(busybox, busyboxFinalizer) { - log.Info("Performing Finalizer Operations for Busybox before delete CR") - - // Let's add here an status "Downgrade" to define that this resource begin its process to be terminated. - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeDegradedBusybox, - Status: metav1.ConditionUnknown, Reason: "Finalizing", - Message: fmt.Sprintf("Performing finalizer operations for the custom resource: %s ", busybox.Name)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - // Perform all operations required before remove the finalizer and allow - // the Kubernetes API to remove the custom resource. - r.doFinalizerOperationsForBusybox(busybox) - - // TODO(user): If you add operations to the doFinalizerOperationsForBusybox method - // then you need to ensure that all worked fine before deleting and updating the Downgrade status - // otherwise, you should requeue here. - - // Re-fetch the busybox Custom Resource before update the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raise the issue "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, busybox); err != nil { - log.Error(err, "Failed to re-fetch busybox") - return ctrl.Result{}, err - } - - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeDegradedBusybox, - Status: metav1.ConditionTrue, Reason: "Finalizing", - Message: fmt.Sprintf("Finalizer operations for custom resource %s name were successfully accomplished", busybox.Name)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - log.Info("Removing Finalizer for Busybox after successfully perform the operations") - if ok := controllerutil.RemoveFinalizer(busybox, busyboxFinalizer); !ok { - log.Error(err, "Failed to remove finalizer for Busybox") - return ctrl.Result{Requeue: true}, nil - } - - if err := r.Update(ctx, busybox); err != nil { - log.Error(err, "Failed to remove finalizer for Busybox") - return ctrl.Result{}, err - } - } - return ctrl.Result{}, nil - } - - // Check if the deployment already exists, if not create a new one - found := &appsv1.Deployment{} - err = r.Get(ctx, types.NamespacedName{Name: busybox.Name, Namespace: busybox.Namespace}, found) - if err != nil && apierrors.IsNotFound(err) { - // Define a new deployment - dep, err := r.deploymentForBusybox(busybox) - if err != nil { - log.Error(err, "Failed to define new Deployment resource for Busybox") - - // The following implementation will update the status - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, - Status: metav1.ConditionFalse, Reason: "Reconciling", - Message: fmt.Sprintf("Failed to create Deployment for the custom resource (%s): (%s)", busybox.Name, err)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - log.Info("Creating a new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - if err = r.Create(ctx, dep); err != nil { - log.Error(err, "Failed to create new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - return ctrl.Result{}, err - } - - // Deployment created successfully - // We will requeue the reconciliation so that we can ensure the state - // and move forward for the next operations - return ctrl.Result{RequeueAfter: time.Minute}, nil - } else if err != nil { - log.Error(err, "Failed to get Deployment") - // Let's return the error for the reconciliation be re-trigged again - return ctrl.Result{}, err - } - - // The CRD API is defining that the Busybox type, have a BusyboxSpec.Size field - // to set the quantity of Deployment instances is the desired state on the cluster. - // Therefore, the following code will ensure the Deployment size is the same as defined - // via the Size spec of the Custom Resource which we are reconciling. - size := busybox.Spec.Size - if *found.Spec.Replicas != size { - found.Spec.Replicas = &size - if err = r.Update(ctx, found); err != nil { - log.Error(err, "Failed to update Deployment", - "Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name) - - // Re-fetch the busybox Custom Resource before update the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raise the issue "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, busybox); err != nil { - log.Error(err, "Failed to re-fetch busybox") - return ctrl.Result{}, err - } - - // The following implementation will update the status - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, - Status: metav1.ConditionFalse, Reason: "Resizing", - Message: fmt.Sprintf("Failed to update the size for the custom resource (%s): (%s)", busybox.Name, err)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - // Now, that we update the size we want to requeue the reconciliation - // so that we can ensure that we have the latest state of the resource before - // update. Also, it will help ensure the desired state on the cluster - return ctrl.Result{Requeue: true}, nil - } - - // The following implementation will update the status - meta.SetStatusCondition(&busybox.Status.Conditions, metav1.Condition{Type: typeAvailableBusybox, - Status: metav1.ConditionTrue, Reason: "Reconciling", - Message: fmt.Sprintf("Deployment for custom resource (%s) with %d replicas created successfully", busybox.Name, size)}) - - if err := r.Status().Update(ctx, busybox); err != nil { - log.Error(err, "Failed to update Busybox status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, nil -} - -// finalizeBusybox will perform the required operations before delete the CR. -func (r *BusyboxReconciler) doFinalizerOperationsForBusybox(cr *examplecomv1alpha1.Busybox) { - // TODO(user): Add the cleanup steps that the operator - // needs to do before the CR can be deleted. Examples - // of finalizers include performing backups and deleting - // resources that are not owned by this CR, like a PVC. - - // Note: It is not recommended to use finalizers with the purpose of delete resources which are - // created and managed in the reconciliation. These ones, such as the Deployment created on this reconcile, - // are defined as depended of the custom resource. See that we use the method ctrl.SetControllerReference. - // to set the ownerRef which means that the Deployment will be deleted by the Kubernetes API. - // More info: https://kubernetes.io/docs/tasks/administer-cluster/use-cascading-deletion/ - - // The following implementation will raise an event - r.Recorder.Event(cr, "Warning", "Deleting", - fmt.Sprintf("Custom Resource %s is being deleted from the namespace %s", - cr.Name, - cr.Namespace)) -} - -// deploymentForBusybox returns a Busybox Deployment object -func (r *BusyboxReconciler) deploymentForBusybox( - busybox *examplecomv1alpha1.Busybox) (*appsv1.Deployment, error) { - ls := labelsForBusybox(busybox.Name) - replicas := busybox.Spec.Size - - // Get the Operand image - image, err := imageForBusybox() - if err != nil { - return nil, err - } - - dep := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: busybox.Name, - Namespace: busybox.Namespace, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: ls, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: ls, - }, - Spec: corev1.PodSpec{ - // TODO(user): Uncomment the following code to configure the nodeAffinity expression - // according to the platforms which are supported by your solution. It is considered - // best practice to support multiple architectures. build your manager image using the - // makefile target docker-buildx. Also, you can use docker manifest inspect - // to check what are the platforms supported. - // More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity - //Affinity: &corev1.Affinity{ - // NodeAffinity: &corev1.NodeAffinity{ - // RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ - // NodeSelectorTerms: []corev1.NodeSelectorTerm{ - // { - // MatchExpressions: []corev1.NodeSelectorRequirement{ - // { - // Key: "kubernetes.io/arch", - // Operator: "In", - // Values: []string{"amd64", "arm64", "ppc64le", "s390x"}, - // }, - // { - // Key: "kubernetes.io/os", - // Operator: "In", - // Values: []string{"linux"}, - // }, - // }, - // }, - // }, - // }, - // }, - //}, - SecurityContext: &corev1.PodSecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - // IMPORTANT: seccomProfile was introduced with Kubernetes 1.19 - // If you are looking for to produce solutions to be supported - // on lower versions you must remove this option. - SeccompProfile: &corev1.SeccompProfile{ - Type: corev1.SeccompProfileTypeRuntimeDefault, - }, - }, - Containers: []corev1.Container{{ - Image: image, - Name: "busybox", - ImagePullPolicy: corev1.PullIfNotPresent, - // Ensure restrictive context for the container - // More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - SecurityContext: &corev1.SecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - AllowPrivilegeEscalation: &[]bool{false}[0], - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - }, - }}, - }, - }, - }, - } - - // Set the ownerRef for the Deployment - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/ - if err := ctrl.SetControllerReference(busybox, dep, r.Scheme); err != nil { - return nil, err - } - return dep, nil -} - -// labelsForBusybox returns the labels for selecting the resources -// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/ -func labelsForBusybox(name string) map[string]string { - var imageTag string - image, err := imageForBusybox() - if err == nil { - imageTag = strings.Split(image, ":")[1] - } - return map[string]string{"app.kubernetes.io/name": "Busybox", - "app.kubernetes.io/instance": name, - "app.kubernetes.io/version": imageTag, - "app.kubernetes.io/part-of": "project-v4-multigroup", - "app.kubernetes.io/created-by": "controller-manager", - } -} - -// imageForBusybox gets the Operand image which is managed by this controller -// from the BUSYBOX_IMAGE environment variable defined in the config/manager/manager.yaml -func imageForBusybox() (string, error) { - var imageEnvVar = "BUSYBOX_IMAGE" - image, found := os.LookupEnv(imageEnvVar) - if !found { - return "", fmt.Errorf("Unable to find %s environment variable with the image", imageEnvVar) - } - return image, nil -} - -// SetupWithManager sets up the controller with the Manager. -// Note that the Deployment will be also watched in order to ensure its -// desirable state on the cluster -func (r *BusyboxReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&examplecomv1alpha1.Busybox{}). - Owns(&appsv1.Deployment{}). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller_test.go b/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller_test.go deleted file mode 100644 index 1d06b715f88..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/example.com/busybox_controller_test.go +++ /dev/null @@ -1,153 +0,0 @@ -/* -Copyright 2023 The Kubernetes authors. - -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. -*/ - -package examplecom - -import ( - "context" - "fmt" - "os" - "time" - - //nolint:golint - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" -) - -var _ = Describe("Busybox controller", func() { - Context("Busybox controller test", func() { - - const BusyboxName = "test-busybox" - - ctx := context.Background() - - namespace := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: BusyboxName, - Namespace: BusyboxName, - }, - } - - typeNamespaceName := types.NamespacedName{ - Name: BusyboxName, - Namespace: BusyboxName, - } - busybox := &examplecomv1alpha1.Busybox{} - - BeforeEach(func() { - By("Creating the Namespace to perform the tests") - err := k8sClient.Create(ctx, namespace) - Expect(err).To(Not(HaveOccurred())) - - By("Setting the Image ENV VAR which stores the Operand image") - err = os.Setenv("BUSYBOX_IMAGE", "example.com/image:test") - Expect(err).To(Not(HaveOccurred())) - - By("creating the custom resource for the Kind Busybox") - err = k8sClient.Get(ctx, typeNamespaceName, busybox) - if err != nil && errors.IsNotFound(err) { - // Let's mock our custom resource at the same way that we would - // apply on the cluster the manifest under config/samples - busybox := &examplecomv1alpha1.Busybox{ - ObjectMeta: metav1.ObjectMeta{ - Name: BusyboxName, - Namespace: namespace.Name, - }, - Spec: examplecomv1alpha1.BusyboxSpec{ - Size: 1, - }, - } - - err = k8sClient.Create(ctx, busybox) - Expect(err).To(Not(HaveOccurred())) - } - }) - - AfterEach(func() { - By("removing the custom resource for the Kind Busybox") - found := &examplecomv1alpha1.Busybox{} - err := k8sClient.Get(ctx, typeNamespaceName, found) - Expect(err).To(Not(HaveOccurred())) - - Eventually(func() error { - return k8sClient.Delete(context.TODO(), found) - }, 2*time.Minute, time.Second).Should(Succeed()) - - // TODO(user): Attention if you improve this code by adding other context test you MUST - // be aware of the current delete namespace limitations. - // More info: https://book.kubebuilder.io/reference/envtest.html#testing-considerations - By("Deleting the Namespace to perform the tests") - _ = k8sClient.Delete(ctx, namespace) - - By("Removing the Image ENV VAR which stores the Operand image") - _ = os.Unsetenv("BUSYBOX_IMAGE") - }) - - It("should successfully reconcile a custom resource for Busybox", func() { - By("Checking if the custom resource was successfully created") - Eventually(func() error { - found := &examplecomv1alpha1.Busybox{} - return k8sClient.Get(ctx, typeNamespaceName, found) - }, time.Minute, time.Second).Should(Succeed()) - - By("Reconciling the custom resource created") - busyboxReconciler := &BusyboxReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := busyboxReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespaceName, - }) - Expect(err).To(Not(HaveOccurred())) - - By("Checking if Deployment was successfully created in the reconciliation") - Eventually(func() error { - found := &appsv1.Deployment{} - return k8sClient.Get(ctx, typeNamespaceName, found) - }, time.Minute, time.Second).Should(Succeed()) - - By("Checking the latest Status Condition added to the Busybox instance") - Eventually(func() error { - if busybox.Status.Conditions != nil && - len(busybox.Status.Conditions) != 0 { - latestStatusCondition := busybox.Status.Conditions[len(busybox.Status.Conditions)-1] - expectedLatestStatusCondition := metav1.Condition{ - Type: typeAvailableBusybox, - Status: metav1.ConditionTrue, - Reason: "Reconciling", - Message: fmt.Sprintf( - "Deployment for custom resource (%s) with %d replicas created successfully", - busybox.Name, - busybox.Spec.Size), - } - if latestStatusCondition != expectedLatestStatusCondition { - return fmt.Errorf("The latest status condition added to the Busybox instance is not as expected") - } - } - return nil - }, time.Minute, time.Second).Should(Succeed()) - }) - }) -}) diff --git a/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller.go b/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller.go deleted file mode 100644 index 5e508374c23..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller.go +++ /dev/null @@ -1,439 +0,0 @@ -/* -Copyright 2023 The Kubernetes authors. - -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. -*/ - -package examplecom - -import ( - "context" - "fmt" - "os" - "strings" - "time" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/record" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/log" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" -) - -const memcachedFinalizer = "example.com.testproject.org/finalizer" - -// Definitions to manage status conditions -const ( - // typeAvailableMemcached represents the status of the Deployment reconciliation - typeAvailableMemcached = "Available" - // typeDegradedMemcached represents the status used when the custom resource is deleted and the finalizer operations are must to occur. - typeDegradedMemcached = "Degraded" -) - -// MemcachedReconciler reconciles a Memcached object -type MemcachedReconciler struct { - client.Client - Scheme *runtime.Scheme - Recorder record.EventRecorder -} - -// The following markers are used to generate the rules permissions (RBAC) on config/rbac using controller-gen -// when the command is executed. -// To know more about markers see: https://book.kubebuilder.io/reference/markers.html - -//+kubebuilder:rbac:groups=example.com.testproject.org,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=example.com.testproject.org,resources=memcacheds/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=example.com.testproject.org,resources=memcacheds/finalizers,verbs=update -//+kubebuilder:rbac:groups=core,resources=events,verbs=create;patch -//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// It is essential for the controller's reconciliation loop to be idempotent. By following the Operator -// pattern you will create Controllers which provide a reconcile function -// responsible for synchronizing resources until the desired state is reached on the cluster. -// Breaking this recommendation goes against the design principles of controller-runtime. -// and may lead to unforeseen consequences such as resources becoming stuck and requiring manual intervention. -// For further info: -// - About Operator Pattern: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/ -// - About Controllers: https://kubernetes.io/docs/concepts/architecture/controller/ -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.1/pkg/reconcile -func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - log := log.FromContext(ctx) - - // Fetch the Memcached instance - // The purpose is check if the Custom Resource for the Kind Memcached - // is applied on the cluster if not we return nil to stop the reconciliation - memcached := &examplecomv1alpha1.Memcached{} - err := r.Get(ctx, req.NamespacedName, memcached) - if err != nil { - if apierrors.IsNotFound(err) { - // If the custom resource is not found then, it usually means that it was deleted or not created - // In this way, we will stop the reconciliation - log.Info("memcached resource not found. Ignoring since object must be deleted") - return ctrl.Result{}, nil - } - // Error reading the object - requeue the request. - log.Error(err, "Failed to get memcached") - return ctrl.Result{}, err - } - - // Let's just set the status as Unknown when no status are available - if memcached.Status.Conditions == nil || len(memcached.Status.Conditions) == 0 { - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, Status: metav1.ConditionUnknown, Reason: "Reconciling", Message: "Starting reconciliation"}) - if err = r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - // Let's re-fetch the memcached Custom Resource after update the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raise the issue "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - // if we try to update it again in the following operations - if err := r.Get(ctx, req.NamespacedName, memcached); err != nil { - log.Error(err, "Failed to re-fetch memcached") - return ctrl.Result{}, err - } - } - - // Let's add a finalizer. Then, we can define some operations which should - // occurs before the custom resource to be deleted. - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers - if !controllerutil.ContainsFinalizer(memcached, memcachedFinalizer) { - log.Info("Adding Finalizer for Memcached") - if ok := controllerutil.AddFinalizer(memcached, memcachedFinalizer); !ok { - log.Error(err, "Failed to add finalizer into the custom resource") - return ctrl.Result{Requeue: true}, nil - } - - if err = r.Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update custom resource to add finalizer") - return ctrl.Result{}, err - } - } - - // Check if the Memcached instance is marked to be deleted, which is - // indicated by the deletion timestamp being set. - isMemcachedMarkedToBeDeleted := memcached.GetDeletionTimestamp() != nil - if isMemcachedMarkedToBeDeleted { - if controllerutil.ContainsFinalizer(memcached, memcachedFinalizer) { - log.Info("Performing Finalizer Operations for Memcached before delete CR") - - // Let's add here an status "Downgrade" to define that this resource begin its process to be terminated. - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeDegradedMemcached, - Status: metav1.ConditionUnknown, Reason: "Finalizing", - Message: fmt.Sprintf("Performing finalizer operations for the custom resource: %s ", memcached.Name)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - // Perform all operations required before remove the finalizer and allow - // the Kubernetes API to remove the custom resource. - r.doFinalizerOperationsForMemcached(memcached) - - // TODO(user): If you add operations to the doFinalizerOperationsForMemcached method - // then you need to ensure that all worked fine before deleting and updating the Downgrade status - // otherwise, you should requeue here. - - // Re-fetch the memcached Custom Resource before update the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raise the issue "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, memcached); err != nil { - log.Error(err, "Failed to re-fetch memcached") - return ctrl.Result{}, err - } - - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeDegradedMemcached, - Status: metav1.ConditionTrue, Reason: "Finalizing", - Message: fmt.Sprintf("Finalizer operations for custom resource %s name were successfully accomplished", memcached.Name)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - log.Info("Removing Finalizer for Memcached after successfully perform the operations") - if ok := controllerutil.RemoveFinalizer(memcached, memcachedFinalizer); !ok { - log.Error(err, "Failed to remove finalizer for Memcached") - return ctrl.Result{Requeue: true}, nil - } - - if err := r.Update(ctx, memcached); err != nil { - log.Error(err, "Failed to remove finalizer for Memcached") - return ctrl.Result{}, err - } - } - return ctrl.Result{}, nil - } - - // Check if the deployment already exists, if not create a new one - found := &appsv1.Deployment{} - err = r.Get(ctx, types.NamespacedName{Name: memcached.Name, Namespace: memcached.Namespace}, found) - if err != nil && apierrors.IsNotFound(err) { - // Define a new deployment - dep, err := r.deploymentForMemcached(memcached) - if err != nil { - log.Error(err, "Failed to define new Deployment resource for Memcached") - - // The following implementation will update the status - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, - Status: metav1.ConditionFalse, Reason: "Reconciling", - Message: fmt.Sprintf("Failed to create Deployment for the custom resource (%s): (%s)", memcached.Name, err)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - log.Info("Creating a new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - if err = r.Create(ctx, dep); err != nil { - log.Error(err, "Failed to create new Deployment", - "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name) - return ctrl.Result{}, err - } - - // Deployment created successfully - // We will requeue the reconciliation so that we can ensure the state - // and move forward for the next operations - return ctrl.Result{RequeueAfter: time.Minute}, nil - } else if err != nil { - log.Error(err, "Failed to get Deployment") - // Let's return the error for the reconciliation be re-trigged again - return ctrl.Result{}, err - } - - // The CRD API is defining that the Memcached type, have a MemcachedSpec.Size field - // to set the quantity of Deployment instances is the desired state on the cluster. - // Therefore, the following code will ensure the Deployment size is the same as defined - // via the Size spec of the Custom Resource which we are reconciling. - size := memcached.Spec.Size - if *found.Spec.Replicas != size { - found.Spec.Replicas = &size - if err = r.Update(ctx, found); err != nil { - log.Error(err, "Failed to update Deployment", - "Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name) - - // Re-fetch the memcached Custom Resource before update the status - // so that we have the latest state of the resource on the cluster and we will avoid - // raise the issue "the object has been modified, please apply - // your changes to the latest version and try again" which would re-trigger the reconciliation - if err := r.Get(ctx, req.NamespacedName, memcached); err != nil { - log.Error(err, "Failed to re-fetch memcached") - return ctrl.Result{}, err - } - - // The following implementation will update the status - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, - Status: metav1.ConditionFalse, Reason: "Resizing", - Message: fmt.Sprintf("Failed to update the size for the custom resource (%s): (%s)", memcached.Name, err)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, err - } - - // Now, that we update the size we want to requeue the reconciliation - // so that we can ensure that we have the latest state of the resource before - // update. Also, it will help ensure the desired state on the cluster - return ctrl.Result{Requeue: true}, nil - } - - // The following implementation will update the status - meta.SetStatusCondition(&memcached.Status.Conditions, metav1.Condition{Type: typeAvailableMemcached, - Status: metav1.ConditionTrue, Reason: "Reconciling", - Message: fmt.Sprintf("Deployment for custom resource (%s) with %d replicas created successfully", memcached.Name, size)}) - - if err := r.Status().Update(ctx, memcached); err != nil { - log.Error(err, "Failed to update Memcached status") - return ctrl.Result{}, err - } - - return ctrl.Result{}, nil -} - -// finalizeMemcached will perform the required operations before delete the CR. -func (r *MemcachedReconciler) doFinalizerOperationsForMemcached(cr *examplecomv1alpha1.Memcached) { - // TODO(user): Add the cleanup steps that the operator - // needs to do before the CR can be deleted. Examples - // of finalizers include performing backups and deleting - // resources that are not owned by this CR, like a PVC. - - // Note: It is not recommended to use finalizers with the purpose of delete resources which are - // created and managed in the reconciliation. These ones, such as the Deployment created on this reconcile, - // are defined as depended of the custom resource. See that we use the method ctrl.SetControllerReference. - // to set the ownerRef which means that the Deployment will be deleted by the Kubernetes API. - // More info: https://kubernetes.io/docs/tasks/administer-cluster/use-cascading-deletion/ - - // The following implementation will raise an event - r.Recorder.Event(cr, "Warning", "Deleting", - fmt.Sprintf("Custom Resource %s is being deleted from the namespace %s", - cr.Name, - cr.Namespace)) -} - -// deploymentForMemcached returns a Memcached Deployment object -func (r *MemcachedReconciler) deploymentForMemcached( - memcached *examplecomv1alpha1.Memcached) (*appsv1.Deployment, error) { - ls := labelsForMemcached(memcached.Name) - replicas := memcached.Spec.Size - - // Get the Operand image - image, err := imageForMemcached() - if err != nil { - return nil, err - } - - dep := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: memcached.Name, - Namespace: memcached.Namespace, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: ls, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: ls, - }, - Spec: corev1.PodSpec{ - // TODO(user): Uncomment the following code to configure the nodeAffinity expression - // according to the platforms which are supported by your solution. It is considered - // best practice to support multiple architectures. build your manager image using the - // makefile target docker-buildx. Also, you can use docker manifest inspect - // to check what are the platforms supported. - // More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity - //Affinity: &corev1.Affinity{ - // NodeAffinity: &corev1.NodeAffinity{ - // RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ - // NodeSelectorTerms: []corev1.NodeSelectorTerm{ - // { - // MatchExpressions: []corev1.NodeSelectorRequirement{ - // { - // Key: "kubernetes.io/arch", - // Operator: "In", - // Values: []string{"amd64", "arm64", "ppc64le", "s390x"}, - // }, - // { - // Key: "kubernetes.io/os", - // Operator: "In", - // Values: []string{"linux"}, - // }, - // }, - // }, - // }, - // }, - // }, - //}, - SecurityContext: &corev1.PodSecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - // IMPORTANT: seccomProfile was introduced with Kubernetes 1.19 - // If you are looking for to produce solutions to be supported - // on lower versions you must remove this option. - SeccompProfile: &corev1.SeccompProfile{ - Type: corev1.SeccompProfileTypeRuntimeDefault, - }, - }, - Containers: []corev1.Container{{ - Image: image, - Name: "memcached", - ImagePullPolicy: corev1.PullIfNotPresent, - // Ensure restrictive context for the container - // More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted - SecurityContext: &corev1.SecurityContext{ - RunAsNonRoot: &[]bool{true}[0], - RunAsUser: &[]int64{1001}[0], - AllowPrivilegeEscalation: &[]bool{false}[0], - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{ - "ALL", - }, - }, - }, - Ports: []corev1.ContainerPort{{ - ContainerPort: memcached.Spec.ContainerPort, - Name: "memcached", - }}, - Command: []string{"memcached", "-m=64", "-o", "modern", "-v"}, - }}, - }, - }, - }, - } - - // Set the ownerRef for the Deployment - // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/ - if err := ctrl.SetControllerReference(memcached, dep, r.Scheme); err != nil { - return nil, err - } - return dep, nil -} - -// labelsForMemcached returns the labels for selecting the resources -// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/ -func labelsForMemcached(name string) map[string]string { - var imageTag string - image, err := imageForMemcached() - if err == nil { - imageTag = strings.Split(image, ":")[1] - } - return map[string]string{"app.kubernetes.io/name": "Memcached", - "app.kubernetes.io/instance": name, - "app.kubernetes.io/version": imageTag, - "app.kubernetes.io/part-of": "project-v4-multigroup", - "app.kubernetes.io/created-by": "controller-manager", - } -} - -// imageForMemcached gets the Operand image which is managed by this controller -// from the MEMCACHED_IMAGE environment variable defined in the config/manager/manager.yaml -func imageForMemcached() (string, error) { - var imageEnvVar = "MEMCACHED_IMAGE" - image, found := os.LookupEnv(imageEnvVar) - if !found { - return "", fmt.Errorf("Unable to find %s environment variable with the image", imageEnvVar) - } - return image, nil -} - -// SetupWithManager sets up the controller with the Manager. -// Note that the Deployment will be also watched in order to ensure its -// desirable state on the cluster -func (r *MemcachedReconciler) SetupWithManager(mgr ctrl.Manager) error { - return ctrl.NewControllerManagedBy(mgr). - For(&examplecomv1alpha1.Memcached{}). - Owns(&appsv1.Deployment{}). - Complete(r) -} diff --git a/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller_test.go b/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller_test.go deleted file mode 100644 index 920db20dd05..00000000000 --- a/testdata/project-v4-multigroup/internal/controller/example.com/memcached_controller_test.go +++ /dev/null @@ -1,154 +0,0 @@ -/* -Copyright 2023 The Kubernetes authors. - -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. -*/ - -package examplecom - -import ( - "context" - "fmt" - "os" - "time" - - //nolint:golint - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - examplecomv1alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/api/example.com/v1alpha1" -) - -var _ = Describe("Memcached controller", func() { - Context("Memcached controller test", func() { - - const MemcachedName = "test-memcached" - - ctx := context.Background() - - namespace := &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: MemcachedName, - Namespace: MemcachedName, - }, - } - - typeNamespaceName := types.NamespacedName{ - Name: MemcachedName, - Namespace: MemcachedName, - } - memcached := &examplecomv1alpha1.Memcached{} - - BeforeEach(func() { - By("Creating the Namespace to perform the tests") - err := k8sClient.Create(ctx, namespace) - Expect(err).To(Not(HaveOccurred())) - - By("Setting the Image ENV VAR which stores the Operand image") - err = os.Setenv("MEMCACHED_IMAGE", "example.com/image:test") - Expect(err).To(Not(HaveOccurred())) - - By("creating the custom resource for the Kind Memcached") - err = k8sClient.Get(ctx, typeNamespaceName, memcached) - if err != nil && errors.IsNotFound(err) { - // Let's mock our custom resource at the same way that we would - // apply on the cluster the manifest under config/samples - memcached := &examplecomv1alpha1.Memcached{ - ObjectMeta: metav1.ObjectMeta{ - Name: MemcachedName, - Namespace: namespace.Name, - }, - Spec: examplecomv1alpha1.MemcachedSpec{ - Size: 1, - ContainerPort: 11211, - }, - } - - err = k8sClient.Create(ctx, memcached) - Expect(err).To(Not(HaveOccurred())) - } - }) - - AfterEach(func() { - By("removing the custom resource for the Kind Memcached") - found := &examplecomv1alpha1.Memcached{} - err := k8sClient.Get(ctx, typeNamespaceName, found) - Expect(err).To(Not(HaveOccurred())) - - Eventually(func() error { - return k8sClient.Delete(context.TODO(), found) - }, 2*time.Minute, time.Second).Should(Succeed()) - - // TODO(user): Attention if you improve this code by adding other context test you MUST - // be aware of the current delete namespace limitations. - // More info: https://book.kubebuilder.io/reference/envtest.html#testing-considerations - By("Deleting the Namespace to perform the tests") - _ = k8sClient.Delete(ctx, namespace) - - By("Removing the Image ENV VAR which stores the Operand image") - _ = os.Unsetenv("MEMCACHED_IMAGE") - }) - - It("should successfully reconcile a custom resource for Memcached", func() { - By("Checking if the custom resource was successfully created") - Eventually(func() error { - found := &examplecomv1alpha1.Memcached{} - return k8sClient.Get(ctx, typeNamespaceName, found) - }, time.Minute, time.Second).Should(Succeed()) - - By("Reconciling the custom resource created") - memcachedReconciler := &MemcachedReconciler{ - Client: k8sClient, - Scheme: k8sClient.Scheme(), - } - - _, err := memcachedReconciler.Reconcile(ctx, reconcile.Request{ - NamespacedName: typeNamespaceName, - }) - Expect(err).To(Not(HaveOccurred())) - - By("Checking if Deployment was successfully created in the reconciliation") - Eventually(func() error { - found := &appsv1.Deployment{} - return k8sClient.Get(ctx, typeNamespaceName, found) - }, time.Minute, time.Second).Should(Succeed()) - - By("Checking the latest Status Condition added to the Memcached instance") - Eventually(func() error { - if memcached.Status.Conditions != nil && - len(memcached.Status.Conditions) != 0 { - latestStatusCondition := memcached.Status.Conditions[len(memcached.Status.Conditions)-1] - expectedLatestStatusCondition := metav1.Condition{ - Type: typeAvailableMemcached, - Status: metav1.ConditionTrue, - Reason: "Reconciling", - Message: fmt.Sprintf( - "Deployment for custom resource (%s) with %d replicas created successfully", - memcached.Name, - memcached.Spec.Size), - } - if latestStatusCondition != expectedLatestStatusCondition { - return fmt.Errorf("The latest status condition added to the Memcached instance is not as expected") - } - } - return nil - }, time.Minute, time.Second).Should(Succeed()) - }) - }) -})