From e311d0a02b597eaef8d179d678ff0ab0b492b456 Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Tue, 22 Oct 2024 15:07:37 +0100 Subject: [PATCH] add helm plugin to distribute the projects --- .github/workflows/test-helm-samples.yml | 110 +++++++ Makefile | 11 +- cmd/main.go | 2 + .../src/plugins/available/helm-v1-alpha.md | 87 +++++ .../src/plugins/to-add-optional-features.md | 12 +- pkg/cli/alpha/internal/generate.go | 36 +++ pkg/plugins/optional/helm/v1alpha/commons.go | 37 +++ pkg/plugins/optional/helm/v1alpha/edit.go | 89 +++++ pkg/plugins/optional/helm/v1alpha/init.go | 64 ++++ pkg/plugins/optional/helm/v1alpha/plugin.go | 65 ++++ .../optional/helm/v1alpha/scaffolds/init.go | 303 ++++++++++++++++++ .../scaffolds/internal/templates/chart.go | 65 ++++ .../templates/chart_templates/helpers_tpl.go | 127 ++++++++ .../templates/chart_templates/manager.go | 113 +++++++ .../chart_templates/webhook/service.go | 51 +++ .../chart_templates/webhook/webhook.go | 159 +++++++++ .../internal/templates/helmignore.go | 80 +++++ .../scaffolds/internal/templates/values.go | 170 ++++++++++ pkg/plugins/optional/helm/webhookYAML.go | 20 ++ test/e2e/alphagenerate/generate_test.go | 22 ++ test/e2e/utils/test_context.go | 55 ++++ test/e2e/v4/plugin_cluster_test.go | 56 +++- test/testdata/generate.sh | 8 +- testdata/project-v4-multigroup/PROJECT | 3 +- .../config/manager/manager.yaml | 2 +- .../dist/chart/.helmignore | 27 ++ .../dist/chart/Chart.yaml | 7 + .../dist/chart/templates/_helpers.tpl | 70 ++++ .../templates/certmanager/certificate.yaml | 29 ++ .../crds/crew.testproject.org_captains.yaml | 58 ++++ ...example.com.testproject.org_busyboxes.yaml | 120 +++++++ ...xample.com.testproject.org_memcacheds.yaml | 125 ++++++++ .../crds/fiz.testproject.org_bars.yaml | 58 ++++ ...y.testproject.org_healthcheckpolicies.yaml | 58 ++++ .../crds/foo.testproject.org_bars.yaml | 58 ++++ ...sea-creatures.testproject.org_krakens.yaml | 58 ++++ ...-creatures.testproject.org_leviathans.yaml | 58 ++++ .../crds/ship.testproject.org_cruisers.yaml | 58 ++++ .../crds/ship.testproject.org_destroyers.yaml | 58 ++++ .../crds/ship.testproject.org_frigates.yaml | 58 ++++ .../dist/chart/templates/manager/manager.yaml | 51 +++ .../network-policy/allow-metrics-traffic.yaml | 27 ++ .../network-policy/allow-webhook-traffic.yaml | 27 ++ .../chart/templates/prometheus/monitor.yaml | 30 ++ .../rbac/crew_captain_editor_role.yaml | 28 ++ .../rbac/crew_captain_viewer_role.yaml | 24 ++ .../rbac/example.com_busybox_editor_role.yaml | 28 ++ .../rbac/example.com_busybox_viewer_role.yaml | 24 ++ .../example.com_memcached_editor_role.yaml | 28 ++ .../example.com_memcached_viewer_role.yaml | 24 ++ .../templates/rbac/fiz_bar_editor_role.yaml | 28 ++ .../templates/rbac/fiz_bar_viewer_role.yaml | 24 ++ ....policy_healthcheckpolicy_editor_role.yaml | 28 ++ ....policy_healthcheckpolicy_viewer_role.yaml | 24 ++ .../templates/rbac/foo_bar_editor_role.yaml | 28 ++ .../templates/rbac/foo_bar_viewer_role.yaml | 24 ++ .../templates/rbac/leader_election_role.yaml | 41 +++ .../rbac/leader_election_role_binding.yaml | 16 + .../templates/rbac/metrics_auth_role.yaml | 21 ++ .../rbac/metrics_auth_role_binding.yaml | 16 + .../templates/rbac/metrics_reader_role.yaml | 13 + .../dist/chart/templates/rbac/role.yaml | 248 ++++++++++++++ .../chart/templates/rbac/role_binding.yaml | 16 + .../sea-creatures_kraken_editor_role.yaml | 28 ++ .../sea-creatures_kraken_viewer_role.yaml | 24 ++ .../sea-creatures_leviathan_editor_role.yaml | 28 ++ .../sea-creatures_leviathan_viewer_role.yaml | 24 ++ .../chart/templates/rbac/service_account.yaml | 9 + .../rbac/ship_cruiser_editor_role.yaml | 28 ++ .../rbac/ship_cruiser_viewer_role.yaml | 24 ++ .../rbac/ship_destroyer_editor_role.yaml | 28 ++ .../rbac/ship_destroyer_viewer_role.yaml | 24 ++ .../rbac/ship_frigate_editor_role.yaml | 28 ++ .../rbac/ship_frigate_viewer_role.yaml | 24 ++ .../dist/chart/templates/webhook/service.yaml | 14 + .../chart/templates/webhook/webhooks.yaml | 104 ++++++ .../dist/chart/values.yaml | 190 +++++++++++ .../project-v4-multigroup/dist/install.yaml | 2 +- testdata/project-v4-with-plugins/PROJECT | 3 +- .../config/manager/manager.yaml | 2 +- .../dist/chart/.helmignore | 27 ++ .../dist/chart/Chart.yaml | 7 + .../dist/chart/templates/_helpers.tpl | 70 ++++ .../templates/certmanager/certificate.yaml | 29 ++ ...example.com.testproject.org_busyboxes.yaml | 120 +++++++ ...xample.com.testproject.org_memcacheds.yaml | 125 ++++++++ .../dist/chart/templates/manager/manager.yaml | 51 +++ .../network-policy/allow-metrics-traffic.yaml | 27 ++ .../network-policy/allow-webhook-traffic.yaml | 27 ++ .../chart/templates/prometheus/monitor.yaml | 30 ++ .../templates/rbac/busybox_editor_role.yaml | 28 ++ .../templates/rbac/busybox_viewer_role.yaml | 24 ++ .../templates/rbac/leader_election_role.yaml | 41 +++ .../rbac/leader_election_role_binding.yaml | 16 + .../templates/rbac/memcached_editor_role.yaml | 28 ++ .../templates/rbac/memcached_viewer_role.yaml | 24 ++ .../templates/rbac/metrics_auth_role.yaml | 21 ++ .../rbac/metrics_auth_role_binding.yaml | 16 + .../templates/rbac/metrics_reader_role.yaml | 13 + .../dist/chart/templates/rbac/role.yaml | 66 ++++ .../chart/templates/rbac/role_binding.yaml | 16 + .../chart/templates/rbac/service_account.yaml | 9 + .../dist/chart/templates/webhook/service.yaml | 14 + .../chart/templates/webhook/webhooks.yaml | 104 ++++++ .../dist/chart/values.yaml | 88 +++++ .../project-v4-with-plugins/dist/install.yaml | 2 +- 106 files changed, 5049 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/test-helm-samples.yml create mode 100644 docs/book/src/plugins/available/helm-v1-alpha.md create mode 100644 pkg/plugins/optional/helm/v1alpha/commons.go create mode 100644 pkg/plugins/optional/helm/v1alpha/edit.go create mode 100644 pkg/plugins/optional/helm/v1alpha/init.go create mode 100644 pkg/plugins/optional/helm/v1alpha/plugin.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/init.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/helpers_tpl.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/manager.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/webhook/service.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/webhook/webhook.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/helmignore.go create mode 100644 pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go create mode 100644 pkg/plugins/optional/helm/webhookYAML.go create mode 100644 testdata/project-v4-multigroup/dist/chart/.helmignore create mode 100644 testdata/project-v4-multigroup/dist/chart/Chart.yaml create mode 100644 testdata/project-v4-multigroup/dist/chart/templates/_helpers.tpl create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/certmanager/certificate.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/crds/crew.testproject.org_captains.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/crds/example.com.testproject.org_busyboxes.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/crds/example.com.testproject.org_memcacheds.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/crds/fiz.testproject.org_bars.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/crds/foo.policy.testproject.org_healthcheckpolicies.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/crds/foo.testproject.org_bars.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/crds/sea-creatures.testproject.org_krakens.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/crds/sea-creatures.testproject.org_leviathans.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_cruisers.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_destroyers.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_frigates.yaml create mode 100644 testdata/project-v4-multigroup/dist/chart/templates/manager/manager.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/network-policy/allow-metrics-traffic.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/network-policy/allow-webhook-traffic.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/prometheus/monitor.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/crew_captain_editor_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/crew_captain_viewer_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_busybox_editor_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_busybox_viewer_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_memcached_editor_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_memcached_viewer_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/fiz_bar_editor_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/fiz_bar_viewer_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/foo.policy_healthcheckpolicy_editor_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/foo_bar_editor_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/foo_bar_viewer_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/leader_election_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/leader_election_role_binding.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_auth_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_auth_role_binding.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_reader_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/role_binding.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_kraken_editor_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_kraken_viewer_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_leviathan_editor_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_leviathan_viewer_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/service_account.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_cruiser_editor_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_cruiser_viewer_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_destroyer_editor_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_destroyer_viewer_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_frigate_editor_role.yaml create mode 100755 testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_frigate_viewer_role.yaml create mode 100644 testdata/project-v4-multigroup/dist/chart/templates/webhook/service.yaml create mode 100644 testdata/project-v4-multigroup/dist/chart/templates/webhook/webhooks.yaml create mode 100644 testdata/project-v4-multigroup/dist/chart/values.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/.helmignore create mode 100644 testdata/project-v4-with-plugins/dist/chart/Chart.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/certmanager/certificate.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/crds/example.com.testproject.org_busyboxes.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/crds/example.com.testproject.org_memcacheds.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-metrics-traffic.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-webhook-traffic.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/prometheus/monitor.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_editor_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_viewer_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role_binding.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_editor_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_viewer_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_reader_role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml create mode 100755 testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/templates/webhook/service.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhooks.yaml create mode 100644 testdata/project-v4-with-plugins/dist/chart/values.yaml diff --git a/.github/workflows/test-helm-samples.yml b/.github/workflows/test-helm-samples.yml new file mode 100644 index 00000000000..4cc3fa3b4e0 --- /dev/null +++ b/.github/workflows/test-helm-samples.yml @@ -0,0 +1,110 @@ +name: Helm Testdata Sample + +on: + push: + paths: + - 'testdata/project-v4-with-plugins/**' + - 'testdata/project-v4-multigroup/**' + - '.github/workflows/test-helm-samples.yml' + pull_request: + paths: + - 'testdata/project-v4-with-plugins/**' + - 'testdata/project-v4-multigroup/**' + - '.github/workflows/test-helm-samples.yml' + +jobs: + helm-test-project-v4-with-plugins: + runs-on: ubuntu-latest + strategy: + fail-fast: true + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '~1.22' + + - name: Install the latest version of kind + run: | + curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64 + chmod +x ./kind + sudo mv ./kind /usr/local/bin/kind + + - name: Verify kind installation + run: kind version + + - name: Create kind cluster + run: kind create cluster + + - name: Prepare project-v4-with-plugins + run: | + cd testdata/project-v4-with-plugins/ + go mod tidy + make docker-build IMG=project-v4-with-plugins:v0.1.0 + kind load docker-image project-v4-with-plugins:v0.1.0 + + - name: Install Helm + run: | + curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + + - name: Verify Helm installation + run: helm version + + - name: Lint Helm chart for project-v4-with-plugins + run: | + helm lint testdata/project-v4-with-plugins/dist/chart + + - name: Install Helm chart for project-v4-with-plugins + run: | + helm install my-release testdata/project-v4-with-plugins/dist/chart --create-namespace --namespace project-v4-with-plugins-system + + helm-test-project-v4-multigroup: + runs-on: ubuntu-latest + strategy: + fail-fast: true + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '~1.22' + + - name: Install the latest version of kind + run: | + curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64 + chmod +x ./kind + sudo mv ./kind /usr/local/bin/kind + + - name: Verify kind installation + run: kind version + + - name: Create kind cluster + run: kind create cluster + + - name: Prepare project-v4-multigroup + run: | + cd testdata/project-v4-multigroup/ + go mod tidy + make docker-build IMG=project-v4-multigroup:v0.1.0 + kind load docker-image project-v4-multigroup:v0.1.0 + + - name: Install Helm + run: | + curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + + - name: Verify Helm installation + run: helm version + + - name: Lint Helm chart for project-v4-multigroup + run: | + helm lint testdata/project-v4-multigroup/dist/chart + + - name: Install Helm chart for project-v4-multigroup + run: | + helm install my-release-multigroup testdata/project-v4-multigroup/dist/chart --create-namespace --namespace project-v4-multigroup-system diff --git a/Makefile b/Makefile index 6d90ad0d036..ec3686b734a 100644 --- a/Makefile +++ b/Makefile @@ -97,7 +97,7 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes .PHONY: yamllint yamllint: - @files=$$(find testdata -name '*.yaml' ! -path 'testdata/*/dist/install.yaml'); \ + @files=$$(find testdata -name '*.yaml' ! -path 'testdata/*/dist/*'); \ docker run --rm $$(tty -s && echo "-it" || echo) -v $(PWD):/data cytopia/yamllint:latest $$files -d "{extends: relaxed, rules: {line-length: {max: 120}}}" --no-warnings GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint @@ -171,3 +171,12 @@ test-spaces: ## Run the trailing spaces check test-legacy: ## Run the tests to validate legacy path for webhooks rm -rf ./testdata/**legacy**/ ./test/testdata/legacy-webhook-path.sh + +.PHONY: install-helm +install-helm: ## Install the latest version of Helm locally + @curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + +.PHONY: helm-lint +helm-lint: install-helm ## Lint the Helm chart in testdata + helm lint testdata/project-v4-multigroup/dist/chart + helm lint testdata/project-v4-with-plugins/dist/chart diff --git a/cmd/main.go b/cmd/main.go index 64a25502cd7..f0e35e16663 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -30,6 +30,7 @@ import ( deployimagev1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/deploy-image/v1alpha1" golangv4 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/v4" grafanav1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha" + helmv1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha" ) func init() { @@ -61,6 +62,7 @@ func main() { &kustomizecommonv2.Plugin{}, &deployimagev1alpha1.Plugin{}, &grafanav1alpha1.Plugin{}, + &helmv1alpha1.Plugin{}, ), cli.WithPlugins(externalPlugins...), cli.WithDefaultPlugins(cfgv3.Version, gov4Bundle), diff --git a/docs/book/src/plugins/available/helm-v1-alpha.md b/docs/book/src/plugins/available/helm-v1-alpha.md new file mode 100644 index 00000000000..3c6e80c8f20 --- /dev/null +++ b/docs/book/src/plugins/available/helm-v1-alpha.md @@ -0,0 +1,87 @@ +# Helm Plugin (`helm/v1-alpha`) + +The Helm plugin is an optional plugin that can be used to scaffold a Helm chart, allowing you to distribute the project using Helm. + +By default, users can generate a bundle with all the manifests by running the following command: + +```bash +make build-installer IMG=/ +``` + +This allows the project consumer to install the solution by applying the bundle with: + +```bash +kubectl apply -f https://raw.githubusercontent.com//project-v4//dist/install.yaml +``` + +However, in many scenarios, you might prefer to provide a Helm chart to package your solution. +If so, you can use this plugin to generate the Helm chart under the `dist` directory. + + + +## When to use it ? + +- If you are looking to provide to your users a HelmChart to install and manage your project +- If you want to update the HelmChart generated under `dist/chart/` with the latest changes + +## How to use it ? + +### Basic Usage + +The Helm plugin is attached to the `init` subcommand and the `edit` subcommand: + +```sh + +# Initialize a new project with helm chart +kubebuilder init --plugins=helm/v1-alpha + +# Enable or Update the helm chart via the helm plugin to an existing project +# Before run the edit command, run `make manifests` to generate the manifest under `config/` +make manifests +kubebuilder edit --plugins=helm/v1-alpha +``` + + +## Subcommands + +The Helm plugin implements the following subcommands: + +- edit (`$ kubebuilder edit [OPTIONS]`) + +- init (`$ kubebuilder init [OPTIONS]`) + +## Affected files + +The following scaffolds will be created or updated by this plugin: + +- `dist/chart/*` + +[testdata]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/testdata/project-v4-with-plugins + diff --git a/docs/book/src/plugins/to-add-optional-features.md b/docs/book/src/plugins/to-add-optional-features.md index 6b95e7c02c2..f6e847672dd 100644 --- a/docs/book/src/plugins/to-add-optional-features.md +++ b/docs/book/src/plugins/to-add-optional-features.md @@ -2,10 +2,12 @@ The following plugins are useful to generate code and take advantage of optional features -| Plugin | Key | Description | -|---------------------------------------------------| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [grafana.kubebuilder.io/v1-alpha][grafana] | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. | -| [deploy-image.go.kubebuilder.io/v1-alpha][deploy] | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). | +| Plugin | Key | Description | +|---------------------------------------------------|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| +| [grafana.kubebuilder.io/v1-alpha][grafana] | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. | +| [deploy-image.go.kubebuilder.io/v1-alpha][deploy] | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). | +| [helm.kubebuilder.io/v1-alpha][helm] | `helm/v1-alpha` | Optional helper plugin which can be used to scaffold a Helm Chart to distribute the project under the `dist` directory | [grafana]: ./available/grafana-v1-alpha.md -[deploy]: ./available/deploy-image-plugin-v1-alpha.md \ No newline at end of file +[deploy]: ./available/deploy-image-plugin-v1-alpha.md +[helm]: ./available/helm-v1-alpha.md \ No newline at end of file diff --git a/pkg/cli/alpha/internal/generate.go b/pkg/cli/alpha/internal/generate.go index 414fefa5102..9126e9befbd 100644 --- a/pkg/cli/alpha/internal/generate.go +++ b/pkg/cli/alpha/internal/generate.go @@ -44,6 +44,7 @@ const ( defaultOutputDir = "output-dir" grafanaPluginKey = "grafana.kubebuilder.io/v1-alpha" deployImagePluginKey = "deploy-image.go.kubebuilder.io/v1-alpha" + helmPluginKey = "helm.kubebuilder.io/v1-alpha" ) // Generate handles the migration and scaffolding process. @@ -77,6 +78,12 @@ func (opts *Generate) Generate() error { return err } + if hasHelmPlugin(config) { + if err := kubebuilderHelmEdit(); err != nil { + return err + } + } + if err := migrateDeployImagePlugin(config); err != nil { return err } @@ -392,3 +399,32 @@ func kubebuilderGrafanaEdit() error { } return nil } + +// Edits the project to include the Grafana plugin. +func kubebuilderHelmEdit() error { + args := []string{"edit", "--plugins", helmPluginKey} + if err := util.RunCmd("kubebuilder edit", "kubebuilder", args...); err != nil { + return fmt.Errorf("failed to run edit subcommand for Helm plugin: %w", err) + } + return nil +} + +// hasHelmPlugin checks if the Helm plugin is present by inspecting the plugin chain or configuration. +func hasHelmPlugin(cfg store.Store) bool { + var pluginConfig map[string]interface{} + + // Decode the Helm plugin configuration to check if it's present + err := cfg.Config().DecodePluginConfig(helmPluginKey, &pluginConfig) + if err != nil { + // If the Helm plugin is not found, return false + if errors.As(err, &config.PluginKeyNotFoundError{}) { + return false + } + // Log other errors if needed + log.Errorf("Error decoding Helm plugin config: %v", err) + return false + } + + // Helm plugin is present + return true +} diff --git a/pkg/plugins/optional/helm/v1alpha/commons.go b/pkg/plugins/optional/helm/v1alpha/commons.go new file mode 100644 index 00000000000..c6942322ec7 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/commons.go @@ -0,0 +1,37 @@ +/* +Copyright 2024 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 v1alpha + +import ( + "errors" + + "sigs.k8s.io/kubebuilder/v4/pkg/config" +) + +func insertPluginMetaToConfig(target config.Config, cfg pluginConfig) error { + err := target.DecodePluginConfig(pluginKey, cfg) + if !errors.As(err, &config.UnsupportedFieldError{}) { + if err != nil && !errors.As(err, &config.PluginKeyNotFoundError{}) { + return err + } + if err = target.EncodePluginConfig(pluginKey, cfg); err != nil { + return err + } + } + + return nil +} diff --git a/pkg/plugins/optional/helm/v1alpha/edit.go b/pkg/plugins/optional/helm/v1alpha/edit.go new file mode 100644 index 00000000000..4ace3313c6a --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/edit.go @@ -0,0 +1,89 @@ +/* +Copyright 2024 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 v1alpha + +import ( + "fmt" + + "github.com/spf13/pflag" + "sigs.k8s.io/kubebuilder/v4/pkg/config" + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" + "sigs.k8s.io/kubebuilder/v4/pkg/plugin" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds" +) + +var _ plugin.EditSubcommand = &editSubcommand{} + +type editSubcommand struct { + config config.Config + force bool +} + +// nolint:lll +func (p *editSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) { + subcmdMeta.Description = `Initialize or update a Helm chart to distribute the project under the dist/ directory. + +**NOTE** Before running the edit command, ensure you first execute 'make manifests' to regenerate +the latest Helm chart with your most recent changes.` + + subcmdMeta.Examples = fmt.Sprintf(`# Initialize or update a Helm chart to distribute the project under the dist/ directory + %[1]s edit --plugins=helm/v1-alpha + +# Update the Helm chart under the dist/ directory and overwrite all files + %[1]s edit --plugins=helm/v1-alpha --force=true + +**IMPORTANT**: If the "--force=true" flag is not used, the following files will not be updated to preserve your customizations: +dist/chart/ +├── values.yaml +├── .helmignore +└── templates/ + ├── _helpers.tpl + └── manager/ + └── manager.yaml + └── webhook/ + └── webhooks.yaml + └── service.yaml + + +All other files will be updated when the edit option is used to ensure that the manifests in the chart align with the latest changes. +`, cliMeta.CommandName) +} + +func (p *editSubcommand) BindFlags(fs *pflag.FlagSet) { + fs.BoolVar(&p.force, "force", true, "if true, run re-generate the files") +} + +func (p *editSubcommand) InjectConfig(c config.Config) error { + p.config = c + return nil +} + +func (p *editSubcommand) Scaffold(fs machinery.Filesystem) error { + scaffolder := scaffolds.NewInitHelmScaffolder(p.config, p.force) + scaffolder.InjectFS(fs) + err := scaffolder.Scaffold() + if err != nil { + return err + } + + // Track the resources following a declarative approach + if err := insertPluginMetaToConfig(p.config, pluginConfig{}); err != nil { + return err + } + + return nil +} diff --git a/pkg/plugins/optional/helm/v1alpha/init.go b/pkg/plugins/optional/helm/v1alpha/init.go new file mode 100644 index 00000000000..d9d0f64eaad --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/init.go @@ -0,0 +1,64 @@ +/* +Copyright 2024 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 v1alpha + +import ( + "fmt" + + "sigs.k8s.io/kubebuilder/v4/pkg/config" + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" + "sigs.k8s.io/kubebuilder/v4/pkg/plugin" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds" +) + +var _ plugin.InitSubcommand = &initSubcommand{} + +type initSubcommand struct { + config config.Config +} + +func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) { + subcmdMeta.Description = `Initialize a helm chart to distribute the project under dist/ +` + subcmdMeta.Examples = fmt.Sprintf(`# Initialize a helm chart to distribute the project under dist/ + %[1]s init --plugins=helm/v1-alpha + +**IMORTANT** You must use %[1]s edit --plugins=helm/v1-alpha to update the chart when changes are made. + +`, cliMeta.CommandName) +} + +func (p *initSubcommand) InjectConfig(c config.Config) error { + p.config = c + return nil +} + +func (p *initSubcommand) Scaffold(fs machinery.Filesystem) error { + scaffolder := scaffolds.NewInitHelmScaffolder(p.config, false) + scaffolder.InjectFS(fs) + err := scaffolder.Scaffold() + if err != nil { + return err + } + + // Track the resources following a declarative approach + if err := insertPluginMetaToConfig(p.config, pluginConfig{}); err != nil { + return err + } + + return nil +} diff --git a/pkg/plugins/optional/helm/v1alpha/plugin.go b/pkg/plugins/optional/helm/v1alpha/plugin.go new file mode 100644 index 00000000000..21690e4db28 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/plugin.go @@ -0,0 +1,65 @@ +/* +Copyright 2024 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 v1alpha + +import ( + "sigs.k8s.io/kubebuilder/v4/pkg/config" + cfgv3 "sigs.k8s.io/kubebuilder/v4/pkg/config/v3" + "sigs.k8s.io/kubebuilder/v4/pkg/model/stage" + "sigs.k8s.io/kubebuilder/v4/pkg/plugin" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins" +) + +const pluginName = "helm." + plugins.DefaultNameQualifier + +var ( + pluginVersion = plugin.Version{Number: 1, Stage: stage.Alpha} + supportedProjectVersions = []config.Version{cfgv3.Version} + pluginKey = plugin.KeyFor(Plugin{}) +) + +// Plugin implements the plugin.Full interface +type Plugin struct { + initSubcommand + editSubcommand +} + +var ( + _ plugin.Init = Plugin{} + _ plugin.Edit = Plugin{} +) + +type pluginConfig struct{} + +// Name returns the name of the plugin +func (Plugin) Name() string { return pluginName } + +// Version returns the version of the grafana plugin +func (Plugin) Version() plugin.Version { return pluginVersion } + +// SupportedProjectVersions returns an array with all project versions supported by the plugin +func (Plugin) SupportedProjectVersions() []config.Version { return supportedProjectVersions } + +// GetInitSubcommand will return the subcommand which is responsible for initializing and scaffolding grafana manifests +func (p Plugin) GetInitSubcommand() plugin.InitSubcommand { return &p.initSubcommand } + +// GetEditSubcommand will return the subcommand which is responsible for adding grafana manifests +func (p Plugin) GetEditSubcommand() plugin.EditSubcommand { return &p.editSubcommand } + +func (p Plugin) DeprecationWarning() string { + return "" +} diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go new file mode 100644 index 00000000000..4c58a5a8233 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/init.go @@ -0,0 +1,303 @@ +/* +Copyright 2024 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 scaffolds + +import ( + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + + "sigs.k8s.io/yaml" + + log "github.com/sirupsen/logrus" + "sigs.k8s.io/kubebuilder/v4/pkg/config" + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates" + templateswebhooks "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/webhook" +) + +var _ plugins.Scaffolder = &initScaffolder{} + +type initScaffolder struct { + config config.Config + + // fs is the filesystem that will be used by the scaffolder + fs machinery.Filesystem + + // force indicates whether to scaffold controller files even if they exist + force bool +} + +// NewInitHelmScaffolder returns a new Scaffolder for HelmPlugin +func NewInitHelmScaffolder(config config.Config, force bool) plugins.Scaffolder { + return &initScaffolder{ + config: config, + force: force, + } +} + +// InjectFS implements cmdutil.Scaffolder +func (s *initScaffolder) InjectFS(fs machinery.Filesystem) { + s.fs = fs +} + +// Scaffold scaffolds the Helm chart with the necessary files. +func (s *initScaffolder) Scaffold() error { + log.Println("Generating Helm Chart to distribute project") + + // Initialize the map to store the extracted images from deploy-image plugin + deployImages := make(map[string]string) + + // Detect and extract the deploy-image plugin configuration + pluginConfig := struct { + Resources []struct { + Kind string `json:"kind"` + Options map[string]string `json:"options"` + } `json:"resources"` + }{} + + err := s.config.DecodePluginConfig("deploy-image.go.kubebuilder.io/v1-alpha", &pluginConfig) + if err == nil { + // Extract images for the resources + for _, res := range pluginConfig.Resources { + image, ok := res.Options["image"] + if ok { + deployImages[strings.ToUpper(res.Kind)] = image + } + } + } + + // Extract webhooks from generated YAML files (generated by controller-gen) + webhooks, err := extractWebhooksFromGeneratedFiles() + if err != nil { + return fmt.Errorf("failed to extract webhooks: %w", err) + } + + // Initialize the machinery.Scaffold that will write the files to disk + scaffold := machinery.NewScaffold(s.fs, + machinery.WithConfig(s.config), + ) + + // Pass the extracted images and webhooks to the HelmValues template + buildScaffold := []machinery.Builder{ + &templates.HelmChart{Force: s.force}, + &templates.HelmValues{ + Webhooks: webhooks, + DeployImages: deployImages, + Force: s.force, + }, + &templates.HelmIgnore{Force: s.force}, + &chart_templates.HelmHelpers{Force: s.force}, + &chart_templates.ManagerDeployment{ + Force: s.force, + DeployImages: len(deployImages) > 0, + HasWebhooks: len(webhooks) > 0, + }, + } + + if len(webhooks) > 0 { + buildScaffold = append(buildScaffold, &templateswebhooks.WebhookTemplate{Force: s.force}) + buildScaffold = append(buildScaffold, &templateswebhooks.WebhookService{Force: s.force}) + } + + if err := scaffold.Execute(buildScaffold...); err != nil { + return fmt.Errorf("error scaffolding helm-chart manifests: %v", err) + } + + // Copy relevant files from config/ to dist/chart/templates/ + err = copyConfigFiles() + if err != nil { + return err + } + + return nil +} + +// Extract webhooks from manifests.yaml file +func extractWebhooksFromGeneratedFiles() ([]helm.WebhookYAML, error) { + var webhooks []helm.WebhookYAML + manifestFile := "config/webhook/manifests.yaml" + if _, err := os.Stat(manifestFile); err == nil { + content, err := os.ReadFile(manifestFile) + if err != nil { + return nil, fmt.Errorf("failed to read manifests.yaml: %w", err) + } + + // Process the content to extract webhooks + webhooks = append(webhooks, extractWebhookYAML(content)...) + } else { + // Return empty if no webhooks were found + return webhooks, nil + } + + return webhooks, nil +} + +// extractWebhookYAML parses the webhook YAML content and returns a list of WebhookYAML +func extractWebhookYAML(content []byte) []helm.WebhookYAML { + var webhooks []helm.WebhookYAML + + type WebhookConfig struct { + Kind string `yaml:"kind"` + Webhooks []struct { + Name string `yaml:"name"` + ClientConfig struct { + Service struct { + Name string `yaml:"name"` + Namespace string `yaml:"namespace"` + Path string `yaml:"path"` + } `yaml:"service"` + CABundle string `yaml:"caBundle"` + } `yaml:"clientConfig"` + Rules []helm.WebhookRule `yaml:"rules"` + FailurePolicy string `yaml:"failurePolicy"` + SideEffects string `yaml:"sideEffects"` + AdmissionReviewVersions []string `yaml:"admissionReviewVersions"` + } `yaml:"webhooks"` + } + + // Split the input into different documents (to handle multiple YAML docs in one file) + docs := strings.Split(string(content), "---") + + for _, doc := range docs { + var webhookConfig WebhookConfig + if err := yaml.Unmarshal([]byte(doc), &webhookConfig); err != nil { + log.Errorf("Error unmarshalling webhook YAML: %v", err) + continue + } + + // Determine the webhook type (mutating or validating) + webhookType := "unknown" + if webhookConfig.Kind == "MutatingWebhookConfiguration" { + webhookType = "mutating" + } else if webhookConfig.Kind == "ValidatingWebhookConfiguration" { + webhookType = "validating" + } + + // Parse each webhook and append it to the result + for _, webhook := range webhookConfig.Webhooks { + for i := range webhook.Rules { + // If apiGroups is empty, set it to [""] to ensure proper YAML output + if len(webhook.Rules[i].APIGroups) == 0 { + webhook.Rules[i].APIGroups = []string{""} + } + } + webhooks = append(webhooks, helm.WebhookYAML{ + Name: webhook.Name, + Type: webhookType, + Path: webhook.ClientConfig.Service.Path, + Rules: webhook.Rules, + FailurePolicy: webhook.FailurePolicy, + SideEffects: webhook.SideEffects, + AdmissionReviewVersions: webhook.AdmissionReviewVersions, + }) + } + } + return webhooks +} + +// Helper function to copy files from config/ to dist/chart/templates/ +func copyConfigFiles() error { + configDirs := []struct { + SrcDir string + DestDir string + SubDir string + }{ + {"config/rbac", "dist/chart/templates/rbac", "rbac"}, + {"config/crd/bases", "dist/chart/templates/crds", "crd"}, + {"config/prometheus", "dist/chart/templates/prometheus", "prometheus"}, + {"config/certmanager", "dist/chart/templates/certmanager", "certmanager"}, + {"config/network-policy", "dist/chart/templates/network-policy", "networkPolicy"}, + } + + for _, dir := range configDirs { + files, err := filepath.Glob(filepath.Join(dir.SrcDir, "*.yaml")) + if err != nil { + return err + } + + for _, srcFile := range files { + destFile := filepath.Join(dir.DestDir, filepath.Base(srcFile)) + err := copyFileWithHelmLogic(srcFile, destFile, dir.SubDir) + if err != nil { + return err + } + } + } + + return nil +} + +// copyFileWithHelmLogic reads the source file, modifies the content for Helm, and writes it to the destination +func copyFileWithHelmLogic(srcFile, destFile, subDir string) error { + if _, err := os.Stat(srcFile); os.IsNotExist(err) { + log.Printf("Source file does not exist: %s", srcFile) + return err + } + + content, err := os.ReadFile(srcFile) + if err != nil { + log.Printf("Error reading source file: %s", srcFile) + return err + } + + contentStr := string(content) + + if strings.HasSuffix(srcFile, "kustomization.yaml") || strings.HasSuffix(srcFile, + "kustomizeconfig.yaml") { + log.Printf("Skipping irrelevant file: %s", srcFile) + return nil + } + + contentStr = removeLabels(contentStr) + + contentStr = strings.ReplaceAll(contentStr, "namespace: system", + "namespace: {{ .Values.namespace }}") + + contentStr = strings.Replace(contentStr, "metadata:", `metadata: + labels: + {{- include "chart.labels" . | nindent 4 }}`, 1) + + // Wrap the content with Helm conditional logic based on the subdirectory (e.g., "rbac", "manager") + wrappedContent := fmt.Sprintf("{{- if .Values.%s.create }}\n%s{{- end -}}\n", subDir, contentStr) + + if err := os.MkdirAll(filepath.Dir(destFile), os.ModePerm); err != nil { + return err + } + + err = os.WriteFile(destFile, []byte(wrappedContent), os.ModePerm) + if err != nil { + log.Printf("Error writing destination file: %s", destFile) + return err + } + + log.Printf("Successfully copied %s to %s", srcFile, destFile) + return nil +} + +// removeLabels removes any existing labels section from the content +func removeLabels(content string) string { + labelRegex := `(?m)^ labels:\n(?: [^\n]+\n)*` + re := regexp.MustCompile(labelRegex) + + return re.ReplaceAllString(content, "") +} diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart.go new file mode 100644 index 00000000000..1fd1e1b4e6f --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart.go @@ -0,0 +1,65 @@ +/* +Copyright 2024 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 templates + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &HelmChart{} + +// Chart scaffolds a file that defines the Helm chart structure +type HelmChart struct { + machinery.TemplateMixin + machinery.ProjectNameMixin + + // Force if true allow overwrite the scaffolded file + Force bool +} + +// SetTemplateDefaults implements file.Template +func (f *HelmChart) SetTemplateDefaults() error { + // Define the path where the Helm Chart.yaml will be created + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "Chart.yaml") + } + + // Use the chart template defined below + f.TemplateBody = helmChartTemplate + + // Define file handling action based on Force flag + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + // If file exists (ex. because a Helm chart was already created), skip creation. + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// Define the content for the Chart.yaml file +const helmChartTemplate = `apiVersion: v2 +name: {{ .ProjectName }} +description: A Helm chart to distribute the project {{ .ProjectName }} +type: application +version: 0.1.0 +appVersion: "0.1.0" +icon: "https://example.com/icon.png" +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/helpers_tpl.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/helpers_tpl.go new file mode 100644 index 00000000000..f0988a6dc82 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/helpers_tpl.go @@ -0,0 +1,127 @@ +/* +Copyright 2024 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 chart_templates + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &HelmHelpers{} + +// HelmHelpers scaffolds the _helpers.tpl file for Helm charts +type HelmHelpers struct { + machinery.TemplateMixin + machinery.ProjectNameMixin + + // Force if true allow overwrite the scaffolded file + Force bool +} + +// SetTemplateDefaults sets the default template configuration +func (f *HelmHelpers) SetTemplateDefaults() error { + // Define the path where _helpers.tpl will be created + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "templates", "_helpers.tpl") + } + + // Use the helpers.tpl template defined below + f.TemplateBody = helmHelpersTemplate + + // Define file handling action based on Force flag + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// nolint:lll +const helmHelpersTemplate = `{{` + "`" + `{{/* +Expand the name of the chart. +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.name" -}}` + "`" + `}} +{{` + "`" + `{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{` + "`" + `{{/* +Create a default fully qualified app name. +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.fullname" -}}` + "`" + `}} +{{` + "`" + `{{- if .Values.fullnameOverride }}` + "`" + `}} +{{` + "`" + `{{ .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}` + "`" + `}} +{{` + "`" + `{{- else }}` + "`" + `}} +{{` + "`" + `{{- $name := default .Chart.Name .Values.nameOverride }}` + "`" + `}} +{{` + "`" + `{{- if contains $name .Release.Name }}` + "`" + `}} +{{` + "`" + `{{ .Release.Name | trunc 63 | trimSuffix "-" }}` + "`" + `}} +{{` + "`" + `{{- else }}` + "`" + `}} +{{` + "`" + `{{ printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{` + "`" + `{{/* +Create chart name and version as used by the chart label. +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.version" -}}` + "`" + `}} +{{` + "`" + `{{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{` + "`" + `{{/* +Common labels +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.labels" -}}` + "`" + `}} +helm.sh/chart: {{` + "`" + `{{ include "chart.version" . }}` + "`" + `}} +app.kubernetes.io/name: {{` + "`" + `{{ include "chart.name" . }}` + "`" + `}} +app.kubernetes.io/instance: {{` + "`" + `{{ .Release.Name }}` + "`" + `}} +app.kubernetes.io/version: {{` + "`" + `{{ .Chart.AppVersion | quote }}` + "`" + `}} +app.kubernetes.io/managed-by: {{` + "`" + `{{ .Release.Service }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{` + "`" + `{{/* +Selector labels +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.selectorLabels" -}}` + "`" + `}} +app.kubernetes.io/name: {{` + "`" + `{{ include "chart.name" . }}` + "`" + `}} +app.kubernetes.io/instance: {{` + "`" + `{{ .Release.Name }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{` + "`" + `{{/* +Helper to check if mutating webhooks exist in the services. +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.hasMutatingWebhooks" -}}` + "`" + `}} +{{` + "`" + `{{- $hasMutating := false }}` + "`" + `}} +{{` + "`" + `{{- range . }}` + "`" + `}} + {{` + "`" + `{{- if eq .type "mutating" }}` + "`" + `}} + {{` + "`" + `$hasMutating = true }}{{- end }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{ $hasMutating }}}}{{- end }}` + "`" + `}} + +{{` + "`" + `{{/* +Helper to check if validating webhooks exist in the services. +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.hasValidatingWebhooks" -}}` + "`" + `}} +{{` + "`" + `{{- $hasValidating := false }}` + "`" + `}} +{{` + "`" + `{{- range . }}` + "`" + `}} + {{` + "`" + `{{- if eq .type "validating" }}` + "`" + `}} + {{` + "`" + `$hasValidating = true }}{{- end }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{ $hasValidating }}}}{{- end }}` + "`" + `}} +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/manager.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/manager.go new file mode 100644 index 00000000000..463fb37c0d8 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/manager.go @@ -0,0 +1,113 @@ +/* +Copyright 2024 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 chart_templates + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &ManagerDeployment{} + +// ManagerDeployment scaffolds the manager Deployment for the Helm chart +type ManagerDeployment struct { + machinery.TemplateMixin + + // Force if true will scaffold the env with the images + DeployImages bool + // Force if true allow overwrite the scaffolded file + Force bool + // HasWebhooks is true when webhooks were found in the config + HasWebhooks bool +} + +// SetTemplateDefaults sets the default template configuration +func (f *ManagerDeployment) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "templates", "manager", "manager.yaml") + } + + f.TemplateBody = managerDeploymentTemplate + + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// Define the content for the manager.yaml file +// nolint:lll +const managerDeploymentTemplate = `apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: {{ "{{ .Values.namespace }}" }} + labels: + {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} + control-plane: controller-manager +spec: + selector: + matchLabels: + {{ "{{- include \"chart.selectorLabels\" . | nindent 6 }}" }} + control-plane: controller-manager + template: + metadata: + labels: + {{ "{{- include \"chart.labels\" . | nindent 8 }}" }} + control-plane: controller-manager + spec: + serviceAccountName: {{ "{{ .Values.controllerManager.serviceAccountName }}" }} + containers: + - name: manager + image: {{ "{{ .Values.controllerManager.image.repository }}" }}:{{ "{{ .Values.controllerManager.image.tag }}" }} + args: + {{ "{{- range .Values.controllerManager.args }}" }} + - {{ "{{ . }}" }} + {{ "{{- end }}" }} + {{ "{{- if .DeployImages }}" }} + env: + {{ "{{- range $key, $value := .Values.controllerManager.env }}" }} + - name: {{ "{{ $key }}" }} + value: {{ "{{ $value }}" }} + {{ "{{- end }}" }} + {{ "{{- end }}" }} + livenessProbe: + {{ "{{- toYaml .Values.controllerManager.livenessProbe | nindent 8 }}" }} + readinessProbe: + {{ "{{- toYaml .Values.controllerManager.readinessProbe | nindent 8 }}" }} + resources: + {{ "{{- toYaml .Values.controllerManager.resources | nindent 8 }}" }} + securityContext: + {{ "{{- toYaml .Values.controllerManager.securityContext | nindent 8 }}" }} + {{- if .HasWebhooks }} + volumeMounts: + - name: webhook-cert + mountPath: /tmp/k8s-webhook-server/serving-certs + readOnly: true + {{- end }} + terminationGracePeriodSeconds: {{ "{{ .Values.controllerManager.terminationGracePeriodSeconds }}" }} + {{- if .HasWebhooks }} + volumes: + - name: webhook-cert + secret: + secretName: webhook-server-cert + {{- end }} +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/webhook/service.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/webhook/service.go new file mode 100644 index 00000000000..9eb797d7731 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/webhook/service.go @@ -0,0 +1,51 @@ +package webhook + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &WebhookService{} + +// WebhookService scaffolds the Service for webhooks in the Helm chart +type WebhookService struct { + machinery.TemplateMixin + + // Force if true allows overwriting the scaffolded file + Force bool +} + +// SetTemplateDefaults sets the default template configuration +func (f *WebhookService) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "templates", "webhook", "service.yaml") + } + + f.TemplateBody = webhookServiceTemplate + + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// Template for webhook-service.yaml with proper escaping +const webhookServiceTemplate = `apiVersion: v1 +kind: Service +metadata: + name: {{ "{{ .Values.namespace }}" }}-webhook-service + namespace: {{ "{{ .Values.namespace }}" }} + labels: + {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/webhook/webhook.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/webhook/webhook.go new file mode 100644 index 00000000000..6c83055ab25 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/chart_templates/webhook/webhook.go @@ -0,0 +1,159 @@ +// Template for webhook.yaml +/* +Copyright 2024 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 webhook + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &WebhookTemplate{} + +// WebhookTemplate scaffolds a file that defines the MutatingWebhookConfiguration +// and ValidatingWebhookConfiguration for the Helm chart +type WebhookTemplate struct { + machinery.TemplateMixin + + // Force if true allows overwriting the scaffolded file + Force bool +} + +// SetTemplateDefaults sets the default template configuration +func (f *WebhookTemplate) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "templates", + "webhook", "webhooks.yaml") + } + + f.TemplateBody = webhookTemplate + + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// nolint:lll +const webhookTemplate = `{{` + "`" + `{{- if .Values.webhook.create }}` + "`" + `}} + +{{` + "`" + `{{- if include "chart.hasMutatingWebhooks" .Values.webhook.services }}` + "`" + `}} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{` + "`" + `{{ .Values.namespace }}` + "`" + `}}-mutating-webhook + labels: + {{` + "`" + `{{- include "chart.labels" . | nindent 4 }}` + "`" + `}} +webhooks: + {{` + "`" + `{{- range .Values.webhook.services }}` + "`" + `}} + {{` + "`" + `{{- if eq .type "mutating" }}` + "`" + `}} + - name: {{` + "`" + `{{ .name }}` + "`" + `}}.{{` + "`" + `{{ $.Values.namespace }}` + "`" + `}}.svc + clientConfig: + service: + name: {{` + "`" + `{{ .name }}` + "`" + `}} + namespace: {{` + "`" + `{{ $.Values.namespace }}` + "`" + `}} + path: {{` + "`" + `{{ .path }}` + "`" + `}} + caBundle: {{` + "`" + `{{ .caBundle }}` + "`" + `}} + failurePolicy: {{` + "`" + `{{ .failurePolicy }}` + "`" + `}} + sideEffects: {{` + "`" + `{{ .sideEffects }}` + "`" + `}} + admissionReviewVersions: + {{` + "`" + `{{- range .admissionReviewVersions }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + rules: + {{` + "`" + `{{- range .rules }}` + "`" + `}} + - operations: + {{` + "`" + `{{- range .operations }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + apiGroups: + {{` + "`" + `{{- if .apiGroups }}` + "`" + `}} + {{` + "`" + `{{- range .apiGroups }}` + "`" + `}} + - {{` + "`" + `{{ default "\"\"" . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- else }}` + "`" + `}} + - "" + {{` + "`" + `{{- end }}` + "`" + `}} + apiVersions: + {{` + "`" + `{{- range .apiVersions }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + resources: + {{` + "`" + `{{- range .resources }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} +--- +{{` + "`" + `{{- end }}` + "`" + `}} + +{{` + "`" + `{{- if include "chart.hasValidatingWebhooks" .Values.webhook.services }}` + "`" + `}} +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{` + "`" + `{{ .Values.namespace }}` + "`" + `}}-validating-webhook + labels: + {{` + "`" + `{{- include "chart.labels" . | nindent 4 }}` + "`" + `}} +webhooks: + {{` + "`" + `{{- range .Values.webhook.services }}` + "`" + `}} + {{` + "`" + `{{- if eq .type "validating" }}` + "`" + `}} + - name: {{` + "`" + `{{ .name }}` + "`" + `}}.{{` + "`" + `{{ $.Values.namespace }}` + "`" + `}}.svc + clientConfig: + service: + name: {{` + "`" + `{{ .name }}` + "`" + `}} + namespace: {{` + "`" + `{{ $.Values.namespace }}` + "`" + `}} + path: {{` + "`" + `{{ .path }}` + "`" + `}} + caBundle: {{` + "`" + `{{ .caBundle }}` + "`" + `}} + failurePolicy: {{` + "`" + `{{ .failurePolicy }}` + "`" + `}} + sideEffects: {{` + "`" + `{{ .sideEffects }}` + "`" + `}} + admissionReviewVersions: + {{` + "`" + `{{- range .admissionReviewVersions }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + rules: + {{` + "`" + `{{- range .rules }}` + "`" + `}} + - operations: + {{` + "`" + `{{- range .operations }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + apiGroups: + {{` + "`" + `{{- if .apiGroups }}` + "`" + `}} + {{` + "`" + `{{- range .apiGroups }}` + "`" + `}} + - {{` + "`" + `{{ default "\"\"" . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- else }}` + "`" + `}} + - "" + {{` + "`" + `{{- end }}` + "`" + `}} + apiVersions: + {{` + "`" + `{{- range .apiVersions }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + resources: + {{` + "`" + `{{- range .resources }}` + "`" + `}} + - {{` + "`" + `{{ . }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} + {{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{` + "`" + `{{- end }}` + "`" + `}} +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/helmignore.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/helmignore.go new file mode 100644 index 00000000000..6f703c9b345 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/helmignore.go @@ -0,0 +1,80 @@ +/* +Copyright 2024 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 templates + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &HelmIgnore{} + +// HelmIgnore scaffolds a file that defines the .helmignore for Helm packaging +type HelmIgnore struct { + machinery.TemplateMixin + + // Force if true allow overwrite the scaffolded file + Force bool +} + +// SetTemplateDefaults implements file.Template +func (f *HelmIgnore) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", ".helmignore") + } + + f.TemplateBody = helmIgnoreTemplate + + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// Define the content for the .helmignore file +const helmIgnoreTemplate = `# Patterns to ignore when building Helm packages. +# Supports shell glob matching, relative path matching, and negation. + +# Operating system files +.DS_Store + +# Version control directories +.git/ +.gitignore +.bzr/ +.hg/ +.hgignore +.svn/ + +# Backup and temporary files +*.swp +*.tmp +*.bak +*.orig +*~ + +# IDE and editor-related files +.idea/ +.vscode/ + +# Helm chart artifacts +dist/chart/*.tgz +` diff --git a/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go new file mode 100644 index 00000000000..bb045883f71 --- /dev/null +++ b/pkg/plugins/optional/helm/v1alpha/scaffolds/internal/templates/values.go @@ -0,0 +1,170 @@ +/* +Copyright 2024 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 templates + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm" +) + +var _ machinery.Template = &HelmValues{} + +// HelmValues scaffolds a file that defines the values.yaml structure for the Helm chart +type HelmValues struct { + machinery.TemplateMixin + machinery.ProjectNameMixin + + // DeployImages stores the images used for the DeployImage plugin + DeployImages map[string]string + // Force if true allows overwriting the scaffolded file + Force bool + // Webhooks stores the webhook configurations + Webhooks []helm.WebhookYAML +} + +// SetTemplateDefaults implements file.Template +func (f *HelmValues) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join("dist", "chart", "values.yaml") + } + f.TemplateBody = helmValuesTemplate + + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// Define the content for the values.yaml file +// Define the content for the values.yaml file +const helmValuesTemplate = `# Default values for the Kubebuilder Helm chart +# Namespace where the Manager will be deployed +namespace: {{ .ProjectName }}-system + +# Controller Manager settings +controllerManager: + image: + repository: controller + tag: latest + replicas: 1 + args: + - "--leader-elect" + - "--metrics-bind-address=:8080" + - "--health-probe-bind-address=:8081" + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + livenessProbe: + initialDelaySeconds: 15 + periodSeconds: 20 + httpGet: + path: /healthz + port: 8081 + readinessProbe: + initialDelaySeconds: 5 + periodSeconds: 10 + httpGet: + path: /readyz + port: 8081 + securityContext: + runAsNonRoot: true + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + serviceAccountName: controller-manager + terminationGracePeriodSeconds: 10 +{{- if .DeployImages }} + env: + {{- range $kind, $image := .DeployImages }} + {{ $kind }}_IMAGE: {{ $image }} + {{- end }} +{{- end }} + +# RBAC settings +rbac: + create: true + +# CRDs settings +crd: + create: true + +{{ if .Webhooks }} +# Webhook service settings +webhook: + create: true + services: + {{- range .Webhooks }} + - name: {{ .Name }} + type: {{ .Type }} + path: {{ .Path }} + failurePolicy: {{ .FailurePolicy }} + sideEffects: {{ .SideEffects }} + admissionReviewVersions: + {{- range .AdmissionReviewVersions }} + - {{ . }} + {{- end }} + rules: + {{- range .Rules }} + - operations: + {{- range .Operations }} + - {{ . }} + {{- end }} + apiGroups: + {{- if .APIGroups }} + {{- range .APIGroups }} + {{- if eq . "" }} + - "" + {{- else }} + - {{ . }} + {{- end }} + {{- end }} + {{- else }} + - "" + {{- end }} + apiVersions: + {{- range .APIVersions }} + - {{ . }} + {{- end }} + resources: + {{- range .Resources }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} +{{ end }} + +# Prometheus monitoring settings +prometheus: + create: false + +# CertManager settings for certificates +certmanager: + create: false + +# Network policies +networkPolicy: + create: false +` diff --git a/pkg/plugins/optional/helm/webhookYAML.go b/pkg/plugins/optional/helm/webhookYAML.go new file mode 100644 index 00000000000..1c95b7ba4e5 --- /dev/null +++ b/pkg/plugins/optional/helm/webhookYAML.go @@ -0,0 +1,20 @@ +package helm + +// WebhookRule represents the rules for operations, API groups, versions, and resources +type WebhookRule struct { + Operations []string `yaml:"operations"` + APIGroups []string `yaml:"apiGroups"` + APIVersions []string `yaml:"apiVersions"` + Resources []string `yaml:"resources"` +} + +// WebhookYAML stores the details of each webhook generated by controller-gen +type WebhookYAML struct { + Name string `yaml:"name"` + Type string `yaml:"type"` + Path string `yaml:"path"` + Rules []WebhookRule `yaml:"rules"` + FailurePolicy string `yaml:"failurePolicy"` + SideEffects string `yaml:"sideEffects"` + AdmissionReviewVersions []string `yaml:"admissionReviewVersions"` +} diff --git a/test/e2e/alphagenerate/generate_test.go b/test/e2e/alphagenerate/generate_test.go index 45353c8d77b..5b896e6f624 100644 --- a/test/e2e/alphagenerate/generate_test.go +++ b/test/e2e/alphagenerate/generate_test.go @@ -85,6 +85,12 @@ var _ = Describe("kubebuilder", func() { regenerateProject(kbc, projectOutputDir) validateDeployImagePlugin(projectFilePath) }) + + It("should regenerate project with helm plugin with success", func() { + generateProjectWithHelmPlugin(kbc) + regenerateProject(kbc, projectOutputDir) + validateHelmPlugin(projectFilePath) + }) }) }) @@ -181,6 +187,12 @@ func generateProjectWithGrafanaPlugin(kbc *utils.TestContext) { Expect(err).NotTo(HaveOccurred(), "Failed to edit project to enable Grafana Plugin") } +func generateProjectWithHelmPlugin(kbc *utils.TestContext) { + By("editing project to enable Helm plugin") + err := kbc.Edit("--plugins", "helm.kubebuilder.io/v1-alpha") + Expect(err).NotTo(HaveOccurred(), "Failed to edit project to enable Helm Plugin") +} + func generateProjectWithDeployImagePlugin(kbc *utils.TestContext) { By("creating an API with DeployImage plugin") err := kbc.CreateAPI( @@ -323,3 +335,13 @@ func validateDeployImagePlugin(projectFile string) { Expect(options.ContainerPort).To(Equal("11211"), "Expected container port to match") Expect(options.RunAsUser).To(Equal("1001"), "Expected runAsUser to match") } + +func validateHelmPlugin(projectFile string) { + projectConfig := getConfigFromProjectFile(projectFile) + + By("checking the Helm plugin in the PROJECT file") + var helmPluginConfig map[string]interface{} + err := projectConfig.DecodePluginConfig("helm.kubebuilder.io/v1-alpha", &helmPluginConfig) + Expect(err).NotTo(HaveOccurred(), "Failed to decode Helm plugin configuration") + Expect(helmPluginConfig).NotTo(BeNil(), "Expected Helm plugin configuration to be present in the PROJECT file") +} diff --git a/test/e2e/utils/test_context.go b/test/e2e/utils/test_context.go index 922e235aa29..9d44902997b 100644 --- a/test/e2e/utils/test_context.go +++ b/test/e2e/utils/test_context.go @@ -331,3 +331,58 @@ func (t *TestContext) AllowProjectBeMultiGroup() error { } return nil } + +// InstallHelm installs Helm in the e2e server. +func (t *TestContext) InstallHelm() error { + // You can fetch the latest Helm installation script from its official website + helmInstallScript := "https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3" + + // Use curl to fetch the Helm installation script and install Helm + cmd := exec.Command("bash", "-c", fmt.Sprintf("curl -fsSL %s | bash", helmInstallScript)) + + // Run the command to install Helm + if output, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("failed to install Helm: %s", string(output)) + } + + // Optionally verify that Helm was installed correctly by running `helm version` + verifyCmd := exec.Command("helm", "version") + if output, err := verifyCmd.CombinedOutput(); err != nil { + return fmt.Errorf("failed to verify Helm installation: %s", string(output)) + } + + return nil +} + +// UninstallHelmRelease removes the specified Helm release from the cluster. +func (t *TestContext) UninstallHelmRelease() error { + ns := fmt.Sprintf("e2e-%s-system", t.TestSuffix) + cmd := exec.Command("helm", "uninstall", + fmt.Sprintf("release-%s", t.TestSuffix), + "--namespace", ns) + + if output, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("failed to uninstall Helm release: %s", string(output)) + } + + if _, err := t.Kubectl.Wait(false, "namespace", ns, "--for=delete", "--timeout=2m"); err != nil { + return fmt.Errorf("failed to wait for namespace deletion: %s", err) + } + + return nil +} + +// EditHelmPlugin is for running `kubebuilder edit --plugins=helm.kubebuilder.io/v1-alpha` +func (t *TestContext) EditHelmPlugin() error { + cmd := exec.Command(t.BinaryName, "edit", "--plugins=helm/v1-alpha") + _, err := t.Run(cmd) + return err +} + +// HelmInstallRelease is for running install the HelmChart +func (t *TestContext) HelmInstallRelease() error { + cmd := exec.Command("helm", "install", fmt.Sprintf("release-%s", t.TestSuffix), "dist/chart", + "--namespace", fmt.Sprintf("e2e-%s-system", t.TestSuffix)) + _, err := t.Run(cmd) + return err +} diff --git a/test/e2e/v4/plugin_cluster_test.go b/test/e2e/v4/plugin_cluster_test.go index 8c47403369b..a803787a8cb 100644 --- a/test/e2e/v4/plugin_cluster_test.go +++ b/test/e2e/v4/plugin_cluster_test.go @@ -61,7 +61,7 @@ var _ = Describe("kubebuilder", func() { _ = kbc.RemoveNamespaceLabelToWarnAboutRestricted() By("clean up API objects created during the test") - Expect(kbc.Make("undeploy")).To(Succeed()) + _ = kbc.Make("undeploy") By("removing controller image and working dir") kbc.Destroy() @@ -69,39 +69,51 @@ var _ = Describe("kubebuilder", func() { It("should generate a runnable project", func() { kbc.IsRestricted = false GenerateV4(kbc) - Run(kbc, true, false, true, false) + Run(kbc, true, false, false, true, false) }) It("should generate a runnable project with the Installer", func() { kbc.IsRestricted = false GenerateV4(kbc) - Run(kbc, false, true, true, false) + Run(kbc, false, true, false, true, false) + }) + It("should generate a runnable project using webhooks and installed with the HelmChart", func() { + kbc.IsRestricted = false + GenerateV4(kbc) + By("installing Helm") + Expect(kbc.InstallHelm()).To(Succeed()) + + Run(kbc, true, false, true, true, false) + + By("uninstalling Helm Release") + Expect(kbc.UninstallHelmRelease()).To(Succeed()) }) It("should generate a runnable project without metrics exposed", func() { kbc.IsRestricted = false GenerateV4WithoutMetrics(kbc) - Run(kbc, true, false, false, false) + Run(kbc, true, false, false, false, false) }) It("should generate a runnable project with metrics protected by network policies", func() { kbc.IsRestricted = false GenerateV4WithNetworkPoliciesWithoutWebhooks(kbc) - Run(kbc, false, false, true, true) + Run(kbc, false, false, false, true, true) }) It("should generate a runnable project with webhooks and metrics protected by network policies", func() { kbc.IsRestricted = false GenerateV4WithNetworkPolicies(kbc) - Run(kbc, true, false, true, true) + Run(kbc, true, false, false, true, true) }) It("should generate a runnable project with the manager running "+ "as restricted and without webhooks", func() { kbc.IsRestricted = true GenerateV4WithoutWebhooks(kbc) - Run(kbc, false, false, true, false) + Run(kbc, false, false, false, true, false) }) }) }) // Run runs a set of e2e tests for a scaffolded project defined by a TestContext. -func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, hasMetrics bool, hasNetworkPolicies bool) { +func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, isToUseHelmChart, hasMetrics bool, + hasNetworkPolicies bool) { var controllerPodName string var err error var output []byte @@ -132,14 +144,14 @@ func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, hasMetrics bool, err = kbc.LoadImageToKindCluster() ExpectWithOffset(1, err).NotTo(HaveOccurred()) - if !isToUseInstaller { + if !isToUseInstaller && !isToUseHelmChart { By("deploying the controller-manager") cmd := exec.Command("make", "deploy", "IMG="+kbc.ImageName) output, err = kbc.Run(cmd) ExpectWithOffset(1, err).NotTo(HaveOccurred()) } - if isToUseInstaller { + if isToUseInstaller && !isToUseHelmChart { By("building the installer") err = kbc.Make("build-installer", "IMG="+kbc.ImageName) ExpectWithOffset(1, err).NotTo(HaveOccurred()) @@ -149,6 +161,30 @@ func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, hasMetrics bool, ExpectWithOffset(1, err).NotTo(HaveOccurred()) } + if isToUseHelmChart && !isToUseInstaller { + By("building the helm-chart") + err = kbc.EditHelmPlugin() + Expect(err).NotTo(HaveOccurred(), "Failed to edit project to generate helm-chart") + + By("updating values with image name") + values := filepath.Join(kbc.Dir, "dist", "chart", "values.yaml") + err = util.ReplaceInFile(values, "repository: controller", "repository: e2e-test/controller-manager") + Expect(err).NotTo(HaveOccurred(), "Failed to edit repository in the chart/values.yaml") + err = util.ReplaceInFile(values, "tag: latest", fmt.Sprintf("tag: %s", kbc.TestSuffix)) + Expect(err).NotTo(HaveOccurred(), "Failed to edit tag in the chart/values.yaml") + + By("updating values to enable prometheus") + err = util.ReplaceInFile(values, "prometheus:\n create: false", "prometheus:\n create: true") + Expect(err).NotTo(HaveOccurred(), "Failed to enable prometheus in the chart/values.yaml") + + By("updating values to enable cert-manager") + err = util.ReplaceInFile(values, "certmanager:\n create: false", "certmanager:\n create: true") + Expect(err).NotTo(HaveOccurred(), "Failed to enable certmanager in the chart/values.yaml") + + By("install with Helm release") + err = kbc.HelmInstallRelease() + Expect(err).NotTo(HaveOccurred(), "Failed to install helm release") + } if kbc.IsRestricted { By("validating that manager Pod/container(s) are restricted") ExpectWithOffset(1, output).NotTo(ContainSubstring("Warning: would violate PodSecurity")) diff --git a/test/testdata/generate.sh b/test/testdata/generate.sh index f9d5d2f3d8d..7dba38e4215 100755 --- a/test/testdata/generate.sh +++ b/test/testdata/generate.sh @@ -86,7 +86,7 @@ function scaffold_test_project { if [[ $project =~ multigroup ]] || [[ $project =~ with-plugins ]] ; then header_text 'With Optional Plugins ...' header_text 'Creating APIs with deploy-image plugin ...' - $kb create api --group example.com --version v1alpha1 --kind Memcached --image=memcached:memcached:1.6.26-alpine3.19 --image-container-command="memcached,--memory-limit=64,-o,modern,-v" --image-container-port="11211" --run-as-user="1001" --plugins="deploy-image/v1-alpha" --make=false + $kb create api --group example.com --version v1alpha1 --kind Memcached --image=memcached:1.6.26-alpine3.19 --image-container-command="memcached,--memory-limit=64,-o,modern,-v" --image-container-port="11211" --run-as-user="1001" --plugins="deploy-image/v1-alpha" --make=false $kb create api --group example.com --version v1alpha1 --kind Busybox --image=busybox:1.36.1 --plugins="deploy-image/v1-alpha" --make=false $kb create webhook --group example.com --version v1alpha1 --kind Memcached --programmatic-validation header_text 'Editing project with Grafana plugin ...' @@ -95,6 +95,12 @@ function scaffold_test_project { make all make build-installer + + if [[ $project =~ multigroup ]] || [[ $project =~ with-plugins ]] ; then + header_text 'Editing project with Helm plugin ...' + $kb edit --plugins=helm.kubebuilder.io/v1-alpha + fi + # To avoid conflicts rm -f go.sum go mod tidy diff --git a/testdata/project-v4-multigroup/PROJECT b/testdata/project-v4-multigroup/PROJECT index ab8ce10ec1e..ebc553aefdd 100644 --- a/testdata/project-v4-multigroup/PROJECT +++ b/testdata/project-v4-multigroup/PROJECT @@ -15,7 +15,7 @@ plugins: options: containerCommand: memcached,--memory-limit=64,-o,modern,-v containerPort: "11211" - image: memcached:memcached:1.6.26-alpine3.19 + image: memcached:1.6.26-alpine3.19 runAsUser: "1001" version: v1alpha1 - domain: testproject.org @@ -25,6 +25,7 @@ plugins: image: busybox:1.36.1 version: v1alpha1 grafana.kubebuilder.io/v1-alpha: {} + helm.kubebuilder.io/v1-alpha: {} projectName: project-v4-multigroup repo: sigs.k8s.io/kubebuilder/testdata/project-v4-multigroup resources: diff --git a/testdata/project-v4-multigroup/config/manager/manager.yaml b/testdata/project-v4-multigroup/config/manager/manager.yaml index dc23b608705..3b3c86f4517 100644 --- a/testdata/project-v4-multigroup/config/manager/manager.yaml +++ b/testdata/project-v4-multigroup/config/manager/manager.yaml @@ -69,7 +69,7 @@ spec: - name: BUSYBOX_IMAGE value: busybox:1.36.1 - name: MEMCACHED_IMAGE - value: memcached:memcached:1.6.26-alpine3.19 + value: memcached:1.6.26-alpine3.19 securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/testdata/project-v4-multigroup/dist/chart/.helmignore b/testdata/project-v4-multigroup/dist/chart/.helmignore new file mode 100644 index 00000000000..4eba77dd129 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/.helmignore @@ -0,0 +1,27 @@ +# Patterns to ignore when building Helm packages. +# Supports shell glob matching, relative path matching, and negation. + +# Operating system files +.DS_Store + +# Version control directories +.git/ +.gitignore +.bzr/ +.hg/ +.hgignore +.svn/ + +# Backup and temporary files +*.swp +*.tmp +*.bak +*.orig +*~ + +# IDE and editor-related files +.idea/ +.vscode/ + +# Helm chart artifacts +dist/chart/*.tgz diff --git a/testdata/project-v4-multigroup/dist/chart/Chart.yaml b/testdata/project-v4-multigroup/dist/chart/Chart.yaml new file mode 100644 index 00000000000..16168e41f30 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: project-v4-multigroup +description: A Helm chart to distribute the project project-v4-multigroup +type: application +version: 0.1.0 +appVersion: "0.1.0" +icon: "https://example.com/icon.png" diff --git a/testdata/project-v4-multigroup/dist/chart/templates/_helpers.tpl b/testdata/project-v4-multigroup/dist/chart/templates/_helpers.tpl new file mode 100644 index 00000000000..94dc7107151 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/_helpers.tpl @@ -0,0 +1,70 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "chart.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "chart.fullname" -}} +{{- if .Values.fullnameOverride }} +{{ .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{ .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{ printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "chart.version" -}} +{{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "chart.labels" -}} +helm.sh/chart: {{ include "chart.version" . }} +app.kubernetes.io/name: {{ include "chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "chart.selectorLabels" -}} +app.kubernetes.io/name: {{ include "chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Helper to check if mutating webhooks exist in the services. +*/}} +{{- define "chart.hasMutatingWebhooks" -}} +{{- $hasMutating := false }} +{{- range . }} + {{- if eq .type "mutating" }} + $hasMutating = true }}{{- end }} +{{- end }} +{{ $hasMutating }}}}{{- end }} + +{{/* +Helper to check if validating webhooks exist in the services. +*/}} +{{- define "chart.hasValidatingWebhooks" -}} +{{- $hasValidating := false }} +{{- range . }} + {{- if eq .type "validating" }} + $hasValidating = true }}{{- end }} +{{- end }} +{{ $hasValidating }}}}{{- end }} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/certmanager/certificate.yaml b/testdata/project-v4-multigroup/dist/chart/templates/certmanager/certificate.yaml new file mode 100755 index 00000000000..dc58c3af859 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/certmanager/certificate.yaml @@ -0,0 +1,29 @@ +{{- if .Values.certmanager.create }} +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: selfsigned-issuer + namespace: {{ .Values.namespace }} +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + namespace: {{ .Values.namespace }} +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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/crds/crew.testproject.org_captains.yaml b/testdata/project-v4-multigroup/dist/chart/templates/crds/crew.testproject.org_captains.yaml new file mode 100755 index 00000000000..02b2d49e8f0 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/crds/crew.testproject.org_captains.yaml @@ -0,0 +1,58 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + 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: {} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/crds/example.com.testproject.org_busyboxes.yaml b/testdata/project-v4-multigroup/dist/chart/templates/crds/example.com.testproject.org_busyboxes.yaml new file mode 100755 index 00000000000..fba78ef68fc --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/crds/example.com.testproject.org_busyboxes.yaml @@ -0,0 +1,120 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + name: busyboxes.example.com.testproject.org +spec: + group: example.com.testproject.org + names: + kind: Busybox + listKind: BusyboxList + plural: busyboxes + singular: busybox + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Busybox is the Schema for the busyboxes API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: BusyboxSpec defines the desired state of Busybox + properties: + size: + description: |- + Size defines the number of Busybox instances + The following markers will use OpenAPI v3 schema to validate the value + More info: https://book.kubebuilder.io/reference/markers/crd-validation.html + format: int32 + maximum: 3 + minimum: 1 + type: integer + type: object + status: + description: BusyboxStatus defines the observed state of Busybox + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/crds/example.com.testproject.org_memcacheds.yaml b/testdata/project-v4-multigroup/dist/chart/templates/crds/example.com.testproject.org_memcacheds.yaml new file mode 100755 index 00000000000..b389828fe06 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/crds/example.com.testproject.org_memcacheds.yaml @@ -0,0 +1,125 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + name: memcacheds.example.com.testproject.org +spec: + group: example.com.testproject.org + names: + kind: Memcached + listKind: MemcachedList + plural: memcacheds + singular: memcached + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Memcached is the Schema for the memcacheds API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MemcachedSpec defines the desired state of Memcached + properties: + containerPort: + description: Port defines the port that will be used to init the container + with the image + format: int32 + type: integer + size: + description: |- + Size defines the number of Memcached instances + The following markers will use OpenAPI v3 schema to validate the value + More info: https://book.kubebuilder.io/reference/markers/crd-validation.html + format: int32 + maximum: 3 + minimum: 1 + type: integer + type: object + status: + description: MemcachedStatus defines the observed state of Memcached + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/crds/fiz.testproject.org_bars.yaml b/testdata/project-v4-multigroup/dist/chart/templates/crds/fiz.testproject.org_bars.yaml new file mode 100755 index 00000000000..fc4814abc54 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/crds/fiz.testproject.org_bars.yaml @@ -0,0 +1,58 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + 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: {} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/crds/foo.policy.testproject.org_healthcheckpolicies.yaml b/testdata/project-v4-multigroup/dist/chart/templates/crds/foo.policy.testproject.org_healthcheckpolicies.yaml new file mode 100755 index 00000000000..c0b156d637c --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/crds/foo.policy.testproject.org_healthcheckpolicies.yaml @@ -0,0 +1,58 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + 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: {} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/crds/foo.testproject.org_bars.yaml b/testdata/project-v4-multigroup/dist/chart/templates/crds/foo.testproject.org_bars.yaml new file mode 100755 index 00000000000..d38a6727bfd --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/crds/foo.testproject.org_bars.yaml @@ -0,0 +1,58 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + 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: {} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/crds/sea-creatures.testproject.org_krakens.yaml b/testdata/project-v4-multigroup/dist/chart/templates/crds/sea-creatures.testproject.org_krakens.yaml new file mode 100755 index 00000000000..271c9a291df --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/crds/sea-creatures.testproject.org_krakens.yaml @@ -0,0 +1,58 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + 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: {} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/crds/sea-creatures.testproject.org_leviathans.yaml b/testdata/project-v4-multigroup/dist/chart/templates/crds/sea-creatures.testproject.org_leviathans.yaml new file mode 100755 index 00000000000..046f746eaa9 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/crds/sea-creatures.testproject.org_leviathans.yaml @@ -0,0 +1,58 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + 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: {} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_cruisers.yaml b/testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_cruisers.yaml new file mode 100755 index 00000000000..73dc3e6fe69 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_cruisers.yaml @@ -0,0 +1,58 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + 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: {} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_destroyers.yaml b/testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_destroyers.yaml new file mode 100755 index 00000000000..91bd867ccc0 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_destroyers.yaml @@ -0,0 +1,58 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + 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: {} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_frigates.yaml b/testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_frigates.yaml new file mode 100755 index 00000000000..68ba6314522 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/crds/ship.testproject.org_frigates.yaml @@ -0,0 +1,58 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + 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: {} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/manager/manager.yaml b/testdata/project-v4-multigroup/dist/chart/templates/manager/manager.yaml new file mode 100644 index 00000000000..ae693d81913 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/manager/manager.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: {{ .Values.namespace }} + labels: + {{- include "chart.labels" . | nindent 4 }} + control-plane: controller-manager +spec: + selector: + matchLabels: + {{- include "chart.selectorLabels" . | nindent 6 }} + control-plane: controller-manager + template: + metadata: + labels: + {{- include "chart.labels" . | nindent 8 }} + control-plane: controller-manager + spec: + serviceAccountName: {{ .Values.controllerManager.serviceAccountName }} + containers: + - name: manager + image: {{ .Values.controllerManager.image.repository }}:{{ .Values.controllerManager.image.tag }} + args: + {{- range .Values.controllerManager.args }} + - {{ . }} + {{- end }} + {{- if .DeployImages }} + env: + {{- range $key, $value := .Values.controllerManager.env }} + - name: {{ $key }} + value: {{ $value }} + {{- end }} + {{- end }} + livenessProbe: + {{- toYaml .Values.controllerManager.livenessProbe | nindent 8 }} + readinessProbe: + {{- toYaml .Values.controllerManager.readinessProbe | nindent 8 }} + resources: + {{- toYaml .Values.controllerManager.resources | nindent 8 }} + securityContext: + {{- toYaml .Values.controllerManager.securityContext | nindent 8 }} + volumeMounts: + - name: webhook-cert + mountPath: /tmp/k8s-webhook-server/serving-certs + readOnly: true + terminationGracePeriodSeconds: {{ .Values.controllerManager.terminationGracePeriodSeconds }} + volumes: + - name: webhook-cert + secret: + secretName: webhook-server-cert diff --git a/testdata/project-v4-multigroup/dist/chart/templates/network-policy/allow-metrics-traffic.yaml b/testdata/project-v4-multigroup/dist/chart/templates/network-policy/allow-metrics-traffic.yaml new file mode 100755 index 00000000000..460cb846983 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/network-policy/allow-metrics-traffic.yaml @@ -0,0 +1,27 @@ +{{- if .Values.networkPolicy.create }} +# This NetworkPolicy allows ingress traffic +# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those +# namespaces are able to gathering data from the metrics endpoint. +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: allow-metrics-traffic + namespace: {{ .Values.namespace }} +spec: + podSelector: + matchLabels: + control-plane: controller-manager + policyTypes: + - Ingress + ingress: + # This allows ingress traffic from any namespace with the label metrics: enabled + - from: + - namespaceSelector: + matchLabels: + metrics: enabled # Only from namespaces with this label + ports: + - port: 8443 + protocol: TCP +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/network-policy/allow-webhook-traffic.yaml b/testdata/project-v4-multigroup/dist/chart/templates/network-policy/allow-webhook-traffic.yaml new file mode 100755 index 00000000000..3a34a352302 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/network-policy/allow-webhook-traffic.yaml @@ -0,0 +1,27 @@ +{{- if .Values.networkPolicy.create }} +# This NetworkPolicy allows ingress traffic to your webhook server running +# as part of the controller-manager from specific namespaces and pods. CR(s) which uses webhooks +# will only work when applied in namespaces labeled with 'webhook: enabled' +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: allow-webhook-traffic + namespace: {{ .Values.namespace }} +spec: + podSelector: + matchLabels: + control-plane: controller-manager + policyTypes: + - Ingress + ingress: + # This allows ingress traffic from any namespace with the label webhook: enabled + - from: + - namespaceSelector: + matchLabels: + webhook: enabled # Only from namespaces with this label + ports: + - port: 443 + protocol: TCP +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/prometheus/monitor.yaml b/testdata/project-v4-multigroup/dist/chart/templates/prometheus/monitor.yaml new file mode 100755 index 00000000000..41ab6e848d7 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/prometheus/monitor.yaml @@ -0,0 +1,30 @@ +{{- if .Values.prometheus.create }} +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: controller-manager-metrics-monitor + namespace: {{ .Values.namespace }} +spec: + endpoints: + - path: /metrics + port: https # Ensure this is the name of the port that exposes HTTPS metrics + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + # TODO(user): The option insecureSkipVerify: true is not recommended for production since it disables + # certificate verification. This poses a significant security risk by making the system vulnerable to + # man-in-the-middle attacks, where an attacker could intercept and manipulate the communication between + # Prometheus and the monitored services. This could lead to unauthorized access to sensitive metrics data, + # compromising the integrity and confidentiality of the information. + # Please use the following options for secure configurations: + # caFile: /etc/metrics-certs/ca.crt + # certFile: /etc/metrics-certs/tls.crt + # keyFile: /etc/metrics-certs/tls.key + insecureSkipVerify: true + selector: + matchLabels: + control-plane: controller-manager +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/crew_captain_editor_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/crew_captain_editor_role.yaml new file mode 100755 index 00000000000..151e92cbccf --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/crew_captain_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: crew-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/crew_captain_viewer_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/crew_captain_viewer_role.yaml new file mode 100755 index 00000000000..bba3bcba01d --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/crew_captain_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view captains. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: crew-captain-viewer-role +rules: +- apiGroups: + - crew.testproject.org + resources: + - captains + verbs: + - get + - list + - watch +- apiGroups: + - crew.testproject.org + resources: + - captains/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_busybox_editor_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_busybox_editor_role.yaml new file mode 100755 index 00000000000..b1fe015cb1a --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_busybox_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit busyboxes. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: example.com-busybox-editor-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_busybox_viewer_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_busybox_viewer_role.yaml new file mode 100755 index 00000000000..db0b7ecb89b --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_busybox_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view busyboxes. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: example.com-busybox-viewer-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - get + - list + - watch +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_memcached_editor_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_memcached_editor_role.yaml new file mode 100755 index 00000000000..19f32db855d --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_memcached_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit memcacheds. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: example.com-memcached-editor-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_memcached_viewer_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_memcached_viewer_role.yaml new file mode 100755 index 00000000000..c93e28c2871 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/example.com_memcached_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view memcacheds. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: example.com-memcached-viewer-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - get + - list + - watch +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/fiz_bar_editor_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/fiz_bar_editor_role.yaml new file mode 100755 index 00000000000..44e7e787327 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/fiz_bar_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit bars. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: fiz-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/fiz_bar_viewer_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/fiz_bar_viewer_role.yaml new file mode 100755 index 00000000000..91326492019 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/fiz_bar_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view bars. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: fiz-bar-viewer-role +rules: +- apiGroups: + - fiz.testproject.org + resources: + - bars + verbs: + - get + - list + - watch +- apiGroups: + - fiz.testproject.org + resources: + - bars/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo.policy_healthcheckpolicy_editor_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo.policy_healthcheckpolicy_editor_role.yaml new file mode 100755 index 00000000000..2be9acfdbda --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo.policy_healthcheckpolicy_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit healthcheckpolicies. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: foo.policy-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml new file mode 100755 index 00000000000..9585db188e7 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo.policy_healthcheckpolicy_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view healthcheckpolicies. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: foo.policy-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo_bar_editor_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo_bar_editor_role.yaml new file mode 100755 index 00000000000..35636a8dce2 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo_bar_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit bars. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: foo-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo_bar_viewer_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo_bar_viewer_role.yaml new file mode 100755 index 00000000000..5ea6e38add2 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/foo_bar_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view bars. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: foo-bar-viewer-role +rules: +- apiGroups: + - foo.testproject.org + resources: + - bars + verbs: + - get + - list + - watch +- apiGroups: + - foo.testproject.org + resources: + - bars/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/leader_election_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/leader_election_role.yaml new file mode 100755 index 00000000000..07bb4a2c407 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/leader_election_role.yaml @@ -0,0 +1,41 @@ +{{- if .Values.rbac.create }} +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + 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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/leader_election_role_binding.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/leader_election_role_binding.yaml new file mode 100755 index 00000000000..f81780e69df --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/leader_election_role_binding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: leader-election-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: {{ .Values.namespace }} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_auth_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_auth_role.yaml new file mode 100755 index 00000000000..d3edf2766af --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_auth_role.yaml @@ -0,0 +1,21 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: metrics-auth-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_auth_role_binding.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_auth_role_binding.yaml new file mode 100755 index 00000000000..f051f06d96f --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_auth_role_binding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: metrics-auth-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: metrics-auth-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: {{ .Values.namespace }} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_reader_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_reader_role.yaml new file mode 100755 index 00000000000..df8bd5b4b1d --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/metrics_reader_role.yaml @@ -0,0 +1,13 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/role.yaml new file mode 100755 index 00000000000..e3c79bb0a2c --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/role.yaml @@ -0,0 +1,248 @@ +{{- if .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: manager-role +rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch +- 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: + - cert-manager.io + resources: + - certificates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - cert-manager.io + resources: + - certificates/finalizers + verbs: + - update +- apiGroups: + - cert-manager.io + resources: + - certificates/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: + - example.com.testproject.org + resources: + - busyboxes + - memcacheds + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/finalizers + - memcacheds/finalizers + verbs: + - update +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + - memcacheds/status + verbs: + - get + - patch + - update +- apiGroups: + - fiz.testproject.org + - foo.testproject.org + resources: + - bars + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - fiz.testproject.org + - foo.testproject.org + resources: + - bars/finalizers + verbs: + - update +- apiGroups: + - fiz.testproject.org + - foo.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: + - sea-creatures.testproject.org + resources: + - krakens + - leviathans + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens/finalizers + - leviathans/finalizers + verbs: + - update +- apiGroups: + - sea-creatures.testproject.org + resources: + - krakens/status + - leviathans/status + verbs: + - get + - patch + - update +- apiGroups: + - ship.testproject.org + resources: + - cruisers + - destroyers + - frigates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - ship.testproject.org + resources: + - cruisers/finalizers + - destroyers/finalizers + - frigates/finalizers + verbs: + - update +- apiGroups: + - ship.testproject.org + resources: + - cruisers/status + - destroyers/status + - frigates/status + verbs: + - get + - patch + - update +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/role_binding.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/role_binding.yaml new file mode 100755 index 00000000000..a0336756722 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/role_binding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: manager-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: {{ .Values.namespace }} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_kraken_editor_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_kraken_editor_role.yaml new file mode 100755 index 00000000000..7c641aac7c5 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_kraken_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit krakens. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: sea-creatures-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_kraken_viewer_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_kraken_viewer_role.yaml new file mode 100755 index 00000000000..e945c0d9a22 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_kraken_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view krakens. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: sea-creatures-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_leviathan_editor_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_leviathan_editor_role.yaml new file mode 100755 index 00000000000..6847507539a --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_leviathan_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit leviathans. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: sea-creatures-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_leviathan_viewer_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_leviathan_viewer_role.yaml new file mode 100755 index 00000000000..7945dabb16a --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/sea-creatures_leviathan_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view leviathans. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: sea-creatures-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/service_account.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/service_account.yaml new file mode 100755 index 00000000000..6d176e3772c --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/service_account.yaml @@ -0,0 +1,9 @@ +{{- if .Values.rbac.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: controller-manager + namespace: {{ .Values.namespace }} +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_cruiser_editor_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_cruiser_editor_role.yaml new file mode 100755 index 00000000000..166030dc6ea --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_cruiser_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit cruisers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: ship-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_cruiser_viewer_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_cruiser_viewer_role.yaml new file mode 100755 index 00000000000..84f28ac829a --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_cruiser_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view cruisers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: ship-cruiser-viewer-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - cruisers + verbs: + - get + - list + - watch +- apiGroups: + - ship.testproject.org + resources: + - cruisers/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_destroyer_editor_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_destroyer_editor_role.yaml new file mode 100755 index 00000000000..a314b5113f0 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_destroyer_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit destroyers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: ship-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_destroyer_viewer_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_destroyer_viewer_role.yaml new file mode 100755 index 00000000000..4910e7049ac --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_destroyer_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view destroyers. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: ship-destroyer-viewer-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - destroyers + verbs: + - get + - list + - watch +- apiGroups: + - ship.testproject.org + resources: + - destroyers/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_frigate_editor_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_frigate_editor_role.yaml new file mode 100755 index 00000000000..197df51ebf1 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_frigate_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit frigates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: ship-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 +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_frigate_viewer_role.yaml b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_frigate_viewer_role.yaml new file mode 100755 index 00000000000..245f7eb7dc3 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/rbac/ship_frigate_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view frigates. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: ship-frigate-viewer-role +rules: +- apiGroups: + - ship.testproject.org + resources: + - frigates + verbs: + - get + - list + - watch +- apiGroups: + - ship.testproject.org + resources: + - frigates/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-multigroup/dist/chart/templates/webhook/service.yaml b/testdata/project-v4-multigroup/dist/chart/templates/webhook/service.yaml new file mode 100644 index 00000000000..eda59d6be90 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/webhook/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.namespace }}-webhook-service + namespace: {{ .Values.namespace }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager diff --git a/testdata/project-v4-multigroup/dist/chart/templates/webhook/webhooks.yaml b/testdata/project-v4-multigroup/dist/chart/templates/webhook/webhooks.yaml new file mode 100644 index 00000000000..6001f2296ee --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/templates/webhook/webhooks.yaml @@ -0,0 +1,104 @@ +{{- if .Values.webhook.create }} + +{{- if include "chart.hasMutatingWebhooks" .Values.webhook.services }} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ .Values.namespace }}-mutating-webhook + labels: + {{- include "chart.labels" . | nindent 4 }} +webhooks: + {{- range .Values.webhook.services }} + {{- if eq .type "mutating" }} + - name: {{ .name }}.{{ $.Values.namespace }}.svc + clientConfig: + service: + name: {{ .name }} + namespace: {{ $.Values.namespace }} + path: {{ .path }} + caBundle: {{ .caBundle }} + failurePolicy: {{ .failurePolicy }} + sideEffects: {{ .sideEffects }} + admissionReviewVersions: + {{- range .admissionReviewVersions }} + - {{ . }} + {{- end }} + rules: + {{- range .rules }} + - operations: + {{- range .operations }} + - {{ . }} + {{- end }} + apiGroups: + {{- if .apiGroups }} + {{- range .apiGroups }} + - {{ default "\"\"" . }} + {{- end }} + {{- else }} + - "" + {{- end }} + apiVersions: + {{- range .apiVersions }} + - {{ . }} + {{- end }} + resources: + {{- range .resources }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +--- +{{- end }} + +{{- if include "chart.hasValidatingWebhooks" .Values.webhook.services }} +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ .Values.namespace }}-validating-webhook + labels: + {{- include "chart.labels" . | nindent 4 }} +webhooks: + {{- range .Values.webhook.services }} + {{- if eq .type "validating" }} + - name: {{ .name }}.{{ $.Values.namespace }}.svc + clientConfig: + service: + name: {{ .name }} + namespace: {{ $.Values.namespace }} + path: {{ .path }} + caBundle: {{ .caBundle }} + failurePolicy: {{ .failurePolicy }} + sideEffects: {{ .sideEffects }} + admissionReviewVersions: + {{- range .admissionReviewVersions }} + - {{ . }} + {{- end }} + rules: + {{- range .rules }} + - operations: + {{- range .operations }} + - {{ . }} + {{- end }} + apiGroups: + {{- if .apiGroups }} + {{- range .apiGroups }} + - {{ default "\"\"" . }} + {{- end }} + {{- else }} + - "" + {{- end }} + apiVersions: + {{- range .apiVersions }} + - {{ . }} + {{- end }} + resources: + {{- range .resources }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- end }} diff --git a/testdata/project-v4-multigroup/dist/chart/values.yaml b/testdata/project-v4-multigroup/dist/chart/values.yaml new file mode 100644 index 00000000000..cfc2b80f059 --- /dev/null +++ b/testdata/project-v4-multigroup/dist/chart/values.yaml @@ -0,0 +1,190 @@ +# Default values for the Kubebuilder Helm chart +# Namespace where the Manager will be deployed +namespace: project-v4-multigroup-system + +# Controller Manager settings +controllerManager: + image: + repository: controller + tag: latest + replicas: 1 + args: + - "--leader-elect" + - "--metrics-bind-address=:8080" + - "--health-probe-bind-address=:8081" + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + livenessProbe: + initialDelaySeconds: 15 + periodSeconds: 20 + httpGet: + path: /healthz + port: 8081 + readinessProbe: + initialDelaySeconds: 5 + periodSeconds: 10 + httpGet: + path: /readyz + port: 8081 + securityContext: + runAsNonRoot: true + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + serviceAccountName: controller-manager + terminationGracePeriodSeconds: 10 + env: + BUSYBOX_IMAGE: busybox:1.36.1 + MEMCACHED_IMAGE: memcached:1.6.26-alpine3.19 + +# RBAC settings +rbac: + create: true + +# CRDs settings +crd: + create: true + + +# Webhook service settings +webhook: + create: true + services: + - name: missuer-v1.kb.io + type: mutating + path: /mutate-cert-manager-io-v1-issuer + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - v1 + rules: + - operations: + - CREATE + - UPDATE + apiGroups: + - cert-manager.io + apiVersions: + - v1 + resources: + - issuers + - name: mcaptain-v1.kb.io + type: mutating + path: /mutate-crew-testproject-org-v1-captain + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - v1 + rules: + - operations: + - CREATE + - UPDATE + apiGroups: + - crew.testproject.org + apiVersions: + - v1 + resources: + - captains + - name: mdestroyer-v1.kb.io + type: mutating + path: /mutate-ship-testproject-org-v1-destroyer + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - v1 + rules: + - operations: + - CREATE + - UPDATE + apiGroups: + - ship.testproject.org + apiVersions: + - v1 + resources: + - destroyers + - name: vpod-v1.kb.io + type: validating + path: /validate--v1-pod + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - v1 + rules: + - operations: + - CREATE + - UPDATE + apiGroups: + - "" + apiVersions: + - v1 + resources: + - pods + - name: vcaptain-v1.kb.io + type: validating + path: /validate-crew-testproject-org-v1-captain + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - v1 + rules: + - operations: + - CREATE + - UPDATE + apiGroups: + - crew.testproject.org + apiVersions: + - v1 + resources: + - captains + - name: vmemcached-v1alpha1.kb.io + type: validating + path: /validate-example-com-testproject-org-v1alpha1-memcached + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - v1 + rules: + - operations: + - CREATE + - UPDATE + apiGroups: + - example.com.testproject.org + apiVersions: + - v1alpha1 + resources: + - memcacheds + - name: vcruiser-v2alpha1.kb.io + type: validating + path: /validate-ship-testproject-org-v2alpha1-cruiser + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - v1 + rules: + - operations: + - CREATE + - UPDATE + apiGroups: + - ship.testproject.org + apiVersions: + - v2alpha1 + resources: + - cruisers + + +# Prometheus monitoring settings +prometheus: + create: false + +# CertManager settings for certificates +certmanager: + create: false + +# Network policies +networkPolicy: + create: false diff --git a/testdata/project-v4-multigroup/dist/install.yaml b/testdata/project-v4-multigroup/dist/install.yaml index 56d97112886..b6f36443784 100644 --- a/testdata/project-v4-multigroup/dist/install.yaml +++ b/testdata/project-v4-multigroup/dist/install.yaml @@ -1764,7 +1764,7 @@ spec: - name: BUSYBOX_IMAGE value: busybox:1.36.1 - name: MEMCACHED_IMAGE - value: memcached:memcached:1.6.26-alpine3.19 + value: memcached:1.6.26-alpine3.19 image: controller:latest livenessProbe: httpGet: diff --git a/testdata/project-v4-with-plugins/PROJECT b/testdata/project-v4-with-plugins/PROJECT index f006d1cad32..de4af054f0e 100644 --- a/testdata/project-v4-with-plugins/PROJECT +++ b/testdata/project-v4-with-plugins/PROJECT @@ -14,7 +14,7 @@ plugins: options: containerCommand: memcached,--memory-limit=64,-o,modern,-v containerPort: "11211" - image: memcached:memcached:1.6.26-alpine3.19 + image: memcached:1.6.26-alpine3.19 runAsUser: "1001" version: v1alpha1 - domain: testproject.org @@ -24,6 +24,7 @@ plugins: image: busybox:1.36.1 version: v1alpha1 grafana.kubebuilder.io/v1-alpha: {} + helm.kubebuilder.io/v1-alpha: {} projectName: project-v4-with-plugins repo: sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins resources: diff --git a/testdata/project-v4-with-plugins/config/manager/manager.yaml b/testdata/project-v4-with-plugins/config/manager/manager.yaml index b04cea1a357..006faaa6680 100644 --- a/testdata/project-v4-with-plugins/config/manager/manager.yaml +++ b/testdata/project-v4-with-plugins/config/manager/manager.yaml @@ -69,7 +69,7 @@ spec: - name: BUSYBOX_IMAGE value: busybox:1.36.1 - name: MEMCACHED_IMAGE - value: memcached:memcached:1.6.26-alpine3.19 + value: memcached:1.6.26-alpine3.19 securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/testdata/project-v4-with-plugins/dist/chart/.helmignore b/testdata/project-v4-with-plugins/dist/chart/.helmignore new file mode 100644 index 00000000000..4eba77dd129 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/.helmignore @@ -0,0 +1,27 @@ +# Patterns to ignore when building Helm packages. +# Supports shell glob matching, relative path matching, and negation. + +# Operating system files +.DS_Store + +# Version control directories +.git/ +.gitignore +.bzr/ +.hg/ +.hgignore +.svn/ + +# Backup and temporary files +*.swp +*.tmp +*.bak +*.orig +*~ + +# IDE and editor-related files +.idea/ +.vscode/ + +# Helm chart artifacts +dist/chart/*.tgz diff --git a/testdata/project-v4-with-plugins/dist/chart/Chart.yaml b/testdata/project-v4-with-plugins/dist/chart/Chart.yaml new file mode 100644 index 00000000000..0f89680c555 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: project-v4-with-plugins +description: A Helm chart to distribute the project project-v4-with-plugins +type: application +version: 0.1.0 +appVersion: "0.1.0" +icon: "https://example.com/icon.png" diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl b/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl new file mode 100644 index 00000000000..94dc7107151 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl @@ -0,0 +1,70 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "chart.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "chart.fullname" -}} +{{- if .Values.fullnameOverride }} +{{ .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{ .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{ printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "chart.version" -}} +{{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "chart.labels" -}} +helm.sh/chart: {{ include "chart.version" . }} +app.kubernetes.io/name: {{ include "chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "chart.selectorLabels" -}} +app.kubernetes.io/name: {{ include "chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Helper to check if mutating webhooks exist in the services. +*/}} +{{- define "chart.hasMutatingWebhooks" -}} +{{- $hasMutating := false }} +{{- range . }} + {{- if eq .type "mutating" }} + $hasMutating = true }}{{- end }} +{{- end }} +{{ $hasMutating }}}}{{- end }} + +{{/* +Helper to check if validating webhooks exist in the services. +*/}} +{{- define "chart.hasValidatingWebhooks" -}} +{{- $hasValidating := false }} +{{- range . }} + {{- if eq .type "validating" }} + $hasValidating = true }}{{- end }} +{{- end }} +{{ $hasValidating }}}}{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/certmanager/certificate.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/certmanager/certificate.yaml new file mode 100755 index 00000000000..dc58c3af859 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/certmanager/certificate.yaml @@ -0,0 +1,29 @@ +{{- if .Values.certmanager.create }} +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: selfsigned-issuer + namespace: {{ .Values.namespace }} +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + namespace: {{ .Values.namespace }} +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 +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crds/example.com.testproject.org_busyboxes.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crds/example.com.testproject.org_busyboxes.yaml new file mode 100755 index 00000000000..fba78ef68fc --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/crds/example.com.testproject.org_busyboxes.yaml @@ -0,0 +1,120 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + name: busyboxes.example.com.testproject.org +spec: + group: example.com.testproject.org + names: + kind: Busybox + listKind: BusyboxList + plural: busyboxes + singular: busybox + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Busybox is the Schema for the busyboxes API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: BusyboxSpec defines the desired state of Busybox + properties: + size: + description: |- + Size defines the number of Busybox instances + The following markers will use OpenAPI v3 schema to validate the value + More info: https://book.kubebuilder.io/reference/markers/crd-validation.html + format: int32 + maximum: 3 + minimum: 1 + type: integer + type: object + status: + description: BusyboxStatus defines the observed state of Busybox + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crds/example.com.testproject.org_memcacheds.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crds/example.com.testproject.org_memcacheds.yaml new file mode 100755 index 00000000000..b389828fe06 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/crds/example.com.testproject.org_memcacheds.yaml @@ -0,0 +1,125 @@ +{{- if .Values.crd.create }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + name: memcacheds.example.com.testproject.org +spec: + group: example.com.testproject.org + names: + kind: Memcached + listKind: MemcachedList + plural: memcacheds + singular: memcached + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Memcached is the Schema for the memcacheds API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: MemcachedSpec defines the desired state of Memcached + properties: + containerPort: + description: Port defines the port that will be used to init the container + with the image + format: int32 + type: integer + size: + description: |- + Size defines the number of Memcached instances + The following markers will use OpenAPI v3 schema to validate the value + More info: https://book.kubebuilder.io/reference/markers/crd-validation.html + format: int32 + maximum: 3 + minimum: 1 + type: integer + type: object + status: + description: MemcachedStatus defines the observed state of Memcached + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml new file mode 100644 index 00000000000..ae693d81913 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: {{ .Values.namespace }} + labels: + {{- include "chart.labels" . | nindent 4 }} + control-plane: controller-manager +spec: + selector: + matchLabels: + {{- include "chart.selectorLabels" . | nindent 6 }} + control-plane: controller-manager + template: + metadata: + labels: + {{- include "chart.labels" . | nindent 8 }} + control-plane: controller-manager + spec: + serviceAccountName: {{ .Values.controllerManager.serviceAccountName }} + containers: + - name: manager + image: {{ .Values.controllerManager.image.repository }}:{{ .Values.controllerManager.image.tag }} + args: + {{- range .Values.controllerManager.args }} + - {{ . }} + {{- end }} + {{- if .DeployImages }} + env: + {{- range $key, $value := .Values.controllerManager.env }} + - name: {{ $key }} + value: {{ $value }} + {{- end }} + {{- end }} + livenessProbe: + {{- toYaml .Values.controllerManager.livenessProbe | nindent 8 }} + readinessProbe: + {{- toYaml .Values.controllerManager.readinessProbe | nindent 8 }} + resources: + {{- toYaml .Values.controllerManager.resources | nindent 8 }} + securityContext: + {{- toYaml .Values.controllerManager.securityContext | nindent 8 }} + volumeMounts: + - name: webhook-cert + mountPath: /tmp/k8s-webhook-server/serving-certs + readOnly: true + terminationGracePeriodSeconds: {{ .Values.controllerManager.terminationGracePeriodSeconds }} + volumes: + - name: webhook-cert + secret: + secretName: webhook-server-cert diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-metrics-traffic.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-metrics-traffic.yaml new file mode 100755 index 00000000000..460cb846983 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-metrics-traffic.yaml @@ -0,0 +1,27 @@ +{{- if .Values.networkPolicy.create }} +# This NetworkPolicy allows ingress traffic +# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those +# namespaces are able to gathering data from the metrics endpoint. +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: allow-metrics-traffic + namespace: {{ .Values.namespace }} +spec: + podSelector: + matchLabels: + control-plane: controller-manager + policyTypes: + - Ingress + ingress: + # This allows ingress traffic from any namespace with the label metrics: enabled + - from: + - namespaceSelector: + matchLabels: + metrics: enabled # Only from namespaces with this label + ports: + - port: 8443 + protocol: TCP +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-webhook-traffic.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-webhook-traffic.yaml new file mode 100755 index 00000000000..3a34a352302 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-webhook-traffic.yaml @@ -0,0 +1,27 @@ +{{- if .Values.networkPolicy.create }} +# This NetworkPolicy allows ingress traffic to your webhook server running +# as part of the controller-manager from specific namespaces and pods. CR(s) which uses webhooks +# will only work when applied in namespaces labeled with 'webhook: enabled' +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: allow-webhook-traffic + namespace: {{ .Values.namespace }} +spec: + podSelector: + matchLabels: + control-plane: controller-manager + policyTypes: + - Ingress + ingress: + # This allows ingress traffic from any namespace with the label webhook: enabled + - from: + - namespaceSelector: + matchLabels: + webhook: enabled # Only from namespaces with this label + ports: + - port: 443 + protocol: TCP +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/prometheus/monitor.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/prometheus/monitor.yaml new file mode 100755 index 00000000000..41ab6e848d7 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/prometheus/monitor.yaml @@ -0,0 +1,30 @@ +{{- if .Values.prometheus.create }} +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: controller-manager-metrics-monitor + namespace: {{ .Values.namespace }} +spec: + endpoints: + - path: /metrics + port: https # Ensure this is the name of the port that exposes HTTPS metrics + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + # TODO(user): The option insecureSkipVerify: true is not recommended for production since it disables + # certificate verification. This poses a significant security risk by making the system vulnerable to + # man-in-the-middle attacks, where an attacker could intercept and manipulate the communication between + # Prometheus and the monitored services. This could lead to unauthorized access to sensitive metrics data, + # compromising the integrity and confidentiality of the information. + # Please use the following options for secure configurations: + # caFile: /etc/metrics-certs/ca.crt + # certFile: /etc/metrics-certs/tls.crt + # keyFile: /etc/metrics-certs/tls.key + insecureSkipVerify: true + selector: + matchLabels: + control-plane: controller-manager +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_editor_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_editor_role.yaml new file mode 100755 index 00000000000..371f3475a6f --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit busyboxes. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: busybox-editor-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_viewer_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_viewer_role.yaml new file mode 100755 index 00000000000..8553e02e781 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view busyboxes. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: busybox-viewer-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - get + - list + - watch +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role.yaml new file mode 100755 index 00000000000..07bb4a2c407 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role.yaml @@ -0,0 +1,41 @@ +{{- if .Values.rbac.create }} +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + 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 +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role_binding.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role_binding.yaml new file mode 100755 index 00000000000..f81780e69df --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role_binding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: leader-election-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: {{ .Values.namespace }} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_editor_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_editor_role.yaml new file mode 100755 index 00000000000..8af2ebbe627 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_editor_role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbac.create }} +# permissions for end users to edit memcacheds. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: memcached-editor-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_viewer_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_viewer_role.yaml new file mode 100755 index 00000000000..c9aac7582e5 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_viewer_role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +# permissions for end users to view memcacheds. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: memcached-viewer-role +rules: +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - get + - list + - watch +- apiGroups: + - example.com.testproject.org + resources: + - memcacheds/status + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml new file mode 100755 index 00000000000..d3edf2766af --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml @@ -0,0 +1,21 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: metrics-auth-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml new file mode 100755 index 00000000000..f051f06d96f --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: metrics-auth-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: metrics-auth-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: {{ .Values.namespace }} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_reader_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_reader_role.yaml new file mode 100755 index 00000000000..df8bd5b4b1d --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_reader_role.yaml @@ -0,0 +1,13 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml new file mode 100755 index 00000000000..f5d1c9448fd --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml @@ -0,0 +1,66 @@ +{{- if .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: manager-role +rules: +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes + - memcacheds + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/finalizers + - memcacheds/finalizers + verbs: + - update +- apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + - memcacheds/status + verbs: + - get + - patch + - update +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml new file mode 100755 index 00000000000..a0336756722 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: manager-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: {{ .Values.namespace }} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml new file mode 100755 index 00000000000..6d176e3772c --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml @@ -0,0 +1,9 @@ +{{- if .Values.rbac.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "chart.labels" . | nindent 4 }} + name: controller-manager + namespace: {{ .Values.namespace }} +{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/webhook/service.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/service.yaml new file mode 100644 index 00000000000..eda59d6be90 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.namespace }}-webhook-service + namespace: {{ .Values.namespace }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + control-plane: controller-manager diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhooks.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhooks.yaml new file mode 100644 index 00000000000..6001f2296ee --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhooks.yaml @@ -0,0 +1,104 @@ +{{- if .Values.webhook.create }} + +{{- if include "chart.hasMutatingWebhooks" .Values.webhook.services }} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ .Values.namespace }}-mutating-webhook + labels: + {{- include "chart.labels" . | nindent 4 }} +webhooks: + {{- range .Values.webhook.services }} + {{- if eq .type "mutating" }} + - name: {{ .name }}.{{ $.Values.namespace }}.svc + clientConfig: + service: + name: {{ .name }} + namespace: {{ $.Values.namespace }} + path: {{ .path }} + caBundle: {{ .caBundle }} + failurePolicy: {{ .failurePolicy }} + sideEffects: {{ .sideEffects }} + admissionReviewVersions: + {{- range .admissionReviewVersions }} + - {{ . }} + {{- end }} + rules: + {{- range .rules }} + - operations: + {{- range .operations }} + - {{ . }} + {{- end }} + apiGroups: + {{- if .apiGroups }} + {{- range .apiGroups }} + - {{ default "\"\"" . }} + {{- end }} + {{- else }} + - "" + {{- end }} + apiVersions: + {{- range .apiVersions }} + - {{ . }} + {{- end }} + resources: + {{- range .resources }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +--- +{{- end }} + +{{- if include "chart.hasValidatingWebhooks" .Values.webhook.services }} +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ .Values.namespace }}-validating-webhook + labels: + {{- include "chart.labels" . | nindent 4 }} +webhooks: + {{- range .Values.webhook.services }} + {{- if eq .type "validating" }} + - name: {{ .name }}.{{ $.Values.namespace }}.svc + clientConfig: + service: + name: {{ .name }} + namespace: {{ $.Values.namespace }} + path: {{ .path }} + caBundle: {{ .caBundle }} + failurePolicy: {{ .failurePolicy }} + sideEffects: {{ .sideEffects }} + admissionReviewVersions: + {{- range .admissionReviewVersions }} + - {{ . }} + {{- end }} + rules: + {{- range .rules }} + - operations: + {{- range .operations }} + - {{ . }} + {{- end }} + apiGroups: + {{- if .apiGroups }} + {{- range .apiGroups }} + - {{ default "\"\"" . }} + {{- end }} + {{- else }} + - "" + {{- end }} + apiVersions: + {{- range .apiVersions }} + - {{ . }} + {{- end }} + resources: + {{- range .resources }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/values.yaml b/testdata/project-v4-with-plugins/dist/chart/values.yaml new file mode 100644 index 00000000000..ce2c63e6416 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/values.yaml @@ -0,0 +1,88 @@ +# Default values for the Kubebuilder Helm chart +# Namespace where the Manager will be deployed +namespace: project-v4-with-plugins-system + +# Controller Manager settings +controllerManager: + image: + repository: controller + tag: latest + replicas: 1 + args: + - "--leader-elect" + - "--metrics-bind-address=:8080" + - "--health-probe-bind-address=:8081" + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + livenessProbe: + initialDelaySeconds: 15 + periodSeconds: 20 + httpGet: + path: /healthz + port: 8081 + readinessProbe: + initialDelaySeconds: 5 + periodSeconds: 10 + httpGet: + path: /readyz + port: 8081 + securityContext: + runAsNonRoot: true + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + serviceAccountName: controller-manager + terminationGracePeriodSeconds: 10 + env: + BUSYBOX_IMAGE: busybox:1.36.1 + MEMCACHED_IMAGE: memcached:1.6.26-alpine3.19 + +# RBAC settings +rbac: + create: true + +# CRDs settings +crd: + create: true + + +# Webhook service settings +webhook: + create: true + services: + - name: vmemcached-v1alpha1.kb.io + type: validating + path: /validate-example-com-testproject-org-v1alpha1-memcached + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: + - v1 + rules: + - operations: + - CREATE + - UPDATE + apiGroups: + - example.com.testproject.org + apiVersions: + - v1alpha1 + resources: + - memcacheds + + +# Prometheus monitoring settings +prometheus: + create: false + +# CertManager settings for certificates +certmanager: + create: false + +# Network policies +networkPolicy: + create: false diff --git a/testdata/project-v4-with-plugins/dist/install.yaml b/testdata/project-v4-with-plugins/dist/install.yaml index 7969821c0be..66788aef372 100644 --- a/testdata/project-v4-with-plugins/dist/install.yaml +++ b/testdata/project-v4-with-plugins/dist/install.yaml @@ -606,7 +606,7 @@ spec: - name: BUSYBOX_IMAGE value: busybox:1.36.1 - name: MEMCACHED_IMAGE - value: memcached:memcached:1.6.26-alpine3.19 + value: memcached:1.6.26-alpine3.19 image: controller:latest livenessProbe: httpGet: