diff --git a/cmd/main.go b/cmd/main.go index bf8411c0659..8ec543b7759 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -25,6 +25,7 @@ import ( cfgv2 "sigs.k8s.io/kubebuilder/v3/pkg/config/v2" cfgv3 "sigs.k8s.io/kubebuilder/v3/pkg/config/v3" "sigs.k8s.io/kubebuilder/v3/pkg/machinery" + "sigs.k8s.io/kubebuilder/v3/pkg/model/stage" "sigs.k8s.io/kubebuilder/v3/pkg/plugin" kustomizecommonv1 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v1" kustomizecommonv2 "sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2" @@ -41,6 +42,11 @@ func main() { kustomizecommonv1.Plugin{}, golangv3.Plugin{}, ) + // / Bundle plugin which built the golang projects scaffold by Kubebuilder go/v4 + gov4Bundle, _ := plugin.NewBundle(golang.DefaultNameQualifier, plugin.Version{Number: 4, Stage: stage.Alpha}, + kustomizecommonv2.Plugin{}, + golangv3.Plugin{}, + ) fs := machinery.Filesystem{ FS: afero.NewOsFs(), @@ -57,6 +63,7 @@ func main() { golangv2.Plugin{}, golangv3.Plugin{}, gov3Bundle, + gov4Bundle, &kustomizecommonv1.Plugin{}, &kustomizecommonv2.Plugin{}, &declarativev1.Plugin{}, diff --git a/test/e2e/v3/generate_test.go b/test/e2e/v3/generate_test.go index 02bcea9123d..615554aa10f 100644 --- a/test/e2e/v3/generate_test.go +++ b/test/e2e/v3/generate_test.go @@ -398,3 +398,101 @@ Count int `+"`"+`json:"count,omitempty"`+"`"+` # create: true`, "#")).To(Succeed()) } + +// GenerateV4 implements a go/v4(-alpha) plugin project defined by a TestContext. +func GenerateV4(kbc *utils.TestContext, crdAndWebhookVersion string) { + var err error + + By("initializing a project") + err = kbc.Init( + "--plugins", "go/v4-alpha", + "--project-version", "3", + "--domain", kbc.Domain, + "--fetch-deps=false", + ) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("creating API definition") + err = kbc.CreateAPI( + "--group", kbc.Group, + "--version", kbc.Version, + "--kind", kbc.Kind, + "--namespaced", + "--resource", + "--controller", + "--make=false", + "--crd-version", crdAndWebhookVersion, + ) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("implementing the API") + ExpectWithOffset(1, pluginutil.InsertCode( + filepath.Join(kbc.Dir, "api", kbc.Version, fmt.Sprintf("%s_types.go", strings.ToLower(kbc.Kind))), + fmt.Sprintf(`type %sSpec struct { +`, kbc.Kind), + ` // +optional +Count int `+"`"+`json:"count,omitempty"`+"`"+` +`)).Should(Succeed()) + + By("scaffolding mutating and validating webhooks") + err = kbc.CreateWebhook( + "--group", kbc.Group, + "--version", kbc.Version, + "--kind", kbc.Kind, + "--defaulting", + "--programmatic-validation", + "--webhook-version", crdAndWebhookVersion, + ) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("implementing the mutating and validating webhooks") + err = pluginutil.ImplementWebhooks(filepath.Join( + kbc.Dir, "api", kbc.Version, + fmt.Sprintf("%s_webhook.go", strings.ToLower(kbc.Kind)))) + ExpectWithOffset(1, err).NotTo(HaveOccurred()) + + By("uncomment kustomization.yaml to enable webhook and ca injection") + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- ../webhook", "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- ../certmanager", "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- ../prometheus", "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- manager_webhook_patch.yaml", "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- webhookcainjection_patch.yaml", "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode(filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + `#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +# fieldref: +# fieldpath: metadata.namespace +#- name: CERTIFICATE_NAME +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +#- name: SERVICE_NAMESPACE # namespace of the service +# objref: +# kind: Service +# version: v1 +# name: webhook-service +# fieldref: +# fieldpath: metadata.namespace +#- name: SERVICE_NAME +# objref: +# kind: Service +# version: v1 +# name: webhook-service`, "#")).To(Succeed()) + +} diff --git a/test/e2e/v3/plugin_cluster_test.go b/test/e2e/v3/plugin_cluster_test.go index 5b7ed63ed3a..6424187739f 100644 --- a/test/e2e/v3/plugin_cluster_test.go +++ b/test/e2e/v3/plugin_cluster_test.go @@ -136,6 +136,28 @@ var _ = Describe("kubebuilder", func() { Run(kbc) }) }) + + Context("plugin base.go.kubebuilder.io/v4-alpha", func() { + // Use cert-manager with v1 CRs. + BeforeEach(func() { + By("installing the cert-manager bundle") + Expect(kbc.InstallCertManager(false)).To(Succeed()) + }) + AfterEach(func() { + By("uninstalling the cert-manager bundle") + kbc.UninstallCertManager(false) + }) + + It("should generate a runnable project", func() { + // Skip if cluster version < 1.16, when v1 CRDs and webhooks did not exist. + if srvVer := kbc.K8sVersion.ServerVersion; srvVer.GetMajorInt() <= 1 && srvVer.GetMinorInt() < 17 { + Skip(fmt.Sprintf("cluster version %s does not support v1 CRDs or webhooks", srvVer.GitVersion)) + } + + GenerateV4(kbc, "v1") + Run(kbc) + }) + }) }) }) diff --git a/test/testdata/generate.sh b/test/testdata/generate.sh index 3885f4597ba..ba4e97cd90b 100755 --- a/test/testdata/generate.sh +++ b/test/testdata/generate.sh @@ -45,7 +45,7 @@ function scaffold_test_project { header_text "Initializing project ..." $kb init $init_flags --domain testproject.org --license apache2 --owner "The Kubernetes authors" - if [ $project == "project-v2" ] || [ $project == "project-v3" ] || [ $project == "project-v3-config" ] || [ $project == "project-v3-with-kustomize-v2" ]; then + if [ $project == "project-v2" ] || [ $project == "project-v3" ] || [ $project == "project-v3-config" ] || [ $project == "project-v3-with-kustomize-v2" ] || [ $project == "project-v4" ] || [ $project == "project-v4-config" ]; then header_text 'Creating APIs ...' $kb create api --group crew --version v1 --kind Captain --controller=true --resource=true --make=false $kb create api --group crew --version v1 --kind Captain --controller=true --resource=true --make=false --force @@ -61,7 +61,7 @@ function scaffold_test_project { fi $kb create webhook --group crew --version v1 --kind FirstMate --conversion - if [ $project == "project-v3" ]; then + if [ $project == "project-v3" ] || [ $project == "project-v4" ]; then $kb create api --group crew --version v1 --kind Admiral --plural=admirales --controller=true --resource=true --namespaced=false --make=false $kb create webhook --group crew --version v1 --kind Admiral --plural=admirales --defaulting else @@ -94,11 +94,11 @@ function scaffold_test_project { $kb create api --group foo.policy --version v1 --kind HealthCheckPolicy --controller=true --resource=true --make=false $kb create api --group apps --version v1 --kind Deployment --controller=true --resource=false --make=false - + $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" ]; then + if [ $project == "project-v3-multigroup" ] || [ $project == "project-v4-multigroup" ]; 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 @@ -132,3 +132,8 @@ scaffold_test_project project-v3-addon --plugins="go/v3,declarative" scaffold_test_project project-v3-config --component-config scaffold_test_project project-v3-v1beta1 scaffold_test_project project-v3-with-kustomize-v2 --plugins="kustomize/v2-alpha,base.go.kubebuilder.io/v3" +# Project version 4 (default) uses plugin go/v4 (default). +scaffold_test_project project-v4 +scaffold_test_project project-v4-multigroup +scaffold_test_project project-v4-addon --plugins="go/v4-alpha,declarative" +scaffold_test_project project-v4-config --component-config diff --git a/testdata/project-v4-addon/.dockerignore b/testdata/project-v4-addon/.dockerignore new file mode 100644 index 00000000000..0f046820f18 --- /dev/null +++ b/testdata/project-v4-addon/.dockerignore @@ -0,0 +1,4 @@ +# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Ignore build and test binaries. +bin/ +testbin/ diff --git a/testdata/project-v4-addon/.gitignore b/testdata/project-v4-addon/.gitignore new file mode 100644 index 00000000000..d97ffc5159b --- /dev/null +++ b/testdata/project-v4-addon/.gitignore @@ -0,0 +1,24 @@ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin + +# 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 +*.swp +*.swo +*~ diff --git a/testdata/project-v4-addon/Dockerfile b/testdata/project-v4-addon/Dockerfile new file mode 100644 index 00000000000..3a486ab6e30 --- /dev/null +++ b/testdata/project-v4-addon/Dockerfile @@ -0,0 +1,34 @@ +# Build the manager binary +FROM golang:1.17 as builder + +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 main.go main.go +COPY api/ api/ +COPY controllers/ controllers/ +# https://github.com/kubernetes-sigs/kubebuilder-declarative-pattern/blob/master/docs/addon/walkthrough/README.md#adding-a-manifest +# Stage channels and make readable +COPY channels/ /channels/ +RUN chmod -R a+rx /channels/ + +# Build +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager 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 . +# copy channels +COPY --from=builder /channels /channels + +USER 65532:65532 + +ENTRYPOINT ["/manager"] diff --git a/testdata/project-v4-addon/Makefile b/testdata/project-v4-addon/Makefile new file mode 100644 index 00000000000..4c98e81e111 --- /dev/null +++ b/testdata/project-v4-addon/Makefile @@ -0,0 +1,133 @@ + +# 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.23 + +# 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 + +# Setting SHELL to bash allows bash commands to be executed by recipes. +# This is a requirement for 'setup-envtest.sh' in the test target. +# 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 commands 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) -p path)" go test ./... -coverprofile cover.out + +##@ Build + +.PHONY: build +build: generate fmt vet ## Build manager binary. + go build -o bin/manager main.go + +.PHONY: run +run: manifests generate fmt vet ## Run a controller from your host. + go run ./main.go + +.PHONY: docker-build +docker-build: test ## Build docker image with the manager. + docker build -t ${IMG} . + +.PHONY: docker-push +docker-push: ## Push docker image with the manager. + docker push ${IMG} + +##@ 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 +KUSTOMIZE ?= $(LOCALBIN)/kustomize +CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen +ENVTEST ?= $(LOCALBIN)/setup-envtest + +## Tool Versions +KUSTOMIZE_VERSION ?= v3.8.7 +CONTROLLER_TOOLS_VERSION ?= v0.8.0 + +KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" +.PHONY: kustomize +kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. +$(KUSTOMIZE): $(LOCALBIN) + curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN) + +.PHONY: controller-gen +controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. +$(CONTROLLER_GEN): $(LOCALBIN) + 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) + GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest diff --git a/testdata/project-v4-addon/PROJECT b/testdata/project-v4-addon/PROJECT new file mode 100644 index 00000000000..0de0fb999c1 --- /dev/null +++ b/testdata/project-v4-addon/PROJECT @@ -0,0 +1,49 @@ +domain: testproject.org +layout: +- go.kubebuilder.io/v4-alpha +- declarative.go.kubebuilder.io/v1 +plugins: + declarative.go.kubebuilder.io/v1: + resources: + - domain: testproject.org + group: crew + kind: Captain + version: v1 + - domain: testproject.org + group: crew + kind: FirstMate + version: v1 + - domain: testproject.org + group: crew + kind: Admiral + version: v1 +projectName: project-v4-addon +repo: sigs.k8s.io/kubebuilder/testdata/project-v4-addon +resources: +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: crew + kind: Captain + path: sigs.k8s.io/kubebuilder/testdata/project-v4-addon/api/v1 + version: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: crew + kind: FirstMate + path: sigs.k8s.io/kubebuilder/testdata/project-v4-addon/api/v1 + version: v1 +- api: + crdVersion: v1 + controller: true + domain: testproject.org + group: crew + kind: Admiral + path: sigs.k8s.io/kubebuilder/testdata/project-v4-addon/api/v1 + version: v1 +version: "3" diff --git a/testdata/project-v4-addon/README.md b/testdata/project-v4-addon/README.md new file mode 100644 index 00000000000..5074c565eea --- /dev/null +++ b/testdata/project-v4-addon/README.md @@ -0,0 +1,94 @@ +# project-v4-addon +// TODO(user): Add simple overview of use/purpose + +## Description +// TODO(user): An in-depth paragraph about your project and overview of use + +## Getting Started +You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster. +**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows). + +### Running on the cluster +1. Install Instances of Custom Resources: + +```sh +kubectl apply -f config/samples/ +``` + +2. Build and push your image to the location specified by `IMG`: + +```sh +make docker-build docker-push IMG=/project-v4-addon:tag +``` + +3. Deploy the controller to the cluster with the image specified by `IMG`: + +```sh +make deploy IMG=/project-v4-addon:tag +``` + +### Uninstall CRDs +To delete the CRDs from the cluster: + +```sh +make uninstall +``` + +### Undeploy controller +UnDeploy the controller to 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 provides a reconcile function responsible for synchronizing resources untile 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 2022 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-addon/api/v1/admiral_types.go b/testdata/project-v4-addon/api/v1/admiral_types.go new file mode 100644 index 00000000000..027432be46a --- /dev/null +++ b/testdata/project-v4-addon/api/v1/admiral_types.go @@ -0,0 +1,90 @@ +/* +Copyright 2022 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" + addonv1alpha1 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/apis/v1alpha1" +) + +// 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. + +// AdmiralSpec defines the desired state of Admiral +type AdmiralSpec struct { + addonv1alpha1.CommonSpec `json:",inline"` + addonv1alpha1.PatchSpec `json:",inline"` + + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// AdmiralStatus defines the observed state of Admiral +type AdmiralStatus struct { + addonv1alpha1.CommonStatus `json:",inline"` + + // 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 + +// Admiral is the Schema for the admirals API +type Admiral struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AdmiralSpec `json:"spec,omitempty"` + Status AdmiralStatus `json:"status,omitempty"` +} + +var _ addonv1alpha1.CommonObject = &Admiral{} + +func (o *Admiral) ComponentName() string { + return "admiral" +} + +func (o *Admiral) CommonSpec() addonv1alpha1.CommonSpec { + return o.Spec.CommonSpec +} + +func (o *Admiral) PatchSpec() addonv1alpha1.PatchSpec { + return o.Spec.PatchSpec +} + +func (o *Admiral) GetCommonStatus() addonv1alpha1.CommonStatus { + return o.Status.CommonStatus +} + +func (o *Admiral) SetCommonStatus(s addonv1alpha1.CommonStatus) { + o.Status.CommonStatus = s +} + +//+kubebuilder:object:root=true + +// AdmiralList contains a list of Admiral +type AdmiralList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Admiral `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Admiral{}, &AdmiralList{}) +} diff --git a/testdata/project-v4-addon/api/v1/captain_types.go b/testdata/project-v4-addon/api/v1/captain_types.go new file mode 100644 index 00000000000..b4bea01a9fb --- /dev/null +++ b/testdata/project-v4-addon/api/v1/captain_types.go @@ -0,0 +1,89 @@ +/* +Copyright 2022 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" + addonv1alpha1 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/apis/v1alpha1" +) + +// 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 { + addonv1alpha1.CommonSpec `json:",inline"` + addonv1alpha1.PatchSpec `json:",inline"` + + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// CaptainStatus defines the observed state of Captain +type CaptainStatus struct { + addonv1alpha1.CommonStatus `json:",inline"` + + // 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"` +} + +var _ addonv1alpha1.CommonObject = &Captain{} + +func (o *Captain) ComponentName() string { + return "captain" +} + +func (o *Captain) CommonSpec() addonv1alpha1.CommonSpec { + return o.Spec.CommonSpec +} + +func (o *Captain) PatchSpec() addonv1alpha1.PatchSpec { + return o.Spec.PatchSpec +} + +func (o *Captain) GetCommonStatus() addonv1alpha1.CommonStatus { + return o.Status.CommonStatus +} + +func (o *Captain) SetCommonStatus(s addonv1alpha1.CommonStatus) { + o.Status.CommonStatus = s +} + +//+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-addon/api/v1/firstmate_types.go b/testdata/project-v4-addon/api/v1/firstmate_types.go new file mode 100644 index 00000000000..12f64ad0697 --- /dev/null +++ b/testdata/project-v4-addon/api/v1/firstmate_types.go @@ -0,0 +1,89 @@ +/* +Copyright 2022 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" + addonv1alpha1 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/apis/v1alpha1" +) + +// 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. + +// FirstMateSpec defines the desired state of FirstMate +type FirstMateSpec struct { + addonv1alpha1.CommonSpec `json:",inline"` + addonv1alpha1.PatchSpec `json:",inline"` + + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// FirstMateStatus defines the observed state of FirstMate +type FirstMateStatus struct { + addonv1alpha1.CommonStatus `json:",inline"` + + // 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 + +// FirstMate is the Schema for the firstmates API +type FirstMate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec FirstMateSpec `json:"spec,omitempty"` + Status FirstMateStatus `json:"status,omitempty"` +} + +var _ addonv1alpha1.CommonObject = &FirstMate{} + +func (o *FirstMate) ComponentName() string { + return "firstmate" +} + +func (o *FirstMate) CommonSpec() addonv1alpha1.CommonSpec { + return o.Spec.CommonSpec +} + +func (o *FirstMate) PatchSpec() addonv1alpha1.PatchSpec { + return o.Spec.PatchSpec +} + +func (o *FirstMate) GetCommonStatus() addonv1alpha1.CommonStatus { + return o.Status.CommonStatus +} + +func (o *FirstMate) SetCommonStatus(s addonv1alpha1.CommonStatus) { + o.Status.CommonStatus = s +} + +//+kubebuilder:object:root=true + +// FirstMateList contains a list of FirstMate +type FirstMateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []FirstMate `json:"items"` +} + +func init() { + SchemeBuilder.Register(&FirstMate{}, &FirstMateList{}) +} diff --git a/testdata/project-v4-addon/api/v1/groupversion_info.go b/testdata/project-v4-addon/api/v1/groupversion_info.go new file mode 100644 index 00000000000..33458c7506e --- /dev/null +++ b/testdata/project-v4-addon/api/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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 crew v1 API group +//+kubebuilder:object:generate=true +//+groupName=crew.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: "crew.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-addon/api/v1/zz_generated.deepcopy.go b/testdata/project-v4-addon/api/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..d7d62dbdb1c --- /dev/null +++ b/testdata/project-v4-addon/api/v1/zz_generated.deepcopy.go @@ -0,0 +1,302 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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 *Admiral) DeepCopyInto(out *Admiral) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Admiral. +func (in *Admiral) DeepCopy() *Admiral { + if in == nil { + return nil + } + out := new(Admiral) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Admiral) 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 *AdmiralList) DeepCopyInto(out *AdmiralList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Admiral, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralList. +func (in *AdmiralList) DeepCopy() *AdmiralList { + if in == nil { + return nil + } + out := new(AdmiralList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AdmiralList) 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 *AdmiralSpec) DeepCopyInto(out *AdmiralSpec) { + *out = *in + out.CommonSpec = in.CommonSpec + in.PatchSpec.DeepCopyInto(&out.PatchSpec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralSpec. +func (in *AdmiralSpec) DeepCopy() *AdmiralSpec { + if in == nil { + return nil + } + out := new(AdmiralSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AdmiralStatus) DeepCopyInto(out *AdmiralStatus) { + *out = *in + in.CommonStatus.DeepCopyInto(&out.CommonStatus) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralStatus. +func (in *AdmiralStatus) DeepCopy() *AdmiralStatus { + if in == nil { + return nil + } + out := new(AdmiralStatus) + in.DeepCopyInto(out) + return out +} + +// 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) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.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 + out.CommonSpec = in.CommonSpec + in.PatchSpec.DeepCopyInto(&out.PatchSpec) +} + +// 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 + in.CommonStatus.DeepCopyInto(&out.CommonStatus) +} + +// 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 +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FirstMate) DeepCopyInto(out *FirstMate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMate. +func (in *FirstMate) DeepCopy() *FirstMate { + if in == nil { + return nil + } + out := new(FirstMate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FirstMate) 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 *FirstMateList) DeepCopyInto(out *FirstMateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]FirstMate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateList. +func (in *FirstMateList) DeepCopy() *FirstMateList { + if in == nil { + return nil + } + out := new(FirstMateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FirstMateList) 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 *FirstMateSpec) DeepCopyInto(out *FirstMateSpec) { + *out = *in + out.CommonSpec = in.CommonSpec + in.PatchSpec.DeepCopyInto(&out.PatchSpec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateSpec. +func (in *FirstMateSpec) DeepCopy() *FirstMateSpec { + if in == nil { + return nil + } + out := new(FirstMateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FirstMateStatus) DeepCopyInto(out *FirstMateStatus) { + *out = *in + in.CommonStatus.DeepCopyInto(&out.CommonStatus) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateStatus. +func (in *FirstMateStatus) DeepCopy() *FirstMateStatus { + if in == nil { + return nil + } + out := new(FirstMateStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-addon/channels/packages/admiral/0.0.1/manifest.yaml b/testdata/project-v4-addon/channels/packages/admiral/0.0.1/manifest.yaml new file mode 100644 index 00000000000..af9a253c582 --- /dev/null +++ b/testdata/project-v4-addon/channels/packages/admiral/0.0.1/manifest.yaml @@ -0,0 +1 @@ +# Placeholder manifest - replace with the manifest for your addon diff --git a/testdata/project-v4-addon/channels/packages/captain/0.0.1/manifest.yaml b/testdata/project-v4-addon/channels/packages/captain/0.0.1/manifest.yaml new file mode 100644 index 00000000000..af9a253c582 --- /dev/null +++ b/testdata/project-v4-addon/channels/packages/captain/0.0.1/manifest.yaml @@ -0,0 +1 @@ +# Placeholder manifest - replace with the manifest for your addon diff --git a/testdata/project-v4-addon/channels/packages/firstmate/0.0.1/manifest.yaml b/testdata/project-v4-addon/channels/packages/firstmate/0.0.1/manifest.yaml new file mode 100644 index 00000000000..af9a253c582 --- /dev/null +++ b/testdata/project-v4-addon/channels/packages/firstmate/0.0.1/manifest.yaml @@ -0,0 +1 @@ +# Placeholder manifest - replace with the manifest for your addon diff --git a/testdata/project-v4-addon/channels/stable b/testdata/project-v4-addon/channels/stable new file mode 100644 index 00000000000..31216a4aca9 --- /dev/null +++ b/testdata/project-v4-addon/channels/stable @@ -0,0 +1,3 @@ +# Versions for the stable channel +manifests: +- version: 0.0.1 diff --git a/testdata/project-v4-addon/config/crd/bases/crew.testproject.org_admirals.yaml b/testdata/project-v4-addon/config/crd/bases/crew.testproject.org_admirals.yaml new file mode 100644 index 00000000000..8953264ea89 --- /dev/null +++ b/testdata/project-v4-addon/config/crd/bases/crew.testproject.org_admirals.yaml @@ -0,0 +1,75 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + name: admirals.crew.testproject.org +spec: + group: crew.testproject.org + names: + kind: Admiral + listKind: AdmiralList + plural: admirals + singular: admiral + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Admiral is the Schema for the admirals 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: AdmiralSpec defines the desired state of Admiral + properties: + channel: + description: 'Channel specifies a channel that can be used to resolve + a specific addon, eg: stable It will be ignored if Version is specified' + type: string + patches: + items: + type: object + type: array + version: + description: Version specifies the exact addon version to be deployed, + eg 1.2.3 It should not be specified if Channel is specified + type: string + type: object + status: + description: AdmiralStatus defines the observed state of Admiral + properties: + errors: + items: + type: string + type: array + healthy: + type: boolean + phase: + type: string + required: + - healthy + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-addon/config/crd/bases/crew.testproject.org_captains.yaml b/testdata/project-v4-addon/config/crd/bases/crew.testproject.org_captains.yaml new file mode 100644 index 00000000000..b7c8d92c6b8 --- /dev/null +++ b/testdata/project-v4-addon/config/crd/bases/crew.testproject.org_captains.yaml @@ -0,0 +1,75 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: + channel: + description: 'Channel specifies a channel that can be used to resolve + a specific addon, eg: stable It will be ignored if Version is specified' + type: string + patches: + items: + type: object + type: array + version: + description: Version specifies the exact addon version to be deployed, + eg 1.2.3 It should not be specified if Channel is specified + type: string + type: object + status: + description: CaptainStatus defines the observed state of Captain + properties: + errors: + items: + type: string + type: array + healthy: + type: boolean + phase: + type: string + required: + - healthy + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-addon/config/crd/bases/crew.testproject.org_firstmates.yaml b/testdata/project-v4-addon/config/crd/bases/crew.testproject.org_firstmates.yaml new file mode 100644 index 00000000000..566f27bcd47 --- /dev/null +++ b/testdata/project-v4-addon/config/crd/bases/crew.testproject.org_firstmates.yaml @@ -0,0 +1,75 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + name: firstmates.crew.testproject.org +spec: + group: crew.testproject.org + names: + kind: FirstMate + listKind: FirstMateList + plural: firstmates + singular: firstmate + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: FirstMate is the Schema for the firstmates 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: FirstMateSpec defines the desired state of FirstMate + properties: + channel: + description: 'Channel specifies a channel that can be used to resolve + a specific addon, eg: stable It will be ignored if Version is specified' + type: string + patches: + items: + type: object + type: array + version: + description: Version specifies the exact addon version to be deployed, + eg 1.2.3 It should not be specified if Channel is specified + type: string + type: object + status: + description: FirstMateStatus defines the observed state of FirstMate + properties: + errors: + items: + type: string + type: array + healthy: + type: boolean + phase: + type: string + required: + - healthy + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-addon/config/crd/kustomization.yaml b/testdata/project-v4-addon/config/crd/kustomization.yaml new file mode 100644 index 00000000000..37c36ffdebd --- /dev/null +++ b/testdata/project-v4-addon/config/crd/kustomization.yaml @@ -0,0 +1,27 @@ +# 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/crew.testproject.org_firstmates.yaml +- bases/crew.testproject.org_admirals.yaml +#+kubebuilder:scaffold:crdkustomizeresource + +patchesStrategicMerge: +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. +# patches here are for enabling the conversion webhook for each CRD +#- patches/webhook_in_captains.yaml +#- patches/webhook_in_firstmates.yaml +#- patches/webhook_in_admirals.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 +#- patches/cainjection_in_captains.yaml +#- patches/cainjection_in_firstmates.yaml +#- patches/cainjection_in_admirals.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-addon/config/crd/kustomizeconfig.yaml b/testdata/project-v4-addon/config/crd/kustomizeconfig.yaml new file mode 100644 index 00000000000..ec5c150a9df --- /dev/null +++ b/testdata/project-v4-addon/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-addon/config/crd/patches/cainjection_in_admirals.yaml b/testdata/project-v4-addon/config/crd/patches/cainjection_in_admirals.yaml new file mode 100644 index 00000000000..ba7fea6e88d --- /dev/null +++ b/testdata/project-v4-addon/config/crd/patches/cainjection_in_admirals.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: admirals.crew.testproject.org diff --git a/testdata/project-v4-addon/config/crd/patches/cainjection_in_captains.yaml b/testdata/project-v4-addon/config/crd/patches/cainjection_in_captains.yaml new file mode 100644 index 00000000000..9c9d61b0c97 --- /dev/null +++ b/testdata/project-v4-addon/config/crd/patches/cainjection_in_captains.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: captains.crew.testproject.org diff --git a/testdata/project-v4-addon/config/crd/patches/cainjection_in_firstmates.yaml b/testdata/project-v4-addon/config/crd/patches/cainjection_in_firstmates.yaml new file mode 100644 index 00000000000..6849f00fb85 --- /dev/null +++ b/testdata/project-v4-addon/config/crd/patches/cainjection_in_firstmates.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: firstmates.crew.testproject.org diff --git a/testdata/project-v4-addon/config/crd/patches/webhook_in_admirals.yaml b/testdata/project-v4-addon/config/crd/patches/webhook_in_admirals.yaml new file mode 100644 index 00000000000..0ce2808578a --- /dev/null +++ b/testdata/project-v4-addon/config/crd/patches/webhook_in_admirals.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: admirals.crew.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-addon/config/crd/patches/webhook_in_captains.yaml b/testdata/project-v4-addon/config/crd/patches/webhook_in_captains.yaml new file mode 100644 index 00000000000..f73ae2e8abc --- /dev/null +++ b/testdata/project-v4-addon/config/crd/patches/webhook_in_captains.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: captains.crew.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-addon/config/crd/patches/webhook_in_firstmates.yaml b/testdata/project-v4-addon/config/crd/patches/webhook_in_firstmates.yaml new file mode 100644 index 00000000000..76ee5acedbd --- /dev/null +++ b/testdata/project-v4-addon/config/crd/patches/webhook_in_firstmates.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: firstmates.crew.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-addon/config/default/kustomization.yaml b/testdata/project-v4-addon/config/default/kustomization.yaml new file mode 100644 index 00000000000..11a41e9edd6 --- /dev/null +++ b/testdata/project-v4-addon/config/default/kustomization.yaml @@ -0,0 +1,144 @@ +# Adds namespace to all resources. +namespace: project-v4-addon-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-addon- + +# Labels to add to all resources and selectors. +#commonLabels: +# someName: someValue + +bases: +- ../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 + +# Mount the controller config file for loading manager configurations +# through a ComponentConfig type +#- manager_config_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-addon/config/default/manager_auth_proxy_patch.yaml b/testdata/project-v4-addon/config/default/manager_auth_proxy_patch.yaml new file mode 100644 index 00000000000..131a3142928 --- /dev/null +++ b/testdata/project-v4-addon/config/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,34 @@ +# 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 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0 + 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-addon/config/default/manager_config_patch.yaml b/testdata/project-v4-addon/config/default/manager_config_patch.yaml new file mode 100644 index 00000000000..6c400155cfb --- /dev/null +++ b/testdata/project-v4-addon/config/default/manager_config_patch.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + args: + - "--config=controller_manager_config.yaml" + volumeMounts: + - name: manager-config + mountPath: /controller_manager_config.yaml + subPath: controller_manager_config.yaml + volumes: + - name: manager-config + configMap: + name: manager-config diff --git a/testdata/project-v4-addon/config/manager/controller_manager_config.yaml b/testdata/project-v4-addon/config/manager/controller_manager_config.yaml new file mode 100644 index 00000000000..46dc3a07ddf --- /dev/null +++ b/testdata/project-v4-addon/config/manager/controller_manager_config.yaml @@ -0,0 +1,11 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +health: + healthProbeBindAddress: :8081 +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: fda80751.testproject.org diff --git a/testdata/project-v4-addon/config/manager/kustomization.yaml b/testdata/project-v4-addon/config/manager/kustomization.yaml new file mode 100644 index 00000000000..2bcd3eeaa94 --- /dev/null +++ b/testdata/project-v4-addon/config/manager/kustomization.yaml @@ -0,0 +1,10 @@ +resources: +- manager.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: +- name: manager-config + files: + - controller_manager_config.yaml diff --git a/testdata/project-v4-addon/config/manager/manager.yaml b/testdata/project-v4-addon/config/manager/manager.yaml new file mode 100644 index 00000000000..cf11cecc26a --- /dev/null +++ b/testdata/project-v4-addon/config/manager/manager.yaml @@ -0,0 +1,60 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager +spec: + selector: + matchLabels: + control-plane: controller-manager + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + securityContext: + runAsNonRoot: true + containers: + - command: + - /manager + args: + - --leader-elect + image: controller:latest + name: manager + securityContext: + allowPrivilegeEscalation: false + 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-addon/config/prometheus/kustomization.yaml b/testdata/project-v4-addon/config/prometheus/kustomization.yaml new file mode 100644 index 00000000000..ed137168a1d --- /dev/null +++ b/testdata/project-v4-addon/config/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/testdata/project-v4-addon/config/prometheus/monitor.yaml b/testdata/project-v4-addon/config/prometheus/monitor.yaml new file mode 100644 index 00000000000..d19136ae710 --- /dev/null +++ b/testdata/project-v4-addon/config/prometheus/monitor.yaml @@ -0,0 +1,20 @@ + +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: controller-manager + 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-addon/config/rbac/admiral_editor_role.yaml b/testdata/project-v4-addon/config/rbac/admiral_editor_role.yaml new file mode 100644 index 00000000000..7f2cc5cd99f --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/admiral_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit admirals. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: admiral-editor-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirals + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - admirals/status + verbs: + - get diff --git a/testdata/project-v4-addon/config/rbac/admiral_viewer_role.yaml b/testdata/project-v4-addon/config/rbac/admiral_viewer_role.yaml new file mode 100644 index 00000000000..ddbb0c2a85b --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/admiral_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view admirals. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: admiral-viewer-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirals + verbs: + - get + - list + - watch +- apiGroups: + - crew.testproject.org + resources: + - admirals/status + verbs: + - get diff --git a/testdata/project-v4-addon/config/rbac/auth_proxy_client_clusterrole.yaml b/testdata/project-v4-addon/config/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 00000000000..51a75db47a5 --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/auth_proxy_client_clusterrole.yaml @@ -0,0 +1,9 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/testdata/project-v4-addon/config/rbac/auth_proxy_role.yaml b/testdata/project-v4-addon/config/rbac/auth_proxy_role.yaml new file mode 100644 index 00000000000..80e1857c594 --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/auth_proxy_role.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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-addon/config/rbac/auth_proxy_role_binding.yaml b/testdata/project-v4-addon/config/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 00000000000..ec7acc0a1b7 --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/auth_proxy_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + 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-addon/config/rbac/auth_proxy_service.yaml b/testdata/project-v4-addon/config/rbac/auth_proxy_service.yaml new file mode 100644 index 00000000000..71f1797279e --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/auth_proxy_service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + 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-addon/config/rbac/captain_editor_role.yaml b/testdata/project-v4-addon/config/rbac/captain_editor_role.yaml new file mode 100644 index 00000000000..4b53ae38ffa --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/captain_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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-addon/config/rbac/captain_viewer_role.yaml b/testdata/project-v4-addon/config/rbac/captain_viewer_role.yaml new file mode 100644 index 00000000000..f19e10439d2 --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/captain_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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-addon/config/rbac/firstmate_editor_role.yaml b/testdata/project-v4-addon/config/rbac/firstmate_editor_role.yaml new file mode 100644 index 00000000000..22a08be29dd --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/firstmate_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit firstmates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: firstmate-editor-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - firstmates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - firstmates/status + verbs: + - get diff --git a/testdata/project-v4-addon/config/rbac/firstmate_viewer_role.yaml b/testdata/project-v4-addon/config/rbac/firstmate_viewer_role.yaml new file mode 100644 index 00000000000..9fd6ba933c7 --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/firstmate_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view firstmates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: firstmate-viewer-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - firstmates + verbs: + - get + - list + - watch +- apiGroups: + - crew.testproject.org + resources: + - firstmates/status + verbs: + - get diff --git a/testdata/project-v4-addon/config/rbac/kustomization.yaml b/testdata/project-v4-addon/config/rbac/kustomization.yaml new file mode 100644 index 00000000000..731832a6ac3 --- /dev/null +++ b/testdata/project-v4-addon/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-addon/config/rbac/leader_election_role.yaml b/testdata/project-v4-addon/config/rbac/leader_election_role.yaml new file mode 100644 index 00000000000..4190ec8059e --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/leader_election_role.yaml @@ -0,0 +1,37 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + 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-addon/config/rbac/leader_election_role_binding.yaml b/testdata/project-v4-addon/config/rbac/leader_election_role_binding.yaml new file mode 100644 index 00000000000..1d1321ed4f0 --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/leader_election_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + 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-addon/config/rbac/role.yaml b/testdata/project-v4-addon/config/rbac/role.yaml new file mode 100644 index 00000000000..2ea68d8593b --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/role.yaml @@ -0,0 +1,67 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: manager-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirals + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - admirals/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/status + verbs: + - get + - patch + - update +- apiGroups: + - crew.testproject.org + resources: + - firstmates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - firstmates/status + verbs: + - get + - patch + - update diff --git a/testdata/project-v4-addon/config/rbac/role_binding.yaml b/testdata/project-v4-addon/config/rbac/role_binding.yaml new file mode 100644 index 00000000000..2070ede4462 --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + 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-addon/config/rbac/service_account.yaml b/testdata/project-v4-addon/config/rbac/service_account.yaml new file mode 100644 index 00000000000..7cd6025bfc4 --- /dev/null +++ b/testdata/project-v4-addon/config/rbac/service_account.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: controller-manager + namespace: system diff --git a/testdata/project-v4-addon/config/samples/crew_v1_admiral.yaml b/testdata/project-v4-addon/config/samples/crew_v1_admiral.yaml new file mode 100644 index 00000000000..588448f7801 --- /dev/null +++ b/testdata/project-v4-addon/config/samples/crew_v1_admiral.yaml @@ -0,0 +1,6 @@ +apiVersion: crew.testproject.org/v1 +kind: Admiral +metadata: + name: admiral-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-addon/config/samples/crew_v1_captain.yaml b/testdata/project-v4-addon/config/samples/crew_v1_captain.yaml new file mode 100644 index 00000000000..d0dcfc6cb4d --- /dev/null +++ b/testdata/project-v4-addon/config/samples/crew_v1_captain.yaml @@ -0,0 +1,6 @@ +apiVersion: crew.testproject.org/v1 +kind: Captain +metadata: + name: captain-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-addon/config/samples/crew_v1_firstmate.yaml b/testdata/project-v4-addon/config/samples/crew_v1_firstmate.yaml new file mode 100644 index 00000000000..61749572695 --- /dev/null +++ b/testdata/project-v4-addon/config/samples/crew_v1_firstmate.yaml @@ -0,0 +1,6 @@ +apiVersion: crew.testproject.org/v1 +kind: FirstMate +metadata: + name: firstmate-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-addon/controllers/admiral_controller.go b/testdata/project-v4-addon/controllers/admiral_controller.go new file mode 100644 index 00000000000..6b8031a2785 --- /dev/null +++ b/testdata/project-v4-addon/controllers/admiral_controller.go @@ -0,0 +1,89 @@ +/* +Copyright 2022 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 controllers + +import ( + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon" + "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/status" + "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-addon/api/v1" +) + +var _ reconcile.Reconciler = &AdmiralReconciler{} + +// AdmiralReconciler reconciles a Admiral object +type AdmiralReconciler struct { + client.Client + Log logr.Logger + Scheme *runtime.Scheme + + declarative.Reconciler +} + +//+kubebuilder:rbac:groups=crew.testproject.org,resources=admirals,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=crew.testproject.org,resources=admirals/status,verbs=get;update;patch + +// SetupWithManager sets up the controller with the Manager. +func (r *AdmiralReconciler) SetupWithManager(mgr ctrl.Manager) error { + addon.Init() + + labels := map[string]string{ + "k8s-app": "admiral", + } + + watchLabels := declarative.SourceLabel(mgr.GetScheme()) + + if err := r.Reconciler.Init(mgr, &crewv1.Admiral{}, + declarative.WithObjectTransform(declarative.AddLabels(labels)), + declarative.WithOwner(declarative.SourceAsOwner), + declarative.WithLabels(watchLabels), + declarative.WithStatus(status.NewBasic(mgr.GetClient())), + // TODO: add an application to your manifest: declarative.WithObjectTransform(addon.TransformApplicationFromStatus), + // TODO: add an application to your manifest: declarative.WithManagedApplication(watchLabels), + declarative.WithObjectTransform(addon.ApplyPatches), + ); err != nil { + return err + } + + c, err := controller.New("admiral-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to Admiral + err = c.Watch(&source.Kind{Type: &crewv1.Admiral{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // Watch for changes to deployed objects + _, err = declarative.WatchAll(mgr.GetConfig(), c, r, watchLabels) + if err != nil { + return err + } + + return nil +} diff --git a/testdata/project-v4-addon/controllers/captain_controller.go b/testdata/project-v4-addon/controllers/captain_controller.go new file mode 100644 index 00000000000..00c15a28715 --- /dev/null +++ b/testdata/project-v4-addon/controllers/captain_controller.go @@ -0,0 +1,89 @@ +/* +Copyright 2022 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 controllers + +import ( + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon" + "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/status" + "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-addon/api/v1" +) + +var _ reconcile.Reconciler = &CaptainReconciler{} + +// CaptainReconciler reconciles a Captain object +type CaptainReconciler struct { + client.Client + Log logr.Logger + Scheme *runtime.Scheme + + declarative.Reconciler +} + +//+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 + +// SetupWithManager sets up the controller with the Manager. +func (r *CaptainReconciler) SetupWithManager(mgr ctrl.Manager) error { + addon.Init() + + labels := map[string]string{ + "k8s-app": "captain", + } + + watchLabels := declarative.SourceLabel(mgr.GetScheme()) + + if err := r.Reconciler.Init(mgr, &crewv1.Captain{}, + declarative.WithObjectTransform(declarative.AddLabels(labels)), + declarative.WithOwner(declarative.SourceAsOwner), + declarative.WithLabels(watchLabels), + declarative.WithStatus(status.NewBasic(mgr.GetClient())), + // TODO: add an application to your manifest: declarative.WithObjectTransform(addon.TransformApplicationFromStatus), + // TODO: add an application to your manifest: declarative.WithManagedApplication(watchLabels), + declarative.WithObjectTransform(addon.ApplyPatches), + ); err != nil { + return err + } + + c, err := controller.New("captain-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to Captain + err = c.Watch(&source.Kind{Type: &crewv1.Captain{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // Watch for changes to deployed objects + _, err = declarative.WatchAll(mgr.GetConfig(), c, r, watchLabels) + if err != nil { + return err + } + + return nil +} diff --git a/testdata/project-v4-addon/controllers/firstmate_controller.go b/testdata/project-v4-addon/controllers/firstmate_controller.go new file mode 100644 index 00000000000..c8976d17a50 --- /dev/null +++ b/testdata/project-v4-addon/controllers/firstmate_controller.go @@ -0,0 +1,89 @@ +/* +Copyright 2022 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 controllers + +import ( + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon" + "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/status" + "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-addon/api/v1" +) + +var _ reconcile.Reconciler = &FirstMateReconciler{} + +// FirstMateReconciler reconciles a FirstMate object +type FirstMateReconciler struct { + client.Client + Log logr.Logger + Scheme *runtime.Scheme + + declarative.Reconciler +} + +//+kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates/status,verbs=get;update;patch + +// SetupWithManager sets up the controller with the Manager. +func (r *FirstMateReconciler) SetupWithManager(mgr ctrl.Manager) error { + addon.Init() + + labels := map[string]string{ + "k8s-app": "firstmate", + } + + watchLabels := declarative.SourceLabel(mgr.GetScheme()) + + if err := r.Reconciler.Init(mgr, &crewv1.FirstMate{}, + declarative.WithObjectTransform(declarative.AddLabels(labels)), + declarative.WithOwner(declarative.SourceAsOwner), + declarative.WithLabels(watchLabels), + declarative.WithStatus(status.NewBasic(mgr.GetClient())), + // TODO: add an application to your manifest: declarative.WithObjectTransform(addon.TransformApplicationFromStatus), + // TODO: add an application to your manifest: declarative.WithManagedApplication(watchLabels), + declarative.WithObjectTransform(addon.ApplyPatches), + ); err != nil { + return err + } + + c, err := controller.New("firstmate-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to FirstMate + err = c.Watch(&source.Kind{Type: &crewv1.FirstMate{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // Watch for changes to deployed objects + _, err = declarative.WatchAll(mgr.GetConfig(), c, r, watchLabels) + if err != nil { + return err + } + + return nil +} diff --git a/testdata/project-v4-addon/controllers/suite_test.go b/testdata/project-v4-addon/controllers/suite_test.go new file mode 100644 index 00000000000..abded9f2c6e --- /dev/null +++ b/testdata/project-v4-addon/controllers/suite_test.go @@ -0,0 +1,82 @@ +/* +Copyright 2022 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 controllers + +import ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-addon/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 TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = crewv1.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()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-addon/go.mod b/testdata/project-v4-addon/go.mod new file mode 100644 index 00000000000..f4c88a68249 --- /dev/null +++ b/testdata/project-v4-addon/go.mod @@ -0,0 +1,122 @@ +module sigs.k8s.io/kubebuilder/testdata/project-v4-addon + +go 1.17 + +require ( + github.com/go-logr/logr v1.2.0 + github.com/onsi/ginkgo v1.16.5 + github.com/onsi/gomega v1.17.0 + k8s.io/apimachinery v0.23.5 + k8s.io/client-go v0.23.5 + sigs.k8s.io/controller-runtime v0.11.2 + sigs.k8s.io/kubebuilder-declarative-pattern v0.11.20220513-0.20220425225139-d0f104b6a96e +) + +require ( + cloud.google.com/go v0.81.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.18 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emirpasic/gods v1.12.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.1.0 // indirect + github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect + github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/fvbommel/sortorder v1.0.1 // indirect + github.com/go-errors/errors v1.0.1 // indirect + github.com/go-git/gcfg v1.5.0 // indirect + github.com/go-git/go-billy/v5 v5.0.0 // indirect + github.com/go-git/go-git/v5 v5.1.0 // indirect + github.com/go-logr/zapr v1.2.0 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.19.5 // indirect + github.com/go-openapi/swag v0.19.14 // 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.2 // indirect + github.com/google/btree v1.0.1 // indirect + github.com/google/go-cmp v0.5.6 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/google/uuid v1.2.0 // indirect + github.com/googleapis/gnostic v0.5.5 // indirect + github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jonboulle/clockwork v0.2.2 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd // indirect + github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/mailru/easyjson v0.7.6 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.0 // indirect + github.com/moby/spdystream v0.2.0 // indirect + github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/nxadm/tail v1.4.8 // indirect + github.com/peterbourgon/diskv v2.0.1+incompatible // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.11.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.28.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect + github.com/russross/blackfriday v1.5.2 // indirect + github.com/sergi/go-diff v1.1.0 // indirect + github.com/spf13/cobra v1.2.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/testify v1.7.0 // indirect + github.com/xanzy/ssh-agent v0.2.1 // indirect + github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect + go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.19.1 // indirect + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect + golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect + golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect + golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + k8s.io/api v0.23.5 // indirect + k8s.io/apiextensions-apiserver v0.23.5 // indirect + k8s.io/cli-runtime v0.23.0 // indirect + k8s.io/component-base v0.23.5 // indirect + k8s.io/klog/v2 v2.30.0 // indirect + k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect + k8s.io/kubectl v0.22.2 // indirect + k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect + sigs.k8s.io/cli-utils v0.26.1 // indirect + sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect + sigs.k8s.io/kustomize/api v0.10.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.13.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/testdata/project-v4-addon/hack/boilerplate.go.txt b/testdata/project-v4-addon/hack/boilerplate.go.txt new file mode 100644 index 00000000000..b54e305f300 --- /dev/null +++ b/testdata/project-v4-addon/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +Copyright 2022 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-addon/main.go b/testdata/project-v4-addon/main.go new file mode 100644 index 00000000000..050bcbc2020 --- /dev/null +++ b/testdata/project-v4-addon/main.go @@ -0,0 +1,129 @@ +/* +Copyright 2022 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" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-addon/api/v1" + "sigs.k8s.io/kubebuilder/testdata/project-v4-addon/controllers" + //+kubebuilder:scaffold:imports +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + + utilruntime.Must(crewv1.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, + MetricsBindAddress: metricsAddr, + Port: 9443, + HealthProbeBindAddress: probeAddr, + LeaderElection: enableLeaderElection, + LeaderElectionID: "fda80751.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 = (&controllers.CaptainReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Captain") + os.Exit(1) + } + if err = (&controllers.FirstMateReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "FirstMate") + os.Exit(1) + } + if err = (&controllers.AdmiralReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Admiral") + 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-config/.dockerignore b/testdata/project-v4-config/.dockerignore new file mode 100644 index 00000000000..0f046820f18 --- /dev/null +++ b/testdata/project-v4-config/.dockerignore @@ -0,0 +1,4 @@ +# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Ignore build and test binaries. +bin/ +testbin/ diff --git a/testdata/project-v4-config/.gitignore b/testdata/project-v4-config/.gitignore new file mode 100644 index 00000000000..c0a7a54cac5 --- /dev/null +++ b/testdata/project-v4-config/.gitignore @@ -0,0 +1,25 @@ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin +testbin/* + +# 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 +*.swp +*.swo +*~ diff --git a/testdata/project-v4-config/Dockerfile b/testdata/project-v4-config/Dockerfile new file mode 100644 index 00000000000..456533d4c2d --- /dev/null +++ b/testdata/project-v4-config/Dockerfile @@ -0,0 +1,27 @@ +# Build the manager binary +FROM golang:1.17 as builder + +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 main.go main.go +COPY api/ api/ +COPY controllers/ controllers/ + +# Build +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager 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-config/Makefile b/testdata/project-v4-config/Makefile new file mode 100644 index 00000000000..4c98e81e111 --- /dev/null +++ b/testdata/project-v4-config/Makefile @@ -0,0 +1,133 @@ + +# 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.23 + +# 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 + +# Setting SHELL to bash allows bash commands to be executed by recipes. +# This is a requirement for 'setup-envtest.sh' in the test target. +# 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 commands 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) -p path)" go test ./... -coverprofile cover.out + +##@ Build + +.PHONY: build +build: generate fmt vet ## Build manager binary. + go build -o bin/manager main.go + +.PHONY: run +run: manifests generate fmt vet ## Run a controller from your host. + go run ./main.go + +.PHONY: docker-build +docker-build: test ## Build docker image with the manager. + docker build -t ${IMG} . + +.PHONY: docker-push +docker-push: ## Push docker image with the manager. + docker push ${IMG} + +##@ 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 +KUSTOMIZE ?= $(LOCALBIN)/kustomize +CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen +ENVTEST ?= $(LOCALBIN)/setup-envtest + +## Tool Versions +KUSTOMIZE_VERSION ?= v3.8.7 +CONTROLLER_TOOLS_VERSION ?= v0.8.0 + +KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" +.PHONY: kustomize +kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. +$(KUSTOMIZE): $(LOCALBIN) + curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN) + +.PHONY: controller-gen +controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. +$(CONTROLLER_GEN): $(LOCALBIN) + 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) + GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest diff --git a/testdata/project-v4-config/PROJECT b/testdata/project-v4-config/PROJECT new file mode 100644 index 00000000000..1e889ebe056 --- /dev/null +++ b/testdata/project-v4-config/PROJECT @@ -0,0 +1,49 @@ +componentConfig: true +domain: testproject.org +layout: +- go.kubebuilder.io/v3 +projectName: project-v4-config +repo: sigs.k8s.io/kubebuilder/testdata/project-v4-config +resources: +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: crew + kind: Captain + path: sigs.k8s.io/kubebuilder/testdata/project-v4-config/api/v1 + version: v1 + webhooks: + defaulting: true + validation: true + webhookVersion: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: crew + kind: FirstMate + path: sigs.k8s.io/kubebuilder/testdata/project-v4-config/api/v1 + version: v1 + webhooks: + conversion: true + webhookVersion: v1 +- api: + crdVersion: v1 + controller: true + domain: testproject.org + group: crew + kind: Admiral + path: sigs.k8s.io/kubebuilder/testdata/project-v4-config/api/v1 + version: v1 + webhooks: + defaulting: true + webhookVersion: v1 +- controller: true + domain: testproject.org + group: crew + kind: Laker + version: v1 +version: "3" diff --git a/testdata/project-v4-config/README.md b/testdata/project-v4-config/README.md new file mode 100644 index 00000000000..d9f81b9eec5 --- /dev/null +++ b/testdata/project-v4-config/README.md @@ -0,0 +1,94 @@ +# project-v4-config +// TODO(user): Add simple overview of use/purpose + +## Description +// TODO(user): An in-depth paragraph about your project and overview of use + +## Getting Started +You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster. +**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows). + +### Running on the cluster +1. Install Instances of Custom Resources: + +```sh +kubectl apply -f config/samples/ +``` + +2. Build and push your image to the location specified by `IMG`: + +```sh +make docker-build docker-push IMG=/project-v4-config:tag +``` + +3. Deploy the controller to the cluster with the image specified by `IMG`: + +```sh +make deploy IMG=/project-v4-config:tag +``` + +### Uninstall CRDs +To delete the CRDs from the cluster: + +```sh +make uninstall +``` + +### Undeploy controller +UnDeploy the controller to 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 provides a reconcile function responsible for synchronizing resources untile 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 2022 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-config/api/v1/admiral_types.go b/testdata/project-v4-config/api/v1/admiral_types.go new file mode 100644 index 00000000000..55d2b767089 --- /dev/null +++ b/testdata/project-v4-config/api/v1/admiral_types.go @@ -0,0 +1,65 @@ +/* +Copyright 2022 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. + +// AdmiralSpec defines the desired state of Admiral +type AdmiralSpec 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 Admiral. Edit admiral_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// AdmiralStatus defines the observed state of Admiral +type AdmiralStatus 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 + +// Admiral is the Schema for the admirals API +type Admiral struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AdmiralSpec `json:"spec,omitempty"` + Status AdmiralStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// AdmiralList contains a list of Admiral +type AdmiralList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Admiral `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Admiral{}, &AdmiralList{}) +} diff --git a/testdata/project-v4-config/api/v1/admiral_webhook.go b/testdata/project-v4-config/api/v1/admiral_webhook.go new file mode 100644 index 00000000000..52fbc5ce79f --- /dev/null +++ b/testdata/project-v4-config/api/v1/admiral_webhook.go @@ -0,0 +1,45 @@ +/* +Copyright 2022 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 admirallog = logf.Log.WithName("admiral-resource") + +func (r *Admiral) 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-admiral,mutating=true,failurePolicy=fail,sideEffects=None,groups=crew.testproject.org,resources=admirals,verbs=create;update,versions=v1,name=madmiral.kb.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &Admiral{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *Admiral) Default() { + admirallog.Info("default", "name", r.Name) + + // TODO(user): fill in your defaulting logic. +} diff --git a/testdata/project-v4-config/api/v1/captain_types.go b/testdata/project-v4-config/api/v1/captain_types.go new file mode 100644 index 00000000000..e81debb719c --- /dev/null +++ b/testdata/project-v4-config/api/v1/captain_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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-config/api/v1/captain_webhook.go b/testdata/project-v4-config/api/v1/captain_webhook.go new file mode 100644 index 00000000000..ba00000c137 --- /dev/null +++ b/testdata/project-v4-config/api/v1/captain_webhook.go @@ -0,0 +1,75 @@ +/* +Copyright 2022 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" +) + +// log is for logging in this package. +var captainlog = logf.Log.WithName("captain-resource") + +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() error { + captainlog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Captain) ValidateUpdate(old runtime.Object) error { + captainlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Captain) ValidateDelete() error { + captainlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil +} diff --git a/testdata/project-v4-config/api/v1/firstmate_types.go b/testdata/project-v4-config/api/v1/firstmate_types.go new file mode 100644 index 00000000000..7515759833a --- /dev/null +++ b/testdata/project-v4-config/api/v1/firstmate_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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. + +// FirstMateSpec defines the desired state of FirstMate +type FirstMateSpec 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 FirstMate. Edit firstmate_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// FirstMateStatus defines the observed state of FirstMate +type FirstMateStatus 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 + +// FirstMate is the Schema for the firstmates API +type FirstMate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec FirstMateSpec `json:"spec,omitempty"` + Status FirstMateStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// FirstMateList contains a list of FirstMate +type FirstMateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []FirstMate `json:"items"` +} + +func init() { + SchemeBuilder.Register(&FirstMate{}, &FirstMateList{}) +} diff --git a/testdata/project-v4-config/api/v1/firstmate_webhook.go b/testdata/project-v4-config/api/v1/firstmate_webhook.go new file mode 100644 index 00000000000..5fa6046165d --- /dev/null +++ b/testdata/project-v4-config/api/v1/firstmate_webhook.go @@ -0,0 +1,33 @@ +/* +Copyright 2022 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" +) + +// log is for logging in this package. +var firstmatelog = logf.Log.WithName("firstmate-resource") + +func (r *FirstMate) 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-config/api/v1/groupversion_info.go b/testdata/project-v4-config/api/v1/groupversion_info.go new file mode 100644 index 00000000000..33458c7506e --- /dev/null +++ b/testdata/project-v4-config/api/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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 crew v1 API group +//+kubebuilder:object:generate=true +//+groupName=crew.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: "crew.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-config/api/v1/webhook_suite_test.go b/testdata/project-v4-config/api/v1/webhook_suite_test.go new file mode 100644 index 00000000000..2c1a26807e7 --- /dev/null +++ b/testdata/project-v4-config/api/v1/webhook_suite_test.go @@ -0,0 +1,138 @@ +/* +Copyright 2022 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" + "testing" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + //+kubebuilder:scaffold:imports + "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// 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) + + RunSpecsWithDefaultAndCustomReporters(t, + "Webhook Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + 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 := runtime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1beta1.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, + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + MetricsBindAddress: "0", + }) + Expect(err).NotTo(HaveOccurred()) + + err = (&Captain{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + err = (&Admiral{}).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 + } + conn.Close() + return nil + }).Should(Succeed()) + +}, 60) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-config/api/v1/zz_generated.deepcopy.go b/testdata/project-v4-config/api/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..eb076ea05ea --- /dev/null +++ b/testdata/project-v4-config/api/v1/zz_generated.deepcopy.go @@ -0,0 +1,293 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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 *Admiral) DeepCopyInto(out *Admiral) { + *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 Admiral. +func (in *Admiral) DeepCopy() *Admiral { + if in == nil { + return nil + } + out := new(Admiral) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Admiral) 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 *AdmiralList) DeepCopyInto(out *AdmiralList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Admiral, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralList. +func (in *AdmiralList) DeepCopy() *AdmiralList { + if in == nil { + return nil + } + out := new(AdmiralList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AdmiralList) 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 *AdmiralSpec) DeepCopyInto(out *AdmiralSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralSpec. +func (in *AdmiralSpec) DeepCopy() *AdmiralSpec { + if in == nil { + return nil + } + out := new(AdmiralSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AdmiralStatus) DeepCopyInto(out *AdmiralStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralStatus. +func (in *AdmiralStatus) DeepCopy() *AdmiralStatus { + if in == nil { + return nil + } + out := new(AdmiralStatus) + in.DeepCopyInto(out) + return out +} + +// 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 +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FirstMate) DeepCopyInto(out *FirstMate) { + *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 FirstMate. +func (in *FirstMate) DeepCopy() *FirstMate { + if in == nil { + return nil + } + out := new(FirstMate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FirstMate) 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 *FirstMateList) DeepCopyInto(out *FirstMateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]FirstMate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateList. +func (in *FirstMateList) DeepCopy() *FirstMateList { + if in == nil { + return nil + } + out := new(FirstMateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FirstMateList) 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 *FirstMateSpec) DeepCopyInto(out *FirstMateSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateSpec. +func (in *FirstMateSpec) DeepCopy() *FirstMateSpec { + if in == nil { + return nil + } + out := new(FirstMateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FirstMateStatus) DeepCopyInto(out *FirstMateStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateStatus. +func (in *FirstMateStatus) DeepCopy() *FirstMateStatus { + if in == nil { + return nil + } + out := new(FirstMateStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4-config/config/certmanager/certificate.yaml b/testdata/project-v4-config/config/certmanager/certificate.yaml new file mode 100644 index 00000000000..52d866183c7 --- /dev/null +++ b/testdata/project-v4-config/config/certmanager/certificate.yaml @@ -0,0 +1,25 @@ +# 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: + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + 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-config/config/certmanager/kustomization.yaml b/testdata/project-v4-config/config/certmanager/kustomization.yaml new file mode 100644 index 00000000000..bebea5a595e --- /dev/null +++ b/testdata/project-v4-config/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- certificate.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/testdata/project-v4-config/config/certmanager/kustomizeconfig.yaml b/testdata/project-v4-config/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 00000000000..90d7c313ca1 --- /dev/null +++ b/testdata/project-v4-config/config/certmanager/kustomizeconfig.yaml @@ -0,0 +1,16 @@ +# This configuration is for teaching kustomize how to update name ref and var substitution +nameReference: +- kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name + +varReference: +- kind: Certificate + group: cert-manager.io + path: spec/commonName +- kind: Certificate + group: cert-manager.io + path: spec/dnsNames diff --git a/testdata/project-v4-config/config/crd/bases/crew.testproject.org_admirals.yaml b/testdata/project-v4-config/config/crd/bases/crew.testproject.org_admirals.yaml new file mode 100644 index 00000000000..5b617849067 --- /dev/null +++ b/testdata/project-v4-config/config/crd/bases/crew.testproject.org_admirals.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + name: admirals.crew.testproject.org +spec: + group: crew.testproject.org + names: + kind: Admiral + listKind: AdmiralList + plural: admirals + singular: admiral + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Admiral is the Schema for the admirals 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: AdmiralSpec defines the desired state of Admiral + properties: + foo: + description: Foo is an example field of Admiral. Edit admiral_types.go + to remove/update + type: string + type: object + status: + description: AdmiralStatus defines the observed state of Admiral + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-config/config/crd/bases/crew.testproject.org_captains.yaml b/testdata/project-v4-config/config/crd/bases/crew.testproject.org_captains.yaml new file mode 100644 index 00000000000..41b080622f6 --- /dev/null +++ b/testdata/project-v4-config/config/crd/bases/crew.testproject.org_captains.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-config/config/crd/bases/crew.testproject.org_firstmates.yaml b/testdata/project-v4-config/config/crd/bases/crew.testproject.org_firstmates.yaml new file mode 100644 index 00000000000..5ccecbc8eb8 --- /dev/null +++ b/testdata/project-v4-config/config/crd/bases/crew.testproject.org_firstmates.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + name: firstmates.crew.testproject.org +spec: + group: crew.testproject.org + names: + kind: FirstMate + listKind: FirstMateList + plural: firstmates + singular: firstmate + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: FirstMate is the Schema for the firstmates 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: FirstMateSpec defines the desired state of FirstMate + properties: + foo: + description: Foo is an example field of FirstMate. Edit firstmate_types.go + to remove/update + type: string + type: object + status: + description: FirstMateStatus defines the observed state of FirstMate + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-config/config/crd/kustomization.yaml b/testdata/project-v4-config/config/crd/kustomization.yaml new file mode 100644 index 00000000000..37c36ffdebd --- /dev/null +++ b/testdata/project-v4-config/config/crd/kustomization.yaml @@ -0,0 +1,27 @@ +# 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/crew.testproject.org_firstmates.yaml +- bases/crew.testproject.org_admirals.yaml +#+kubebuilder:scaffold:crdkustomizeresource + +patchesStrategicMerge: +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. +# patches here are for enabling the conversion webhook for each CRD +#- patches/webhook_in_captains.yaml +#- patches/webhook_in_firstmates.yaml +#- patches/webhook_in_admirals.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 +#- patches/cainjection_in_captains.yaml +#- patches/cainjection_in_firstmates.yaml +#- patches/cainjection_in_admirals.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-config/config/crd/kustomizeconfig.yaml b/testdata/project-v4-config/config/crd/kustomizeconfig.yaml new file mode 100644 index 00000000000..ec5c150a9df --- /dev/null +++ b/testdata/project-v4-config/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-config/config/crd/patches/cainjection_in_admirals.yaml b/testdata/project-v4-config/config/crd/patches/cainjection_in_admirals.yaml new file mode 100644 index 00000000000..ba7fea6e88d --- /dev/null +++ b/testdata/project-v4-config/config/crd/patches/cainjection_in_admirals.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: admirals.crew.testproject.org diff --git a/testdata/project-v4-config/config/crd/patches/cainjection_in_captains.yaml b/testdata/project-v4-config/config/crd/patches/cainjection_in_captains.yaml new file mode 100644 index 00000000000..9c9d61b0c97 --- /dev/null +++ b/testdata/project-v4-config/config/crd/patches/cainjection_in_captains.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: captains.crew.testproject.org diff --git a/testdata/project-v4-config/config/crd/patches/cainjection_in_firstmates.yaml b/testdata/project-v4-config/config/crd/patches/cainjection_in_firstmates.yaml new file mode 100644 index 00000000000..6849f00fb85 --- /dev/null +++ b/testdata/project-v4-config/config/crd/patches/cainjection_in_firstmates.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: firstmates.crew.testproject.org diff --git a/testdata/project-v4-config/config/crd/patches/webhook_in_admirals.yaml b/testdata/project-v4-config/config/crd/patches/webhook_in_admirals.yaml new file mode 100644 index 00000000000..0ce2808578a --- /dev/null +++ b/testdata/project-v4-config/config/crd/patches/webhook_in_admirals.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: admirals.crew.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-config/config/crd/patches/webhook_in_captains.yaml b/testdata/project-v4-config/config/crd/patches/webhook_in_captains.yaml new file mode 100644 index 00000000000..f73ae2e8abc --- /dev/null +++ b/testdata/project-v4-config/config/crd/patches/webhook_in_captains.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: captains.crew.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-config/config/crd/patches/webhook_in_firstmates.yaml b/testdata/project-v4-config/config/crd/patches/webhook_in_firstmates.yaml new file mode 100644 index 00000000000..76ee5acedbd --- /dev/null +++ b/testdata/project-v4-config/config/crd/patches/webhook_in_firstmates.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: firstmates.crew.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4-config/config/default/kustomization.yaml b/testdata/project-v4-config/config/default/kustomization.yaml new file mode 100644 index 00000000000..1471ea3fabe --- /dev/null +++ b/testdata/project-v4-config/config/default/kustomization.yaml @@ -0,0 +1,74 @@ +# Adds namespace to all resources. +namespace: project-v4-config-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-config- + +# Labels to add to all resources and selectors. +#commonLabels: +# someName: someValue + +bases: +- ../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 + +# Mount the controller config file for loading manager configurations +# through a ComponentConfig type +- manager_config_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 + +# the following config is for teaching kustomize how to do var substitution +vars: +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +# fieldref: +# fieldpath: metadata.namespace +#- name: CERTIFICATE_NAME +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +#- name: SERVICE_NAMESPACE # namespace of the service +# objref: +# kind: Service +# version: v1 +# name: webhook-service +# fieldref: +# fieldpath: metadata.namespace +#- name: SERVICE_NAME +# objref: +# kind: Service +# version: v1 +# name: webhook-service diff --git a/testdata/project-v4-config/config/default/manager_auth_proxy_patch.yaml b/testdata/project-v4-config/config/default/manager_auth_proxy_patch.yaml new file mode 100644 index 00000000000..e2c4e233765 --- /dev/null +++ b/testdata/project-v4-config/config/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,29 @@ +# 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 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0 + 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 diff --git a/testdata/project-v4-config/config/default/manager_config_patch.yaml b/testdata/project-v4-config/config/default/manager_config_patch.yaml new file mode 100644 index 00000000000..6c400155cfb --- /dev/null +++ b/testdata/project-v4-config/config/default/manager_config_patch.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + args: + - "--config=controller_manager_config.yaml" + volumeMounts: + - name: manager-config + mountPath: /controller_manager_config.yaml + subPath: controller_manager_config.yaml + volumes: + - name: manager-config + configMap: + name: manager-config diff --git a/testdata/project-v4-config/config/default/manager_webhook_patch.yaml b/testdata/project-v4-config/config/default/manager_webhook_patch.yaml new file mode 100644 index 00000000000..738de350b71 --- /dev/null +++ b/testdata/project-v4-config/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-config/config/default/webhookcainjection_patch.yaml b/testdata/project-v4-config/config/default/webhookcainjection_patch.yaml new file mode 100644 index 00000000000..02ab515d428 --- /dev/null +++ b/testdata/project-v4-config/config/default/webhookcainjection_patch.yaml @@ -0,0 +1,15 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/testdata/project-v4-config/config/manager/controller_manager_config.yaml b/testdata/project-v4-config/config/manager/controller_manager_config.yaml new file mode 100644 index 00000000000..43e39ca38f1 --- /dev/null +++ b/testdata/project-v4-config/config/manager/controller_manager_config.yaml @@ -0,0 +1,21 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +health: + healthProbeBindAddress: :8081 +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: 89f7a333.testproject.org +# leaderElectionReleaseOnCancel defines if the leader should step down volume +# 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 diff --git a/testdata/project-v4-config/config/manager/kustomization.yaml b/testdata/project-v4-config/config/manager/kustomization.yaml new file mode 100644 index 00000000000..2bcd3eeaa94 --- /dev/null +++ b/testdata/project-v4-config/config/manager/kustomization.yaml @@ -0,0 +1,10 @@ +resources: +- manager.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: +- name: manager-config + files: + - controller_manager_config.yaml diff --git a/testdata/project-v4-config/config/manager/manager.yaml b/testdata/project-v4-config/config/manager/manager.yaml new file mode 100644 index 00000000000..8af96e4bddf --- /dev/null +++ b/testdata/project-v4-config/config/manager/manager.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager +spec: + selector: + matchLabels: + control-plane: controller-manager + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + securityContext: + runAsNonRoot: true + containers: + - command: + - /manager + image: controller:latest + name: manager + securityContext: + allowPrivilegeEscalation: false + 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-config/config/prometheus/kustomization.yaml b/testdata/project-v4-config/config/prometheus/kustomization.yaml new file mode 100644 index 00000000000..ed137168a1d --- /dev/null +++ b/testdata/project-v4-config/config/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/testdata/project-v4-config/config/prometheus/monitor.yaml b/testdata/project-v4-config/config/prometheus/monitor.yaml new file mode 100644 index 00000000000..d19136ae710 --- /dev/null +++ b/testdata/project-v4-config/config/prometheus/monitor.yaml @@ -0,0 +1,20 @@ + +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: controller-manager + 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-config/config/rbac/admiral_editor_role.yaml b/testdata/project-v4-config/config/rbac/admiral_editor_role.yaml new file mode 100644 index 00000000000..7f2cc5cd99f --- /dev/null +++ b/testdata/project-v4-config/config/rbac/admiral_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit admirals. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: admiral-editor-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirals + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - admirals/status + verbs: + - get diff --git a/testdata/project-v4-config/config/rbac/admiral_viewer_role.yaml b/testdata/project-v4-config/config/rbac/admiral_viewer_role.yaml new file mode 100644 index 00000000000..ddbb0c2a85b --- /dev/null +++ b/testdata/project-v4-config/config/rbac/admiral_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view admirals. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: admiral-viewer-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirals + verbs: + - get + - list + - watch +- apiGroups: + - crew.testproject.org + resources: + - admirals/status + verbs: + - get diff --git a/testdata/project-v4-config/config/rbac/auth_proxy_client_clusterrole.yaml b/testdata/project-v4-config/config/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 00000000000..51a75db47a5 --- /dev/null +++ b/testdata/project-v4-config/config/rbac/auth_proxy_client_clusterrole.yaml @@ -0,0 +1,9 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/testdata/project-v4-config/config/rbac/auth_proxy_role.yaml b/testdata/project-v4-config/config/rbac/auth_proxy_role.yaml new file mode 100644 index 00000000000..80e1857c594 --- /dev/null +++ b/testdata/project-v4-config/config/rbac/auth_proxy_role.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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-config/config/rbac/auth_proxy_role_binding.yaml b/testdata/project-v4-config/config/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 00000000000..ec7acc0a1b7 --- /dev/null +++ b/testdata/project-v4-config/config/rbac/auth_proxy_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + 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-config/config/rbac/auth_proxy_service.yaml b/testdata/project-v4-config/config/rbac/auth_proxy_service.yaml new file mode 100644 index 00000000000..71f1797279e --- /dev/null +++ b/testdata/project-v4-config/config/rbac/auth_proxy_service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + 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-config/config/rbac/captain_editor_role.yaml b/testdata/project-v4-config/config/rbac/captain_editor_role.yaml new file mode 100644 index 00000000000..4b53ae38ffa --- /dev/null +++ b/testdata/project-v4-config/config/rbac/captain_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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-config/config/rbac/captain_viewer_role.yaml b/testdata/project-v4-config/config/rbac/captain_viewer_role.yaml new file mode 100644 index 00000000000..f19e10439d2 --- /dev/null +++ b/testdata/project-v4-config/config/rbac/captain_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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-config/config/rbac/firstmate_editor_role.yaml b/testdata/project-v4-config/config/rbac/firstmate_editor_role.yaml new file mode 100644 index 00000000000..22a08be29dd --- /dev/null +++ b/testdata/project-v4-config/config/rbac/firstmate_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit firstmates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: firstmate-editor-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - firstmates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - firstmates/status + verbs: + - get diff --git a/testdata/project-v4-config/config/rbac/firstmate_viewer_role.yaml b/testdata/project-v4-config/config/rbac/firstmate_viewer_role.yaml new file mode 100644 index 00000000000..9fd6ba933c7 --- /dev/null +++ b/testdata/project-v4-config/config/rbac/firstmate_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view firstmates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: firstmate-viewer-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - firstmates + verbs: + - get + - list + - watch +- apiGroups: + - crew.testproject.org + resources: + - firstmates/status + verbs: + - get diff --git a/testdata/project-v4-config/config/rbac/kustomization.yaml b/testdata/project-v4-config/config/rbac/kustomization.yaml new file mode 100644 index 00000000000..731832a6ac3 --- /dev/null +++ b/testdata/project-v4-config/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-config/config/rbac/leader_election_role.yaml b/testdata/project-v4-config/config/rbac/leader_election_role.yaml new file mode 100644 index 00000000000..4190ec8059e --- /dev/null +++ b/testdata/project-v4-config/config/rbac/leader_election_role.yaml @@ -0,0 +1,37 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + 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-config/config/rbac/leader_election_role_binding.yaml b/testdata/project-v4-config/config/rbac/leader_election_role_binding.yaml new file mode 100644 index 00000000000..1d1321ed4f0 --- /dev/null +++ b/testdata/project-v4-config/config/rbac/leader_election_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + 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-config/config/rbac/role.yaml b/testdata/project-v4-config/config/rbac/role.yaml new file mode 100644 index 00000000000..ef9a7a2e8ed --- /dev/null +++ b/testdata/project-v4-config/config/rbac/role.yaml @@ -0,0 +1,111 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: manager-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirals + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - admirals/finalizers + verbs: + - update +- apiGroups: + - crew.testproject.org + resources: + - admirals/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: + - crew.testproject.org + resources: + - firstmates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - firstmates/finalizers + verbs: + - update +- apiGroups: + - crew.testproject.org + resources: + - firstmates/status + verbs: + - get + - patch + - update +- apiGroups: + - crew.testproject.org + resources: + - lakers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - lakers/finalizers + verbs: + - update +- apiGroups: + - crew.testproject.org + resources: + - lakers/status + verbs: + - get + - patch + - update diff --git a/testdata/project-v4-config/config/rbac/role_binding.yaml b/testdata/project-v4-config/config/rbac/role_binding.yaml new file mode 100644 index 00000000000..2070ede4462 --- /dev/null +++ b/testdata/project-v4-config/config/rbac/role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + 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-config/config/rbac/service_account.yaml b/testdata/project-v4-config/config/rbac/service_account.yaml new file mode 100644 index 00000000000..7cd6025bfc4 --- /dev/null +++ b/testdata/project-v4-config/config/rbac/service_account.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: controller-manager + namespace: system diff --git a/testdata/project-v4-config/config/samples/crew_v1_admiral.yaml b/testdata/project-v4-config/config/samples/crew_v1_admiral.yaml new file mode 100644 index 00000000000..588448f7801 --- /dev/null +++ b/testdata/project-v4-config/config/samples/crew_v1_admiral.yaml @@ -0,0 +1,6 @@ +apiVersion: crew.testproject.org/v1 +kind: Admiral +metadata: + name: admiral-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-config/config/samples/crew_v1_captain.yaml b/testdata/project-v4-config/config/samples/crew_v1_captain.yaml new file mode 100644 index 00000000000..d0dcfc6cb4d --- /dev/null +++ b/testdata/project-v4-config/config/samples/crew_v1_captain.yaml @@ -0,0 +1,6 @@ +apiVersion: crew.testproject.org/v1 +kind: Captain +metadata: + name: captain-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-config/config/samples/crew_v1_firstmate.yaml b/testdata/project-v4-config/config/samples/crew_v1_firstmate.yaml new file mode 100644 index 00000000000..61749572695 --- /dev/null +++ b/testdata/project-v4-config/config/samples/crew_v1_firstmate.yaml @@ -0,0 +1,6 @@ +apiVersion: crew.testproject.org/v1 +kind: FirstMate +metadata: + name: firstmate-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-config/config/webhook/kustomization.yaml b/testdata/project-v4-config/config/webhook/kustomization.yaml new file mode 100644 index 00000000000..9cf26134e4d --- /dev/null +++ b/testdata/project-v4-config/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/testdata/project-v4-config/config/webhook/kustomizeconfig.yaml b/testdata/project-v4-config/config/webhook/kustomizeconfig.yaml new file mode 100644 index 00000000000..25e21e3c963 --- /dev/null +++ b/testdata/project-v4-config/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,25 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# 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 + +varReference: +- path: metadata/annotations diff --git a/testdata/project-v4-config/config/webhook/manifests.yaml b/testdata/project-v4-config/config/webhook/manifests.yaml new file mode 100644 index 00000000000..80eb36fdc3f --- /dev/null +++ b/testdata/project-v4-config/config/webhook/manifests.yaml @@ -0,0 +1,74 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-crew-testproject-org-v1-admiral + failurePolicy: Fail + name: madmiral.kb.io + rules: + - apiGroups: + - crew.testproject.org + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - admirals + sideEffects: None +- 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 +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + 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 diff --git a/testdata/project-v4-config/config/webhook/service.yaml b/testdata/project-v4-config/config/webhook/service.yaml new file mode 100644 index 00000000000..3f638bd9c68 --- /dev/null +++ b/testdata/project-v4-config/config/webhook/service.yaml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Service +metadata: + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager diff --git a/testdata/project-v4-config/controllers/admiral_controller.go b/testdata/project-v4-config/controllers/admiral_controller.go new file mode 100644 index 00000000000..c379ecfa4f2 --- /dev/null +++ b/testdata/project-v4-config/controllers/admiral_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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 controllers + +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-config/api/v1" +) + +// AdmiralReconciler reconciles a Admiral object +type AdmiralReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=crew.testproject.org,resources=admirals,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=crew.testproject.org,resources=admirals/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=crew.testproject.org,resources=admirals/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 Admiral 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.11.2/pkg/reconcile +func (r *AdmiralReconciler) 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 *AdmiralReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&crewv1.Admiral{}). + Complete(r) +} diff --git a/testdata/project-v4-config/controllers/captain_controller.go b/testdata/project-v4-config/controllers/captain_controller.go new file mode 100644 index 00000000000..7724def2426 --- /dev/null +++ b/testdata/project-v4-config/controllers/captain_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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 controllers + +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-config/api/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.11.2/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-config/controllers/firstmate_controller.go b/testdata/project-v4-config/controllers/firstmate_controller.go new file mode 100644 index 00000000000..91168e64cfd --- /dev/null +++ b/testdata/project-v4-config/controllers/firstmate_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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 controllers + +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-config/api/v1" +) + +// FirstMateReconciler reconciles a FirstMate object +type FirstMateReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates/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 FirstMate 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.11.2/pkg/reconcile +func (r *FirstMateReconciler) 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 *FirstMateReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&crewv1.FirstMate{}). + Complete(r) +} diff --git a/testdata/project-v4-config/controllers/laker_controller.go b/testdata/project-v4-config/controllers/laker_controller.go new file mode 100644 index 00000000000..ea0906629e4 --- /dev/null +++ b/testdata/project-v4-config/controllers/laker_controller.go @@ -0,0 +1,61 @@ +/* +Copyright 2022 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 controllers + +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" +) + +// LakerReconciler reconciles a Laker object +type LakerReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=crew.testproject.org,resources=lakers,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=crew.testproject.org,resources=lakers/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=crew.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 Laker 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.11.2/pkg/reconcile +func (r *LakerReconciler) 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 *LakerReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + // Uncomment the following line adding a pointer to an instance of the controlled resource as an argument + // For(). + Complete(r) +} diff --git a/testdata/project-v4-config/controllers/suite_test.go b/testdata/project-v4-config/controllers/suite_test.go new file mode 100644 index 00000000000..8eddacf4987 --- /dev/null +++ b/testdata/project-v4-config/controllers/suite_test.go @@ -0,0 +1,82 @@ +/* +Copyright 2022 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 controllers + +import ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-config/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 TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = crewv1.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()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-config/go.mod b/testdata/project-v4-config/go.mod new file mode 100644 index 00000000000..a3bbf31a9e4 --- /dev/null +++ b/testdata/project-v4-config/go.mod @@ -0,0 +1,74 @@ +module sigs.k8s.io/kubebuilder/testdata/project-v4-config + +go 1.17 + +require ( + github.com/onsi/ginkgo v1.16.5 + github.com/onsi/gomega v1.17.0 + k8s.io/api v0.23.5 + k8s.io/apimachinery v0.23.5 + k8s.io/client-go v0.23.5 + sigs.k8s.io/controller-runtime v0.11.2 +) + +require ( + cloud.google.com/go v0.81.0 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.18 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/go-logr/logr v1.2.0 // indirect + github.com/go-logr/zapr v1.2.0 // 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.2 // indirect + github.com/google/go-cmp v0.5.5 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/google/uuid v1.1.2 // indirect + github.com/googleapis/gnostic v0.5.5 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/nxadm/tail v1.4.8 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.11.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.28.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.19.1 // indirect + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect + golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect + golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect + golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + k8s.io/apiextensions-apiserver v0.23.5 // indirect + k8s.io/component-base v0.23.5 // indirect + k8s.io/klog/v2 v2.30.0 // indirect + k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect + k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect + sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/testdata/project-v4-config/hack/boilerplate.go.txt b/testdata/project-v4-config/hack/boilerplate.go.txt new file mode 100644 index 00000000000..b54e305f300 --- /dev/null +++ b/testdata/project-v4-config/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +Copyright 2022 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-config/main.go b/testdata/project-v4-config/main.go new file mode 100644 index 00000000000..296c9d8af21 --- /dev/null +++ b/testdata/project-v4-config/main.go @@ -0,0 +1,137 @@ +/* +Copyright 2022 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" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-config/api/v1" + "sigs.k8s.io/kubebuilder/testdata/project-v4-config/controllers" + //+kubebuilder:scaffold:imports +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + + utilruntime.Must(crewv1.AddToScheme(scheme)) + //+kubebuilder:scaffold:scheme +} + +func main() { + var configFile string + flag.StringVar(&configFile, "config", "", + "The controller will load its initial configuration from this file. "+ + "Omit this flag to use the default configuration values. "+ + "Command-line flags override configuration from this file.") + opts := zap.Options{ + Development: true, + } + opts.BindFlags(flag.CommandLine) + flag.Parse() + + ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + + var err error + options := ctrl.Options{Scheme: scheme} + if configFile != "" { + options, err = options.AndFrom(ctrl.ConfigFile().AtPath(configFile)) + if err != nil { + setupLog.Error(err, "unable to load the config file") + os.Exit(1) + } + } + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + if err = (&controllers.CaptainReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Captain") + os.Exit(1) + } + if err = (&crewv1.Captain{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Captain") + os.Exit(1) + } + if err = (&controllers.FirstMateReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "FirstMate") + os.Exit(1) + } + if err = (&crewv1.FirstMate{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "FirstMate") + os.Exit(1) + } + if err = (&controllers.AdmiralReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Admiral") + os.Exit(1) + } + if err = (&crewv1.Admiral{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Admiral") + os.Exit(1) + } + if err = (&controllers.LakerReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Laker") + 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/.dockerignore b/testdata/project-v4-multigroup/.dockerignore new file mode 100644 index 00000000000..0f046820f18 --- /dev/null +++ b/testdata/project-v4-multigroup/.dockerignore @@ -0,0 +1,4 @@ +# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Ignore build and test binaries. +bin/ +testbin/ diff --git a/testdata/project-v4-multigroup/.gitignore b/testdata/project-v4-multigroup/.gitignore new file mode 100644 index 00000000000..d97ffc5159b --- /dev/null +++ b/testdata/project-v4-multigroup/.gitignore @@ -0,0 +1,24 @@ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin + +# 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 +*.swp +*.swo +*~ diff --git a/testdata/project-v4-multigroup/Dockerfile b/testdata/project-v4-multigroup/Dockerfile new file mode 100644 index 00000000000..9a23dc6ee57 --- /dev/null +++ b/testdata/project-v4-multigroup/Dockerfile @@ -0,0 +1,27 @@ +# Build the manager binary +FROM golang:1.17 as builder + +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 main.go main.go +COPY apis/ apis/ +COPY controllers/ controllers/ + +# Build +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager 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/Makefile b/testdata/project-v4-multigroup/Makefile new file mode 100644 index 00000000000..4c98e81e111 --- /dev/null +++ b/testdata/project-v4-multigroup/Makefile @@ -0,0 +1,133 @@ + +# 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.23 + +# 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 + +# Setting SHELL to bash allows bash commands to be executed by recipes. +# This is a requirement for 'setup-envtest.sh' in the test target. +# 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 commands 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) -p path)" go test ./... -coverprofile cover.out + +##@ Build + +.PHONY: build +build: generate fmt vet ## Build manager binary. + go build -o bin/manager main.go + +.PHONY: run +run: manifests generate fmt vet ## Run a controller from your host. + go run ./main.go + +.PHONY: docker-build +docker-build: test ## Build docker image with the manager. + docker build -t ${IMG} . + +.PHONY: docker-push +docker-push: ## Push docker image with the manager. + docker push ${IMG} + +##@ 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 +KUSTOMIZE ?= $(LOCALBIN)/kustomize +CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen +ENVTEST ?= $(LOCALBIN)/setup-envtest + +## Tool Versions +KUSTOMIZE_VERSION ?= v3.8.7 +CONTROLLER_TOOLS_VERSION ?= v0.8.0 + +KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" +.PHONY: kustomize +kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. +$(KUSTOMIZE): $(LOCALBIN) + curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN) + +.PHONY: controller-gen +controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. +$(CONTROLLER_GEN): $(LOCALBIN) + 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) + GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest diff --git a/testdata/project-v4-multigroup/PROJECT b/testdata/project-v4-multigroup/PROJECT new file mode 100644 index 00000000000..5055d02f62b --- /dev/null +++ b/testdata/project-v4-multigroup/PROJECT @@ -0,0 +1,117 @@ +domain: testproject.org +layout: +- go.kubebuilder.io/v3 +multigroup: true +projectName: project-v4-multigroup +repo: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup +resources: +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: crew + kind: Captain + path: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/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/apis/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/apis/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/apis/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/apis/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/apis/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/apis/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/apis/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/apis/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/apis/v1 + version: v1 + webhooks: + defaulting: true + validation: true + webhookVersion: v1 +version: "3" diff --git a/testdata/project-v4-multigroup/README.md b/testdata/project-v4-multigroup/README.md new file mode 100644 index 00000000000..f17e454dbed --- /dev/null +++ b/testdata/project-v4-multigroup/README.md @@ -0,0 +1,94 @@ +# project-v4-multigroup +// TODO(user): Add simple overview of use/purpose + +## Description +// TODO(user): An in-depth paragraph about your project and overview of use + +## Getting Started +You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster. +**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows). + +### Running on the cluster +1. Install Instances of Custom Resources: + +```sh +kubectl apply -f config/samples/ +``` + +2. Build and push your image to the location specified by `IMG`: + +```sh +make docker-build docker-push IMG=/project-v4-multigroup:tag +``` + +3. Deploy the controller to the cluster with the image specified by `IMG`: + +```sh +make deploy IMG=/project-v4-multigroup:tag +``` + +### Uninstall CRDs +To delete the CRDs from the cluster: + +```sh +make uninstall +``` + +### Undeploy controller +UnDeploy the controller to 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 provides a reconcile function responsible for synchronizing resources untile 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 2022 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/apis/crew/v1/captain_types.go b/testdata/project-v4-multigroup/apis/crew/v1/captain_types.go new file mode 100644 index 00000000000..e81debb719c --- /dev/null +++ b/testdata/project-v4-multigroup/apis/crew/v1/captain_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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/apis/crew/v1/captain_webhook.go b/testdata/project-v4-multigroup/apis/crew/v1/captain_webhook.go new file mode 100644 index 00000000000..ba00000c137 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/crew/v1/captain_webhook.go @@ -0,0 +1,75 @@ +/* +Copyright 2022 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" +) + +// log is for logging in this package. +var captainlog = logf.Log.WithName("captain-resource") + +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() error { + captainlog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Captain) ValidateUpdate(old runtime.Object) error { + captainlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Captain) ValidateDelete() error { + captainlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil +} diff --git a/testdata/project-v4-multigroup/apis/crew/v1/groupversion_info.go b/testdata/project-v4-multigroup/apis/crew/v1/groupversion_info.go new file mode 100644 index 00000000000..33458c7506e --- /dev/null +++ b/testdata/project-v4-multigroup/apis/crew/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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 crew v1 API group +//+kubebuilder:object:generate=true +//+groupName=crew.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: "crew.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/apis/crew/v1/webhook_suite_test.go b/testdata/project-v4-multigroup/apis/crew/v1/webhook_suite_test.go new file mode 100644 index 00000000000..31df367d94d --- /dev/null +++ b/testdata/project-v4-multigroup/apis/crew/v1/webhook_suite_test.go @@ -0,0 +1,135 @@ +/* +Copyright 2022 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" + "testing" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + //+kubebuilder:scaffold:imports + "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// 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) + + RunSpecsWithDefaultAndCustomReporters(t, + "Webhook Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + 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 := runtime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1beta1.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, + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + MetricsBindAddress: "0", + }) + Expect(err).NotTo(HaveOccurred()) + + err = (&Captain{}).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 + } + conn.Close() + return nil + }).Should(Succeed()) + +}, 60) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/apis/crew/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/apis/crew/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..3d19f0cd037 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/crew/v1/zz_generated.deepcopy.go @@ -0,0 +1,115 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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/apis/fiz/v1/bar_types.go b/testdata/project-v4-multigroup/apis/fiz/v1/bar_types.go new file mode 100644 index 00000000000..398da384cda --- /dev/null +++ b/testdata/project-v4-multigroup/apis/fiz/v1/bar_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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/apis/fiz/v1/groupversion_info.go b/testdata/project-v4-multigroup/apis/fiz/v1/groupversion_info.go new file mode 100644 index 00000000000..8fbae6ea708 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/fiz/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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/apis/fiz/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/apis/fiz/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..f46b6a1cb10 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/fiz/v1/zz_generated.deepcopy.go @@ -0,0 +1,115 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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/apis/foo.policy/v1/groupversion_info.go b/testdata/project-v4-multigroup/apis/foo.policy/v1/groupversion_info.go new file mode 100644 index 00000000000..29bb003c035 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/foo.policy/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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/apis/foo.policy/v1/healthcheckpolicy_types.go b/testdata/project-v4-multigroup/apis/foo.policy/v1/healthcheckpolicy_types.go new file mode 100644 index 00000000000..db63b3139a5 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/foo.policy/v1/healthcheckpolicy_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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/apis/foo.policy/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/apis/foo.policy/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..384b31870fe --- /dev/null +++ b/testdata/project-v4-multigroup/apis/foo.policy/v1/zz_generated.deepcopy.go @@ -0,0 +1,115 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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/apis/foo/v1/bar_types.go b/testdata/project-v4-multigroup/apis/foo/v1/bar_types.go new file mode 100644 index 00000000000..398da384cda --- /dev/null +++ b/testdata/project-v4-multigroup/apis/foo/v1/bar_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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/apis/foo/v1/groupversion_info.go b/testdata/project-v4-multigroup/apis/foo/v1/groupversion_info.go new file mode 100644 index 00000000000..06774db9bf0 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/foo/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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/apis/foo/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/apis/foo/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..f46b6a1cb10 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/foo/v1/zz_generated.deepcopy.go @@ -0,0 +1,115 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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/apis/sea-creatures/v1beta1/groupversion_info.go b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta1/groupversion_info.go new file mode 100644 index 00000000000..7613a89964a --- /dev/null +++ b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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/apis/sea-creatures/v1beta1/kraken_types.go b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta1/kraken_types.go new file mode 100644 index 00000000000..afb57fff4b0 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta1/kraken_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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/apis/sea-creatures/v1beta1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..e8b5ea29fc8 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,115 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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/apis/sea-creatures/v1beta2/groupversion_info.go b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta2/groupversion_info.go new file mode 100644 index 00000000000..4334497f3a0 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta2/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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/apis/sea-creatures/v1beta2/leviathan_types.go b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta2/leviathan_types.go new file mode 100644 index 00000000000..47da45524f6 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta2/leviathan_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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/apis/sea-creatures/v1beta2/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta2/zz_generated.deepcopy.go new file mode 100644 index 00000000000..e5a09f90a46 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/sea-creatures/v1beta2/zz_generated.deepcopy.go @@ -0,0 +1,115 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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/apis/ship/v1/destroyer_types.go b/testdata/project-v4-multigroup/apis/ship/v1/destroyer_types.go new file mode 100644 index 00000000000..8efa6fad827 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v1/destroyer_types.go @@ -0,0 +1,65 @@ +/* +Copyright 2022 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/apis/ship/v1/destroyer_webhook.go b/testdata/project-v4-multigroup/apis/ship/v1/destroyer_webhook.go new file mode 100644 index 00000000000..e1c0a0a05db --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v1/destroyer_webhook.go @@ -0,0 +1,45 @@ +/* +Copyright 2022 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") + +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/apis/ship/v1/groupversion_info.go b/testdata/project-v4-multigroup/apis/ship/v1/groupversion_info.go new file mode 100644 index 00000000000..633f5a4e398 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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/apis/ship/v1/webhook_suite_test.go b/testdata/project-v4-multigroup/apis/ship/v1/webhook_suite_test.go new file mode 100644 index 00000000000..b719e728118 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v1/webhook_suite_test.go @@ -0,0 +1,135 @@ +/* +Copyright 2022 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" + "testing" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + //+kubebuilder:scaffold:imports + "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// 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) + + RunSpecsWithDefaultAndCustomReporters(t, + "Webhook Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + 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 := runtime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1beta1.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, + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + MetricsBindAddress: "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 + } + conn.Close() + return nil + }).Should(Succeed()) + +}, 60) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/apis/ship/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/apis/ship/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..c02c174f0d0 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v1/zz_generated.deepcopy.go @@ -0,0 +1,115 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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/apis/ship/v1beta1/frigate_types.go b/testdata/project-v4-multigroup/apis/ship/v1beta1/frigate_types.go new file mode 100644 index 00000000000..c8734a6cf9e --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v1beta1/frigate_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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/apis/ship/v1beta1/frigate_webhook.go b/testdata/project-v4-multigroup/apis/ship/v1beta1/frigate_webhook.go new file mode 100644 index 00000000000..8cf9bc5b41a --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v1beta1/frigate_webhook.go @@ -0,0 +1,33 @@ +/* +Copyright 2022 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") + +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/apis/ship/v1beta1/groupversion_info.go b/testdata/project-v4-multigroup/apis/ship/v1beta1/groupversion_info.go new file mode 100644 index 00000000000..26b0fbd2752 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v1beta1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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/apis/ship/v1beta1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/apis/ship/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..d1ac770b5c7 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,115 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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/apis/ship/v2alpha1/cruiser_types.go b/testdata/project-v4-multigroup/apis/ship/v2alpha1/cruiser_types.go new file mode 100644 index 00000000000..6160dc14b1d --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v2alpha1/cruiser_types.go @@ -0,0 +1,65 @@ +/* +Copyright 2022 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/apis/ship/v2alpha1/cruiser_webhook.go b/testdata/project-v4-multigroup/apis/ship/v2alpha1/cruiser_webhook.go new file mode 100644 index 00000000000..877deb965a3 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v2alpha1/cruiser_webhook.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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 ( + "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" +) + +// log is for logging in this package. +var cruiserlog = logf.Log.WithName("cruiser-resource") + +func (r *Cruiser) SetupWebhookWithManager(mgr ctrl.Manager) error { + return ctrl.NewWebhookManagedBy(mgr). + For(r). + Complete() +} + +// 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-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 = &Cruiser{} + +// ValidateCreate implements webhook.Validator so a webhook will be registered for the type +func (r *Cruiser) ValidateCreate() error { + cruiserlog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Cruiser) ValidateUpdate(old runtime.Object) error { + cruiserlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Cruiser) ValidateDelete() error { + cruiserlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil +} diff --git a/testdata/project-v4-multigroup/apis/ship/v2alpha1/groupversion_info.go b/testdata/project-v4-multigroup/apis/ship/v2alpha1/groupversion_info.go new file mode 100644 index 00000000000..ac5d9ee826a --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v2alpha1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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/apis/ship/v2alpha1/webhook_suite_test.go b/testdata/project-v4-multigroup/apis/ship/v2alpha1/webhook_suite_test.go new file mode 100644 index 00000000000..72b018424a4 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v2alpha1/webhook_suite_test.go @@ -0,0 +1,135 @@ +/* +Copyright 2022 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" + "testing" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + //+kubebuilder:scaffold:imports + "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// 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) + + RunSpecsWithDefaultAndCustomReporters(t, + "Webhook Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + 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 := runtime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1beta1.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, + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + MetricsBindAddress: "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 + } + conn.Close() + return nil + }).Should(Succeed()) + +}, 60) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/apis/ship/v2alpha1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/apis/ship/v2alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..e335a81bb7d --- /dev/null +++ b/testdata/project-v4-multigroup/apis/ship/v2alpha1/zz_generated.deepcopy.go @@ -0,0 +1,115 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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/apis/v1/groupversion_info.go b/testdata/project-v4-multigroup/apis/v1/groupversion_info.go new file mode 100644 index 00000000000..a6ea0aa2b65 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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/apis/v1/lakers_types.go b/testdata/project-v4-multigroup/apis/v1/lakers_types.go new file mode 100644 index 00000000000..5dca1f9accf --- /dev/null +++ b/testdata/project-v4-multigroup/apis/v1/lakers_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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/apis/v1/lakers_webhook.go b/testdata/project-v4-multigroup/apis/v1/lakers_webhook.go new file mode 100644 index 00000000000..c358e00ad67 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/v1/lakers_webhook.go @@ -0,0 +1,75 @@ +/* +Copyright 2022 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" +) + +// log is for logging in this package. +var lakerslog = logf.Log.WithName("lakers-resource") + +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() error { + lakerslog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Lakers) ValidateUpdate(old runtime.Object) error { + lakerslog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Lakers) ValidateDelete() error { + lakerslog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil +} diff --git a/testdata/project-v4-multigroup/apis/v1/webhook_suite_test.go b/testdata/project-v4-multigroup/apis/v1/webhook_suite_test.go new file mode 100644 index 00000000000..0f843751fb1 --- /dev/null +++ b/testdata/project-v4-multigroup/apis/v1/webhook_suite_test.go @@ -0,0 +1,135 @@ +/* +Copyright 2022 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" + "testing" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + //+kubebuilder:scaffold:imports + "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// 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) + + RunSpecsWithDefaultAndCustomReporters(t, + "Webhook Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + 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 := runtime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1beta1.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, + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + MetricsBindAddress: "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 + } + conn.Close() + return nil + }).Should(Succeed()) + +}, 60) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/apis/v1/zz_generated.deepcopy.go b/testdata/project-v4-multigroup/apis/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..523ce2ac7ac --- /dev/null +++ b/testdata/project-v4-multigroup/apis/v1/zz_generated.deepcopy.go @@ -0,0 +1,115 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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/config/certmanager/certificate.yaml b/testdata/project-v4-multigroup/config/certmanager/certificate.yaml new file mode 100644 index 00000000000..52d866183c7 --- /dev/null +++ b/testdata/project-v4-multigroup/config/certmanager/certificate.yaml @@ -0,0 +1,25 @@ +# 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: + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + 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/config/certmanager/kustomization.yaml b/testdata/project-v4-multigroup/config/certmanager/kustomization.yaml new file mode 100644 index 00000000000..bebea5a595e --- /dev/null +++ b/testdata/project-v4-multigroup/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- certificate.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/testdata/project-v4-multigroup/config/certmanager/kustomizeconfig.yaml b/testdata/project-v4-multigroup/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 00000000000..90d7c313ca1 --- /dev/null +++ b/testdata/project-v4-multigroup/config/certmanager/kustomizeconfig.yaml @@ -0,0 +1,16 @@ +# This configuration is for teaching kustomize how to update name ref and var substitution +nameReference: +- kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name + +varReference: +- kind: Certificate + group: cert-manager.io + path: spec/commonName +- kind: Certificate + group: cert-manager.io + path: spec/dnsNames diff --git a/testdata/project-v4-multigroup/config/crd/bases/crew.testproject.org_captains.yaml b/testdata/project-v4-multigroup/config/crd/bases/crew.testproject.org_captains.yaml new file mode 100644 index 00000000000..41b080622f6 --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/bases/crew.testproject.org_captains.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-multigroup/config/crd/bases/fiz.testproject.org_bars.yaml b/testdata/project-v4-multigroup/config/crd/bases/fiz.testproject.org_bars.yaml new file mode 100644 index 00000000000..9e9c2b5a1a3 --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/bases/fiz.testproject.org_bars.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-multigroup/config/crd/bases/foo.policy.testproject.org_healthcheckpolicies.yaml b/testdata/project-v4-multigroup/config/crd/bases/foo.policy.testproject.org_healthcheckpolicies.yaml new file mode 100644 index 00000000000..ca1642fc31c --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/bases/foo.policy.testproject.org_healthcheckpolicies.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-multigroup/config/crd/bases/foo.testproject.org_bars.yaml b/testdata/project-v4-multigroup/config/crd/bases/foo.testproject.org_bars.yaml new file mode 100644 index 00000000000..24002b5b0c8 --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/bases/foo.testproject.org_bars.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_krakens.yaml b/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_krakens.yaml new file mode 100644 index 00000000000..392d5f48e32 --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_krakens.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_leviathans.yaml b/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_leviathans.yaml new file mode 100644 index 00000000000..df8b9b4eedb --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/bases/sea-creatures.testproject.org_leviathans.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_cruisers.yaml b/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_cruisers.yaml new file mode 100644 index 00000000000..1eea0d2b28f --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_cruisers.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_destroyers.yaml b/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_destroyers.yaml new file mode 100644 index 00000000000..8b00c07bf02 --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_destroyers.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_frigates.yaml b/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_frigates.yaml new file mode 100644 index 00000000000..31811f7c74a --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/bases/ship.testproject.org_frigates.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-multigroup/config/crd/bases/testproject.org_lakers.yaml b/testdata/project-v4-multigroup/config/crd/bases/testproject.org_lakers.yaml new file mode 100644 index 00000000000..0403dd77d65 --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/bases/testproject.org_lakers.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4-multigroup/config/crd/kustomization.yaml b/testdata/project-v4-multigroup/config/crd/kustomization.yaml new file mode 100644 index 00000000000..be93af7e522 --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/kustomization.yaml @@ -0,0 +1,46 @@ +# 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 + +patchesStrategicMerge: +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. +# patches here are for enabling the conversion webhook for each CRD +#- patches/webhook_in_captains.yaml +#- patches/webhook_in_frigates.yaml +#- patches/webhook_in_destroyers.yaml +#- patches/webhook_in_cruisers.yaml +#- patches/webhook_in_krakens.yaml +#- patches/webhook_in_leviathans.yaml +#- patches/webhook_in_healthcheckpolicies.yaml +#- patches/webhook_in_bars.yaml +#- 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 +#- patches/cainjection_in_captains.yaml +#- patches/cainjection_in_frigates.yaml +#- patches/cainjection_in_destroyers.yaml +#- patches/cainjection_in_cruisers.yaml +#- patches/cainjection_in_krakens.yaml +#- patches/cainjection_in_leviathans.yaml +#- patches/cainjection_in_healthcheckpolicies.yaml +#- patches/cainjection_in_bars.yaml +#- 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/config/crd/kustomizeconfig.yaml b/testdata/project-v4-multigroup/config/crd/kustomizeconfig.yaml new file mode 100644 index 00000000000..ec5c150a9df --- /dev/null +++ b/testdata/project-v4-multigroup/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__lakers.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in__lakers.yaml new file mode 100644 index 00000000000..99c8d3b175c --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in__lakers.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: lakers.testproject.org diff --git a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_crew_captains.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_crew_captains.yaml new file mode 100644 index 00000000000..9c9d61b0c97 --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_crew_captains.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: captains.crew.testproject.org diff --git a/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_fiz_bars.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_fiz_bars.yaml new file mode 100644 index 00000000000..515b99a8104 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/cainjection_in_foo.policy_healthcheckpolicies.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_foo.policy_healthcheckpolicies.yaml new file mode 100644 index 00000000000..8bc7c37f105 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/cainjection_in_foo_bars.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_foo_bars.yaml new file mode 100644 index 00000000000..35fd01aedea --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/cainjection_in_sea-creatures_krakens.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_sea-creatures_krakens.yaml new file mode 100644 index 00000000000..cadcf28d0a0 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/cainjection_in_sea-creatures_leviathans.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_sea-creatures_leviathans.yaml new file mode 100644 index 00000000000..7fdf23361d9 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/cainjection_in_ship_cruisers.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_cruisers.yaml new file mode 100644 index 00000000000..f45c67e889a --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/cainjection_in_ship_destroyers.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_destroyers.yaml new file mode 100644 index 00000000000..420660947f2 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/cainjection_in_ship_frigates.yaml b/testdata/project-v4-multigroup/config/crd/patches/cainjection_in_ship_frigates.yaml new file mode 100644 index 00000000000..89bcb665a22 --- /dev/null +++ b/testdata/project-v4-multigroup/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__lakers.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in__lakers.yaml new file mode 100644 index 00000000000..58df2264dde --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/patches/webhook_in__lakers.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: lakers.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/config/crd/patches/webhook_in_crew_captains.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_crew_captains.yaml new file mode 100644 index 00000000000..f73ae2e8abc --- /dev/null +++ b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_crew_captains.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: captains.crew.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/config/crd/patches/webhook_in_fiz_bars.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_fiz_bars.yaml new file mode 100644 index 00000000000..eddaa868fdd --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/webhook_in_foo.policy_healthcheckpolicies.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_foo.policy_healthcheckpolicies.yaml new file mode 100644 index 00000000000..61381b747c5 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/webhook_in_foo_bars.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_foo_bars.yaml new file mode 100644 index 00000000000..831ad1b8164 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/webhook_in_sea-creatures_krakens.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_sea-creatures_krakens.yaml new file mode 100644 index 00000000000..620a12faaee --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/webhook_in_sea-creatures_leviathans.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_sea-creatures_leviathans.yaml new file mode 100644 index 00000000000..5cb95bc7b38 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/webhook_in_ship_cruisers.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_cruisers.yaml new file mode 100644 index 00000000000..99b6b6741b6 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/webhook_in_ship_destroyers.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_destroyers.yaml new file mode 100644 index 00000000000..0e0095cb3a6 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/crd/patches/webhook_in_ship_frigates.yaml b/testdata/project-v4-multigroup/config/crd/patches/webhook_in_ship_frigates.yaml new file mode 100644 index 00000000000..cdc5078ae71 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/default/kustomization.yaml b/testdata/project-v4-multigroup/config/default/kustomization.yaml new file mode 100644 index 00000000000..6536fa6d326 --- /dev/null +++ b/testdata/project-v4-multigroup/config/default/kustomization.yaml @@ -0,0 +1,74 @@ +# Adds namespace to all resources. +namespace: project-v4-multigroup-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- + +# Labels to add to all resources and selectors. +#commonLabels: +# someName: someValue + +bases: +- ../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 + +# Mount the controller config file for loading manager configurations +# through a ComponentConfig type +#- manager_config_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 + +# the following config is for teaching kustomize how to do var substitution +vars: +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +# fieldref: +# fieldpath: metadata.namespace +#- name: CERTIFICATE_NAME +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +#- name: SERVICE_NAMESPACE # namespace of the service +# objref: +# kind: Service +# version: v1 +# name: webhook-service +# fieldref: +# fieldpath: metadata.namespace +#- name: SERVICE_NAME +# objref: +# kind: Service +# version: v1 +# name: webhook-service diff --git a/testdata/project-v4-multigroup/config/default/manager_auth_proxy_patch.yaml b/testdata/project-v4-multigroup/config/default/manager_auth_proxy_patch.yaml new file mode 100644 index 00000000000..131a3142928 --- /dev/null +++ b/testdata/project-v4-multigroup/config/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,34 @@ +# 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 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0 + 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/config/default/manager_config_patch.yaml b/testdata/project-v4-multigroup/config/default/manager_config_patch.yaml new file mode 100644 index 00000000000..6c400155cfb --- /dev/null +++ b/testdata/project-v4-multigroup/config/default/manager_config_patch.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + args: + - "--config=controller_manager_config.yaml" + volumeMounts: + - name: manager-config + mountPath: /controller_manager_config.yaml + subPath: controller_manager_config.yaml + volumes: + - name: manager-config + configMap: + name: manager-config diff --git a/testdata/project-v4-multigroup/config/default/manager_webhook_patch.yaml b/testdata/project-v4-multigroup/config/default/manager_webhook_patch.yaml new file mode 100644 index 00000000000..738de350b71 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/default/webhookcainjection_patch.yaml b/testdata/project-v4-multigroup/config/default/webhookcainjection_patch.yaml new file mode 100644 index 00000000000..02ab515d428 --- /dev/null +++ b/testdata/project-v4-multigroup/config/default/webhookcainjection_patch.yaml @@ -0,0 +1,15 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/testdata/project-v4-multigroup/config/manager/controller_manager_config.yaml b/testdata/project-v4-multigroup/config/manager/controller_manager_config.yaml new file mode 100644 index 00000000000..ced7ed928a5 --- /dev/null +++ b/testdata/project-v4-multigroup/config/manager/controller_manager_config.yaml @@ -0,0 +1,21 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +health: + healthProbeBindAddress: :8081 +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: 3e9f67a9.testproject.org +# leaderElectionReleaseOnCancel defines if the leader should step down volume +# 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 diff --git a/testdata/project-v4-multigroup/config/manager/kustomization.yaml b/testdata/project-v4-multigroup/config/manager/kustomization.yaml new file mode 100644 index 00000000000..2bcd3eeaa94 --- /dev/null +++ b/testdata/project-v4-multigroup/config/manager/kustomization.yaml @@ -0,0 +1,10 @@ +resources: +- manager.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: +- name: manager-config + files: + - controller_manager_config.yaml diff --git a/testdata/project-v4-multigroup/config/manager/manager.yaml b/testdata/project-v4-multigroup/config/manager/manager.yaml new file mode 100644 index 00000000000..cf11cecc26a --- /dev/null +++ b/testdata/project-v4-multigroup/config/manager/manager.yaml @@ -0,0 +1,60 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager +spec: + selector: + matchLabels: + control-plane: controller-manager + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + securityContext: + runAsNonRoot: true + containers: + - command: + - /manager + args: + - --leader-elect + image: controller:latest + name: manager + securityContext: + allowPrivilegeEscalation: false + 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/config/prometheus/kustomization.yaml b/testdata/project-v4-multigroup/config/prometheus/kustomization.yaml new file mode 100644 index 00000000000..ed137168a1d --- /dev/null +++ b/testdata/project-v4-multigroup/config/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/testdata/project-v4-multigroup/config/prometheus/monitor.yaml b/testdata/project-v4-multigroup/config/prometheus/monitor.yaml new file mode 100644 index 00000000000..d19136ae710 --- /dev/null +++ b/testdata/project-v4-multigroup/config/prometheus/monitor.yaml @@ -0,0 +1,20 @@ + +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: controller-manager + 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/_lakers_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/_lakers_editor_role.yaml new file mode 100644 index 00000000000..cead239193e --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/_lakers_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit lakers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: lakers-editor-role +rules: +- apiGroups: + - testproject.org + resources: + - lakers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - testproject.org + resources: + - lakers/status + verbs: + - get diff --git a/testdata/project-v4-multigroup/config/rbac/_lakers_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/_lakers_viewer_role.yaml new file mode 100644 index 00000000000..e82b03dd0c3 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/_lakers_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view lakers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/auth_proxy_client_clusterrole.yaml b/testdata/project-v4-multigroup/config/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 00000000000..51a75db47a5 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/auth_proxy_client_clusterrole.yaml @@ -0,0 +1,9 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/testdata/project-v4-multigroup/config/rbac/auth_proxy_role.yaml b/testdata/project-v4-multigroup/config/rbac/auth_proxy_role.yaml new file mode 100644 index 00000000000..80e1857c594 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/auth_proxy_role.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/auth_proxy_role_binding.yaml b/testdata/project-v4-multigroup/config/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 00000000000..ec7acc0a1b7 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/auth_proxy_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + 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/config/rbac/auth_proxy_service.yaml b/testdata/project-v4-multigroup/config/rbac/auth_proxy_service.yaml new file mode 100644 index 00000000000..71f1797279e --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/auth_proxy_service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + 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/config/rbac/crew_captain_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/crew_captain_editor_role.yaml new file mode 100644 index 00000000000..4b53ae38ffa --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/crew_captain_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/crew_captain_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/crew_captain_viewer_role.yaml new file mode 100644 index 00000000000..f19e10439d2 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/crew_captain_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/fiz_bar_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/fiz_bar_editor_role.yaml new file mode 100644 index 00000000000..6b34df93f0b --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/fiz_bar_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit bars. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: bar-editor-role +rules: +- apiGroups: + - fiz.testproject.org + resources: + - bars + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - fiz.testproject.org + resources: + - bars/status + verbs: + - get diff --git a/testdata/project-v4-multigroup/config/rbac/fiz_bar_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/fiz_bar_viewer_role.yaml new file mode 100644 index 00000000000..64d4dd9ea85 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/fiz_bar_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view bars. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/foo.policy_healthcheckpolicy_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_editor_role.yaml new file mode 100644 index 00000000000..bbec63d13e8 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit healthcheckpolicies. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml new file mode 100644 index 00000000000..66acbe3a35f --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view healthcheckpolicies. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/foo_bar_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/foo_bar_editor_role.yaml new file mode 100644 index 00000000000..e9915a5b9c3 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/foo_bar_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit bars. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/foo_bar_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/foo_bar_viewer_role.yaml new file mode 100644 index 00000000000..a4569ac9654 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/foo_bar_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view bars. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/kustomization.yaml b/testdata/project-v4-multigroup/config/rbac/kustomization.yaml new file mode 100644 index 00000000000..731832a6ac3 --- /dev/null +++ b/testdata/project-v4-multigroup/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/config/rbac/leader_election_role.yaml b/testdata/project-v4-multigroup/config/rbac/leader_election_role.yaml new file mode 100644 index 00000000000..4190ec8059e --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/leader_election_role.yaml @@ -0,0 +1,37 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + 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/config/rbac/leader_election_role_binding.yaml b/testdata/project-v4-multigroup/config/rbac/leader_election_role_binding.yaml new file mode 100644 index 00000000000..1d1321ed4f0 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/leader_election_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + 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/config/rbac/role.yaml b/testdata/project-v4-multigroup/config/rbac/role.yaml new file mode 100644 index 00000000000..569506669d7 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/role.yaml @@ -0,0 +1,293 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + 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/config/rbac/role_binding.yaml b/testdata/project-v4-multigroup/config/rbac/role_binding.yaml new file mode 100644 index 00000000000..2070ede4462 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + 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/config/rbac/sea-creatures_kraken_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_editor_role.yaml new file mode 100644 index 00000000000..c0601ecc6d7 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit krakens. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/sea-creatures_kraken_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_viewer_role.yaml new file mode 100644 index 00000000000..f9c55e9dafe --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/sea-creatures_kraken_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view krakens. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/sea-creatures_leviathan_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_editor_role.yaml new file mode 100644 index 00000000000..a062a277fca --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit leviathans. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/sea-creatures_leviathan_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_viewer_role.yaml new file mode 100644 index 00000000000..9791727c656 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/sea-creatures_leviathan_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view leviathans. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/service_account.yaml b/testdata/project-v4-multigroup/config/rbac/service_account.yaml new file mode 100644 index 00000000000..7cd6025bfc4 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/service_account.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: controller-manager + namespace: system diff --git a/testdata/project-v4-multigroup/config/rbac/ship_cruiser_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_cruiser_editor_role.yaml new file mode 100644 index 00000000000..2bbc0e18027 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/ship_cruiser_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit cruisers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/ship_cruiser_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_cruiser_viewer_role.yaml new file mode 100644 index 00000000000..bc0afd3335b --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/ship_cruiser_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view cruisers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/ship_destroyer_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_destroyer_editor_role.yaml new file mode 100644 index 00000000000..36533983918 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/ship_destroyer_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit destroyers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/ship_destroyer_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_destroyer_viewer_role.yaml new file mode 100644 index 00000000000..bf71d1276cb --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/ship_destroyer_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view destroyers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/ship_frigate_editor_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_frigate_editor_role.yaml new file mode 100644 index 00000000000..4191d6c22f6 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/ship_frigate_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit frigates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/ship_frigate_viewer_role.yaml b/testdata/project-v4-multigroup/config/rbac/ship_frigate_viewer_role.yaml new file mode 100644 index 00000000000..155416066b8 --- /dev/null +++ b/testdata/project-v4-multigroup/config/rbac/ship_frigate_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view frigates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/samples/_v1_lakers.yaml b/testdata/project-v4-multigroup/config/samples/_v1_lakers.yaml new file mode 100644 index 00000000000..91bf466c894 --- /dev/null +++ b/testdata/project-v4-multigroup/config/samples/_v1_lakers.yaml @@ -0,0 +1,6 @@ +apiVersion: testproject.org/v1 +kind: Lakers +metadata: + name: lakers-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/crew_v1_captain.yaml b/testdata/project-v4-multigroup/config/samples/crew_v1_captain.yaml new file mode 100644 index 00000000000..d0dcfc6cb4d --- /dev/null +++ b/testdata/project-v4-multigroup/config/samples/crew_v1_captain.yaml @@ -0,0 +1,6 @@ +apiVersion: crew.testproject.org/v1 +kind: Captain +metadata: + name: captain-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/fiz_v1_bar.yaml b/testdata/project-v4-multigroup/config/samples/fiz_v1_bar.yaml new file mode 100644 index 00000000000..5f4d6ced1e2 --- /dev/null +++ b/testdata/project-v4-multigroup/config/samples/fiz_v1_bar.yaml @@ -0,0 +1,6 @@ +apiVersion: fiz.testproject.org/v1 +kind: Bar +metadata: + name: bar-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/foo.policy_v1_healthcheckpolicy.yaml b/testdata/project-v4-multigroup/config/samples/foo.policy_v1_healthcheckpolicy.yaml new file mode 100644 index 00000000000..6e6d5e572ea --- /dev/null +++ b/testdata/project-v4-multigroup/config/samples/foo.policy_v1_healthcheckpolicy.yaml @@ -0,0 +1,6 @@ +apiVersion: foo.policy.testproject.org/v1 +kind: HealthCheckPolicy +metadata: + name: healthcheckpolicy-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/foo_v1_bar.yaml b/testdata/project-v4-multigroup/config/samples/foo_v1_bar.yaml new file mode 100644 index 00000000000..f43fb43849f --- /dev/null +++ b/testdata/project-v4-multigroup/config/samples/foo_v1_bar.yaml @@ -0,0 +1,6 @@ +apiVersion: foo.testproject.org/v1 +kind: Bar +metadata: + name: bar-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta1_kraken.yaml b/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta1_kraken.yaml new file mode 100644 index 00000000000..7d6055ff7a2 --- /dev/null +++ b/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta1_kraken.yaml @@ -0,0 +1,6 @@ +apiVersion: sea-creatures.testproject.org/v1beta1 +kind: Kraken +metadata: + name: kraken-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta2_leviathan.yaml b/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta2_leviathan.yaml new file mode 100644 index 00000000000..afcf8bc87fd --- /dev/null +++ b/testdata/project-v4-multigroup/config/samples/sea-creatures_v1beta2_leviathan.yaml @@ -0,0 +1,6 @@ +apiVersion: sea-creatures.testproject.org/v1beta2 +kind: Leviathan +metadata: + name: leviathan-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/ship_v1_destroyer.yaml b/testdata/project-v4-multigroup/config/samples/ship_v1_destroyer.yaml new file mode 100644 index 00000000000..a5bfa12cc0c --- /dev/null +++ b/testdata/project-v4-multigroup/config/samples/ship_v1_destroyer.yaml @@ -0,0 +1,6 @@ +apiVersion: ship.testproject.org/v1 +kind: Destroyer +metadata: + name: destroyer-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/ship_v1beta1_frigate.yaml b/testdata/project-v4-multigroup/config/samples/ship_v1beta1_frigate.yaml new file mode 100644 index 00000000000..1aa9f130cf5 --- /dev/null +++ b/testdata/project-v4-multigroup/config/samples/ship_v1beta1_frigate.yaml @@ -0,0 +1,6 @@ +apiVersion: ship.testproject.org/v1beta1 +kind: Frigate +metadata: + name: frigate-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/samples/ship_v2alpha1_cruiser.yaml b/testdata/project-v4-multigroup/config/samples/ship_v2alpha1_cruiser.yaml new file mode 100644 index 00000000000..d87858cb882 --- /dev/null +++ b/testdata/project-v4-multigroup/config/samples/ship_v2alpha1_cruiser.yaml @@ -0,0 +1,6 @@ +apiVersion: ship.testproject.org/v2alpha1 +kind: Cruiser +metadata: + name: cruiser-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4-multigroup/config/webhook/kustomization.yaml b/testdata/project-v4-multigroup/config/webhook/kustomization.yaml new file mode 100644 index 00000000000..9cf26134e4d --- /dev/null +++ b/testdata/project-v4-multigroup/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/testdata/project-v4-multigroup/config/webhook/kustomizeconfig.yaml b/testdata/project-v4-multigroup/config/webhook/kustomizeconfig.yaml new file mode 100644 index 00000000000..25e21e3c963 --- /dev/null +++ b/testdata/project-v4-multigroup/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,25 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# 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 + +varReference: +- path: metadata/annotations diff --git a/testdata/project-v4-multigroup/config/webhook/manifests.yaml b/testdata/project-v4-multigroup/config/webhook/manifests.yaml new file mode 100644 index 00000000000..77c371e3d44 --- /dev/null +++ b/testdata/project-v4-multigroup/config/webhook/manifests.yaml @@ -0,0 +1,134 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + 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: + creationTimestamp: null + 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/config/webhook/service.yaml b/testdata/project-v4-multigroup/config/webhook/service.yaml new file mode 100644 index 00000000000..3f638bd9c68 --- /dev/null +++ b/testdata/project-v4-multigroup/config/webhook/service.yaml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Service +metadata: + 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/controllers/apps/deployment_controller.go b/testdata/project-v4-multigroup/controllers/apps/deployment_controller.go new file mode 100644 index 00000000000..e62755f4166 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/apps/deployment_controller.go @@ -0,0 +1,61 @@ +/* +Copyright 2022 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.11.2/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/controllers/apps/suite_test.go b/testdata/project-v4-multigroup/controllers/apps/suite_test.go new file mode 100644 index 00000000000..e9d34ce2009 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/apps/suite_test.go @@ -0,0 +1,81 @@ +/* +Copyright 2022 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 ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + 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 TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + } + + 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()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/controllers/crew/captain_controller.go b/testdata/project-v4-multigroup/controllers/crew/captain_controller.go new file mode 100644 index 00000000000..78e25e39630 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/crew/captain_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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/apis/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.11.2/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/controllers/crew/suite_test.go b/testdata/project-v4-multigroup/controllers/crew/suite_test.go new file mode 100644 index 00000000000..15552b263cd --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/crew/suite_test.go @@ -0,0 +1,82 @@ +/* +Copyright 2022 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 ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/crew/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 TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = crewv1.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()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/controllers/fiz/bar_controller.go b/testdata/project-v4-multigroup/controllers/fiz/bar_controller.go new file mode 100644 index 00000000000..a86d4ee6e65 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/fiz/bar_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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/apis/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.11.2/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/controllers/fiz/suite_test.go b/testdata/project-v4-multigroup/controllers/fiz/suite_test.go new file mode 100644 index 00000000000..0c3ac024d57 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/fiz/suite_test.go @@ -0,0 +1,82 @@ +/* +Copyright 2022 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 ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + 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/apis/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 TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + } + + 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()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/controllers/foo.policy/healthcheckpolicy_controller.go b/testdata/project-v4-multigroup/controllers/foo.policy/healthcheckpolicy_controller.go new file mode 100644 index 00000000000..572af64269f --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/foo.policy/healthcheckpolicy_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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/apis/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.11.2/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/controllers/foo.policy/suite_test.go b/testdata/project-v4-multigroup/controllers/foo.policy/suite_test.go new file mode 100644 index 00000000000..974df369388 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/foo.policy/suite_test.go @@ -0,0 +1,82 @@ +/* +Copyright 2022 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 ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + 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/apis/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 TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + } + + 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()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/controllers/foo/bar_controller.go b/testdata/project-v4-multigroup/controllers/foo/bar_controller.go new file mode 100644 index 00000000000..aa8c2f7594b --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/foo/bar_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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/apis/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.11.2/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/controllers/foo/suite_test.go b/testdata/project-v4-multigroup/controllers/foo/suite_test.go new file mode 100644 index 00000000000..bba4736da90 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/foo/suite_test.go @@ -0,0 +1,82 @@ +/* +Copyright 2022 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 ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + 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/apis/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 TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + } + + 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()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/controllers/lakers_controller.go b/testdata/project-v4-multigroup/controllers/lakers_controller.go new file mode 100644 index 00000000000..11b958581cc --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/lakers_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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 controllers + +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/apis/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.11.2/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/controllers/sea-creatures/kraken_controller.go b/testdata/project-v4-multigroup/controllers/sea-creatures/kraken_controller.go new file mode 100644 index 00000000000..ecf5be01ff8 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/sea-creatures/kraken_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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/apis/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.11.2/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/controllers/sea-creatures/leviathan_controller.go b/testdata/project-v4-multigroup/controllers/sea-creatures/leviathan_controller.go new file mode 100644 index 00000000000..0151732e619 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/sea-creatures/leviathan_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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/apis/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.11.2/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/controllers/sea-creatures/suite_test.go b/testdata/project-v4-multigroup/controllers/sea-creatures/suite_test.go new file mode 100644 index 00000000000..ee6ec81d3b6 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/sea-creatures/suite_test.go @@ -0,0 +1,86 @@ +/* +Copyright 2022 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 ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + 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/apis/sea-creatures/v1beta1" + seacreaturesv1beta2 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/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 TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + } + + 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()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/controllers/ship/cruiser_controller.go b/testdata/project-v4-multigroup/controllers/ship/cruiser_controller.go new file mode 100644 index 00000000000..79c56de1edc --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/ship/cruiser_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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/apis/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.11.2/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/controllers/ship/destroyer_controller.go b/testdata/project-v4-multigroup/controllers/ship/destroyer_controller.go new file mode 100644 index 00000000000..550c6c57270 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/ship/destroyer_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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/apis/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.11.2/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/controllers/ship/frigate_controller.go b/testdata/project-v4-multigroup/controllers/ship/frigate_controller.go new file mode 100644 index 00000000000..fad8a8b5c6e --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/ship/frigate_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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/apis/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.11.2/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/controllers/ship/suite_test.go b/testdata/project-v4-multigroup/controllers/ship/suite_test.go new file mode 100644 index 00000000000..02328bb9960 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/ship/suite_test.go @@ -0,0 +1,90 @@ +/* +Copyright 2022 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 ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + 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/apis/ship/v1" + shipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/ship/v1beta1" + shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/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 TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + } + + 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()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/controllers/suite_test.go b/testdata/project-v4-multigroup/controllers/suite_test.go new file mode 100644 index 00000000000..4f27b40e436 --- /dev/null +++ b/testdata/project-v4-multigroup/controllers/suite_test.go @@ -0,0 +1,82 @@ +/* +Copyright 2022 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 controllers + +import ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + 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/apis/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 TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + } + + 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()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4-multigroup/go.mod b/testdata/project-v4-multigroup/go.mod new file mode 100644 index 00000000000..97d467d76d3 --- /dev/null +++ b/testdata/project-v4-multigroup/go.mod @@ -0,0 +1,74 @@ +module sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup + +go 1.17 + +require ( + github.com/onsi/ginkgo v1.16.5 + github.com/onsi/gomega v1.17.0 + k8s.io/api v0.23.5 + k8s.io/apimachinery v0.23.5 + k8s.io/client-go v0.23.5 + sigs.k8s.io/controller-runtime v0.11.2 +) + +require ( + cloud.google.com/go v0.81.0 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.18 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/go-logr/logr v1.2.0 // indirect + github.com/go-logr/zapr v1.2.0 // 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.2 // indirect + github.com/google/go-cmp v0.5.5 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/google/uuid v1.1.2 // indirect + github.com/googleapis/gnostic v0.5.5 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/nxadm/tail v1.4.8 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.11.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.28.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.19.1 // indirect + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect + golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect + golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect + golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + k8s.io/apiextensions-apiserver v0.23.5 // indirect + k8s.io/component-base v0.23.5 // indirect + k8s.io/klog/v2 v2.30.0 // indirect + k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect + k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect + sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/testdata/project-v4-multigroup/hack/boilerplate.go.txt b/testdata/project-v4-multigroup/hack/boilerplate.go.txt new file mode 100644 index 00000000000..b54e305f300 --- /dev/null +++ b/testdata/project-v4-multigroup/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +Copyright 2022 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/main.go b/testdata/project-v4-multigroup/main.go new file mode 100644 index 00000000000..fb53924ca8f --- /dev/null +++ b/testdata/project-v4-multigroup/main.go @@ -0,0 +1,230 @@ +/* +Copyright 2022 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" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/crew/v1" + fizv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/fiz/v1" + foopolicyv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/foo.policy/v1" + foov1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/foo/v1" + seacreaturesv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/sea-creatures/v1beta1" + seacreaturesv1beta2 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/sea-creatures/v1beta2" + shipv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/ship/v1" + shipv1beta1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/ship/v1beta1" + shipv2alpha1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/ship/v2alpha1" + testprojectorgv1 "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/apis/v1" + "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/controllers" + appscontrollers "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/controllers/apps" + crewcontrollers "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/controllers/crew" + fizcontrollers "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/controllers/fiz" + foocontrollers "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/controllers/foo" + foopolicycontrollers "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/controllers/foo.policy" + seacreaturescontrollers "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/controllers/sea-creatures" + shipcontrollers "sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup/controllers/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, + MetricsBindAddress: metricsAddr, + Port: 9443, + HealthProbeBindAddress: probeAddr, + LeaderElection: enableLeaderElection, + LeaderElectionID: "3e9f67a9.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 = (&crewcontrollers.CaptainReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Captain") + os.Exit(1) + } + if err = (&crewv1.Captain{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Captain") + os.Exit(1) + } + if err = (&shipcontrollers.FrigateReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Frigate") + os.Exit(1) + } + if err = (&shipv1beta1.Frigate{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Frigate") + os.Exit(1) + } + if err = (&shipcontrollers.DestroyerReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Destroyer") + os.Exit(1) + } + if err = (&shipv1.Destroyer{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Destroyer") + os.Exit(1) + } + if err = (&shipcontrollers.CruiserReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Cruiser") + os.Exit(1) + } + if err = (&shipv2alpha1.Cruiser{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Cruiser") + os.Exit(1) + } + if err = (&seacreaturescontrollers.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 = (&seacreaturescontrollers.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 = (&foopolicycontrollers.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 = (&appscontrollers.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 = (&foocontrollers.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 = (&fizcontrollers.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 = (&controllers.LakersReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Lakers") + os.Exit(1) + } + 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/.dockerignore b/testdata/project-v4/.dockerignore new file mode 100644 index 00000000000..0f046820f18 --- /dev/null +++ b/testdata/project-v4/.dockerignore @@ -0,0 +1,4 @@ +# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Ignore build and test binaries. +bin/ +testbin/ diff --git a/testdata/project-v4/.gitignore b/testdata/project-v4/.gitignore new file mode 100644 index 00000000000..d97ffc5159b --- /dev/null +++ b/testdata/project-v4/.gitignore @@ -0,0 +1,24 @@ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin + +# 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 +*.swp +*.swo +*~ diff --git a/testdata/project-v4/Dockerfile b/testdata/project-v4/Dockerfile new file mode 100644 index 00000000000..456533d4c2d --- /dev/null +++ b/testdata/project-v4/Dockerfile @@ -0,0 +1,27 @@ +# Build the manager binary +FROM golang:1.17 as builder + +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 main.go main.go +COPY api/ api/ +COPY controllers/ controllers/ + +# Build +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager 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/Makefile b/testdata/project-v4/Makefile new file mode 100644 index 00000000000..4c98e81e111 --- /dev/null +++ b/testdata/project-v4/Makefile @@ -0,0 +1,133 @@ + +# 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.23 + +# 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 + +# Setting SHELL to bash allows bash commands to be executed by recipes. +# This is a requirement for 'setup-envtest.sh' in the test target. +# 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 commands 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) -p path)" go test ./... -coverprofile cover.out + +##@ Build + +.PHONY: build +build: generate fmt vet ## Build manager binary. + go build -o bin/manager main.go + +.PHONY: run +run: manifests generate fmt vet ## Run a controller from your host. + go run ./main.go + +.PHONY: docker-build +docker-build: test ## Build docker image with the manager. + docker build -t ${IMG} . + +.PHONY: docker-push +docker-push: ## Push docker image with the manager. + docker push ${IMG} + +##@ 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 +KUSTOMIZE ?= $(LOCALBIN)/kustomize +CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen +ENVTEST ?= $(LOCALBIN)/setup-envtest + +## Tool Versions +KUSTOMIZE_VERSION ?= v3.8.7 +CONTROLLER_TOOLS_VERSION ?= v0.8.0 + +KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" +.PHONY: kustomize +kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. +$(KUSTOMIZE): $(LOCALBIN) + curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN) + +.PHONY: controller-gen +controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. +$(CONTROLLER_GEN): $(LOCALBIN) + 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) + GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest diff --git a/testdata/project-v4/PROJECT b/testdata/project-v4/PROJECT new file mode 100644 index 00000000000..a383bc2bf60 --- /dev/null +++ b/testdata/project-v4/PROJECT @@ -0,0 +1,49 @@ +domain: testproject.org +layout: +- go.kubebuilder.io/v3 +projectName: project-v4 +repo: sigs.k8s.io/kubebuilder/testdata/project-v4 +resources: +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: crew + kind: Captain + path: sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1 + version: v1 + webhooks: + defaulting: true + validation: true + webhookVersion: v1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: testproject.org + group: crew + kind: FirstMate + path: sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1 + version: v1 + webhooks: + conversion: true + webhookVersion: v1 +- api: + crdVersion: v1 + controller: true + domain: testproject.org + group: crew + kind: Admiral + path: sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1 + plural: admirales + version: v1 + webhooks: + defaulting: true + webhookVersion: v1 +- controller: true + domain: testproject.org + group: crew + kind: Laker + version: v1 +version: "3" diff --git a/testdata/project-v4/README.md b/testdata/project-v4/README.md new file mode 100644 index 00000000000..6d125e643a0 --- /dev/null +++ b/testdata/project-v4/README.md @@ -0,0 +1,94 @@ +# project-v4 +// TODO(user): Add simple overview of use/purpose + +## Description +// TODO(user): An in-depth paragraph about your project and overview of use + +## Getting Started +You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster. +**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows). + +### Running on the cluster +1. Install Instances of Custom Resources: + +```sh +kubectl apply -f config/samples/ +``` + +2. Build and push your image to the location specified by `IMG`: + +```sh +make docker-build docker-push IMG=/project-v4:tag +``` + +3. Deploy the controller to the cluster with the image specified by `IMG`: + +```sh +make deploy IMG=/project-v4:tag +``` + +### Uninstall CRDs +To delete the CRDs from the cluster: + +```sh +make uninstall +``` + +### Undeploy controller +UnDeploy the controller to 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 provides a reconcile function responsible for synchronizing resources untile 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 2022 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/api/v1/admiral_types.go b/testdata/project-v4/api/v1/admiral_types.go new file mode 100644 index 00000000000..9cbac39e7d2 --- /dev/null +++ b/testdata/project-v4/api/v1/admiral_types.go @@ -0,0 +1,65 @@ +/* +Copyright 2022 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. + +// AdmiralSpec defines the desired state of Admiral +type AdmiralSpec 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 Admiral. Edit admiral_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// AdmiralStatus defines the observed state of Admiral +type AdmiralStatus 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:path=admirales,scope=Cluster + +// Admiral is the Schema for the admirales API +type Admiral struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec AdmiralSpec `json:"spec,omitempty"` + Status AdmiralStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// AdmiralList contains a list of Admiral +type AdmiralList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Admiral `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Admiral{}, &AdmiralList{}) +} diff --git a/testdata/project-v4/api/v1/admiral_webhook.go b/testdata/project-v4/api/v1/admiral_webhook.go new file mode 100644 index 00000000000..acc74d793f0 --- /dev/null +++ b/testdata/project-v4/api/v1/admiral_webhook.go @@ -0,0 +1,45 @@ +/* +Copyright 2022 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 admirallog = logf.Log.WithName("admiral-resource") + +func (r *Admiral) 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-admiral,mutating=true,failurePolicy=fail,sideEffects=None,groups=crew.testproject.org,resources=admirales,verbs=create;update,versions=v1,name=madmiral.kb.io,admissionReviewVersions=v1 + +var _ webhook.Defaulter = &Admiral{} + +// Default implements webhook.Defaulter so a webhook will be registered for the type +func (r *Admiral) Default() { + admirallog.Info("default", "name", r.Name) + + // TODO(user): fill in your defaulting logic. +} diff --git a/testdata/project-v4/api/v1/captain_types.go b/testdata/project-v4/api/v1/captain_types.go new file mode 100644 index 00000000000..e81debb719c --- /dev/null +++ b/testdata/project-v4/api/v1/captain_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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/api/v1/captain_webhook.go b/testdata/project-v4/api/v1/captain_webhook.go new file mode 100644 index 00000000000..ba00000c137 --- /dev/null +++ b/testdata/project-v4/api/v1/captain_webhook.go @@ -0,0 +1,75 @@ +/* +Copyright 2022 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" +) + +// log is for logging in this package. +var captainlog = logf.Log.WithName("captain-resource") + +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() error { + captainlog.Info("validate create", "name", r.Name) + + // TODO(user): fill in your validation logic upon object creation. + return nil +} + +// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type +func (r *Captain) ValidateUpdate(old runtime.Object) error { + captainlog.Info("validate update", "name", r.Name) + + // TODO(user): fill in your validation logic upon object update. + return nil +} + +// ValidateDelete implements webhook.Validator so a webhook will be registered for the type +func (r *Captain) ValidateDelete() error { + captainlog.Info("validate delete", "name", r.Name) + + // TODO(user): fill in your validation logic upon object deletion. + return nil +} diff --git a/testdata/project-v4/api/v1/firstmate_types.go b/testdata/project-v4/api/v1/firstmate_types.go new file mode 100644 index 00000000000..7515759833a --- /dev/null +++ b/testdata/project-v4/api/v1/firstmate_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2022 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. + +// FirstMateSpec defines the desired state of FirstMate +type FirstMateSpec 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 FirstMate. Edit firstmate_types.go to remove/update + Foo string `json:"foo,omitempty"` +} + +// FirstMateStatus defines the observed state of FirstMate +type FirstMateStatus 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 + +// FirstMate is the Schema for the firstmates API +type FirstMate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec FirstMateSpec `json:"spec,omitempty"` + Status FirstMateStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// FirstMateList contains a list of FirstMate +type FirstMateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []FirstMate `json:"items"` +} + +func init() { + SchemeBuilder.Register(&FirstMate{}, &FirstMateList{}) +} diff --git a/testdata/project-v4/api/v1/firstmate_webhook.go b/testdata/project-v4/api/v1/firstmate_webhook.go new file mode 100644 index 00000000000..5fa6046165d --- /dev/null +++ b/testdata/project-v4/api/v1/firstmate_webhook.go @@ -0,0 +1,33 @@ +/* +Copyright 2022 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" +) + +// log is for logging in this package. +var firstmatelog = logf.Log.WithName("firstmate-resource") + +func (r *FirstMate) 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/api/v1/groupversion_info.go b/testdata/project-v4/api/v1/groupversion_info.go new file mode 100644 index 00000000000..33458c7506e --- /dev/null +++ b/testdata/project-v4/api/v1/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright 2022 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 crew v1 API group +//+kubebuilder:object:generate=true +//+groupName=crew.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: "crew.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/api/v1/webhook_suite_test.go b/testdata/project-v4/api/v1/webhook_suite_test.go new file mode 100644 index 00000000000..2c1a26807e7 --- /dev/null +++ b/testdata/project-v4/api/v1/webhook_suite_test.go @@ -0,0 +1,138 @@ +/* +Copyright 2022 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" + "testing" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + admissionv1beta1 "k8s.io/api/admission/v1beta1" + //+kubebuilder:scaffold:imports + "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// 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) + + RunSpecsWithDefaultAndCustomReporters(t, + "Webhook Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + 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 := runtime.NewScheme() + err = AddToScheme(scheme) + Expect(err).NotTo(HaveOccurred()) + + err = admissionv1beta1.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, + Host: webhookInstallOptions.LocalServingHost, + Port: webhookInstallOptions.LocalServingPort, + CertDir: webhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + MetricsBindAddress: "0", + }) + Expect(err).NotTo(HaveOccurred()) + + err = (&Captain{}).SetupWebhookWithManager(mgr) + Expect(err).NotTo(HaveOccurred()) + + err = (&Admiral{}).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 + } + conn.Close() + return nil + }).Should(Succeed()) + +}, 60) + +var _ = AfterSuite(func() { + cancel() + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4/api/v1/zz_generated.deepcopy.go b/testdata/project-v4/api/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000000..eb076ea05ea --- /dev/null +++ b/testdata/project-v4/api/v1/zz_generated.deepcopy.go @@ -0,0 +1,293 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright 2022 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 *Admiral) DeepCopyInto(out *Admiral) { + *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 Admiral. +func (in *Admiral) DeepCopy() *Admiral { + if in == nil { + return nil + } + out := new(Admiral) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Admiral) 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 *AdmiralList) DeepCopyInto(out *AdmiralList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Admiral, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralList. +func (in *AdmiralList) DeepCopy() *AdmiralList { + if in == nil { + return nil + } + out := new(AdmiralList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AdmiralList) 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 *AdmiralSpec) DeepCopyInto(out *AdmiralSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralSpec. +func (in *AdmiralSpec) DeepCopy() *AdmiralSpec { + if in == nil { + return nil + } + out := new(AdmiralSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AdmiralStatus) DeepCopyInto(out *AdmiralStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmiralStatus. +func (in *AdmiralStatus) DeepCopy() *AdmiralStatus { + if in == nil { + return nil + } + out := new(AdmiralStatus) + in.DeepCopyInto(out) + return out +} + +// 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 +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FirstMate) DeepCopyInto(out *FirstMate) { + *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 FirstMate. +func (in *FirstMate) DeepCopy() *FirstMate { + if in == nil { + return nil + } + out := new(FirstMate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FirstMate) 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 *FirstMateList) DeepCopyInto(out *FirstMateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]FirstMate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateList. +func (in *FirstMateList) DeepCopy() *FirstMateList { + if in == nil { + return nil + } + out := new(FirstMateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *FirstMateList) 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 *FirstMateSpec) DeepCopyInto(out *FirstMateSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateSpec. +func (in *FirstMateSpec) DeepCopy() *FirstMateSpec { + if in == nil { + return nil + } + out := new(FirstMateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FirstMateStatus) DeepCopyInto(out *FirstMateStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstMateStatus. +func (in *FirstMateStatus) DeepCopy() *FirstMateStatus { + if in == nil { + return nil + } + out := new(FirstMateStatus) + in.DeepCopyInto(out) + return out +} diff --git a/testdata/project-v4/config/certmanager/certificate.yaml b/testdata/project-v4/config/certmanager/certificate.yaml new file mode 100644 index 00000000000..52d866183c7 --- /dev/null +++ b/testdata/project-v4/config/certmanager/certificate.yaml @@ -0,0 +1,25 @@ +# 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: + name: selfsigned-issuer + namespace: system +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + 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/config/certmanager/kustomization.yaml b/testdata/project-v4/config/certmanager/kustomization.yaml new file mode 100644 index 00000000000..bebea5a595e --- /dev/null +++ b/testdata/project-v4/config/certmanager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- certificate.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/testdata/project-v4/config/certmanager/kustomizeconfig.yaml b/testdata/project-v4/config/certmanager/kustomizeconfig.yaml new file mode 100644 index 00000000000..90d7c313ca1 --- /dev/null +++ b/testdata/project-v4/config/certmanager/kustomizeconfig.yaml @@ -0,0 +1,16 @@ +# This configuration is for teaching kustomize how to update name ref and var substitution +nameReference: +- kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name + +varReference: +- kind: Certificate + group: cert-manager.io + path: spec/commonName +- kind: Certificate + group: cert-manager.io + path: spec/dnsNames diff --git a/testdata/project-v4/config/crd/bases/crew.testproject.org_admirales.yaml b/testdata/project-v4/config/crd/bases/crew.testproject.org_admirales.yaml new file mode 100644 index 00000000000..2b18f84f649 --- /dev/null +++ b/testdata/project-v4/config/crd/bases/crew.testproject.org_admirales.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + name: admirales.crew.testproject.org +spec: + group: crew.testproject.org + names: + kind: Admiral + listKind: AdmiralList + plural: admirales + singular: admiral + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Admiral is the Schema for the admirales 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: AdmiralSpec defines the desired state of Admiral + properties: + foo: + description: Foo is an example field of Admiral. Edit admiral_types.go + to remove/update + type: string + type: object + status: + description: AdmiralStatus defines the observed state of Admiral + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4/config/crd/bases/crew.testproject.org_captains.yaml b/testdata/project-v4/config/crd/bases/crew.testproject.org_captains.yaml new file mode 100644 index 00000000000..41b080622f6 --- /dev/null +++ b/testdata/project-v4/config/crd/bases/crew.testproject.org_captains.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + 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: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4/config/crd/bases/crew.testproject.org_firstmates.yaml b/testdata/project-v4/config/crd/bases/crew.testproject.org_firstmates.yaml new file mode 100644 index 00000000000..5ccecbc8eb8 --- /dev/null +++ b/testdata/project-v4/config/crd/bases/crew.testproject.org_firstmates.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + name: firstmates.crew.testproject.org +spec: + group: crew.testproject.org + names: + kind: FirstMate + listKind: FirstMateList + plural: firstmates + singular: firstmate + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: FirstMate is the Schema for the firstmates 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: FirstMateSpec defines the desired state of FirstMate + properties: + foo: + description: Foo is an example field of FirstMate. Edit firstmate_types.go + to remove/update + type: string + type: object + status: + description: FirstMateStatus defines the observed state of FirstMate + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/testdata/project-v4/config/crd/kustomization.yaml b/testdata/project-v4/config/crd/kustomization.yaml new file mode 100644 index 00000000000..0d38144170a --- /dev/null +++ b/testdata/project-v4/config/crd/kustomization.yaml @@ -0,0 +1,27 @@ +# 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/crew.testproject.org_firstmates.yaml +- bases/crew.testproject.org_admirales.yaml +#+kubebuilder:scaffold:crdkustomizeresource + +patchesStrategicMerge: +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. +# patches here are for enabling the conversion webhook for each CRD +#- patches/webhook_in_captains.yaml +#- patches/webhook_in_firstmates.yaml +#- patches/webhook_in_admirales.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 +#- patches/cainjection_in_captains.yaml +#- patches/cainjection_in_firstmates.yaml +#- patches/cainjection_in_admirales.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/config/crd/kustomizeconfig.yaml b/testdata/project-v4/config/crd/kustomizeconfig.yaml new file mode 100644 index 00000000000..ec5c150a9df --- /dev/null +++ b/testdata/project-v4/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/config/crd/patches/cainjection_in_admirales.yaml b/testdata/project-v4/config/crd/patches/cainjection_in_admirales.yaml new file mode 100644 index 00000000000..04882738e44 --- /dev/null +++ b/testdata/project-v4/config/crd/patches/cainjection_in_admirales.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: admirales.crew.testproject.org diff --git a/testdata/project-v4/config/crd/patches/cainjection_in_captains.yaml b/testdata/project-v4/config/crd/patches/cainjection_in_captains.yaml new file mode 100644 index 00000000000..9c9d61b0c97 --- /dev/null +++ b/testdata/project-v4/config/crd/patches/cainjection_in_captains.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: captains.crew.testproject.org diff --git a/testdata/project-v4/config/crd/patches/cainjection_in_firstmates.yaml b/testdata/project-v4/config/crd/patches/cainjection_in_firstmates.yaml new file mode 100644 index 00000000000..6849f00fb85 --- /dev/null +++ b/testdata/project-v4/config/crd/patches/cainjection_in_firstmates.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: firstmates.crew.testproject.org diff --git a/testdata/project-v4/config/crd/patches/webhook_in_admirales.yaml b/testdata/project-v4/config/crd/patches/webhook_in_admirales.yaml new file mode 100644 index 00000000000..cf986a6a411 --- /dev/null +++ b/testdata/project-v4/config/crd/patches/webhook_in_admirales.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: admirales.crew.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4/config/crd/patches/webhook_in_captains.yaml b/testdata/project-v4/config/crd/patches/webhook_in_captains.yaml new file mode 100644 index 00000000000..f73ae2e8abc --- /dev/null +++ b/testdata/project-v4/config/crd/patches/webhook_in_captains.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: captains.crew.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4/config/crd/patches/webhook_in_firstmates.yaml b/testdata/project-v4/config/crd/patches/webhook_in_firstmates.yaml new file mode 100644 index 00000000000..76ee5acedbd --- /dev/null +++ b/testdata/project-v4/config/crd/patches/webhook_in_firstmates.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: firstmates.crew.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/testdata/project-v4/config/default/kustomization.yaml b/testdata/project-v4/config/default/kustomization.yaml new file mode 100644 index 00000000000..f0b6642ecd3 --- /dev/null +++ b/testdata/project-v4/config/default/kustomization.yaml @@ -0,0 +1,74 @@ +# Adds namespace to all resources. +namespace: project-v4-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- + +# Labels to add to all resources and selectors. +#commonLabels: +# someName: someValue + +bases: +- ../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 + +# Mount the controller config file for loading manager configurations +# through a ComponentConfig type +#- manager_config_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 + +# the following config is for teaching kustomize how to do var substitution +vars: +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +# fieldref: +# fieldpath: metadata.namespace +#- name: CERTIFICATE_NAME +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +#- name: SERVICE_NAMESPACE # namespace of the service +# objref: +# kind: Service +# version: v1 +# name: webhook-service +# fieldref: +# fieldpath: metadata.namespace +#- name: SERVICE_NAME +# objref: +# kind: Service +# version: v1 +# name: webhook-service diff --git a/testdata/project-v4/config/default/manager_auth_proxy_patch.yaml b/testdata/project-v4/config/default/manager_auth_proxy_patch.yaml new file mode 100644 index 00000000000..131a3142928 --- /dev/null +++ b/testdata/project-v4/config/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,34 @@ +# 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 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0 + 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/config/default/manager_config_patch.yaml b/testdata/project-v4/config/default/manager_config_patch.yaml new file mode 100644 index 00000000000..6c400155cfb --- /dev/null +++ b/testdata/project-v4/config/default/manager_config_patch.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + args: + - "--config=controller_manager_config.yaml" + volumeMounts: + - name: manager-config + mountPath: /controller_manager_config.yaml + subPath: controller_manager_config.yaml + volumes: + - name: manager-config + configMap: + name: manager-config diff --git a/testdata/project-v4/config/default/manager_webhook_patch.yaml b/testdata/project-v4/config/default/manager_webhook_patch.yaml new file mode 100644 index 00000000000..738de350b71 --- /dev/null +++ b/testdata/project-v4/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/config/default/webhookcainjection_patch.yaml b/testdata/project-v4/config/default/webhookcainjection_patch.yaml new file mode 100644 index 00000000000..02ab515d428 --- /dev/null +++ b/testdata/project-v4/config/default/webhookcainjection_patch.yaml @@ -0,0 +1,15 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/testdata/project-v4/config/manager/controller_manager_config.yaml b/testdata/project-v4/config/manager/controller_manager_config.yaml new file mode 100644 index 00000000000..6ec455b8d87 --- /dev/null +++ b/testdata/project-v4/config/manager/controller_manager_config.yaml @@ -0,0 +1,21 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +health: + healthProbeBindAddress: :8081 +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: da1d9c86.testproject.org +# leaderElectionReleaseOnCancel defines if the leader should step down volume +# 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 diff --git a/testdata/project-v4/config/manager/kustomization.yaml b/testdata/project-v4/config/manager/kustomization.yaml new file mode 100644 index 00000000000..2bcd3eeaa94 --- /dev/null +++ b/testdata/project-v4/config/manager/kustomization.yaml @@ -0,0 +1,10 @@ +resources: +- manager.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: +- name: manager-config + files: + - controller_manager_config.yaml diff --git a/testdata/project-v4/config/manager/manager.yaml b/testdata/project-v4/config/manager/manager.yaml new file mode 100644 index 00000000000..cf11cecc26a --- /dev/null +++ b/testdata/project-v4/config/manager/manager.yaml @@ -0,0 +1,60 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager +spec: + selector: + matchLabels: + control-plane: controller-manager + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + securityContext: + runAsNonRoot: true + containers: + - command: + - /manager + args: + - --leader-elect + image: controller:latest + name: manager + securityContext: + allowPrivilegeEscalation: false + 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/config/prometheus/kustomization.yaml b/testdata/project-v4/config/prometheus/kustomization.yaml new file mode 100644 index 00000000000..ed137168a1d --- /dev/null +++ b/testdata/project-v4/config/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/testdata/project-v4/config/prometheus/monitor.yaml b/testdata/project-v4/config/prometheus/monitor.yaml new file mode 100644 index 00000000000..d19136ae710 --- /dev/null +++ b/testdata/project-v4/config/prometheus/monitor.yaml @@ -0,0 +1,20 @@ + +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: controller-manager + 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/config/rbac/admiral_editor_role.yaml b/testdata/project-v4/config/rbac/admiral_editor_role.yaml new file mode 100644 index 00000000000..08184d661d2 --- /dev/null +++ b/testdata/project-v4/config/rbac/admiral_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit admirales. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: admiral-editor-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirales + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - admirales/status + verbs: + - get diff --git a/testdata/project-v4/config/rbac/admiral_viewer_role.yaml b/testdata/project-v4/config/rbac/admiral_viewer_role.yaml new file mode 100644 index 00000000000..65df31b4b48 --- /dev/null +++ b/testdata/project-v4/config/rbac/admiral_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view admirales. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: admiral-viewer-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirales + verbs: + - get + - list + - watch +- apiGroups: + - crew.testproject.org + resources: + - admirales/status + verbs: + - get diff --git a/testdata/project-v4/config/rbac/auth_proxy_client_clusterrole.yaml b/testdata/project-v4/config/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 00000000000..51a75db47a5 --- /dev/null +++ b/testdata/project-v4/config/rbac/auth_proxy_client_clusterrole.yaml @@ -0,0 +1,9 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/testdata/project-v4/config/rbac/auth_proxy_role.yaml b/testdata/project-v4/config/rbac/auth_proxy_role.yaml new file mode 100644 index 00000000000..80e1857c594 --- /dev/null +++ b/testdata/project-v4/config/rbac/auth_proxy_role.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/auth_proxy_role_binding.yaml b/testdata/project-v4/config/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 00000000000..ec7acc0a1b7 --- /dev/null +++ b/testdata/project-v4/config/rbac/auth_proxy_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + 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/config/rbac/auth_proxy_service.yaml b/testdata/project-v4/config/rbac/auth_proxy_service.yaml new file mode 100644 index 00000000000..71f1797279e --- /dev/null +++ b/testdata/project-v4/config/rbac/auth_proxy_service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + 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/config/rbac/captain_editor_role.yaml b/testdata/project-v4/config/rbac/captain_editor_role.yaml new file mode 100644 index 00000000000..4b53ae38ffa --- /dev/null +++ b/testdata/project-v4/config/rbac/captain_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/captain_viewer_role.yaml b/testdata/project-v4/config/rbac/captain_viewer_role.yaml new file mode 100644 index 00000000000..f19e10439d2 --- /dev/null +++ b/testdata/project-v4/config/rbac/captain_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + 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/config/rbac/firstmate_editor_role.yaml b/testdata/project-v4/config/rbac/firstmate_editor_role.yaml new file mode 100644 index 00000000000..22a08be29dd --- /dev/null +++ b/testdata/project-v4/config/rbac/firstmate_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit firstmates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: firstmate-editor-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - firstmates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - firstmates/status + verbs: + - get diff --git a/testdata/project-v4/config/rbac/firstmate_viewer_role.yaml b/testdata/project-v4/config/rbac/firstmate_viewer_role.yaml new file mode 100644 index 00000000000..9fd6ba933c7 --- /dev/null +++ b/testdata/project-v4/config/rbac/firstmate_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view firstmates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: firstmate-viewer-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - firstmates + verbs: + - get + - list + - watch +- apiGroups: + - crew.testproject.org + resources: + - firstmates/status + verbs: + - get diff --git a/testdata/project-v4/config/rbac/kustomization.yaml b/testdata/project-v4/config/rbac/kustomization.yaml new file mode 100644 index 00000000000..731832a6ac3 --- /dev/null +++ b/testdata/project-v4/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/config/rbac/leader_election_role.yaml b/testdata/project-v4/config/rbac/leader_election_role.yaml new file mode 100644 index 00000000000..4190ec8059e --- /dev/null +++ b/testdata/project-v4/config/rbac/leader_election_role.yaml @@ -0,0 +1,37 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + 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/config/rbac/leader_election_role_binding.yaml b/testdata/project-v4/config/rbac/leader_election_role_binding.yaml new file mode 100644 index 00000000000..1d1321ed4f0 --- /dev/null +++ b/testdata/project-v4/config/rbac/leader_election_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + 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/config/rbac/role.yaml b/testdata/project-v4/config/rbac/role.yaml new file mode 100644 index 00000000000..8c4e2fa042c --- /dev/null +++ b/testdata/project-v4/config/rbac/role.yaml @@ -0,0 +1,111 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: manager-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - admirales + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - admirales/finalizers + verbs: + - update +- apiGroups: + - crew.testproject.org + resources: + - admirales/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: + - crew.testproject.org + resources: + - firstmates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - firstmates/finalizers + verbs: + - update +- apiGroups: + - crew.testproject.org + resources: + - firstmates/status + verbs: + - get + - patch + - update +- apiGroups: + - crew.testproject.org + resources: + - lakers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - crew.testproject.org + resources: + - lakers/finalizers + verbs: + - update +- apiGroups: + - crew.testproject.org + resources: + - lakers/status + verbs: + - get + - patch + - update diff --git a/testdata/project-v4/config/rbac/role_binding.yaml b/testdata/project-v4/config/rbac/role_binding.yaml new file mode 100644 index 00000000000..2070ede4462 --- /dev/null +++ b/testdata/project-v4/config/rbac/role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + 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/config/rbac/service_account.yaml b/testdata/project-v4/config/rbac/service_account.yaml new file mode 100644 index 00000000000..7cd6025bfc4 --- /dev/null +++ b/testdata/project-v4/config/rbac/service_account.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: controller-manager + namespace: system diff --git a/testdata/project-v4/config/samples/crew_v1_admiral.yaml b/testdata/project-v4/config/samples/crew_v1_admiral.yaml new file mode 100644 index 00000000000..588448f7801 --- /dev/null +++ b/testdata/project-v4/config/samples/crew_v1_admiral.yaml @@ -0,0 +1,6 @@ +apiVersion: crew.testproject.org/v1 +kind: Admiral +metadata: + name: admiral-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4/config/samples/crew_v1_captain.yaml b/testdata/project-v4/config/samples/crew_v1_captain.yaml new file mode 100644 index 00000000000..d0dcfc6cb4d --- /dev/null +++ b/testdata/project-v4/config/samples/crew_v1_captain.yaml @@ -0,0 +1,6 @@ +apiVersion: crew.testproject.org/v1 +kind: Captain +metadata: + name: captain-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4/config/samples/crew_v1_firstmate.yaml b/testdata/project-v4/config/samples/crew_v1_firstmate.yaml new file mode 100644 index 00000000000..61749572695 --- /dev/null +++ b/testdata/project-v4/config/samples/crew_v1_firstmate.yaml @@ -0,0 +1,6 @@ +apiVersion: crew.testproject.org/v1 +kind: FirstMate +metadata: + name: firstmate-sample +spec: + # TODO(user): Add fields here diff --git a/testdata/project-v4/config/webhook/kustomization.yaml b/testdata/project-v4/config/webhook/kustomization.yaml new file mode 100644 index 00000000000..9cf26134e4d --- /dev/null +++ b/testdata/project-v4/config/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +resources: +- manifests.yaml +- service.yaml + +configurations: +- kustomizeconfig.yaml diff --git a/testdata/project-v4/config/webhook/kustomizeconfig.yaml b/testdata/project-v4/config/webhook/kustomizeconfig.yaml new file mode 100644 index 00000000000..25e21e3c963 --- /dev/null +++ b/testdata/project-v4/config/webhook/kustomizeconfig.yaml @@ -0,0 +1,25 @@ +# the following config is for teaching kustomize where to look at when substituting vars. +# 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 + +varReference: +- path: metadata/annotations diff --git a/testdata/project-v4/config/webhook/manifests.yaml b/testdata/project-v4/config/webhook/manifests.yaml new file mode 100644 index 00000000000..89f3689513d --- /dev/null +++ b/testdata/project-v4/config/webhook/manifests.yaml @@ -0,0 +1,74 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook-service + namespace: system + path: /mutate-crew-testproject-org-v1-admiral + failurePolicy: Fail + name: madmiral.kb.io + rules: + - apiGroups: + - crew.testproject.org + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - admirales + sideEffects: None +- 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 +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + 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 diff --git a/testdata/project-v4/config/webhook/service.yaml b/testdata/project-v4/config/webhook/service.yaml new file mode 100644 index 00000000000..3f638bd9c68 --- /dev/null +++ b/testdata/project-v4/config/webhook/service.yaml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: Service +metadata: + name: webhook-service + namespace: system +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager diff --git a/testdata/project-v4/controllers/admiral_controller.go b/testdata/project-v4/controllers/admiral_controller.go new file mode 100644 index 00000000000..a7cf113bbbd --- /dev/null +++ b/testdata/project-v4/controllers/admiral_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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 controllers + +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/api/v1" +) + +// AdmiralReconciler reconciles a Admiral object +type AdmiralReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=crew.testproject.org,resources=admirales,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=crew.testproject.org,resources=admirales/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=crew.testproject.org,resources=admirales/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 Admiral 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.11.2/pkg/reconcile +func (r *AdmiralReconciler) 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 *AdmiralReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&crewv1.Admiral{}). + Complete(r) +} diff --git a/testdata/project-v4/controllers/captain_controller.go b/testdata/project-v4/controllers/captain_controller.go new file mode 100644 index 00000000000..1ba478925ac --- /dev/null +++ b/testdata/project-v4/controllers/captain_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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 controllers + +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/api/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.11.2/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/controllers/firstmate_controller.go b/testdata/project-v4/controllers/firstmate_controller.go new file mode 100644 index 00000000000..f32f48c7ae8 --- /dev/null +++ b/testdata/project-v4/controllers/firstmate_controller.go @@ -0,0 +1,62 @@ +/* +Copyright 2022 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 controllers + +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/api/v1" +) + +// FirstMateReconciler reconciles a FirstMate object +type FirstMateReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates/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 FirstMate 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.11.2/pkg/reconcile +func (r *FirstMateReconciler) 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 *FirstMateReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&crewv1.FirstMate{}). + Complete(r) +} diff --git a/testdata/project-v4/controllers/laker_controller.go b/testdata/project-v4/controllers/laker_controller.go new file mode 100644 index 00000000000..ea0906629e4 --- /dev/null +++ b/testdata/project-v4/controllers/laker_controller.go @@ -0,0 +1,61 @@ +/* +Copyright 2022 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 controllers + +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" +) + +// LakerReconciler reconciles a Laker object +type LakerReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=crew.testproject.org,resources=lakers,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=crew.testproject.org,resources=lakers/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=crew.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 Laker 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.11.2/pkg/reconcile +func (r *LakerReconciler) 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 *LakerReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + // Uncomment the following line adding a pointer to an instance of the controlled resource as an argument + // For(). + Complete(r) +} diff --git a/testdata/project-v4/controllers/suite_test.go b/testdata/project-v4/controllers/suite_test.go new file mode 100644 index 00000000000..a3ba81b776f --- /dev/null +++ b/testdata/project-v4/controllers/suite_test.go @@ -0,0 +1,82 @@ +/* +Copyright 2022 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 controllers + +import ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo" + . "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" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/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 TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecsWithDefaultAndCustomReporters(t, + "Controller Suite", + []Reporter{printer.NewlineReporter{}}) +} + +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, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = crewv1.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()) + +}, 60) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/testdata/project-v4/go.mod b/testdata/project-v4/go.mod new file mode 100644 index 00000000000..7560b893b5d --- /dev/null +++ b/testdata/project-v4/go.mod @@ -0,0 +1,74 @@ +module sigs.k8s.io/kubebuilder/testdata/project-v4 + +go 1.17 + +require ( + github.com/onsi/ginkgo v1.16.5 + github.com/onsi/gomega v1.17.0 + k8s.io/api v0.23.5 + k8s.io/apimachinery v0.23.5 + k8s.io/client-go v0.23.5 + sigs.k8s.io/controller-runtime v0.11.2 +) + +require ( + cloud.google.com/go v0.81.0 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.18 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/go-logr/logr v1.2.0 // indirect + github.com/go-logr/zapr v1.2.0 // 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.2 // indirect + github.com/google/go-cmp v0.5.5 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/google/uuid v1.1.2 // indirect + github.com/googleapis/gnostic v0.5.5 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/nxadm/tail v1.4.8 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.11.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.28.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.19.1 // indirect + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect + golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect + golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8 // indirect + golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + k8s.io/apiextensions-apiserver v0.23.5 // indirect + k8s.io/component-base v0.23.5 // indirect + k8s.io/klog/v2 v2.30.0 // indirect + k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect + k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect + sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/testdata/project-v4/hack/boilerplate.go.txt b/testdata/project-v4/hack/boilerplate.go.txt new file mode 100644 index 00000000000..b54e305f300 --- /dev/null +++ b/testdata/project-v4/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +Copyright 2022 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/main.go b/testdata/project-v4/main.go new file mode 100644 index 00000000000..1c44a24f4dc --- /dev/null +++ b/testdata/project-v4/main.go @@ -0,0 +1,148 @@ +/* +Copyright 2022 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" + + crewv1 "sigs.k8s.io/kubebuilder/testdata/project-v4/api/v1" + "sigs.k8s.io/kubebuilder/testdata/project-v4/controllers" + //+kubebuilder:scaffold:imports +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + + utilruntime.Must(crewv1.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, + MetricsBindAddress: metricsAddr, + Port: 9443, + HealthProbeBindAddress: probeAddr, + LeaderElection: enableLeaderElection, + LeaderElectionID: "da1d9c86.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 = (&controllers.CaptainReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Captain") + os.Exit(1) + } + if err = (&crewv1.Captain{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Captain") + os.Exit(1) + } + if err = (&controllers.FirstMateReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "FirstMate") + os.Exit(1) + } + if err = (&crewv1.FirstMate{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "FirstMate") + os.Exit(1) + } + if err = (&controllers.AdmiralReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Admiral") + os.Exit(1) + } + if err = (&crewv1.Admiral{}).SetupWebhookWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create webhook", "webhook", "Admiral") + os.Exit(1) + } + if err = (&controllers.LakerReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Laker") + 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) + } +}