diff --git a/.github/workflows/test-helm-samples.yml b/.github/workflows/test-helm-samples.yml index b81e565b10d..c12bf89a24a 100644 --- a/.github/workflows/test-helm-samples.yml +++ b/.github/workflows/test-helm-samples.yml @@ -20,11 +20,30 @@ jobs: - name: Checkout repository uses: actions/checkout@v5 + - name: Enable Prometheus in kustomize (testdata sample) + run: | + sed -i 's/^#- \.\.\/prometheus/- ..\/prometheus/' testdata/project-v4-with-plugins/config/default/kustomization.yaml + + - name: Build kubebuilder CLI + run: make build + - name: Setup Go uses: actions/setup-go@v6 with: go-version-file: go.mod + - name: Prepare project-v4-with-plugins + run: | + cd testdata/project-v4-with-plugins/ + go mod tidy + make all + + - name: Rebuild installer and regenerate Helm chart (v2-alpha) + working-directory: testdata/project-v4-with-plugins + run: | + make build-installer + ../../bin/kubebuilder edit --plugins=helm/v2-alpha --force + - name: Install the latest version of kind run: | curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64 @@ -37,13 +56,6 @@ jobs: - 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 @@ -55,23 +67,29 @@ jobs: run: | helm lint testdata/project-v4-with-plugins/dist/chart + - name: Build 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 Prometheus Operator CRDs run: | helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update helm install prometheus-crds prometheus-community/prometheus-operator-crds - - name: Install cert-manager via Helm + - name: Install cert-manager via Helm (wait for readiness) run: | helm repo add jetstack https://charts.jetstack.io helm repo update - helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set crds.enabled=true - - - name: Wait for cert-manager to be ready - run: | - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-cainjector - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-webhook + helm install cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --set crds.enabled=true \ + --wait \ + --timeout 300s - name: Render Helm chart for project-v4-with-plugins run: | @@ -79,15 +97,20 @@ jobs: - 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 --set prometheus.enable=true + helm install my-release \ + testdata/project-v4-with-plugins/dist/chart \ + --namespace project-v4-with-plugins-system \ + --create-namespace \ + --set prometheus.enable=true - name: Check Helm release status run: | helm status my-release --namespace project-v4-with-plugins-system - - name: Check Presence of ServiceMonitor + - name: Delete kind cluster + if: always() run: | - kubectl wait --namespace project-v4-with-plugins-system --for=jsonpath='{.kind}'=ServiceMonitor servicemonitor/project-v4-with-plugins-controller-manager-metrics-monitor + kind delete cluster || true # Test scenario: # - scaffold project without creating webhooks, @@ -97,7 +120,7 @@ jobs: # Command to use to scaffold project without creating webhooks and so no need to install cert manager: # - kubebuilder init # - kubebuilder create api --group example.com --version v1 --kind App --controller=true --resource=true - # - kubebuilder edit --plugins=helm.kubebuilder.io/v1-alpha + # - kubebuilder edit --plugins=helm.kubebuilder.io/v2-alpha test-helm-no-webhooks: runs-on: ubuntu-latest if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository @@ -149,9 +172,18 @@ jobs: - name: Deploy Helm chart without cert-manager working-directory: test-helm-no-webhooks - run: helm install my-release ./dist/chart --create-namespace --namespace test-helm-no-webhooks-system + run: | + helm install my-release \ + ./dist/chart \ + --create-namespace \ + --namespace test-helm-no-webhooks-system - name: Verify deployment is working working-directory: test-helm-no-webhooks run: | helm status my-release --namespace test-helm-no-webhooks-system + + - name: Delete kind cluster + if: always() + run: | + kind delete cluster || true diff --git a/Makefile b/Makefile index 85347e1315f..eec50d4af26 100644 --- a/Makefile +++ b/Makefile @@ -103,10 +103,11 @@ generate-charts: build ## Re-generate the helm chart testdata and docs samples rm -rf docs/book/src/cronjob-tutorial/testdata/project/dist/chart rm -rf docs/book/src/multiversion-tutorial/testdata/project/dist/chart - (cd testdata/project-v4-with-plugins && ../../bin/kubebuilder edit --plugins=helm/v1-alpha) - (cd docs/book/src/getting-started/testdata/project && ../../../../../../bin/kubebuilder edit --plugins=helm/v1-alpha) - (cd docs/book/src/cronjob-tutorial/testdata/project && ../../../../../../bin/kubebuilder edit --plugins=helm/v1-alpha) - (cd docs/book/src/multiversion-tutorial/testdata/project && ../../../../../../bin/kubebuilder edit --plugins=helm/v1-alpha) + # Generate helm charts from kustomize manifests using v2-alpha plugin + (cd testdata/project-v4-with-plugins && make build-installer && ../../bin/kubebuilder edit --plugins=helm/v2-alpha) + (cd docs/book/src/getting-started/testdata/project && make build-installer && ../../../../../../bin/kubebuilder edit --plugins=helm/v2-alpha) + (cd docs/book/src/cronjob-tutorial/testdata/project && make build-installer && ../../../../../../bin/kubebuilder edit --plugins=helm/v2-alpha) + (cd docs/book/src/multiversion-tutorial/testdata/project && make build-installer && ../../../../../../bin/kubebuilder edit --plugins=helm/v2-alpha) .PHONY: check-docs check-docs: ## Run the script to ensure that the docs are updated diff --git a/cmd/cmd.go b/cmd/cmd.go index 6991421ad9c..6ed46941555 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -34,6 +34,7 @@ import ( autoupdatev1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/autoupdate/v1alpha" grafanav1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha" helmv1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha" + helmv2alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v2alpha" ) // Run bootstraps & runs the CLI @@ -72,6 +73,7 @@ func Run() { &deployimagev1alpha1.Plugin{}, &grafanav1alpha1.Plugin{}, &helmv1alpha1.Plugin{}, + &helmv2alpha1.Plugin{}, &autoupdatev1alpha1.Plugin{}, ), cli.WithPlugins(externalPlugins...), diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index 5ff34bc3f70..1645dbb07dd 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -125,6 +125,7 @@ - [go/v4](./plugins/available/go-v4-plugin.md) - [grafana/v1-alpha](./plugins/available/grafana-v1-alpha.md) - [helm/v1-alpha](./plugins/available/helm-v1-alpha.md) + - [helm/v2-alpha](./plugins/available/helm-v2-alpha.md) - [kustomize/v2](./plugins/available/kustomize-v2.md) - [Extending](./plugins/extending.md) - [CLI and Plugins](./plugins/extending/extending_cli_features_and_plugins.md) diff --git a/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test-chart.yml b/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test-chart.yml index e520fe6a3d6..09e815ed361 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test-chart.yml +++ b/docs/book/src/cronjob-tutorial/testdata/project/.github/workflows/test-chart.yml @@ -46,18 +46,17 @@ jobs: run: | helm lint ./dist/chart -# TODO: Uncomment if cert-manager is enabled - - name: Install cert-manager via Helm + + - name: Install cert-manager via Helm (wait for readiness) run: | helm repo add jetstack https://charts.jetstack.io helm repo update - helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set crds.enabled=true - - - name: Wait for cert-manager to be ready - run: | - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-cainjector - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-webhook + helm install cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --set crds.enabled=true \ + --wait \ + --timeout 300s # TODO: Uncomment if Prometheus is enabled # - name: Install Prometheus Operator CRDs @@ -65,16 +64,6 @@ jobs: # helm repo add prometheus-community https://prometheus-community.github.io/helm-charts # helm repo update # helm install prometheus-crds prometheus-community/prometheus-operator-crds -# -# - name: Install Prometheus via Helm -# run: | -# helm repo add prometheus-community https://prometheus-community.github.io/helm-charts -# helm repo update -# helm install prometheus prometheus-community/prometheus --namespace monitoring --create-namespace -# -# - name: Wait for Prometheus to be ready -# run: | -# kubectl wait --namespace monitoring --for=condition=available --timeout=300s deployment/prometheus-server - name: Install Helm chart for project run: | @@ -83,8 +72,3 @@ jobs: - name: Check Helm release status run: | helm status my-release --namespace project-system - -# TODO: Uncomment if prometheus.enabled is set to true to confirm that the ServiceMonitor gets created -# - name: Check Presence of ServiceMonitor -# run: | -# kubectl wait --namespace project-system --for=jsonpath='{.kind}'=ServiceMonitor servicemonitor/project-controller-manager-metrics-monitor diff --git a/docs/book/src/cronjob-tutorial/testdata/project/PROJECT b/docs/book/src/cronjob-tutorial/testdata/project/PROJECT index 9de48f17971..69670a776ef 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/PROJECT +++ b/docs/book/src/cronjob-tutorial/testdata/project/PROJECT @@ -7,7 +7,9 @@ domain: tutorial.kubebuilder.io layout: - go.kubebuilder.io/v4 plugins: - helm.kubebuilder.io/v1-alpha: {} + helm.kubebuilder.io/v2-alpha: + manifests: dist/install.yaml + output: dist projectName: project repo: tutorial.kubebuilder.io/project resources: diff --git a/docs/book/src/cronjob-tutorial/testdata/project/README.md b/docs/book/src/cronjob-tutorial/testdata/project/README.md index 9ab7abd998f..1f97b7906a3 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/README.md +++ b/docs/book/src/cronjob-tutorial/testdata/project/README.md @@ -97,7 +97,7 @@ kubectl apply -f https://raw.githubusercontent.com//project/ 1. Build the chart using the optional helm plugin ```sh -kubebuilder edit --plugins=helm/v1-alpha +kubebuilder edit --plugins=helm/v2-alpha ``` 2. See that a chart was generated under 'dist/chart', and users diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/_helpers.tpl b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/_helpers.tpl index 0a078cf9f24..5aced50daec 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/_helpers.tpl +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/_helpers.tpl @@ -1,9 +1,11 @@ +{{/* +Chart name based on project name. +Truncated to 63 characters for Kubernetes compatibility. +*/}} {{- define "chart.name" -}} {{- if .Chart }} {{- if .Chart.Name }} {{- .Chart.Name | trunc 63 | trimSuffix "-" }} - {{- else if .Values.nameOverride }} - {{ .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- else }} project {{- end }} @@ -12,7 +14,48 @@ {{- end }} {{- end }} +{{/* +Full name of the chart (with release name prefix). +Combines release name with chart name. +Truncated to 63 characters for Kubernetes compatibility. +*/}} +{{- define "chart.fullname" -}} +{{- $name := include "chart.name" . }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Namespace for generated references. +Always uses the Helm release namespace. +*/}} +{{- define "chart.namespaceName" -}} +{{ .Release.Namespace }} +{{- end }} + + + +{{/* +Service name with proper truncation for Kubernetes 63-character limit. +Takes a context with .suffix for the service type (e.g., "webhook-service"). +If fullname + suffix exceeds 63 chars, truncates fullname to 45 chars. +*/}} +{{- define "chart.serviceName" -}} +{{- $fullname := include "chart.fullname" .context -}} +{{- if gt (len $fullname) 45 -}} +{{- printf "%s-%s" (trunc 45 $fullname | trimSuffix "-") .suffix | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" $fullname .suffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end }} +{{/* +Common labels for Helm charts. +Includes app version, chart version, app name, instance, and managed-by labels. +*/}} {{- define "chart.labels" -}} {{- if .Chart.AppVersion -}} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} @@ -25,26 +68,11 @@ app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end }} - +{{/* +Selector labels for matching pods and services. +Only includes name and instance for consistent selection. +*/}} {{- define "chart.selectorLabels" -}} app.kubernetes.io/name: {{ include "chart.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} - - -{{- define "chart.hasMutatingWebhooks" -}} -{{- $hasMutating := false }} -{{- range . }} - {{- if eq .type "mutating" }} - $hasMutating = true }}{{- end }} -{{- end }} -{{ $hasMutating }}}}{{- end }} - - -{{- define "chart.hasValidatingWebhooks" -}} -{{- $hasValidating := false }} -{{- range . }} - {{- if eq .type "validating" }} - $hasValidating = true }}{{- end }} -{{- end }} -{{ $hasValidating }}}}{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/cert-manager/metrics-certs.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/cert-manager/metrics-certs.yaml new file mode 100644 index 00000000000..972b8fed25a --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/cert-manager/metrics-certs.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.certManager.enable .Values.metrics.enable }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-metrics-certs + namespace: {{ .Release.Namespace }} +spec: + dnsNames: + - {{ include "chart.serviceName" (dict "suffix" "controller-manager-metrics-service" "context" .) }}.{{ .Release.Namespace }}.svc + - {{ include "chart.serviceName" (dict "suffix" "controller-manager-metrics-service" "context" .) }}.{{ .Release.Namespace }}.svc.cluster.local + issuerRef: + kind: Issuer + name: {{ include "chart.name" . }}-selfsigned-issuer + secretName: metrics-server-cert +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/cert-manager/selfsigned-issuer.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/cert-manager/selfsigned-issuer.yaml new file mode 100644 index 00000000000..ede8ccde366 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/cert-manager/selfsigned-issuer.yaml @@ -0,0 +1,12 @@ +{{- if .Values.certManager.enable }} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-selfsigned-issuer + namespace: {{ .Release.Namespace }} +spec: + selfSigned: {} +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/cert-manager/serving-cert.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/cert-manager/serving-cert.yaml new file mode 100644 index 00000000000..8cc0c296f6b --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/cert-manager/serving-cert.yaml @@ -0,0 +1,18 @@ +{{- if .Values.certManager.enable }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-serving-cert + namespace: {{ .Release.Namespace }} +spec: + dnsNames: + - project-webhook-service.{{ .Release.Namespace }}.svc + - project-webhook-service.{{ .Release.Namespace }}.svc.cluster.local + issuerRef: + kind: Issuer + name: {{ include "chart.name" . }}-selfsigned-issuer + secretName: webhook-server-cert +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/certmanager/certificate.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/certmanager/certificate.yaml deleted file mode 100644 index cf309d66456..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/certmanager/certificate.yaml +++ /dev/null @@ -1,60 +0,0 @@ -{{- if .Values.certmanager.enable }} -# Self-signed Issuer -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: selfsigned-issuer - namespace: {{ .Release.Namespace }} -spec: - selfSigned: {} -{{- if .Values.webhook.enable }} ---- -# Certificate for the webhook -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - annotations: - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - name: serving-cert - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} -spec: - dnsNames: - - project.{{ .Release.Namespace }}.svc - - project.{{ .Release.Namespace }}.svc.cluster.local - - project-webhook-service.{{ .Release.Namespace }}.svc - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: webhook-server-cert -{{- end }} -{{- if .Values.metrics.enable }} ---- -# Certificate for the metrics -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - annotations: - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - labels: - {{- include "chart.labels" . | nindent 4 }} - name: metrics-certs - namespace: {{ .Release.Namespace }} -spec: - dnsNames: - - project.{{ .Release.Namespace }}.svc - - project.{{ .Release.Namespace }}.svc.cluster.local - - project-metrics-service.{{ .Release.Namespace }}.svc - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: metrics-server-cert -{{- end }} -{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/crd/batch.tutorial.kubebuilder.io_cronjobs.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/crd/batch.tutorial.kubebuilder.io_cronjobs.yaml deleted file mode 100644 index 485582f1fd6..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/crd/batch.tutorial.kubebuilder.io_cronjobs.yaml +++ /dev/null @@ -1,4040 +0,0 @@ -{{- if .Values.crd.enable }} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - annotations: - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - controller-gen.kubebuilder.io/version: v0.19.0 - name: cronjobs.batch.tutorial.kubebuilder.io -spec: - group: batch.tutorial.kubebuilder.io - names: - kind: CronJob - listKind: CronJobList - plural: cronjobs - singular: cronjob - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - properties: - apiVersion: - type: string - kind: - type: string - metadata: - type: object - spec: - properties: - concurrencyPolicy: - default: Allow - enum: - - Allow - - Forbid - - Replace - type: string - failedJobsHistoryLimit: - format: int32 - minimum: 0 - type: integer - jobTemplate: - properties: - metadata: - type: object - spec: - properties: - activeDeadlineSeconds: - format: int64 - type: integer - backoffLimit: - format: int32 - type: integer - backoffLimitPerIndex: - format: int32 - type: integer - completionMode: - type: string - completions: - format: int32 - type: integer - managedBy: - type: string - manualSelector: - type: boolean - maxFailedIndexes: - format: int32 - type: integer - parallelism: - format: int32 - type: integer - podFailurePolicy: - properties: - rules: - items: - properties: - action: - type: string - onExitCodes: - properties: - containerName: - type: string - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - - values - type: object - onPodConditions: - items: - properties: - status: - type: string - type: - type: string - required: - - status - - type - type: object - type: array - x-kubernetes-list-type: atomic - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - required: - - rules - type: object - podReplacementPolicy: - type: string - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - successPolicy: - properties: - rules: - items: - properties: - succeededCount: - format: int32 - type: integer - succeededIndexes: - type: string - type: object - type: array - x-kubernetes-list-type: atomic - required: - - rules - type: object - suspend: - type: boolean - template: - properties: - metadata: - type: object - spec: - properties: - activeDeadlineSeconds: - format: int64 - type: integer - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchFields: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - type: object - x-kubernetes-map-type: atomic - weight: - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchFields: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - type: object - x-kubernetes-map-type: atomic - type: array - x-kubernetes-list-type: atomic - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - x-kubernetes-list-type: atomic - type: object - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - x-kubernetes-list-type: atomic - type: object - type: object - automountServiceAccountToken: - type: boolean - containers: - items: - properties: - args: - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - properties: - key: - type: string - optional: - default: false - type: boolean - path: - type: string - volumeName: - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - items: - properties: - configMapRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - type: string - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resizePolicy: - items: - properties: - resourceName: - type: string - restartPolicy: - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - restartPolicyRules: - items: - properties: - action: - type: string - exitCodes: - properties: - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - capabilities: - properties: - add: - items: - type: string - type: array - x-kubernetes-list-type: atomic - drop: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - dnsConfig: - properties: - nameservers: - items: - type: string - type: array - x-kubernetes-list-type: atomic - options: - items: - properties: - name: - type: string - value: - type: string - type: object - type: array - x-kubernetes-list-type: atomic - searches: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - dnsPolicy: - type: string - enableServiceLinks: - type: boolean - ephemeralContainers: - items: - properties: - args: - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - properties: - key: - type: string - optional: - default: false - type: boolean - path: - type: string - volumeName: - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - items: - properties: - configMapRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - type: string - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resizePolicy: - items: - properties: - resourceName: - type: string - restartPolicy: - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - restartPolicyRules: - items: - properties: - action: - type: string - exitCodes: - properties: - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - capabilities: - properties: - add: - items: - type: string - type: array - x-kubernetes-list-type: atomic - drop: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - targetContainerName: - type: string - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - hostAliases: - items: - properties: - hostnames: - items: - type: string - type: array - x-kubernetes-list-type: atomic - ip: - type: string - required: - - ip - type: object - type: array - x-kubernetes-list-map-keys: - - ip - x-kubernetes-list-type: map - hostIPC: - type: boolean - hostNetwork: - type: boolean - hostPID: - type: boolean - hostUsers: - type: boolean - hostname: - type: string - hostnameOverride: - type: string - imagePullSecrets: - items: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - initContainers: - items: - properties: - args: - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - properties: - key: - type: string - optional: - default: false - type: boolean - path: - type: string - volumeName: - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - items: - properties: - configMapRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - type: string - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resizePolicy: - items: - properties: - resourceName: - type: string - restartPolicy: - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - restartPolicyRules: - items: - properties: - action: - type: string - exitCodes: - properties: - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - capabilities: - properties: - add: - items: - type: string - type: array - x-kubernetes-list-type: atomic - drop: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - nodeName: - type: string - nodeSelector: - additionalProperties: - type: string - type: object - x-kubernetes-map-type: atomic - os: - properties: - name: - type: string - required: - - name - type: object - overhead: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - preemptionPolicy: - type: string - priority: - format: int32 - type: integer - priorityClassName: - type: string - readinessGates: - items: - properties: - conditionType: - type: string - required: - - conditionType - type: object - type: array - x-kubernetes-list-type: atomic - resourceClaims: - items: - properties: - name: - type: string - resourceClaimName: - type: string - resourceClaimTemplateName: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - runtimeClassName: - type: string - schedulerName: - type: string - schedulingGates: - items: - properties: - name: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - securityContext: - properties: - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - fsGroup: - format: int64 - type: integer - fsGroupChangePolicy: - type: string - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxChangePolicy: - type: string - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - supplementalGroups: - items: - format: int64 - type: integer - type: array - x-kubernetes-list-type: atomic - supplementalGroupsPolicy: - type: string - sysctls: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - serviceAccount: - type: string - serviceAccountName: - type: string - setHostnameAsFQDN: - type: boolean - shareProcessNamespace: - type: boolean - subdomain: - type: string - terminationGracePeriodSeconds: - format: int64 - type: integer - tolerations: - items: - properties: - effect: - type: string - key: - type: string - operator: - type: string - tolerationSeconds: - format: int64 - type: integer - value: - type: string - type: object - type: array - x-kubernetes-list-type: atomic - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - maxSkew: - format: int32 - type: integer - minDomains: - format: int32 - type: integer - nodeAffinityPolicy: - type: string - nodeTaintsPolicy: - type: string - topologyKey: - type: string - whenUnsatisfiable: - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - x-kubernetes-list-map-keys: - - topologyKey - - whenUnsatisfiable - x-kubernetes-list-type: map - volumes: - items: - properties: - awsElasticBlockStore: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - azureDisk: - properties: - cachingMode: - type: string - diskName: - type: string - diskURI: - type: string - fsType: - default: ext4 - type: string - kind: - type: string - readOnly: - default: false - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - properties: - readOnly: - type: boolean - secretName: - type: string - shareName: - type: string - required: - - secretName - - shareName - type: object - cephfs: - properties: - monitors: - items: - type: string - type: array - x-kubernetes-list-type: atomic - path: - type: string - readOnly: - type: boolean - secretFile: - type: string - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - user: - type: string - required: - - monitors - type: object - cinder: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - volumeID: - type: string - required: - - volumeID - type: object - configMap: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - csi: - properties: - driver: - type: string - fsType: - type: string - nodePublishSecretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - readOnly: - type: boolean - volumeAttributes: - additionalProperties: - type: string - type: object - required: - - driver - type: object - downwardAPI: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - emptyDir: - properties: - medium: - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - properties: - volumeClaimTemplate: - properties: - metadata: - type: object - spec: - properties: - accessModes: - items: - type: string - type: array - x-kubernetes-list-type: atomic - dataSource: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - namespace: - type: string - required: - - kind - - name - type: object - resources: - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - type: string - volumeAttributesClassName: - type: string - volumeMode: - type: string - volumeName: - type: string - type: object - required: - - spec - type: object - type: object - fc: - properties: - fsType: - type: string - lun: - format: int32 - type: integer - readOnly: - type: boolean - targetWWNs: - items: - type: string - type: array - x-kubernetes-list-type: atomic - wwids: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - flexVolume: - properties: - driver: - type: string - fsType: - type: string - options: - additionalProperties: - type: string - type: object - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - required: - - driver - type: object - flocker: - properties: - datasetName: - type: string - datasetUUID: - type: string - type: object - gcePersistentDisk: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - pdName: - type: string - readOnly: - type: boolean - required: - - pdName - type: object - gitRepo: - properties: - directory: - type: string - repository: - type: string - revision: - type: string - required: - - repository - type: object - glusterfs: - properties: - endpoints: - type: string - path: - type: string - readOnly: - type: boolean - required: - - endpoints - - path - type: object - hostPath: - properties: - path: - type: string - type: - type: string - required: - - path - type: object - image: - properties: - pullPolicy: - type: string - reference: - type: string - type: object - iscsi: - properties: - chapAuthDiscovery: - type: boolean - chapAuthSession: - type: boolean - fsType: - type: string - initiatorName: - type: string - iqn: - type: string - iscsiInterface: - default: default - type: string - lun: - format: int32 - type: integer - portals: - items: - type: string - type: array - x-kubernetes-list-type: atomic - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - targetPortal: - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - type: string - nfs: - properties: - path: - type: string - readOnly: - type: boolean - server: - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - properties: - claimName: - type: string - readOnly: - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - properties: - fsType: - type: string - pdID: - type: string - required: - - pdID - type: object - portworxVolume: - properties: - fsType: - type: string - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - projected: - properties: - defaultMode: - format: int32 - type: integer - sources: - items: - properties: - clusterTrustBundle: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - name: - type: string - optional: - type: boolean - path: - type: string - signerName: - type: string - required: - - path - type: object - configMap: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - downwardAPI: - properties: - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - podCertificate: - properties: - certificateChainPath: - type: string - credentialBundlePath: - type: string - keyPath: - type: string - keyType: - type: string - maxExpirationSeconds: - format: int32 - type: integer - signerName: - type: string - required: - - keyType - - signerName - type: object - secret: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - serviceAccountToken: - properties: - audience: - type: string - expirationSeconds: - format: int64 - type: integer - path: - type: string - required: - - path - type: object - type: object - type: array - x-kubernetes-list-type: atomic - type: object - quobyte: - properties: - group: - type: string - readOnly: - type: boolean - registry: - type: string - tenant: - type: string - user: - type: string - volume: - type: string - required: - - registry - - volume - type: object - rbd: - properties: - fsType: - type: string - image: - type: string - keyring: - default: /etc/ceph/keyring - type: string - monitors: - items: - type: string - type: array - x-kubernetes-list-type: atomic - pool: - default: rbd - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - user: - default: admin - type: string - required: - - image - - monitors - type: object - scaleIO: - properties: - fsType: - default: xfs - type: string - gateway: - type: string - protectionDomain: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - sslEnabled: - type: boolean - storageMode: - default: ThinProvisioned - type: string - storagePool: - type: string - system: - type: string - volumeName: - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - optional: - type: boolean - secretName: - type: string - type: object - storageos: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - volumeName: - type: string - volumeNamespace: - type: string - type: object - vsphereVolume: - properties: - fsType: - type: string - storagePolicyID: - type: string - storagePolicyName: - type: string - volumePath: - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - required: - - containers - type: object - type: object - ttlSecondsAfterFinished: - format: int32 - type: integer - required: - - template - type: object - type: object - schedule: - minLength: 0 - type: string - startingDeadlineSeconds: - format: int64 - minimum: 0 - type: integer - successfulJobsHistoryLimit: - format: int32 - minimum: 0 - type: integer - suspend: - type: boolean - required: - - jobTemplate - - schedule - type: object - status: - properties: - active: - items: - properties: - apiVersion: - type: string - fieldPath: - type: string - kind: - type: string - name: - type: string - namespace: - type: string - resourceVersion: - type: string - uid: - type: string - type: object - x-kubernetes-map-type: atomic - maxItems: 10 - minItems: 1 - type: array - x-kubernetes-list-type: atomic - conditions: - items: - properties: - lastTransitionTime: - format: date-time - type: string - message: - maxLength: 32768 - type: string - observedGeneration: - format: int64 - minimum: 0 - type: integer - reason: - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - enum: - - "True" - - "False" - - Unknown - type: string - type: - 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 - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - lastScheduleTime: - format: date-time - type: string - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -{{- end -}} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/crd/cronjobs.batch.tutorial.kubebuilder.io.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/crd/cronjobs.batch.tutorial.kubebuilder.io.yaml new file mode 100644 index 00000000000..41393487e9d --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/crd/cronjobs.batch.tutorial.kubebuilder.io.yaml @@ -0,0 +1,4034 @@ +{{- if .Values.crd.enable }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: cronjobs.batch.tutorial.kubebuilder.io +spec: + group: batch.tutorial.kubebuilder.io + names: + kind: CronJob + listKind: CronJobList + plural: cronjobs + singular: cronjob + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + concurrencyPolicy: + default: Allow + enum: + - Allow + - Forbid + - Replace + type: string + failedJobsHistoryLimit: + format: int32 + minimum: 0 + type: integer + jobTemplate: + properties: + metadata: + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + backoffLimit: + format: int32 + type: integer + backoffLimitPerIndex: + format: int32 + type: integer + completionMode: + type: string + completions: + format: int32 + type: integer + managedBy: + type: string + manualSelector: + type: boolean + maxFailedIndexes: + format: int32 + type: integer + parallelism: + format: int32 + type: integer + podFailurePolicy: + properties: + rules: + items: + properties: + action: + type: string + onExitCodes: + properties: + containerName: + type: string + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + - values + type: object + onPodConditions: + items: + properties: + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-type: atomic + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + required: + - rules + type: object + podReplacementPolicy: + type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + successPolicy: + properties: + rules: + items: + properties: + succeededCount: + format: int32 + type: integer + succeededIndexes: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + required: + - rules + type: object + suspend: + type: boolean + template: + properties: + metadata: + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + hostnameOverride: + type: string + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + x-kubernetes-list-type: atomic + resourceClaims: + items: + properties: + name: + type: string + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxChangePolicy: + type: string + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podCertificate: + properties: + certificateChainPath: + type: string + credentialBundlePath: + type: string + keyPath: + type: string + keyType: + type: string + maxExpirationSeconds: + format: int32 + type: integer + signerName: + type: string + required: + - keyType + - signerName + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - containers + type: object + type: object + ttlSecondsAfterFinished: + format: int32 + type: integer + required: + - template + type: object + type: object + schedule: + minLength: 0 + type: string + startingDeadlineSeconds: + format: int64 + minimum: 0 + type: integer + successfulJobsHistoryLimit: + format: int32 + minimum: 0 + type: integer + suspend: + type: boolean + required: + - jobTemplate + - schedule + type: object + status: + properties: + active: + items: + properties: + apiVersion: + type: string + fieldPath: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + resourceVersion: + type: string + uid: + type: string + type: object + x-kubernetes-map-type: atomic + maxItems: 10 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + maxLength: 32768 + type: string + observedGeneration: + format: int64 + minimum: 0 + type: integer + reason: + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + enum: + - "True" + - "False" + - Unknown + type: string + type: + 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 + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + lastScheduleTime: + format: date-time + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/manager/manager.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/manager/manager.yaml index 800be0a90d2..4b09d27c50c 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/manager/manager.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/manager/manager.yaml @@ -1,90 +1,103 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: project-controller-manager - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} - control-plane: controller-manager -spec: - replicas: {{ .Values.controllerManager.replicas }} - selector: - matchLabels: - {{- include "chart.selectorLabels" . | nindent 6 }} - control-plane: controller-manager - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - {{- include "chart.labels" . | nindent 8 }} + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project control-plane: controller-manager - {{- if and .Values.controllerManager.pod .Values.controllerManager.pod.labels }} - {{- range $key, $value := .Values.controllerManager.pod.labels }} - {{ $key }}: {{ $value }} - {{- end }} - {{- end }} - spec: - containers: - - name: manager - args: - {{- range .Values.controllerManager.container.args }} - - {{ . }} - {{- end }} - command: - - /manager - image: {{ .Values.controllerManager.container.image.repository }}:{{ .Values.controllerManager.container.image.tag }} - {{- if .Values.controllerManager.container.imagePullPolicy }} - imagePullPolicy: {{ .Values.controllerManager.container.imagePullPolicy }} - {{- end }} - {{- if .Values.controllerManager.container.env }} - env: - {{- range $key, $value := .Values.controllerManager.container.env }} - - name: {{ $key }} - value: {{ $value }} - {{- end }} - {{- end }} - livenessProbe: - {{- toYaml .Values.controllerManager.container.livenessProbe | nindent 12 }} - readinessProbe: - {{- toYaml .Values.controllerManager.container.readinessProbe | nindent 12 }} - {{- if .Values.webhook.enable }} - ports: - - containerPort: 9443 - name: webhook-server - protocol: TCP - {{- end }} - resources: - {{- toYaml .Values.controllerManager.container.resources | nindent 12 }} - securityContext: - {{- toYaml .Values.controllerManager.container.securityContext | nindent 12 }} - {{- if and .Values.certmanager.enable (or .Values.webhook.enable .Values.metrics.enable) }} - volumeMounts: - {{- if and .Values.webhook.enable .Values.certmanager.enable }} - - name: webhook-cert - mountPath: /tmp/k8s-webhook-server/serving-certs - readOnly: true - {{- end }} - {{- if and .Values.metrics.enable .Values.certmanager.enable }} - - name: metrics-certs - mountPath: /tmp/k8s-metrics-server/metrics-certs - readOnly: true - {{- end }} - {{- end }} - securityContext: - {{- toYaml .Values.controllerManager.securityContext | nindent 8 }} - serviceAccountName: {{ .Values.controllerManager.serviceAccountName }} - terminationGracePeriodSeconds: {{ .Values.controllerManager.terminationGracePeriodSeconds }} - {{- if and .Values.certmanager.enable (or .Values.webhook.enable .Values.metrics.enable) }} - volumes: - {{- if and .Values.webhook.enable .Values.certmanager.enable }} - - name: webhook-cert - secret: - secretName: webhook-server-cert - {{- end }} - {{- if and .Values.metrics.enable .Values.certmanager.enable }} - - name: metrics-certs - secret: - secretName: metrics-server-cert - {{- end }} - {{- end }} + name: project-controller-manager + namespace: {{ .Release.Namespace }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: project + control-plane: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + app.kubernetes.io/name: project + control-plane: controller-manager + spec: + containers: + - args: + - --metrics-bind-address=:8443 + - --leader-elect + - --health-probe-bind-address=:8081 + {{- if and .Values.certManager.enable .Values.metrics.enable }} + - --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs + {{- end }} + {{- if .Values.certManager.enable }} + - --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs + {{- end }} + command: + - /manager + image: "{{ .Values.controllerManager.image.repository }}:{{ .Values.controllerManager.image.tag }}" + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + {{- if and .Values.certManager.enable .Values.metrics.enable }} + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + {{- end }} + {{- if .Values.certManager.enable }} + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: webhook-certs + readOnly: true + {{- end }} + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: project-controller-manager + terminationGracePeriodSeconds: 10 + volumes: + {{- if and .Values.certManager.enable .Values.metrics.enable }} + - name: metrics-certs + secret: + items: + - key: ca.crt + path: ca.crt + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + optional: false + secretName: metrics-server-cert + {{- end }} + {{- if .Values.certManager.enable }} + - name: webhook-certs + secret: + secretName: webhook-server-cert + {{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/metrics/controller-manager-metrics-service.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/metrics/controller-manager-metrics-service.yaml new file mode 100644 index 00000000000..8f3149ca16e --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/metrics/controller-manager-metrics-service.yaml @@ -0,0 +1,20 @@ +{{- if .Values.metrics.enable }} +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + control-plane: controller-manager + name: project-controller-manager-metrics-service + namespace: {{ .Release.Namespace }} +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + app.kubernetes.io/name: project + control-plane: controller-manager +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/metrics/metrics-service.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/metrics/metrics-service.yaml deleted file mode 100644 index ea32e21785b..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/metrics/metrics-service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.metrics.enable }} -apiVersion: v1 -kind: Service -metadata: - name: project-controller-manager-metrics-service - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} - control-plane: controller-manager -spec: - ports: - - port: 8443 - targetPort: 8443 - protocol: TCP - name: https - selector: - control-plane: controller-manager -{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/network-policy/allow-metrics-traffic.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/network-policy/allow-metrics-traffic.yaml deleted file mode 100644 index 9446b2c290b..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/network-policy/allow-metrics-traffic.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.networkPolicy.enable }} -# This NetworkPolicy allows ingress traffic -# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those -# namespaces are able to gather data from the metrics endpoint. -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: allow-metrics-traffic - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - control-plane: controller-manager - app.kubernetes.io/name: project - 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/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/network-policy/allow-webhook-traffic.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/network-policy/allow-webhook-traffic.yaml deleted file mode 100644 index 313b570fe42..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/network-policy/allow-webhook-traffic.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.networkPolicy.enable }} -# 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: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - control-plane: controller-manager - app.kubernetes.io/name: project - 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/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/prometheus/controller-manager-metrics-monitor.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/prometheus/controller-manager-metrics-monitor.yaml new file mode 100644 index 00000000000..a31654193d4 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/prometheus/controller-manager-metrics-monitor.yaml @@ -0,0 +1,35 @@ +{{- if .Values.prometheus.enable }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + control-plane: controller-manager + name: {{ include "chart.name" . }}-controller-manager-metrics-monitor + namespace: {{ .Release.Namespace }} +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + path: /metrics + port: https + scheme: https + tlsConfig: + ca: + secret: + key: ca.crt + name: metrics-server-cert + cert: + secret: + key: tls.crt + name: metrics-server-cert + insecureSkipVerify: false + keySecret: + key: tls.key + name: metrics-server-cert + serverName: project-controller-manager-metrics-service.{{ .Release.Namespace }}.svc + selector: + matchLabels: + app.kubernetes.io/name: project + control-plane: controller-manager +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/prometheus/monitor.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/prometheus/monitor.yaml deleted file mode 100644 index 62e5ae2df10..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/prometheus/monitor.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# To integrate with Prometheus. -{{- if .Values.prometheus.enable }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - control-plane: controller-manager - name: project-controller-manager-metrics-monitor - namespace: {{ .Release.Namespace }} -spec: - endpoints: - - path: /metrics - port: https - scheme: https - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - tlsConfig: - {{- if .Values.certmanager.enable }} - serverName: project-controller-manager-metrics-service.{{ .Release.Namespace }}.svc - # Apply secure TLS configuration with cert-manager - insecureSkipVerify: false - ca: - secret: - name: metrics-server-cert - key: ca.crt - cert: - secret: - name: metrics-server-cert - key: tls.crt - keySecret: - name: metrics-server-cert - key: tls.key - {{- else }} - # Development/Test mode (insecure configuration) - insecureSkipVerify: true - {{- end }} - selector: - matchLabels: - control-plane: controller-manager -{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/controller-manager.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/controller-manager.yaml new file mode 100644 index 00000000000..a757441625d --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/controller-manager.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-controller-manager + namespace: {{ .Release.Namespace }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-admin-role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-admin-role.yaml new file mode 100644 index 00000000000..f0d8d50f4de --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-admin-role.yaml @@ -0,0 +1,22 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-cronjob-admin-role +rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - '*' + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-editor-role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-editor-role.yaml new file mode 100644 index 00000000000..b9e0db896d6 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-editor-role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-cronjob-editor-role +rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-viewer-role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-viewer-role.yaml new file mode 100644 index 00000000000..88e43a7d001 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-viewer-role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-cronjob-viewer-role +rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - get + - list + - watch + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_admin_role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_admin_role.yaml deleted file mode 100644 index 97077428f5c..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_admin_role.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants full permissions ('*') over batch.tutorial.kubebuilder.io. -# This role is intended for users authorized to modify roles and bindings within the cluster, -# enabling them to delegate specific permissions to other users or groups as needed. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: cronjob-admin-role -rules: -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs - verbs: - - '*' -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs/status - verbs: - - get -{{- end -}} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_editor_role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_editor_role.yaml deleted file mode 100644 index 6f3d47ebb39..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_editor_role.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants permissions to create, update, and delete resources within the batch.tutorial.kubebuilder.io. -# This role is intended for users who need to manage these resources -# but should not control RBAC or manage permissions for others. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: cronjob-editor-role -rules: -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs/status - verbs: - - get -{{- end -}} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_viewer_role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_viewer_role.yaml deleted file mode 100644 index 175a658f6e8..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_viewer_role.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants read-only access to batch.tutorial.kubebuilder.io resources. -# This role is intended for users who need visibility into these resources -# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: cronjob-viewer-role -rules: -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs - verbs: - - get - - list - - watch -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs/status - verbs: - - get -{{- end -}} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-role.yaml new file mode 100644 index 00000000000..17bb2531ff8 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-role.yaml @@ -0,0 +1,40 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-leader-election-role + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-rolebinding.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-rolebinding.yaml new file mode 100644 index 00000000000..4966c4ac459 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-rolebinding.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-leader-election-rolebinding + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: project-leader-election-role +subjects: + - kind: ServiceAccount + name: project-controller-manager + namespace: {{ .Release.Namespace }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role.yaml deleted file mode 100644 index 2829e9912c5..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role.yaml +++ /dev/null @@ -1,42 +0,0 @@ -{{- if .Values.rbac.enable }} -# permissions to do leader election. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - namespace: {{ .Release.Namespace }} - name: project-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/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role_binding.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role_binding.yaml deleted file mode 100644 index 79885d91895..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role_binding.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - namespace: {{ .Release.Namespace }} - name: project-leader-election-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: project-leader-election-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/manager-role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/manager-role.yaml new file mode 100644 index 00000000000..4261a27fa49 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/manager-role.yaml @@ -0,0 +1,49 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-manager-role +rules: + - apiGroups: + - batch + resources: + - jobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - batch + resources: + - jobs/status + verbs: + - get + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/finalizers + verbs: + - update + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get + - patch + - update diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/manager-rolebinding.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/manager-rolebinding.yaml new file mode 100644 index 00000000000..b82536997bc --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/manager-rolebinding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: project-manager-role +subjects: + - kind: ServiceAccount + name: project-controller-manager + namespace: {{ .Release.Namespace }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-role.yaml new file mode 100644 index 00000000000..5954a82944e --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-role.yaml @@ -0,0 +1,19 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-metrics-auth-role +rules: + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-rolebinding.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-rolebinding.yaml new file mode 100644 index 00000000000..33549b4c5ba --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-rolebinding.yaml @@ -0,0 +1,14 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: project-metrics-auth-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: project-metrics-auth-role +subjects: + - kind: ServiceAccount + name: project-controller-manager + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics-reader.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics-reader.yaml new file mode 100644 index 00000000000..609835fe71f --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics-reader.yaml @@ -0,0 +1,11 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-metrics-reader +rules: + - nonResourceURLs: + - /metrics + verbs: + - get +{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role.yaml deleted file mode 100644 index d8efe8d2264..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-metrics-auth-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create -{{- end -}} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role_binding.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role_binding.yaml deleted file mode 100644 index 7df99695c66..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role_binding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-metrics-auth-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-metrics-auth-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics_reader_role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics_reader_role.yaml deleted file mode 100644 index 097846af52c..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/metrics_reader_role.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-metrics-reader -rules: -- nonResourceURLs: - - "/metrics" - verbs: - - get -{{- end -}} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/role.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/role.yaml deleted file mode 100644 index 854f9c92e22..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/role.yaml +++ /dev/null @@ -1,54 +0,0 @@ -{{- if .Values.rbac.enable }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-manager-role -rules: -- apiGroups: - - batch - resources: - - jobs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - batch - resources: - - jobs/status - verbs: - - get -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs/finalizers - verbs: - - update -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs/status - verbs: - - get - - patch - - update -{{- end -}} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/role_binding.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/role_binding.yaml deleted file mode 100644 index e6310b045ee..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/role_binding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-manager-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/service_account.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/service_account.yaml deleted file mode 100644 index 93e0a323e1d..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/rbac/service_account.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - {{- if and .Values.controllerManager.serviceAccount .Values.controllerManager.serviceAccount.annotations }} - annotations: - {{- range $key, $value := .Values.controllerManager.serviceAccount.annotations }} - {{ $key }}: {{ $value }} - {{- end }} - {{- end }} - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/mutating-webhook-configuration.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/mutating-webhook-configuration.yaml new file mode 100644 index 00000000000..c1daf64a335 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/mutating-webhook-configuration.yaml @@ -0,0 +1,29 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + {{- if .Values.certManager.enable }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/project-serving-cert + {{- end }} + name: project-mutating-webhook-configuration +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: project-webhook-service + namespace: {{ .Release.Namespace }} + path: /mutate-batch-tutorial-kubebuilder-io-v1-cronjob + failurePolicy: Fail + name: mcronjob-v1.kb.io + rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - cronjobs + sideEffects: None diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/service.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/service.yaml deleted file mode 100644 index 9dae918ebd1..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if .Values.webhook.enable }} -apiVersion: v1 -kind: Service -metadata: - name: project-webhook-service - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} -spec: - ports: - - port: 443 - protocol: TCP - targetPort: 9443 - selector: - control-plane: controller-manager -{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/validating-webhook-configuration.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/validating-webhook-configuration.yaml new file mode 100644 index 00000000000..317669ab731 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/validating-webhook-configuration.yaml @@ -0,0 +1,29 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + {{- if .Values.certManager.enable }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/project-serving-cert + {{- end }} + name: project-validating-webhook-configuration +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: project-webhook-service + namespace: {{ .Release.Namespace }} + path: /validate-batch-tutorial-kubebuilder-io-v1-cronjob + failurePolicy: Fail + name: vcronjob-v1.kb.io + rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - cronjobs + sideEffects: None diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/webhook-service.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/webhook-service.yaml new file mode 100644 index 00000000000..0fa69736ed4 --- /dev/null +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/webhook-service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-webhook-service + namespace: {{ .Release.Namespace }} +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + app.kubernetes.io/name: project + control-plane: controller-manager diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/webhooks.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/webhooks.yaml deleted file mode 100644 index 5d24c10c54c..00000000000 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/templates/webhook/webhooks.yaml +++ /dev/null @@ -1,67 +0,0 @@ -{{- if .Values.webhook.enable }} -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: project-mutating-webhook-configuration - namespace: {{ .Release.Namespace }} - annotations: - {{- if .Values.certmanager.enable }} - cert-manager.io/inject-ca-from: "{{ $.Release.Namespace }}/serving-cert" - {{- end }} - labels: - {{- include "chart.labels" . | nindent 4 }} -webhooks: - - name: mcronjob-v1.kb.io - clientConfig: - service: - name: project-webhook-service - namespace: {{ .Release.Namespace }} - path: /mutate-batch-tutorial-kubebuilder-io-v1-cronjob - failurePolicy: Fail - sideEffects: None - admissionReviewVersions: - - v1 - rules: - - operations: - - CREATE - - UPDATE - apiGroups: - - batch.tutorial.kubebuilder.io - apiVersions: - - v1 - resources: - - cronjobs ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: project-validating-webhook-configuration - namespace: {{ .Release.Namespace }} - annotations: - {{- if .Values.certmanager.enable }} - cert-manager.io/inject-ca-from: "{{ $.Release.Namespace }}/serving-cert" - {{- end }} - labels: - {{- include "chart.labels" . | nindent 4 }} -webhooks: - - name: vcronjob-v1.kb.io - clientConfig: - service: - name: project-webhook-service - namespace: {{ .Release.Namespace }} - path: /validate-batch-tutorial-kubebuilder-io-v1-cronjob - failurePolicy: Fail - sideEffects: None - admissionReviewVersions: - - v1 - rules: - - operations: - - CREATE - - UPDATE - apiGroups: - - batch.tutorial.kubebuilder.io - apiVersions: - - v1 - resources: - - cronjobs -{{- end }} diff --git a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/values.yaml b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/values.yaml index 52879a5615c..1598abb5ea7 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/values.yaml +++ b/docs/book/src/cronjob-tutorial/testdata/project/dist/chart/values.yaml @@ -1,84 +1,65 @@ -# [MANAGER]: Manager Deployment Configurations +# Configure the controller manager deployment controllerManager: replicas: 1 - container: - image: - repository: controller - tag: latest - imagePullPolicy: IfNotPresent - args: - - "--leader-elect" - - "--metrics-bind-address=:8443" - - "--health-probe-bind-address=:8081" - resources: - limits: + + image: + repository: controller + tag: latest + pullPolicy: IfNotPresent + + # Environment variables + env: [] + + # Pod-level security settings + podSecurityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + + # Container-level security settings + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + + # Resource limits and requests + resources: + limits: cpu: 500m memory: 128Mi - requests: + 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: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - securityContext: - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - terminationGracePeriodSeconds: 10 - serviceAccountName: project-controller-manager -# [RBAC]: To enable RBAC (Permissions) configurations -rbac: - enable: true +# Essential RBAC permissions (required for controller operation) +# These include ServiceAccount, controller permissions, leader election, and metrics access +# Note: Essential RBAC is always enabled as it's required for the controller to function -# [CRDs]: To enable the CRDs -crd: - # This option determines whether the CRDs are included - # in the installation process. - enable: true +# Helper RBAC roles for managing custom resources +# These provide convenient admin/editor/viewer roles for each CRD type +# Useful for giving users different levels of access to your custom resources +rbacHelpers: + enable: false # Install convenience admin/editor/viewer roles for CRDs - # Enabling this option adds the "helm.sh/resource-policy": keep - # annotation to the CRD, ensuring it remains installed even when - # the Helm release is uninstalled. - # NOTE: Removing the CRDs will also remove all cert-manager CR(s) - # (Certificates, Issuers, ...) due to garbage collection. - keep: true +# Custom Resource Definitions +crd: + enable: true # Install CRDs with the chart + keep: true # Keep CRDs when uninstalling -# [METRICS]: Set to true to generate manifests for exporting metrics. -# To disable metrics export set false, and ensure that the -# ControllerManager argument "--metrics-bind-address=:8443" is removed. +# Controller metrics endpoint. +# Enable to expose /metrics endpoint with RBAC protection. metrics: enable: true -# [WEBHOOKS]: Webhooks configuration -# The following configuration is automatically generated from the manifests -# generated by controller-gen. To update run 'make manifests' and -# the edit command with the '--force' flag -webhook: +# Cert-manager integration for TLS certificates. +# Required for webhook certificates and metrics endpoint certificates. +certManager: enable: true -# [PROMETHEUS]: To enable a ServiceMonitor to export metrics to Prometheus set true +# Prometheus ServiceMonitor for metrics scraping. +# Requires prometheus-operator to be installed in the cluster. prometheus: enable: false -# [CERT-MANAGER]: To enable cert-manager injection to webhooks set true -certmanager: - enable: true - -# [NETWORK POLICIES]: To enable NetworkPolicies set true -networkPolicy: - enable: false diff --git a/docs/book/src/getting-started/testdata/project/.github/workflows/test-chart.yml b/docs/book/src/getting-started/testdata/project/.github/workflows/test-chart.yml index 574149d7ff7..759f334b7b1 100644 --- a/docs/book/src/getting-started/testdata/project/.github/workflows/test-chart.yml +++ b/docs/book/src/getting-started/testdata/project/.github/workflows/test-chart.yml @@ -47,17 +47,16 @@ jobs: helm lint ./dist/chart # TODO: Uncomment if cert-manager is enabled -# - name: Install cert-manager via Helm +# - name: Install cert-manager via Helm (wait for readiness) # run: | # helm repo add jetstack https://charts.jetstack.io # helm repo update -# helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set crds.enabled=true -# -# - name: Wait for cert-manager to be ready -# run: | -# kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager -# kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-cainjector -# kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-webhook +# helm install cert-manager jetstack/cert-manager \ +# --namespace cert-manager \ +# --create-namespace \ +# --set crds.enabled=true \ +# --wait \ +# --timeout 300s # TODO: Uncomment if Prometheus is enabled # - name: Install Prometheus Operator CRDs @@ -65,16 +64,6 @@ jobs: # helm repo add prometheus-community https://prometheus-community.github.io/helm-charts # helm repo update # helm install prometheus-crds prometheus-community/prometheus-operator-crds -# -# - name: Install Prometheus via Helm -# run: | -# helm repo add prometheus-community https://prometheus-community.github.io/helm-charts -# helm repo update -# helm install prometheus prometheus-community/prometheus --namespace monitoring --create-namespace -# -# - name: Wait for Prometheus to be ready -# run: | -# kubectl wait --namespace monitoring --for=condition=available --timeout=300s deployment/prometheus-server - name: Install Helm chart for project run: | @@ -83,8 +72,3 @@ jobs: - name: Check Helm release status run: | helm status my-release --namespace project-system - -# TODO: Uncomment if prometheus.enabled is set to true to confirm that the ServiceMonitor gets created -# - name: Check Presence of ServiceMonitor -# run: | -# kubectl wait --namespace project-system --for=jsonpath='{.kind}'=ServiceMonitor servicemonitor/project-controller-manager-metrics-monitor diff --git a/docs/book/src/getting-started/testdata/project/PROJECT b/docs/book/src/getting-started/testdata/project/PROJECT index 4fa2229dd2d..64dea029144 100644 --- a/docs/book/src/getting-started/testdata/project/PROJECT +++ b/docs/book/src/getting-started/testdata/project/PROJECT @@ -8,7 +8,9 @@ layout: - go.kubebuilder.io/v4 plugins: autoupdate.kubebuilder.io/v1-alpha: {} - helm.kubebuilder.io/v1-alpha: {} + helm.kubebuilder.io/v2-alpha: + manifests: dist/install.yaml + output: dist projectName: project repo: example.com/memcached resources: diff --git a/docs/book/src/getting-started/testdata/project/README.md b/docs/book/src/getting-started/testdata/project/README.md index 9ab7abd998f..1f97b7906a3 100644 --- a/docs/book/src/getting-started/testdata/project/README.md +++ b/docs/book/src/getting-started/testdata/project/README.md @@ -97,7 +97,7 @@ kubectl apply -f https://raw.githubusercontent.com//project/ 1. Build the chart using the optional helm plugin ```sh -kubebuilder edit --plugins=helm/v1-alpha +kubebuilder edit --plugins=helm/v2-alpha ``` 2. See that a chart was generated under 'dist/chart', and users diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/_helpers.tpl b/docs/book/src/getting-started/testdata/project/dist/chart/templates/_helpers.tpl index 0a078cf9f24..5aced50daec 100644 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/_helpers.tpl +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/_helpers.tpl @@ -1,9 +1,11 @@ +{{/* +Chart name based on project name. +Truncated to 63 characters for Kubernetes compatibility. +*/}} {{- define "chart.name" -}} {{- if .Chart }} {{- if .Chart.Name }} {{- .Chart.Name | trunc 63 | trimSuffix "-" }} - {{- else if .Values.nameOverride }} - {{ .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- else }} project {{- end }} @@ -12,7 +14,48 @@ {{- end }} {{- end }} +{{/* +Full name of the chart (with release name prefix). +Combines release name with chart name. +Truncated to 63 characters for Kubernetes compatibility. +*/}} +{{- define "chart.fullname" -}} +{{- $name := include "chart.name" . }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Namespace for generated references. +Always uses the Helm release namespace. +*/}} +{{- define "chart.namespaceName" -}} +{{ .Release.Namespace }} +{{- end }} + + + +{{/* +Service name with proper truncation for Kubernetes 63-character limit. +Takes a context with .suffix for the service type (e.g., "webhook-service"). +If fullname + suffix exceeds 63 chars, truncates fullname to 45 chars. +*/}} +{{- define "chart.serviceName" -}} +{{- $fullname := include "chart.fullname" .context -}} +{{- if gt (len $fullname) 45 -}} +{{- printf "%s-%s" (trunc 45 $fullname | trimSuffix "-") .suffix | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" $fullname .suffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end }} +{{/* +Common labels for Helm charts. +Includes app version, chart version, app name, instance, and managed-by labels. +*/}} {{- define "chart.labels" -}} {{- if .Chart.AppVersion -}} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} @@ -25,26 +68,11 @@ app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end }} - +{{/* +Selector labels for matching pods and services. +Only includes name and instance for consistent selection. +*/}} {{- define "chart.selectorLabels" -}} app.kubernetes.io/name: {{ include "chart.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} - - -{{- define "chart.hasMutatingWebhooks" -}} -{{- $hasMutating := false }} -{{- range . }} - {{- if eq .type "mutating" }} - $hasMutating = true }}{{- end }} -{{- end }} -{{ $hasMutating }}}}{{- end }} - - -{{- define "chart.hasValidatingWebhooks" -}} -{{- $hasValidating := false }} -{{- range . }} - {{- if eq .type "validating" }} - $hasValidating = true }}{{- end }} -{{- end }} -{{ $hasValidating }}}}{{- end }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/certmanager/certificate.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/certmanager/certificate.yaml deleted file mode 100644 index aa1731782bf..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/certmanager/certificate.yaml +++ /dev/null @@ -1,36 +0,0 @@ -{{- if .Values.certmanager.enable }} -# Self-signed Issuer -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: selfsigned-issuer - namespace: {{ .Release.Namespace }} -spec: - selfSigned: {} -{{- if .Values.metrics.enable }} ---- -# Certificate for the metrics -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - annotations: - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - labels: - {{- include "chart.labels" . | nindent 4 }} - name: metrics-certs - namespace: {{ .Release.Namespace }} -spec: - dnsNames: - - project.{{ .Release.Namespace }}.svc - - project.{{ .Release.Namespace }}.svc.cluster.local - - project-metrics-service.{{ .Release.Namespace }}.svc - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: metrics-server-cert -{{- end }} -{{- end }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/crd/cache.example.com_memcacheds.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/crd/cache.example.com_memcacheds.yaml deleted file mode 100644 index 132cb589ed5..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/crd/cache.example.com_memcacheds.yaml +++ /dev/null @@ -1,138 +0,0 @@ -{{- if .Values.crd.enable }} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - annotations: - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - controller-gen.kubebuilder.io/version: v0.19.0 - name: memcacheds.cache.example.com -spec: - group: cache.example.com - 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: spec defines the desired state of Memcached - properties: - 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: status defines the observed state of Memcached - properties: - conditions: - description: |- - conditions represent the current state of the Memcached resource. - Each condition has a unique type and reflects the status of a specific aspect of the resource. - - Standard condition types include: - - "Available": the resource is fully functional - - "Progressing": the resource is being created or updated - - "Degraded": the resource failed to reach or maintain its desired state - - The status of each condition is one of True, False, or Unknown. - 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 - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -{{- end -}} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/crd/memcacheds.cache.example.com.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/crd/memcacheds.cache.example.com.yaml new file mode 100644 index 00000000000..f25cd75ab51 --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/crd/memcacheds.cache.example.com.yaml @@ -0,0 +1,131 @@ +{{- if .Values.crd.enable }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: memcacheds.cache.example.com +spec: + group: cache.example.com + 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: spec defines the desired state of Memcached + properties: + 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: status defines the observed state of Memcached + properties: + conditions: + description: |- + conditions represent the current state of the Memcached resource. + Each condition has a unique type and reflects the status of a specific aspect of the resource. + + Standard condition types include: + - "Available": the resource is fully functional + - "Progressing": the resource is being created or updated + - "Degraded": the resource failed to reach or maintain its desired state + + The status of each condition is one of True, False, or Unknown. + 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 + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/manager/manager.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/manager/manager.yaml index f32a67b2cff..f0dd2dcc57d 100644 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/manager/manager.yaml +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/manager/manager.yaml @@ -1,74 +1,66 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: project-controller-manager - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} - control-plane: controller-manager -spec: - replicas: {{ .Values.controllerManager.replicas }} - selector: - matchLabels: - {{- include "chart.selectorLabels" . | nindent 6 }} - control-plane: controller-manager - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - {{- include "chart.labels" . | nindent 8 }} + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project control-plane: controller-manager - {{- if and .Values.controllerManager.pod .Values.controllerManager.pod.labels }} - {{- range $key, $value := .Values.controllerManager.pod.labels }} - {{ $key }}: {{ $value }} - {{- end }} - {{- end }} - spec: - containers: - - name: manager - args: - {{- range .Values.controllerManager.container.args }} - - {{ . }} - {{- end }} - command: - - /manager - image: {{ .Values.controllerManager.container.image.repository }}:{{ .Values.controllerManager.container.image.tag }} - {{- if .Values.controllerManager.container.imagePullPolicy }} - imagePullPolicy: {{ .Values.controllerManager.container.imagePullPolicy }} - {{- end }} - {{- if .Values.controllerManager.container.env }} - env: - {{- range $key, $value := .Values.controllerManager.container.env }} - - name: {{ $key }} - value: {{ $value }} - {{- end }} - {{- end }} - livenessProbe: - {{- toYaml .Values.controllerManager.container.livenessProbe | nindent 12 }} - readinessProbe: - {{- toYaml .Values.controllerManager.container.readinessProbe | nindent 12 }} - resources: - {{- toYaml .Values.controllerManager.container.resources | nindent 12 }} - securityContext: - {{- toYaml .Values.controllerManager.container.securityContext | nindent 12 }} - {{- if and .Values.certmanager.enable .Values.metrics.enable }} - volumeMounts: - {{- if and .Values.metrics.enable .Values.certmanager.enable }} - - name: metrics-certs - mountPath: /tmp/k8s-metrics-server/metrics-certs - readOnly: true - {{- end }} - {{- end }} - securityContext: - {{- toYaml .Values.controllerManager.securityContext | nindent 8 }} - serviceAccountName: {{ .Values.controllerManager.serviceAccountName }} - terminationGracePeriodSeconds: {{ .Values.controllerManager.terminationGracePeriodSeconds }} - {{- if and .Values.certmanager.enable .Values.metrics.enable }} - volumes: - {{- if and .Values.metrics.enable .Values.certmanager.enable }} - - name: metrics-certs - secret: - secretName: metrics-server-cert - {{- end }} - {{- end }} + name: project-controller-manager + namespace: {{ .Release.Namespace }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: project + control-plane: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + app.kubernetes.io/name: project + control-plane: controller-manager + spec: + containers: + - args: + - --metrics-bind-address=:8443 + - --leader-elect + - --health-probe-bind-address=:8081 + command: + - /manager + image: "{{ .Values.controllerManager.image.repository }}:{{ .Values.controllerManager.image.tag }}" + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + ports: [] + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: [] + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: project-controller-manager + terminationGracePeriodSeconds: 10 + volumes: [] diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/metrics/controller-manager-metrics-service.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/metrics/controller-manager-metrics-service.yaml new file mode 100644 index 00000000000..8f3149ca16e --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/metrics/controller-manager-metrics-service.yaml @@ -0,0 +1,20 @@ +{{- if .Values.metrics.enable }} +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + control-plane: controller-manager + name: project-controller-manager-metrics-service + namespace: {{ .Release.Namespace }} +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + app.kubernetes.io/name: project + control-plane: controller-manager +{{- end }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/metrics/metrics-service.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/metrics/metrics-service.yaml deleted file mode 100644 index ea32e21785b..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/metrics/metrics-service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.metrics.enable }} -apiVersion: v1 -kind: Service -metadata: - name: project-controller-manager-metrics-service - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} - control-plane: controller-manager -spec: - ports: - - port: 8443 - targetPort: 8443 - protocol: TCP - name: https - selector: - control-plane: controller-manager -{{- end }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/prometheus/monitor.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/monitoring/servicemonitor.yaml similarity index 93% rename from docs/book/src/getting-started/testdata/project/dist/chart/templates/prometheus/monitor.yaml rename to docs/book/src/getting-started/testdata/project/dist/chart/templates/monitoring/servicemonitor.yaml index 62e5ae2df10..35d515eac00 100644 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/prometheus/monitor.yaml +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/monitoring/servicemonitor.yaml @@ -1,4 +1,3 @@ -# To integrate with Prometheus. {{- if .Values.prometheus.enable }} apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor @@ -15,7 +14,7 @@ spec: scheme: https bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token tlsConfig: - {{- if .Values.certmanager.enable }} + {{- if .Values.certManager.enable }} serverName: project-controller-manager-metrics-service.{{ .Release.Namespace }}.svc # Apply secure TLS configuration with cert-manager insecureSkipVerify: false diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/network-policy/allow-metrics-traffic.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/network-policy/allow-metrics-traffic.yaml deleted file mode 100644 index 9446b2c290b..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/network-policy/allow-metrics-traffic.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.networkPolicy.enable }} -# This NetworkPolicy allows ingress traffic -# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those -# namespaces are able to gather data from the metrics endpoint. -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: allow-metrics-traffic - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - control-plane: controller-manager - app.kubernetes.io/name: project - 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/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/controller-manager.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/controller-manager.yaml new file mode 100644 index 00000000000..a757441625d --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/controller-manager.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-controller-manager + namespace: {{ .Release.Namespace }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader-election-role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader-election-role.yaml new file mode 100644 index 00000000000..17bb2531ff8 --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader-election-role.yaml @@ -0,0 +1,40 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-leader-election-role + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader-election-rolebinding.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader-election-rolebinding.yaml new file mode 100644 index 00000000000..4966c4ac459 --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader-election-rolebinding.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-leader-election-rolebinding + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: project-leader-election-role +subjects: + - kind: ServiceAccount + name: project-controller-manager + namespace: {{ .Release.Namespace }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader_election_role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader_election_role.yaml deleted file mode 100644 index 2829e9912c5..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader_election_role.yaml +++ /dev/null @@ -1,42 +0,0 @@ -{{- if .Values.rbac.enable }} -# permissions to do leader election. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - namespace: {{ .Release.Namespace }} - name: project-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/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader_election_role_binding.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader_election_role_binding.yaml deleted file mode 100644 index 79885d91895..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/leader_election_role_binding.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - namespace: {{ .Release.Namespace }} - name: project-leader-election-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: project-leader-election-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/manager-role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/manager-role.yaml new file mode 100644 index 00000000000..921b10f6aa8 --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/manager-role.yaml @@ -0,0 +1,58 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-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: + - cache.example.com + resources: + - memcacheds + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - cache.example.com + resources: + - memcacheds/finalizers + verbs: + - update + - apiGroups: + - cache.example.com + resources: + - memcacheds/status + verbs: + - get + - patch + - update diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/manager-rolebinding.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/manager-rolebinding.yaml new file mode 100644 index 00000000000..b82536997bc --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/manager-rolebinding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: project-manager-role +subjects: + - kind: ServiceAccount + name: project-controller-manager + namespace: {{ .Release.Namespace }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached-admin-role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached-admin-role.yaml new file mode 100644 index 00000000000..cfb99887720 --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached-admin-role.yaml @@ -0,0 +1,22 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-memcached-admin-role +rules: + - apiGroups: + - cache.example.com + resources: + - memcacheds + verbs: + - '*' + - apiGroups: + - cache.example.com + resources: + - memcacheds/status + verbs: + - get +{{- end }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached-editor-role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached-editor-role.yaml new file mode 100644 index 00000000000..0ce7b8da43f --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached-editor-role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-memcached-editor-role +rules: + - apiGroups: + - cache.example.com + resources: + - memcacheds + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - cache.example.com + resources: + - memcacheds/status + verbs: + - get +{{- end }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached-viewer-role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached-viewer-role.yaml new file mode 100644 index 00000000000..02a6c7d1e93 --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached-viewer-role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-memcached-viewer-role +rules: + - apiGroups: + - cache.example.com + resources: + - memcacheds + verbs: + - get + - list + - watch + - apiGroups: + - cache.example.com + resources: + - memcacheds/status + verbs: + - get +{{- end }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached_admin_role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached_admin_role.yaml deleted file mode 100644 index 77ca79feb07..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached_admin_role.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants full permissions ('*') over cache.example.com. -# This role is intended for users authorized to modify roles and bindings within the cluster, -# enabling them to delegate specific permissions to other users or groups as needed. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: memcached-admin-role -rules: -- apiGroups: - - cache.example.com - resources: - - memcacheds - verbs: - - '*' -- apiGroups: - - cache.example.com - resources: - - memcacheds/status - verbs: - - get -{{- end -}} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached_editor_role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached_editor_role.yaml deleted file mode 100644 index 2ee1a2f60b7..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached_editor_role.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants permissions to create, update, and delete resources within the cache.example.com. -# This role is intended for users who need to manage these resources -# but should not control RBAC or manage permissions for others. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: memcached-editor-role -rules: -- apiGroups: - - cache.example.com - resources: - - memcacheds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - cache.example.com - resources: - - memcacheds/status - verbs: - - get -{{- end -}} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached_viewer_role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached_viewer_role.yaml deleted file mode 100644 index 733a5e2245a..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/memcached_viewer_role.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants read-only access to cache.example.com resources. -# This role is intended for users who need visibility into these resources -# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: memcached-viewer-role -rules: -- apiGroups: - - cache.example.com - resources: - - memcacheds - verbs: - - get - - list - - watch -- apiGroups: - - cache.example.com - resources: - - memcacheds/status - verbs: - - get -{{- end -}} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics-auth-role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics-auth-role.yaml new file mode 100644 index 00000000000..5954a82944e --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics-auth-role.yaml @@ -0,0 +1,19 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-metrics-auth-role +rules: + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics-auth-rolebinding.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics-auth-rolebinding.yaml new file mode 100644 index 00000000000..33549b4c5ba --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics-auth-rolebinding.yaml @@ -0,0 +1,14 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: project-metrics-auth-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: project-metrics-auth-role +subjects: + - kind: ServiceAccount + name: project-controller-manager + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics-reader.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics-reader.yaml new file mode 100644 index 00000000000..609835fe71f --- /dev/null +++ b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics-reader.yaml @@ -0,0 +1,11 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-metrics-reader +rules: + - nonResourceURLs: + - /metrics + verbs: + - get +{{- end }} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics_auth_role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics_auth_role.yaml deleted file mode 100644 index d8efe8d2264..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics_auth_role.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-metrics-auth-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create -{{- end -}} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics_auth_role_binding.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics_auth_role_binding.yaml deleted file mode 100644 index 7df99695c66..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics_auth_role_binding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-metrics-auth-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-metrics-auth-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics_reader_role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics_reader_role.yaml deleted file mode 100644 index 097846af52c..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/metrics_reader_role.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-metrics-reader -rules: -- nonResourceURLs: - - "/metrics" - verbs: - - get -{{- end -}} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/role.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/role.yaml deleted file mode 100644 index 3310cb6fc98..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/role.yaml +++ /dev/null @@ -1,63 +0,0 @@ -{{- if .Values.rbac.enable }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-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: - - cache.example.com - resources: - - memcacheds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - cache.example.com - resources: - - memcacheds/finalizers - verbs: - - update -- apiGroups: - - cache.example.com - resources: - - memcacheds/status - verbs: - - get - - patch - - update -{{- end -}} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/role_binding.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/role_binding.yaml deleted file mode 100644 index e6310b045ee..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/role_binding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-manager-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/service_account.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/service_account.yaml deleted file mode 100644 index 93e0a323e1d..00000000000 --- a/docs/book/src/getting-started/testdata/project/dist/chart/templates/rbac/service_account.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - {{- if and .Values.controllerManager.serviceAccount .Values.controllerManager.serviceAccount.annotations }} - annotations: - {{- range $key, $value := .Values.controllerManager.serviceAccount.annotations }} - {{ $key }}: {{ $value }} - {{- end }} - {{- end }} - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/getting-started/testdata/project/dist/chart/values.yaml b/docs/book/src/getting-started/testdata/project/dist/chart/values.yaml index 8b45502619e..8126c63b558 100644 --- a/docs/book/src/getting-started/testdata/project/dist/chart/values.yaml +++ b/docs/book/src/getting-started/testdata/project/dist/chart/values.yaml @@ -1,77 +1,60 @@ -# [MANAGER]: Manager Deployment Configurations +# Configure the controller manager deployment controllerManager: replicas: 1 - container: - image: - repository: controller - tag: latest - imagePullPolicy: IfNotPresent - args: - - "--leader-elect" - - "--metrics-bind-address=:8443" - - "--health-probe-bind-address=:8081" - resources: - limits: + + image: + repository: controller + tag: latest + pullPolicy: IfNotPresent + + # Environment variables + env: [] + + # Pod-level security settings + podSecurityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + + # Container-level security settings + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + + # Resource limits and requests + resources: + limits: cpu: 500m memory: 128Mi - requests: + 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: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - securityContext: - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - terminationGracePeriodSeconds: 10 - serviceAccountName: project-controller-manager -# [RBAC]: To enable RBAC (Permissions) configurations -rbac: - enable: true +# Essential RBAC permissions (required for controller operation) +# These include ServiceAccount, controller permissions, leader election, and metrics access +# Note: Essential RBAC is always enabled as it's required for the controller to function -# [CRDs]: To enable the CRDs -crd: - # This option determines whether the CRDs are included - # in the installation process. - enable: true +# Helper RBAC roles for managing custom resources +# These provide convenient admin/editor/viewer roles for each CRD type +# Useful for giving users different levels of access to your custom resources +rbacHelpers: + enable: false # Install convenience admin/editor/viewer roles for CRDs - # Enabling this option adds the "helm.sh/resource-policy": keep - # annotation to the CRD, ensuring it remains installed even when - # the Helm release is uninstalled. - # NOTE: Removing the CRDs will also remove all cert-manager CR(s) - # (Certificates, Issuers, ...) due to garbage collection. - keep: true +# Custom Resource Definitions +crd: + enable: true # Install CRDs with the chart + keep: true # Keep CRDs when uninstalling -# [METRICS]: Set to true to generate manifests for exporting metrics. -# To disable metrics export set false, and ensure that the -# ControllerManager argument "--metrics-bind-address=:8443" is removed. +# Controller metrics endpoint. +# Enable to expose /metrics endpoint with RBAC protection. metrics: enable: true -# [PROMETHEUS]: To enable a ServiceMonitor to export metrics to Prometheus set true +# Prometheus ServiceMonitor for metrics scraping. +# Requires prometheus-operator to be installed in the cluster. prometheus: enable: false -# [CERT-MANAGER]: To enable cert-manager injection to webhooks set true -certmanager: - enable: false - -# [NETWORK POLICIES]: To enable NetworkPolicies set true -networkPolicy: - enable: false diff --git a/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test-chart.yml b/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test-chart.yml index d62a1b68108..09e815ed361 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test-chart.yml +++ b/docs/book/src/multiversion-tutorial/testdata/project/.github/workflows/test-chart.yml @@ -47,17 +47,16 @@ jobs: helm lint ./dist/chart - - name: Install cert-manager via Helm + - name: Install cert-manager via Helm (wait for readiness) run: | helm repo add jetstack https://charts.jetstack.io helm repo update - helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set crds.enabled=true - - - name: Wait for cert-manager to be ready - run: | - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-cainjector - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-webhook + helm install cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --set crds.enabled=true \ + --wait \ + --timeout 300s # TODO: Uncomment if Prometheus is enabled # - name: Install Prometheus Operator CRDs @@ -65,16 +64,6 @@ jobs: # helm repo add prometheus-community https://prometheus-community.github.io/helm-charts # helm repo update # helm install prometheus-crds prometheus-community/prometheus-operator-crds -# -# - name: Install Prometheus via Helm -# run: | -# helm repo add prometheus-community https://prometheus-community.github.io/helm-charts -# helm repo update -# helm install prometheus prometheus-community/prometheus --namespace monitoring --create-namespace -# -# - name: Wait for Prometheus to be ready -# run: | -# kubectl wait --namespace monitoring --for=condition=available --timeout=300s deployment/prometheus-server - name: Install Helm chart for project run: | @@ -83,8 +72,3 @@ jobs: - name: Check Helm release status run: | helm status my-release --namespace project-system - -# TODO: Uncomment if prometheus.enabled is set to true to confirm that the ServiceMonitor gets created -# - name: Check Presence of ServiceMonitor -# run: | -# kubectl wait --namespace project-system --for=jsonpath='{.kind}'=ServiceMonitor servicemonitor/project-controller-manager-metrics-monitor diff --git a/docs/book/src/multiversion-tutorial/testdata/project/PROJECT b/docs/book/src/multiversion-tutorial/testdata/project/PROJECT index 6071b21b6a7..2fa0948c203 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/PROJECT +++ b/docs/book/src/multiversion-tutorial/testdata/project/PROJECT @@ -7,7 +7,9 @@ domain: tutorial.kubebuilder.io layout: - go.kubebuilder.io/v4 plugins: - helm.kubebuilder.io/v1-alpha: {} + helm.kubebuilder.io/v2-alpha: + manifests: dist/install.yaml + output: dist projectName: project repo: tutorial.kubebuilder.io/project resources: diff --git a/docs/book/src/multiversion-tutorial/testdata/project/README.md b/docs/book/src/multiversion-tutorial/testdata/project/README.md index 9ab7abd998f..1f97b7906a3 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/README.md +++ b/docs/book/src/multiversion-tutorial/testdata/project/README.md @@ -97,7 +97,7 @@ kubectl apply -f https://raw.githubusercontent.com//project/ 1. Build the chart using the optional helm plugin ```sh -kubebuilder edit --plugins=helm/v1-alpha +kubebuilder edit --plugins=helm/v2-alpha ``` 2. See that a chart was generated under 'dist/chart', and users diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/_helpers.tpl b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/_helpers.tpl index 0a078cf9f24..5aced50daec 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/_helpers.tpl +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/_helpers.tpl @@ -1,9 +1,11 @@ +{{/* +Chart name based on project name. +Truncated to 63 characters for Kubernetes compatibility. +*/}} {{- define "chart.name" -}} {{- if .Chart }} {{- if .Chart.Name }} {{- .Chart.Name | trunc 63 | trimSuffix "-" }} - {{- else if .Values.nameOverride }} - {{ .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- else }} project {{- end }} @@ -12,7 +14,48 @@ {{- end }} {{- end }} +{{/* +Full name of the chart (with release name prefix). +Combines release name with chart name. +Truncated to 63 characters for Kubernetes compatibility. +*/}} +{{- define "chart.fullname" -}} +{{- $name := include "chart.name" . }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Namespace for generated references. +Always uses the Helm release namespace. +*/}} +{{- define "chart.namespaceName" -}} +{{ .Release.Namespace }} +{{- end }} + + + +{{/* +Service name with proper truncation for Kubernetes 63-character limit. +Takes a context with .suffix for the service type (e.g., "webhook-service"). +If fullname + suffix exceeds 63 chars, truncates fullname to 45 chars. +*/}} +{{- define "chart.serviceName" -}} +{{- $fullname := include "chart.fullname" .context -}} +{{- if gt (len $fullname) 45 -}} +{{- printf "%s-%s" (trunc 45 $fullname | trimSuffix "-") .suffix | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" $fullname .suffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end }} +{{/* +Common labels for Helm charts. +Includes app version, chart version, app name, instance, and managed-by labels. +*/}} {{- define "chart.labels" -}} {{- if .Chart.AppVersion -}} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} @@ -25,26 +68,11 @@ app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end }} - +{{/* +Selector labels for matching pods and services. +Only includes name and instance for consistent selection. +*/}} {{- define "chart.selectorLabels" -}} app.kubernetes.io/name: {{ include "chart.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} - - -{{- define "chart.hasMutatingWebhooks" -}} -{{- $hasMutating := false }} -{{- range . }} - {{- if eq .type "mutating" }} - $hasMutating = true }}{{- end }} -{{- end }} -{{ $hasMutating }}}}{{- end }} - - -{{- define "chart.hasValidatingWebhooks" -}} -{{- $hasValidating := false }} -{{- range . }} - {{- if eq .type "validating" }} - $hasValidating = true }}{{- end }} -{{- end }} -{{ $hasValidating }}}}{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/cert-manager/metrics-certs.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/cert-manager/metrics-certs.yaml new file mode 100644 index 00000000000..972b8fed25a --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/cert-manager/metrics-certs.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.certManager.enable .Values.metrics.enable }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-metrics-certs + namespace: {{ .Release.Namespace }} +spec: + dnsNames: + - {{ include "chart.serviceName" (dict "suffix" "controller-manager-metrics-service" "context" .) }}.{{ .Release.Namespace }}.svc + - {{ include "chart.serviceName" (dict "suffix" "controller-manager-metrics-service" "context" .) }}.{{ .Release.Namespace }}.svc.cluster.local + issuerRef: + kind: Issuer + name: {{ include "chart.name" . }}-selfsigned-issuer + secretName: metrics-server-cert +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/cert-manager/selfsigned-issuer.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/cert-manager/selfsigned-issuer.yaml new file mode 100644 index 00000000000..ede8ccde366 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/cert-manager/selfsigned-issuer.yaml @@ -0,0 +1,12 @@ +{{- if .Values.certManager.enable }} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-selfsigned-issuer + namespace: {{ .Release.Namespace }} +spec: + selfSigned: {} +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/cert-manager/serving-cert.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/cert-manager/serving-cert.yaml new file mode 100644 index 00000000000..8cc0c296f6b --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/cert-manager/serving-cert.yaml @@ -0,0 +1,18 @@ +{{- if .Values.certManager.enable }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-serving-cert + namespace: {{ .Release.Namespace }} +spec: + dnsNames: + - project-webhook-service.{{ .Release.Namespace }}.svc + - project-webhook-service.{{ .Release.Namespace }}.svc.cluster.local + issuerRef: + kind: Issuer + name: {{ include "chart.name" . }}-selfsigned-issuer + secretName: webhook-server-cert +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/certmanager/certificate.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/certmanager/certificate.yaml deleted file mode 100644 index cf309d66456..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/certmanager/certificate.yaml +++ /dev/null @@ -1,60 +0,0 @@ -{{- if .Values.certmanager.enable }} -# Self-signed Issuer -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: selfsigned-issuer - namespace: {{ .Release.Namespace }} -spec: - selfSigned: {} -{{- if .Values.webhook.enable }} ---- -# Certificate for the webhook -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - annotations: - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - name: serving-cert - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} -spec: - dnsNames: - - project.{{ .Release.Namespace }}.svc - - project.{{ .Release.Namespace }}.svc.cluster.local - - project-webhook-service.{{ .Release.Namespace }}.svc - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: webhook-server-cert -{{- end }} -{{- if .Values.metrics.enable }} ---- -# Certificate for the metrics -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - annotations: - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - labels: - {{- include "chart.labels" . | nindent 4 }} - name: metrics-certs - namespace: {{ .Release.Namespace }} -spec: - dnsNames: - - project.{{ .Release.Namespace }}.svc - - project.{{ .Release.Namespace }}.svc.cluster.local - - project-metrics-service.{{ .Release.Namespace }}.svc - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: metrics-server-cert -{{- end }} -{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/crd/batch.tutorial.kubebuilder.io_cronjobs.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/crd/batch.tutorial.kubebuilder.io_cronjobs.yaml deleted file mode 100644 index b3f3e8dbde8..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/crd/batch.tutorial.kubebuilder.io_cronjobs.yaml +++ /dev/null @@ -1,8082 +0,0 @@ -{{- if .Values.crd.enable }} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - annotations: - {{- if .Values.certmanager.enable }} - cert-manager.io/inject-ca-from: "{{ .Release.Namespace }}/serving-cert" - {{- end }} - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - controller-gen.kubebuilder.io/version: v0.19.0 - name: cronjobs.batch.tutorial.kubebuilder.io -spec: - {{- if .Values.webhook.enable }} - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: {{ .Release.Namespace }} - name: project-webhook-service - path: /convert - conversionReviewVersions: - - v1 - {{- end }} - group: batch.tutorial.kubebuilder.io - names: - kind: CronJob - listKind: CronJobList - plural: cronjobs - singular: cronjob - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - properties: - apiVersion: - type: string - kind: - type: string - metadata: - type: object - spec: - properties: - concurrencyPolicy: - default: Allow - enum: - - Allow - - Forbid - - Replace - type: string - failedJobsHistoryLimit: - format: int32 - minimum: 0 - type: integer - jobTemplate: - properties: - metadata: - type: object - spec: - properties: - activeDeadlineSeconds: - format: int64 - type: integer - backoffLimit: - format: int32 - type: integer - backoffLimitPerIndex: - format: int32 - type: integer - completionMode: - type: string - completions: - format: int32 - type: integer - managedBy: - type: string - manualSelector: - type: boolean - maxFailedIndexes: - format: int32 - type: integer - parallelism: - format: int32 - type: integer - podFailurePolicy: - properties: - rules: - items: - properties: - action: - type: string - onExitCodes: - properties: - containerName: - type: string - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - - values - type: object - onPodConditions: - items: - properties: - status: - type: string - type: - type: string - required: - - status - - type - type: object - type: array - x-kubernetes-list-type: atomic - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - required: - - rules - type: object - podReplacementPolicy: - type: string - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - successPolicy: - properties: - rules: - items: - properties: - succeededCount: - format: int32 - type: integer - succeededIndexes: - type: string - type: object - type: array - x-kubernetes-list-type: atomic - required: - - rules - type: object - suspend: - type: boolean - template: - properties: - metadata: - type: object - spec: - properties: - activeDeadlineSeconds: - format: int64 - type: integer - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchFields: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - type: object - x-kubernetes-map-type: atomic - weight: - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchFields: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - type: object - x-kubernetes-map-type: atomic - type: array - x-kubernetes-list-type: atomic - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - x-kubernetes-list-type: atomic - type: object - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - x-kubernetes-list-type: atomic - type: object - type: object - automountServiceAccountToken: - type: boolean - containers: - items: - properties: - args: - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - properties: - key: - type: string - optional: - default: false - type: boolean - path: - type: string - volumeName: - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - items: - properties: - configMapRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - type: string - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resizePolicy: - items: - properties: - resourceName: - type: string - restartPolicy: - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - restartPolicyRules: - items: - properties: - action: - type: string - exitCodes: - properties: - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - capabilities: - properties: - add: - items: - type: string - type: array - x-kubernetes-list-type: atomic - drop: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - dnsConfig: - properties: - nameservers: - items: - type: string - type: array - x-kubernetes-list-type: atomic - options: - items: - properties: - name: - type: string - value: - type: string - type: object - type: array - x-kubernetes-list-type: atomic - searches: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - dnsPolicy: - type: string - enableServiceLinks: - type: boolean - ephemeralContainers: - items: - properties: - args: - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - properties: - key: - type: string - optional: - default: false - type: boolean - path: - type: string - volumeName: - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - items: - properties: - configMapRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - type: string - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resizePolicy: - items: - properties: - resourceName: - type: string - restartPolicy: - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - restartPolicyRules: - items: - properties: - action: - type: string - exitCodes: - properties: - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - capabilities: - properties: - add: - items: - type: string - type: array - x-kubernetes-list-type: atomic - drop: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - targetContainerName: - type: string - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - hostAliases: - items: - properties: - hostnames: - items: - type: string - type: array - x-kubernetes-list-type: atomic - ip: - type: string - required: - - ip - type: object - type: array - x-kubernetes-list-map-keys: - - ip - x-kubernetes-list-type: map - hostIPC: - type: boolean - hostNetwork: - type: boolean - hostPID: - type: boolean - hostUsers: - type: boolean - hostname: - type: string - hostnameOverride: - type: string - imagePullSecrets: - items: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - initContainers: - items: - properties: - args: - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - properties: - key: - type: string - optional: - default: false - type: boolean - path: - type: string - volumeName: - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - items: - properties: - configMapRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - type: string - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resizePolicy: - items: - properties: - resourceName: - type: string - restartPolicy: - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - restartPolicyRules: - items: - properties: - action: - type: string - exitCodes: - properties: - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - capabilities: - properties: - add: - items: - type: string - type: array - x-kubernetes-list-type: atomic - drop: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - nodeName: - type: string - nodeSelector: - additionalProperties: - type: string - type: object - x-kubernetes-map-type: atomic - os: - properties: - name: - type: string - required: - - name - type: object - overhead: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - preemptionPolicy: - type: string - priority: - format: int32 - type: integer - priorityClassName: - type: string - readinessGates: - items: - properties: - conditionType: - type: string - required: - - conditionType - type: object - type: array - x-kubernetes-list-type: atomic - resourceClaims: - items: - properties: - name: - type: string - resourceClaimName: - type: string - resourceClaimTemplateName: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - runtimeClassName: - type: string - schedulerName: - type: string - schedulingGates: - items: - properties: - name: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - securityContext: - properties: - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - fsGroup: - format: int64 - type: integer - fsGroupChangePolicy: - type: string - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxChangePolicy: - type: string - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - supplementalGroups: - items: - format: int64 - type: integer - type: array - x-kubernetes-list-type: atomic - supplementalGroupsPolicy: - type: string - sysctls: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - serviceAccount: - type: string - serviceAccountName: - type: string - setHostnameAsFQDN: - type: boolean - shareProcessNamespace: - type: boolean - subdomain: - type: string - terminationGracePeriodSeconds: - format: int64 - type: integer - tolerations: - items: - properties: - effect: - type: string - key: - type: string - operator: - type: string - tolerationSeconds: - format: int64 - type: integer - value: - type: string - type: object - type: array - x-kubernetes-list-type: atomic - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - maxSkew: - format: int32 - type: integer - minDomains: - format: int32 - type: integer - nodeAffinityPolicy: - type: string - nodeTaintsPolicy: - type: string - topologyKey: - type: string - whenUnsatisfiable: - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - x-kubernetes-list-map-keys: - - topologyKey - - whenUnsatisfiable - x-kubernetes-list-type: map - volumes: - items: - properties: - awsElasticBlockStore: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - azureDisk: - properties: - cachingMode: - type: string - diskName: - type: string - diskURI: - type: string - fsType: - default: ext4 - type: string - kind: - type: string - readOnly: - default: false - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - properties: - readOnly: - type: boolean - secretName: - type: string - shareName: - type: string - required: - - secretName - - shareName - type: object - cephfs: - properties: - monitors: - items: - type: string - type: array - x-kubernetes-list-type: atomic - path: - type: string - readOnly: - type: boolean - secretFile: - type: string - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - user: - type: string - required: - - monitors - type: object - cinder: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - volumeID: - type: string - required: - - volumeID - type: object - configMap: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - csi: - properties: - driver: - type: string - fsType: - type: string - nodePublishSecretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - readOnly: - type: boolean - volumeAttributes: - additionalProperties: - type: string - type: object - required: - - driver - type: object - downwardAPI: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - emptyDir: - properties: - medium: - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - properties: - volumeClaimTemplate: - properties: - metadata: - type: object - spec: - properties: - accessModes: - items: - type: string - type: array - x-kubernetes-list-type: atomic - dataSource: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - namespace: - type: string - required: - - kind - - name - type: object - resources: - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - type: string - volumeAttributesClassName: - type: string - volumeMode: - type: string - volumeName: - type: string - type: object - required: - - spec - type: object - type: object - fc: - properties: - fsType: - type: string - lun: - format: int32 - type: integer - readOnly: - type: boolean - targetWWNs: - items: - type: string - type: array - x-kubernetes-list-type: atomic - wwids: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - flexVolume: - properties: - driver: - type: string - fsType: - type: string - options: - additionalProperties: - type: string - type: object - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - required: - - driver - type: object - flocker: - properties: - datasetName: - type: string - datasetUUID: - type: string - type: object - gcePersistentDisk: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - pdName: - type: string - readOnly: - type: boolean - required: - - pdName - type: object - gitRepo: - properties: - directory: - type: string - repository: - type: string - revision: - type: string - required: - - repository - type: object - glusterfs: - properties: - endpoints: - type: string - path: - type: string - readOnly: - type: boolean - required: - - endpoints - - path - type: object - hostPath: - properties: - path: - type: string - type: - type: string - required: - - path - type: object - image: - properties: - pullPolicy: - type: string - reference: - type: string - type: object - iscsi: - properties: - chapAuthDiscovery: - type: boolean - chapAuthSession: - type: boolean - fsType: - type: string - initiatorName: - type: string - iqn: - type: string - iscsiInterface: - default: default - type: string - lun: - format: int32 - type: integer - portals: - items: - type: string - type: array - x-kubernetes-list-type: atomic - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - targetPortal: - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - type: string - nfs: - properties: - path: - type: string - readOnly: - type: boolean - server: - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - properties: - claimName: - type: string - readOnly: - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - properties: - fsType: - type: string - pdID: - type: string - required: - - pdID - type: object - portworxVolume: - properties: - fsType: - type: string - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - projected: - properties: - defaultMode: - format: int32 - type: integer - sources: - items: - properties: - clusterTrustBundle: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - name: - type: string - optional: - type: boolean - path: - type: string - signerName: - type: string - required: - - path - type: object - configMap: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - downwardAPI: - properties: - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - podCertificate: - properties: - certificateChainPath: - type: string - credentialBundlePath: - type: string - keyPath: - type: string - keyType: - type: string - maxExpirationSeconds: - format: int32 - type: integer - signerName: - type: string - required: - - keyType - - signerName - type: object - secret: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - serviceAccountToken: - properties: - audience: - type: string - expirationSeconds: - format: int64 - type: integer - path: - type: string - required: - - path - type: object - type: object - type: array - x-kubernetes-list-type: atomic - type: object - quobyte: - properties: - group: - type: string - readOnly: - type: boolean - registry: - type: string - tenant: - type: string - user: - type: string - volume: - type: string - required: - - registry - - volume - type: object - rbd: - properties: - fsType: - type: string - image: - type: string - keyring: - default: /etc/ceph/keyring - type: string - monitors: - items: - type: string - type: array - x-kubernetes-list-type: atomic - pool: - default: rbd - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - user: - default: admin - type: string - required: - - image - - monitors - type: object - scaleIO: - properties: - fsType: - default: xfs - type: string - gateway: - type: string - protectionDomain: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - sslEnabled: - type: boolean - storageMode: - default: ThinProvisioned - type: string - storagePool: - type: string - system: - type: string - volumeName: - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - optional: - type: boolean - secretName: - type: string - type: object - storageos: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - volumeName: - type: string - volumeNamespace: - type: string - type: object - vsphereVolume: - properties: - fsType: - type: string - storagePolicyID: - type: string - storagePolicyName: - type: string - volumePath: - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - required: - - containers - type: object - type: object - ttlSecondsAfterFinished: - format: int32 - type: integer - required: - - template - type: object - type: object - schedule: - minLength: 0 - type: string - startingDeadlineSeconds: - format: int64 - minimum: 0 - type: integer - successfulJobsHistoryLimit: - format: int32 - minimum: 0 - type: integer - suspend: - type: boolean - required: - - jobTemplate - - schedule - type: object - status: - properties: - active: - items: - properties: - apiVersion: - type: string - fieldPath: - type: string - kind: - type: string - name: - type: string - namespace: - type: string - resourceVersion: - type: string - uid: - type: string - type: object - x-kubernetes-map-type: atomic - maxItems: 10 - minItems: 1 - type: array - x-kubernetes-list-type: atomic - conditions: - items: - properties: - lastTransitionTime: - format: date-time - type: string - message: - maxLength: 32768 - type: string - observedGeneration: - format: int64 - minimum: 0 - type: integer - reason: - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - enum: - - "True" - - "False" - - Unknown - type: string - type: - 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 - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - lastScheduleTime: - format: date-time - type: string - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} - - name: v2 - schema: - openAPIV3Schema: - properties: - apiVersion: - type: string - kind: - type: string - metadata: - type: object - spec: - properties: - concurrencyPolicy: - default: Allow - enum: - - Allow - - Forbid - - Replace - type: string - failedJobsHistoryLimit: - format: int32 - minimum: 0 - type: integer - jobTemplate: - properties: - metadata: - type: object - spec: - properties: - activeDeadlineSeconds: - format: int64 - type: integer - backoffLimit: - format: int32 - type: integer - backoffLimitPerIndex: - format: int32 - type: integer - completionMode: - type: string - completions: - format: int32 - type: integer - managedBy: - type: string - manualSelector: - type: boolean - maxFailedIndexes: - format: int32 - type: integer - parallelism: - format: int32 - type: integer - podFailurePolicy: - properties: - rules: - items: - properties: - action: - type: string - onExitCodes: - properties: - containerName: - type: string - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - - values - type: object - onPodConditions: - items: - properties: - status: - type: string - type: - type: string - required: - - status - - type - type: object - type: array - x-kubernetes-list-type: atomic - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - required: - - rules - type: object - podReplacementPolicy: - type: string - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - successPolicy: - properties: - rules: - items: - properties: - succeededCount: - format: int32 - type: integer - succeededIndexes: - type: string - type: object - type: array - x-kubernetes-list-type: atomic - required: - - rules - type: object - suspend: - type: boolean - template: - properties: - metadata: - type: object - spec: - properties: - activeDeadlineSeconds: - format: int64 - type: integer - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchFields: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - type: object - x-kubernetes-map-type: atomic - weight: - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchFields: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - type: object - x-kubernetes-map-type: atomic - type: array - x-kubernetes-list-type: atomic - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - x-kubernetes-list-type: atomic - type: object - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - weight: - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - x-kubernetes-list-type: atomic - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - mismatchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - items: - type: string - type: array - x-kubernetes-list-type: atomic - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - x-kubernetes-list-type: atomic - type: object - type: object - automountServiceAccountToken: - type: boolean - containers: - items: - properties: - args: - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - properties: - key: - type: string - optional: - default: false - type: boolean - path: - type: string - volumeName: - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - items: - properties: - configMapRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - type: string - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resizePolicy: - items: - properties: - resourceName: - type: string - restartPolicy: - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - restartPolicyRules: - items: - properties: - action: - type: string - exitCodes: - properties: - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - capabilities: - properties: - add: - items: - type: string - type: array - x-kubernetes-list-type: atomic - drop: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - dnsConfig: - properties: - nameservers: - items: - type: string - type: array - x-kubernetes-list-type: atomic - options: - items: - properties: - name: - type: string - value: - type: string - type: object - type: array - x-kubernetes-list-type: atomic - searches: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - dnsPolicy: - type: string - enableServiceLinks: - type: boolean - ephemeralContainers: - items: - properties: - args: - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - properties: - key: - type: string - optional: - default: false - type: boolean - path: - type: string - volumeName: - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - items: - properties: - configMapRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - type: string - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resizePolicy: - items: - properties: - resourceName: - type: string - restartPolicy: - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - restartPolicyRules: - items: - properties: - action: - type: string - exitCodes: - properties: - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - capabilities: - properties: - add: - items: - type: string - type: array - x-kubernetes-list-type: atomic - drop: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - targetContainerName: - type: string - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - hostAliases: - items: - properties: - hostnames: - items: - type: string - type: array - x-kubernetes-list-type: atomic - ip: - type: string - required: - - ip - type: object - type: array - x-kubernetes-list-map-keys: - - ip - x-kubernetes-list-type: map - hostIPC: - type: boolean - hostNetwork: - type: boolean - hostPID: - type: boolean - hostUsers: - type: boolean - hostname: - type: string - hostnameOverride: - type: string - imagePullSecrets: - items: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - initContainers: - items: - properties: - args: - items: - type: string - type: array - x-kubernetes-list-type: atomic - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - fileKeyRef: - properties: - key: - type: string - optional: - default: false - type: boolean - path: - type: string - volumeName: - type: string - required: - - key - - path - - volumeName - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - envFrom: - items: - properties: - configMapRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - type: string - secretRef: - properties: - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - x-kubernetes-list-type: atomic - image: - type: string - imagePullPolicy: - type: string - lifecycle: - properties: - postStart: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - sleep: - properties: - seconds: - format: int64 - type: integer - required: - - seconds - type: object - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - stopSignal: - type: string - type: object - livenessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - name: - type: string - ports: - items: - properties: - containerPort: - format: int32 - type: integer - hostIP: - type: string - hostPort: - format: int32 - type: integer - name: - type: string - protocol: - default: TCP - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - resizePolicy: - items: - properties: - resourceName: - type: string - restartPolicy: - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - restartPolicyRules: - items: - properties: - action: - type: string - exitCodes: - properties: - operator: - type: string - values: - items: - format: int32 - type: integer - type: array - x-kubernetes-list-type: set - required: - - operator - type: object - required: - - action - type: object - type: array - x-kubernetes-list-type: atomic - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - capabilities: - properties: - add: - items: - type: string - type: array - x-kubernetes-list-type: atomic - drop: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - startupProbe: - properties: - exec: - properties: - command: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - failureThreshold: - format: int32 - type: integer - grpc: - properties: - port: - format: int32 - type: integer - service: - default: "" - type: string - required: - - port - type: object - httpGet: - properties: - host: - type: string - httpHeaders: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - path: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - scheme: - type: string - required: - - port - type: object - initialDelaySeconds: - format: int32 - type: integer - periodSeconds: - format: int32 - type: integer - successThreshold: - format: int32 - type: integer - tcpSocket: - properties: - host: - type: string - port: - anyOf: - - type: integer - - type: string - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - format: int64 - type: integer - timeoutSeconds: - format: int32 - type: integer - type: object - stdin: - type: boolean - stdinOnce: - type: boolean - terminationMessagePath: - type: string - terminationMessagePolicy: - type: string - tty: - type: boolean - volumeDevices: - items: - properties: - devicePath: - type: string - name: - type: string - required: - - devicePath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - devicePath - x-kubernetes-list-type: map - volumeMounts: - items: - properties: - mountPath: - type: string - mountPropagation: - type: string - name: - type: string - readOnly: - type: boolean - recursiveReadOnly: - type: string - subPath: - type: string - subPathExpr: - type: string - required: - - mountPath - - name - type: object - type: array - x-kubernetes-list-map-keys: - - mountPath - x-kubernetes-list-type: map - workingDir: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - nodeName: - type: string - nodeSelector: - additionalProperties: - type: string - type: object - x-kubernetes-map-type: atomic - os: - properties: - name: - type: string - required: - - name - type: object - overhead: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - preemptionPolicy: - type: string - priority: - format: int32 - type: integer - priorityClassName: - type: string - readinessGates: - items: - properties: - conditionType: - type: string - required: - - conditionType - type: object - type: array - x-kubernetes-list-type: atomic - resourceClaims: - items: - properties: - name: - type: string - resourceClaimName: - type: string - resourceClaimTemplateName: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - resources: - properties: - claims: - items: - properties: - name: - type: string - request: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - restartPolicy: - type: string - runtimeClassName: - type: string - schedulerName: - type: string - schedulingGates: - items: - properties: - name: - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - securityContext: - properties: - appArmorProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - fsGroup: - format: int64 - type: integer - fsGroupChangePolicy: - type: string - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxChangePolicy: - type: string - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - supplementalGroups: - items: - format: int64 - type: integer - type: array - x-kubernetes-list-type: atomic - supplementalGroupsPolicy: - type: string - sysctls: - items: - properties: - name: - type: string - value: - type: string - required: - - name - - value - type: object - type: array - x-kubernetes-list-type: atomic - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object - type: object - serviceAccount: - type: string - serviceAccountName: - type: string - setHostnameAsFQDN: - type: boolean - shareProcessNamespace: - type: boolean - subdomain: - type: string - terminationGracePeriodSeconds: - format: int64 - type: integer - tolerations: - items: - properties: - effect: - type: string - key: - type: string - operator: - type: string - tolerationSeconds: - format: int64 - type: integer - value: - type: string - type: object - type: array - x-kubernetes-list-type: atomic - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - items: - type: string - type: array - x-kubernetes-list-type: atomic - maxSkew: - format: int32 - type: integer - minDomains: - format: int32 - type: integer - nodeAffinityPolicy: - type: string - nodeTaintsPolicy: - type: string - topologyKey: - type: string - whenUnsatisfiable: - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - x-kubernetes-list-map-keys: - - topologyKey - - whenUnsatisfiable - x-kubernetes-list-type: map - volumes: - items: - properties: - awsElasticBlockStore: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - azureDisk: - properties: - cachingMode: - type: string - diskName: - type: string - diskURI: - type: string - fsType: - default: ext4 - type: string - kind: - type: string - readOnly: - default: false - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - properties: - readOnly: - type: boolean - secretName: - type: string - shareName: - type: string - required: - - secretName - - shareName - type: object - cephfs: - properties: - monitors: - items: - type: string - type: array - x-kubernetes-list-type: atomic - path: - type: string - readOnly: - type: boolean - secretFile: - type: string - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - user: - type: string - required: - - monitors - type: object - cinder: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - volumeID: - type: string - required: - - volumeID - type: object - configMap: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - csi: - properties: - driver: - type: string - fsType: - type: string - nodePublishSecretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - readOnly: - type: boolean - volumeAttributes: - additionalProperties: - type: string - type: object - required: - - driver - type: object - downwardAPI: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - emptyDir: - properties: - medium: - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - properties: - volumeClaimTemplate: - properties: - metadata: - type: object - spec: - properties: - accessModes: - items: - type: string - type: array - x-kubernetes-list-type: atomic - dataSource: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - properties: - apiGroup: - type: string - kind: - type: string - name: - type: string - namespace: - type: string - required: - - kind - - name - type: object - resources: - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - selector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - type: string - volumeAttributesClassName: - type: string - volumeMode: - type: string - volumeName: - type: string - type: object - required: - - spec - type: object - type: object - fc: - properties: - fsType: - type: string - lun: - format: int32 - type: integer - readOnly: - type: boolean - targetWWNs: - items: - type: string - type: array - x-kubernetes-list-type: atomic - wwids: - items: - type: string - type: array - x-kubernetes-list-type: atomic - type: object - flexVolume: - properties: - driver: - type: string - fsType: - type: string - options: - additionalProperties: - type: string - type: object - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - required: - - driver - type: object - flocker: - properties: - datasetName: - type: string - datasetUUID: - type: string - type: object - gcePersistentDisk: - properties: - fsType: - type: string - partition: - format: int32 - type: integer - pdName: - type: string - readOnly: - type: boolean - required: - - pdName - type: object - gitRepo: - properties: - directory: - type: string - repository: - type: string - revision: - type: string - required: - - repository - type: object - glusterfs: - properties: - endpoints: - type: string - path: - type: string - readOnly: - type: boolean - required: - - endpoints - - path - type: object - hostPath: - properties: - path: - type: string - type: - type: string - required: - - path - type: object - image: - properties: - pullPolicy: - type: string - reference: - type: string - type: object - iscsi: - properties: - chapAuthDiscovery: - type: boolean - chapAuthSession: - type: boolean - fsType: - type: string - initiatorName: - type: string - iqn: - type: string - iscsiInterface: - default: default - type: string - lun: - format: int32 - type: integer - portals: - items: - type: string - type: array - x-kubernetes-list-type: atomic - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - targetPortal: - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - type: string - nfs: - properties: - path: - type: string - readOnly: - type: boolean - server: - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - properties: - claimName: - type: string - readOnly: - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - properties: - fsType: - type: string - pdID: - type: string - required: - - pdID - type: object - portworxVolume: - properties: - fsType: - type: string - readOnly: - type: boolean - volumeID: - type: string - required: - - volumeID - type: object - projected: - properties: - defaultMode: - format: int32 - type: integer - sources: - items: - properties: - clusterTrustBundle: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - type: object - type: object - x-kubernetes-map-type: atomic - name: - type: string - optional: - type: boolean - path: - type: string - signerName: - type: string - required: - - path - type: object - configMap: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - downwardAPI: - properties: - items: - items: - properties: - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - format: int32 - type: integer - path: - type: string - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - x-kubernetes-list-type: atomic - type: object - podCertificate: - properties: - certificateChainPath: - type: string - credentialBundlePath: - type: string - keyPath: - type: string - keyType: - type: string - maxExpirationSeconds: - format: int32 - type: integer - signerName: - type: string - required: - - keyType - - signerName - type: object - secret: - properties: - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - name: - default: "" - type: string - optional: - type: boolean - type: object - x-kubernetes-map-type: atomic - serviceAccountToken: - properties: - audience: - type: string - expirationSeconds: - format: int64 - type: integer - path: - type: string - required: - - path - type: object - type: object - type: array - x-kubernetes-list-type: atomic - type: object - quobyte: - properties: - group: - type: string - readOnly: - type: boolean - registry: - type: string - tenant: - type: string - user: - type: string - volume: - type: string - required: - - registry - - volume - type: object - rbd: - properties: - fsType: - type: string - image: - type: string - keyring: - default: /etc/ceph/keyring - type: string - monitors: - items: - type: string - type: array - x-kubernetes-list-type: atomic - pool: - default: rbd - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - user: - default: admin - type: string - required: - - image - - monitors - type: object - scaleIO: - properties: - fsType: - default: xfs - type: string - gateway: - type: string - protectionDomain: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - sslEnabled: - type: boolean - storageMode: - default: ThinProvisioned - type: string - storagePool: - type: string - system: - type: string - volumeName: - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - properties: - defaultMode: - format: int32 - type: integer - items: - items: - properties: - key: - type: string - mode: - format: int32 - type: integer - path: - type: string - required: - - key - - path - type: object - type: array - x-kubernetes-list-type: atomic - optional: - type: boolean - secretName: - type: string - type: object - storageos: - properties: - fsType: - type: string - readOnly: - type: boolean - secretRef: - properties: - name: - default: "" - type: string - type: object - x-kubernetes-map-type: atomic - volumeName: - type: string - volumeNamespace: - type: string - type: object - vsphereVolume: - properties: - fsType: - type: string - storagePolicyID: - type: string - storagePolicyName: - type: string - volumePath: - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - required: - - containers - type: object - type: object - ttlSecondsAfterFinished: - format: int32 - type: integer - required: - - template - type: object - type: object - schedule: - properties: - dayOfMonth: - type: string - dayOfWeek: - type: string - hour: - type: string - minute: - type: string - month: - type: string - type: object - startingDeadlineSeconds: - format: int64 - minimum: 0 - type: integer - successfulJobsHistoryLimit: - format: int32 - minimum: 0 - type: integer - suspend: - type: boolean - required: - - jobTemplate - - schedule - type: object - status: - properties: - active: - items: - properties: - apiVersion: - type: string - fieldPath: - type: string - kind: - type: string - name: - type: string - namespace: - type: string - resourceVersion: - type: string - uid: - type: string - type: object - x-kubernetes-map-type: atomic - maxItems: 10 - minItems: 1 - type: array - x-kubernetes-list-type: atomic - conditions: - items: - properties: - lastTransitionTime: - format: date-time - type: string - message: - maxLength: 32768 - type: string - observedGeneration: - format: int64 - minimum: 0 - type: integer - reason: - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - enum: - - "True" - - "False" - - Unknown - type: string - type: - 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 - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - lastScheduleTime: - format: date-time - type: string - type: object - required: - - spec - type: object - served: true - storage: false - subresources: - status: {} -{{- end -}} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/crd/cronjobs.batch.tutorial.kubebuilder.io.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/crd/cronjobs.batch.tutorial.kubebuilder.io.yaml new file mode 100644 index 00000000000..4df6b68185a --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/crd/cronjobs.batch.tutorial.kubebuilder.io.yaml @@ -0,0 +1,8072 @@ +{{- if .Values.crd.enable }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/project-serving-cert + controller-gen.kubebuilder.io/version: v0.19.0 + name: cronjobs.batch.tutorial.kubebuilder.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: project-webhook-service + namespace: {{ .Release.Namespace }} + path: /convert + conversionReviewVersions: + - v1 + group: batch.tutorial.kubebuilder.io + names: + kind: CronJob + listKind: CronJobList + plural: cronjobs + singular: cronjob + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + concurrencyPolicy: + default: Allow + enum: + - Allow + - Forbid + - Replace + type: string + failedJobsHistoryLimit: + format: int32 + minimum: 0 + type: integer + jobTemplate: + properties: + metadata: + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + backoffLimit: + format: int32 + type: integer + backoffLimitPerIndex: + format: int32 + type: integer + completionMode: + type: string + completions: + format: int32 + type: integer + managedBy: + type: string + manualSelector: + type: boolean + maxFailedIndexes: + format: int32 + type: integer + parallelism: + format: int32 + type: integer + podFailurePolicy: + properties: + rules: + items: + properties: + action: + type: string + onExitCodes: + properties: + containerName: + type: string + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + - values + type: object + onPodConditions: + items: + properties: + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-type: atomic + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + required: + - rules + type: object + podReplacementPolicy: + type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + successPolicy: + properties: + rules: + items: + properties: + succeededCount: + format: int32 + type: integer + succeededIndexes: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + required: + - rules + type: object + suspend: + type: boolean + template: + properties: + metadata: + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + hostnameOverride: + type: string + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + x-kubernetes-list-type: atomic + resourceClaims: + items: + properties: + name: + type: string + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxChangePolicy: + type: string + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podCertificate: + properties: + certificateChainPath: + type: string + credentialBundlePath: + type: string + keyPath: + type: string + keyType: + type: string + maxExpirationSeconds: + format: int32 + type: integer + signerName: + type: string + required: + - keyType + - signerName + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - containers + type: object + type: object + ttlSecondsAfterFinished: + format: int32 + type: integer + required: + - template + type: object + type: object + schedule: + minLength: 0 + type: string + startingDeadlineSeconds: + format: int64 + minimum: 0 + type: integer + successfulJobsHistoryLimit: + format: int32 + minimum: 0 + type: integer + suspend: + type: boolean + required: + - jobTemplate + - schedule + type: object + status: + properties: + active: + items: + properties: + apiVersion: + type: string + fieldPath: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + resourceVersion: + type: string + uid: + type: string + type: object + x-kubernetes-map-type: atomic + maxItems: 10 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + maxLength: 32768 + type: string + observedGeneration: + format: int64 + minimum: 0 + type: integer + reason: + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + enum: + - "True" + - "False" + - Unknown + type: string + type: + 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 + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + lastScheduleTime: + format: date-time + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - name: v2 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + concurrencyPolicy: + default: Allow + enum: + - Allow + - Forbid + - Replace + type: string + failedJobsHistoryLimit: + format: int32 + minimum: 0 + type: integer + jobTemplate: + properties: + metadata: + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + backoffLimit: + format: int32 + type: integer + backoffLimitPerIndex: + format: int32 + type: integer + completionMode: + type: string + completions: + format: int32 + type: integer + managedBy: + type: string + manualSelector: + type: boolean + maxFailedIndexes: + format: int32 + type: integer + parallelism: + format: int32 + type: integer + podFailurePolicy: + properties: + rules: + items: + properties: + action: + type: string + onExitCodes: + properties: + containerName: + type: string + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + - values + type: object + onPodConditions: + items: + properties: + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-type: atomic + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + required: + - rules + type: object + podReplacementPolicy: + type: string + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + successPolicy: + properties: + rules: + items: + properties: + succeededCount: + format: int32 + type: integer + succeededIndexes: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + required: + - rules + type: object + suspend: + type: boolean + template: + properties: + metadata: + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + hostnameOverride: + type: string + imagePullSecrets: + items: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: "" + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + x-kubernetes-list-type: atomic + resourceClaims: + items: + properties: + name: + type: string + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxChangePolicy: + type: string + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podCertificate: + properties: + certificateChainPath: + type: string + credentialBundlePath: + type: string + keyPath: + type: string + keyType: + type: string + maxExpirationSeconds: + format: int32 + type: integer + signerName: + type: string + required: + - keyType + - signerName + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: "" + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: "" + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - containers + type: object + type: object + ttlSecondsAfterFinished: + format: int32 + type: integer + required: + - template + type: object + type: object + schedule: + properties: + dayOfMonth: + type: string + dayOfWeek: + type: string + hour: + type: string + minute: + type: string + month: + type: string + type: object + startingDeadlineSeconds: + format: int64 + minimum: 0 + type: integer + successfulJobsHistoryLimit: + format: int32 + minimum: 0 + type: integer + suspend: + type: boolean + required: + - jobTemplate + - schedule + type: object + status: + properties: + active: + items: + properties: + apiVersion: + type: string + fieldPath: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + resourceVersion: + type: string + uid: + type: string + type: object + x-kubernetes-map-type: atomic + maxItems: 10 + minItems: 1 + type: array + x-kubernetes-list-type: atomic + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + maxLength: 32768 + type: string + observedGeneration: + format: int64 + minimum: 0 + type: integer + reason: + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + enum: + - "True" + - "False" + - Unknown + type: string + type: + 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 + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + lastScheduleTime: + format: date-time + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/manager/manager.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/manager/manager.yaml index 800be0a90d2..4b09d27c50c 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/manager/manager.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/manager/manager.yaml @@ -1,90 +1,103 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: project-controller-manager - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} - control-plane: controller-manager -spec: - replicas: {{ .Values.controllerManager.replicas }} - selector: - matchLabels: - {{- include "chart.selectorLabels" . | nindent 6 }} - control-plane: controller-manager - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - {{- include "chart.labels" . | nindent 8 }} + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project control-plane: controller-manager - {{- if and .Values.controllerManager.pod .Values.controllerManager.pod.labels }} - {{- range $key, $value := .Values.controllerManager.pod.labels }} - {{ $key }}: {{ $value }} - {{- end }} - {{- end }} - spec: - containers: - - name: manager - args: - {{- range .Values.controllerManager.container.args }} - - {{ . }} - {{- end }} - command: - - /manager - image: {{ .Values.controllerManager.container.image.repository }}:{{ .Values.controllerManager.container.image.tag }} - {{- if .Values.controllerManager.container.imagePullPolicy }} - imagePullPolicy: {{ .Values.controllerManager.container.imagePullPolicy }} - {{- end }} - {{- if .Values.controllerManager.container.env }} - env: - {{- range $key, $value := .Values.controllerManager.container.env }} - - name: {{ $key }} - value: {{ $value }} - {{- end }} - {{- end }} - livenessProbe: - {{- toYaml .Values.controllerManager.container.livenessProbe | nindent 12 }} - readinessProbe: - {{- toYaml .Values.controllerManager.container.readinessProbe | nindent 12 }} - {{- if .Values.webhook.enable }} - ports: - - containerPort: 9443 - name: webhook-server - protocol: TCP - {{- end }} - resources: - {{- toYaml .Values.controllerManager.container.resources | nindent 12 }} - securityContext: - {{- toYaml .Values.controllerManager.container.securityContext | nindent 12 }} - {{- if and .Values.certmanager.enable (or .Values.webhook.enable .Values.metrics.enable) }} - volumeMounts: - {{- if and .Values.webhook.enable .Values.certmanager.enable }} - - name: webhook-cert - mountPath: /tmp/k8s-webhook-server/serving-certs - readOnly: true - {{- end }} - {{- if and .Values.metrics.enable .Values.certmanager.enable }} - - name: metrics-certs - mountPath: /tmp/k8s-metrics-server/metrics-certs - readOnly: true - {{- end }} - {{- end }} - securityContext: - {{- toYaml .Values.controllerManager.securityContext | nindent 8 }} - serviceAccountName: {{ .Values.controllerManager.serviceAccountName }} - terminationGracePeriodSeconds: {{ .Values.controllerManager.terminationGracePeriodSeconds }} - {{- if and .Values.certmanager.enable (or .Values.webhook.enable .Values.metrics.enable) }} - volumes: - {{- if and .Values.webhook.enable .Values.certmanager.enable }} - - name: webhook-cert - secret: - secretName: webhook-server-cert - {{- end }} - {{- if and .Values.metrics.enable .Values.certmanager.enable }} - - name: metrics-certs - secret: - secretName: metrics-server-cert - {{- end }} - {{- end }} + name: project-controller-manager + namespace: {{ .Release.Namespace }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: project + control-plane: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + app.kubernetes.io/name: project + control-plane: controller-manager + spec: + containers: + - args: + - --metrics-bind-address=:8443 + - --leader-elect + - --health-probe-bind-address=:8081 + {{- if and .Values.certManager.enable .Values.metrics.enable }} + - --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs + {{- end }} + {{- if .Values.certManager.enable }} + - --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs + {{- end }} + command: + - /manager + image: "{{ .Values.controllerManager.image.repository }}:{{ .Values.controllerManager.image.tag }}" + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + {{- if and .Values.certManager.enable .Values.metrics.enable }} + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true + {{- end }} + {{- if .Values.certManager.enable }} + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: webhook-certs + readOnly: true + {{- end }} + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: project-controller-manager + terminationGracePeriodSeconds: 10 + volumes: + {{- if and .Values.certManager.enable .Values.metrics.enable }} + - name: metrics-certs + secret: + items: + - key: ca.crt + path: ca.crt + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + optional: false + secretName: metrics-server-cert + {{- end }} + {{- if .Values.certManager.enable }} + - name: webhook-certs + secret: + secretName: webhook-server-cert + {{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/metrics/controller-manager-metrics-service.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/metrics/controller-manager-metrics-service.yaml new file mode 100644 index 00000000000..8f3149ca16e --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/metrics/controller-manager-metrics-service.yaml @@ -0,0 +1,20 @@ +{{- if .Values.metrics.enable }} +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + control-plane: controller-manager + name: project-controller-manager-metrics-service + namespace: {{ .Release.Namespace }} +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + app.kubernetes.io/name: project + control-plane: controller-manager +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/metrics/metrics-service.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/metrics/metrics-service.yaml deleted file mode 100644 index ea32e21785b..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/metrics/metrics-service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.metrics.enable }} -apiVersion: v1 -kind: Service -metadata: - name: project-controller-manager-metrics-service - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} - control-plane: controller-manager -spec: - ports: - - port: 8443 - targetPort: 8443 - protocol: TCP - name: https - selector: - control-plane: controller-manager -{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/network-policy/allow-metrics-traffic.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/network-policy/allow-metrics-traffic.yaml deleted file mode 100644 index 9446b2c290b..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/network-policy/allow-metrics-traffic.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.networkPolicy.enable }} -# This NetworkPolicy allows ingress traffic -# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those -# namespaces are able to gather data from the metrics endpoint. -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: allow-metrics-traffic - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - control-plane: controller-manager - app.kubernetes.io/name: project - 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/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/network-policy/allow-webhook-traffic.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/network-policy/allow-webhook-traffic.yaml deleted file mode 100644 index 313b570fe42..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/network-policy/allow-webhook-traffic.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.networkPolicy.enable }} -# 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: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - control-plane: controller-manager - app.kubernetes.io/name: project - 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/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/prometheus/controller-manager-metrics-monitor.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/prometheus/controller-manager-metrics-monitor.yaml new file mode 100644 index 00000000000..a31654193d4 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/prometheus/controller-manager-metrics-monitor.yaml @@ -0,0 +1,35 @@ +{{- if .Values.prometheus.enable }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + control-plane: controller-manager + name: {{ include "chart.name" . }}-controller-manager-metrics-monitor + namespace: {{ .Release.Namespace }} +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + path: /metrics + port: https + scheme: https + tlsConfig: + ca: + secret: + key: ca.crt + name: metrics-server-cert + cert: + secret: + key: tls.crt + name: metrics-server-cert + insecureSkipVerify: false + keySecret: + key: tls.key + name: metrics-server-cert + serverName: project-controller-manager-metrics-service.{{ .Release.Namespace }}.svc + selector: + matchLabels: + app.kubernetes.io/name: project + control-plane: controller-manager +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/prometheus/monitor.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/prometheus/monitor.yaml deleted file mode 100644 index 62e5ae2df10..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/prometheus/monitor.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# To integrate with Prometheus. -{{- if .Values.prometheus.enable }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - control-plane: controller-manager - name: project-controller-manager-metrics-monitor - namespace: {{ .Release.Namespace }} -spec: - endpoints: - - path: /metrics - port: https - scheme: https - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - tlsConfig: - {{- if .Values.certmanager.enable }} - serverName: project-controller-manager-metrics-service.{{ .Release.Namespace }}.svc - # Apply secure TLS configuration with cert-manager - insecureSkipVerify: false - ca: - secret: - name: metrics-server-cert - key: ca.crt - cert: - secret: - name: metrics-server-cert - key: tls.crt - keySecret: - name: metrics-server-cert - key: tls.key - {{- else }} - # Development/Test mode (insecure configuration) - insecureSkipVerify: true - {{- end }} - selector: - matchLabels: - control-plane: controller-manager -{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/controller-manager.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/controller-manager.yaml new file mode 100644 index 00000000000..a757441625d --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/controller-manager.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-controller-manager + namespace: {{ .Release.Namespace }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-admin-role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-admin-role.yaml new file mode 100644 index 00000000000..f0d8d50f4de --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-admin-role.yaml @@ -0,0 +1,22 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-cronjob-admin-role +rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - '*' + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-editor-role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-editor-role.yaml new file mode 100644 index 00000000000..b9e0db896d6 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-editor-role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-cronjob-editor-role +rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-viewer-role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-viewer-role.yaml new file mode 100644 index 00000000000..88e43a7d001 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob-viewer-role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-cronjob-viewer-role +rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - get + - list + - watch + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_admin_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_admin_role.yaml deleted file mode 100644 index 97077428f5c..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_admin_role.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants full permissions ('*') over batch.tutorial.kubebuilder.io. -# This role is intended for users authorized to modify roles and bindings within the cluster, -# enabling them to delegate specific permissions to other users or groups as needed. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: cronjob-admin-role -rules: -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs - verbs: - - '*' -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs/status - verbs: - - get -{{- end -}} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_editor_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_editor_role.yaml deleted file mode 100644 index 6f3d47ebb39..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_editor_role.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants permissions to create, update, and delete resources within the batch.tutorial.kubebuilder.io. -# This role is intended for users who need to manage these resources -# but should not control RBAC or manage permissions for others. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: cronjob-editor-role -rules: -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs/status - verbs: - - get -{{- end -}} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_viewer_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_viewer_role.yaml deleted file mode 100644 index 175a658f6e8..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/cronjob_viewer_role.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants read-only access to batch.tutorial.kubebuilder.io resources. -# This role is intended for users who need visibility into these resources -# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: cronjob-viewer-role -rules: -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs - verbs: - - get - - list - - watch -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs/status - verbs: - - get -{{- end -}} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-role.yaml new file mode 100644 index 00000000000..17bb2531ff8 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-role.yaml @@ -0,0 +1,40 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-leader-election-role + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-rolebinding.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-rolebinding.yaml new file mode 100644 index 00000000000..4966c4ac459 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader-election-rolebinding.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-leader-election-rolebinding + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: project-leader-election-role +subjects: + - kind: ServiceAccount + name: project-controller-manager + namespace: {{ .Release.Namespace }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role.yaml deleted file mode 100644 index 2829e9912c5..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role.yaml +++ /dev/null @@ -1,42 +0,0 @@ -{{- if .Values.rbac.enable }} -# permissions to do leader election. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - namespace: {{ .Release.Namespace }} - name: project-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/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role_binding.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role_binding.yaml deleted file mode 100644 index 79885d91895..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/leader_election_role_binding.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - namespace: {{ .Release.Namespace }} - name: project-leader-election-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: project-leader-election-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/manager-role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/manager-role.yaml new file mode 100644 index 00000000000..4261a27fa49 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/manager-role.yaml @@ -0,0 +1,49 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-manager-role +rules: + - apiGroups: + - batch + resources: + - jobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - batch + resources: + - jobs/status + verbs: + - get + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/finalizers + verbs: + - update + - apiGroups: + - batch.tutorial.kubebuilder.io + resources: + - cronjobs/status + verbs: + - get + - patch + - update diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/manager-rolebinding.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/manager-rolebinding.yaml new file mode 100644 index 00000000000..b82536997bc --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/manager-rolebinding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: project-manager-role +subjects: + - kind: ServiceAccount + name: project-controller-manager + namespace: {{ .Release.Namespace }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-role.yaml new file mode 100644 index 00000000000..5954a82944e --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-role.yaml @@ -0,0 +1,19 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-metrics-auth-role +rules: + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-rolebinding.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-rolebinding.yaml new file mode 100644 index 00000000000..33549b4c5ba --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics-auth-rolebinding.yaml @@ -0,0 +1,14 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: project-metrics-auth-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: project-metrics-auth-role +subjects: + - kind: ServiceAccount + name: project-controller-manager + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics-reader.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics-reader.yaml new file mode 100644 index 00000000000..609835fe71f --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics-reader.yaml @@ -0,0 +1,11 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-metrics-reader +rules: + - nonResourceURLs: + - /metrics + verbs: + - get +{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role.yaml deleted file mode 100644 index d8efe8d2264..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-metrics-auth-role -rules: -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create -{{- end -}} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role_binding.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role_binding.yaml deleted file mode 100644 index 7df99695c66..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics_auth_role_binding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-metrics-auth-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-metrics-auth-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics_reader_role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics_reader_role.yaml deleted file mode 100644 index 097846af52c..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/metrics_reader_role.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-metrics-reader -rules: -- nonResourceURLs: - - "/metrics" - verbs: - - get -{{- end -}} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/role.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/role.yaml deleted file mode 100644 index 854f9c92e22..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/role.yaml +++ /dev/null @@ -1,54 +0,0 @@ -{{- if .Values.rbac.enable }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-manager-role -rules: -- apiGroups: - - batch - resources: - - jobs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - batch - resources: - - jobs/status - verbs: - - get -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs/finalizers - verbs: - - update -- apiGroups: - - batch.tutorial.kubebuilder.io - resources: - - cronjobs/status - verbs: - - get - - patch - - update -{{- end -}} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/role_binding.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/role_binding.yaml deleted file mode 100644 index e6310b045ee..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/role_binding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-manager-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/service_account.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/service_account.yaml deleted file mode 100644 index 93e0a323e1d..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/rbac/service_account.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - {{- if and .Values.controllerManager.serviceAccount .Values.controllerManager.serviceAccount.annotations }} - annotations: - {{- range $key, $value := .Values.controllerManager.serviceAccount.annotations }} - {{ $key }}: {{ $value }} - {{- end }} - {{- end }} - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/mutating-webhook-configuration.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/mutating-webhook-configuration.yaml new file mode 100644 index 00000000000..53b847b7a29 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/mutating-webhook-configuration.yaml @@ -0,0 +1,49 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + annotations: + {{- if .Values.certManager.enable }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/project-serving-cert + {{- end }} + name: project-mutating-webhook-configuration +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: project-webhook-service + namespace: {{ .Release.Namespace }} + path: /mutate-batch-tutorial-kubebuilder-io-v1-cronjob + failurePolicy: Fail + name: mcronjob-v1.kb.io + rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - cronjobs + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: project-webhook-service + namespace: {{ .Release.Namespace }} + path: /mutate-batch-tutorial-kubebuilder-io-v2-cronjob + failurePolicy: Fail + name: mcronjob-v2.kb.io + rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + apiVersions: + - v2 + operations: + - CREATE + - UPDATE + resources: + - cronjobs + sideEffects: None diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/service.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/service.yaml deleted file mode 100644 index 9dae918ebd1..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if .Values.webhook.enable }} -apiVersion: v1 -kind: Service -metadata: - name: project-webhook-service - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} -spec: - ports: - - port: 443 - protocol: TCP - targetPort: 9443 - selector: - control-plane: controller-manager -{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/validating-webhook-configuration.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/validating-webhook-configuration.yaml new file mode 100644 index 00000000000..566f7b513d5 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/validating-webhook-configuration.yaml @@ -0,0 +1,49 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + {{- if .Values.certManager.enable }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/project-serving-cert + {{- end }} + name: project-validating-webhook-configuration +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: project-webhook-service + namespace: {{ .Release.Namespace }} + path: /validate-batch-tutorial-kubebuilder-io-v1-cronjob + failurePolicy: Fail + name: vcronjob-v1.kb.io + rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - cronjobs + sideEffects: None + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: project-webhook-service + namespace: {{ .Release.Namespace }} + path: /validate-batch-tutorial-kubebuilder-io-v2-cronjob + failurePolicy: Fail + name: vcronjob-v2.kb.io + rules: + - apiGroups: + - batch.tutorial.kubebuilder.io + apiVersions: + - v2 + operations: + - CREATE + - UPDATE + resources: + - cronjobs + sideEffects: None diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/webhook-service.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/webhook-service.yaml new file mode 100644 index 00000000000..0fa69736ed4 --- /dev/null +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/webhook-service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project + name: project-webhook-service + namespace: {{ .Release.Namespace }} +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + app.kubernetes.io/name: project + control-plane: controller-manager diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/webhooks.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/webhooks.yaml deleted file mode 100644 index 55c78831b3f..00000000000 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/templates/webhook/webhooks.yaml +++ /dev/null @@ -1,107 +0,0 @@ -{{- if .Values.webhook.enable }} -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: project-mutating-webhook-configuration - namespace: {{ .Release.Namespace }} - annotations: - {{- if .Values.certmanager.enable }} - cert-manager.io/inject-ca-from: "{{ $.Release.Namespace }}/serving-cert" - {{- end }} - labels: - {{- include "chart.labels" . | nindent 4 }} -webhooks: - - name: mcronjob-v1.kb.io - clientConfig: - service: - name: project-webhook-service - namespace: {{ .Release.Namespace }} - path: /mutate-batch-tutorial-kubebuilder-io-v1-cronjob - failurePolicy: Fail - sideEffects: None - admissionReviewVersions: - - v1 - rules: - - operations: - - CREATE - - UPDATE - apiGroups: - - batch.tutorial.kubebuilder.io - apiVersions: - - v1 - resources: - - cronjobs - - name: mcronjob-v2.kb.io - clientConfig: - service: - name: project-webhook-service - namespace: {{ .Release.Namespace }} - path: /mutate-batch-tutorial-kubebuilder-io-v2-cronjob - failurePolicy: Fail - sideEffects: None - admissionReviewVersions: - - v1 - rules: - - operations: - - CREATE - - UPDATE - apiGroups: - - batch.tutorial.kubebuilder.io - apiVersions: - - v2 - resources: - - cronjobs ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: project-validating-webhook-configuration - namespace: {{ .Release.Namespace }} - annotations: - {{- if .Values.certmanager.enable }} - cert-manager.io/inject-ca-from: "{{ $.Release.Namespace }}/serving-cert" - {{- end }} - labels: - {{- include "chart.labels" . | nindent 4 }} -webhooks: - - name: vcronjob-v1.kb.io - clientConfig: - service: - name: project-webhook-service - namespace: {{ .Release.Namespace }} - path: /validate-batch-tutorial-kubebuilder-io-v1-cronjob - failurePolicy: Fail - sideEffects: None - admissionReviewVersions: - - v1 - rules: - - operations: - - CREATE - - UPDATE - apiGroups: - - batch.tutorial.kubebuilder.io - apiVersions: - - v1 - resources: - - cronjobs - - name: vcronjob-v2.kb.io - clientConfig: - service: - name: project-webhook-service - namespace: {{ .Release.Namespace }} - path: /validate-batch-tutorial-kubebuilder-io-v2-cronjob - failurePolicy: Fail - sideEffects: None - admissionReviewVersions: - - v1 - rules: - - operations: - - CREATE - - UPDATE - apiGroups: - - batch.tutorial.kubebuilder.io - apiVersions: - - v2 - resources: - - cronjobs -{{- end }} diff --git a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/values.yaml b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/values.yaml index 52879a5615c..1598abb5ea7 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/values.yaml +++ b/docs/book/src/multiversion-tutorial/testdata/project/dist/chart/values.yaml @@ -1,84 +1,65 @@ -# [MANAGER]: Manager Deployment Configurations +# Configure the controller manager deployment controllerManager: replicas: 1 - container: - image: - repository: controller - tag: latest - imagePullPolicy: IfNotPresent - args: - - "--leader-elect" - - "--metrics-bind-address=:8443" - - "--health-probe-bind-address=:8081" - resources: - limits: + + image: + repository: controller + tag: latest + pullPolicy: IfNotPresent + + # Environment variables + env: [] + + # Pod-level security settings + podSecurityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + + # Container-level security settings + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + + # Resource limits and requests + resources: + limits: cpu: 500m memory: 128Mi - requests: + 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: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - securityContext: - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - terminationGracePeriodSeconds: 10 - serviceAccountName: project-controller-manager -# [RBAC]: To enable RBAC (Permissions) configurations -rbac: - enable: true +# Essential RBAC permissions (required for controller operation) +# These include ServiceAccount, controller permissions, leader election, and metrics access +# Note: Essential RBAC is always enabled as it's required for the controller to function -# [CRDs]: To enable the CRDs -crd: - # This option determines whether the CRDs are included - # in the installation process. - enable: true +# Helper RBAC roles for managing custom resources +# These provide convenient admin/editor/viewer roles for each CRD type +# Useful for giving users different levels of access to your custom resources +rbacHelpers: + enable: false # Install convenience admin/editor/viewer roles for CRDs - # Enabling this option adds the "helm.sh/resource-policy": keep - # annotation to the CRD, ensuring it remains installed even when - # the Helm release is uninstalled. - # NOTE: Removing the CRDs will also remove all cert-manager CR(s) - # (Certificates, Issuers, ...) due to garbage collection. - keep: true +# Custom Resource Definitions +crd: + enable: true # Install CRDs with the chart + keep: true # Keep CRDs when uninstalling -# [METRICS]: Set to true to generate manifests for exporting metrics. -# To disable metrics export set false, and ensure that the -# ControllerManager argument "--metrics-bind-address=:8443" is removed. +# Controller metrics endpoint. +# Enable to expose /metrics endpoint with RBAC protection. metrics: enable: true -# [WEBHOOKS]: Webhooks configuration -# The following configuration is automatically generated from the manifests -# generated by controller-gen. To update run 'make manifests' and -# the edit command with the '--force' flag -webhook: +# Cert-manager integration for TLS certificates. +# Required for webhook certificates and metrics endpoint certificates. +certManager: enable: true -# [PROMETHEUS]: To enable a ServiceMonitor to export metrics to Prometheus set true +# Prometheus ServiceMonitor for metrics scraping. +# Requires prometheus-operator to be installed in the cluster. prometheus: enable: false -# [CERT-MANAGER]: To enable cert-manager injection to webhooks set true -certmanager: - enable: true - -# [NETWORK POLICIES]: To enable NetworkPolicies set true -networkPolicy: - enable: false diff --git a/docs/book/src/plugins/available/helm-v1-alpha.md b/docs/book/src/plugins/available/helm-v1-alpha.md index 72a5772b394..d5f5c5f89c6 100644 --- a/docs/book/src/plugins/available/helm-v1-alpha.md +++ b/docs/book/src/plugins/available/helm-v1-alpha.md @@ -1,4 +1,17 @@ -# Helm Plugin (`helm/v1-alpha`) +# Helm Plugin (`helm/v1-alpha`) - **DEPRECATED** + + The Helm plugin is an optional plugin that can be used to scaffold a Helm chart, allowing you to distribute the project using Helm. diff --git a/docs/book/src/plugins/available/helm-v2-alpha.md b/docs/book/src/plugins/available/helm-v2-alpha.md new file mode 100644 index 00000000000..1eefec39f70 --- /dev/null +++ b/docs/book/src/plugins/available/helm-v2-alpha.md @@ -0,0 +1,248 @@ +# Helm Plugin `(helm/v2-alpha)` + +The Helm plugin **v2-alpha** provides a way to package your project as a Helm chart, enabling distribution in Helm’s native format. +Instead of using static templates, this plugin dynamically generates Helm charts from your project’s **kustomize output** (via `make build-installer`). +It keeps your custom settings such as environment variables, labels, annotations, and security contexts. + +This lets you deliver your Kubebuilder project in two ways: +- As a **bundle** (`dist/install.yaml`) generated with kustomize +- As a **Helm chart** that matches the same output + +## Why Helm? + +By default, you can create a bundle of manifests with: + +```shell +make build-installer IMG=/ +``` + +Users can install it directly: + +```shell +kubectl apply -f https://raw.githubusercontent.com//project-v4//dist/install.yaml +``` +But many people prefer Helm for packaging, upgrades, and distribution. +The **helm/v2-alpha** plugin converts the bundle (`dist/install.yaml`) into a Helm chart that mirrors your project. + +## Key Features + +- **Dynamic Generation**: Charts are built from real kustomize output, not boilerplate. +- **Preserves Customizations**: Keeps env vars, labels, annotations, and patches. +- **Structured Output**: Templates follow your `config/` directory layout. +- **Smart Values**: `values.yaml` includes only actual configurable parameters. +- **File Preservation**: Manual edits in `values.yaml`, `Chart.yaml`, `_helpers.tpl` are kept unless `--force` is used. + +## When to Use It + +Use the **helm/v2-alpha** plugin if: +- You want Helm charts that stay true to your kustomize setup +- You need charts that update with your project automatically +- You want a clean template layout similar to `config/` +- You want to distribute your solution using either this format + +## Usage + +### Basic Workflow + +```shell +# Create a new project +kubebuilder init + +# Build the installer bundle +make build-installer IMG=/ + +# Create Helm chart from kustomize output +kubebuilder edit --plugins=helm/v2-alpha + +# Overwrite preserved files if needed +kubebuilder edit --plugins=helm/v2-alpha --force +``` + +### Advanced Options + +```shell +# Use a custom manifests file +kubebuilder edit --plugins=helm/v2-alpha --manifests=manifests/custom-install.yaml + +# Write chart to a custom output directory +kubebuilder edit --plugins=helm/v2-alpha --output-dir=charts + +# Combine manifests and output +kubebuilder edit --plugins=helm/v2-alpha \ + --manifests=manifests/install.yaml \ + --output-dir=helm-charts +``` + +## Chart Structure + +The plugin creates a chart layout that matches your `config/`: + +```shell +/chart/ +├── Chart.yaml +├── values.yaml +├── .helmignore +└── templates/ + ├── _helpers.tpl + ├── rbac/ # Individual RBAC files + │ ├── controller-manager.yaml + │ ├── leader-election-role.yaml + │ ├── leader-election-rolebinding.yaml + │ ├── manager-role.yaml + │ ├── manager-rolebinding.yaml + │ ├── metrics-auth-role.yaml + │ ├── metrics-auth-rolebinding.yaml + │ ├── metrics-reader.yaml + │ ├── memcached-admin-role.yaml + │ ├── memcached-editor-role.yaml + │ ├── memcached-viewer-role.yaml + │ └── ... + ├── crd/ # Individual CRD files + │ ├── memcacheds.example.com.testproject.org.yaml + │ ├── busyboxes.example.com.testproject.org.yaml + │ ├── wordpresses.example.com.testproject.org.yaml + │ └── ... + ├── cert-manager/ + │ ├── metrics-certs.yaml + │ ├── serving-cert.yaml + │ └── selfsigned-issuer.yaml + ├── manager/ + │ └── manager.yaml + ├── service/ + │ └── service.yaml + ├── webhook/ + │ └── validating-webhook-configuration.yaml + └── prometheus/ + └── servicemonitor.yaml +``` + + + +## Values Configuration + +The generated `values.yaml` provides configuration options extracted from your actual deployment. +Namespace creation is not managed by the chart; use Helm's `--namespace` and `--create-namespace` flags when installing. + +**Example** + +```yaml +# Configure the controller manager deployment +controllerManager: + replicas: 1 + + image: + repository: controller + tag: latest + pullPolicy: IfNotPresent + + # Environment variables from your deployment + env: + - name: BUSYBOX_IMAGE + value: busybox:1.36.1 + - name: MEMCACHED_IMAGE + value: memcached:1.6.26-alpine3.19 + + # Pod-level security settings + podSecurityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + + # Container-level security settings + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + + # Resource limits and requests + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + +# Essential RBAC permissions (required for controller operation) +# These include ServiceAccount, controller permissions, leader election, and metrics access +# Note: Essential RBAC is always enabled as it's required for the controller to function + +# Extra labels applied to all rendered manifests +commonLabels: {} + +# Helper RBAC roles for managing custom resources +# These provide convenient admin/editor/viewer roles for each CRD type +# Useful for giving users different levels of access to your custom resources +rbacHelpers: + enable: false # Install convenience admin/editor/viewer roles for CRDs + +# Custom Resource Definitions +crd: + enable: true # Install CRDs with the chart + keep: true # Keep CRDs when uninstalling + +# Controller metrics endpoint. +# Enable to expose /metrics endpoint with RBAC protection. +metrics: + enable: true + +# Cert-manager integration for TLS certificates. +# Required for webhook certificates and metrics endpoint certificates. +certManager: + enable: true + +# Prometheus ServiceMonitor for metrics scraping. +# Requires prometheus-operator to be installed in the cluster. +prometheus: + enable: false +``` + +### Installation Tip + +Install the chart into a namespace using Helm flags (the chart does not create namespaces): + +```shell +helm install my-release ./dist/chart \ + --namespace my-project-system \ + --create-namespace +``` + +## Flags + +| Flag | Description | +|---------------------|-----------------------------------------------------------------------------| +| **--manifests** | Path to YAML file containing Kubernetes manifests (default: `dist/install.yaml`) | +| **--output-dir** string | Output directory for chart (default: `dist`) | +| **--force** | Overwrites preserved files (`values.yaml`, `Chart.yaml`, `_helpers.tpl`) | + + diff --git a/docs/book/src/plugins/to-add-optional-features.md b/docs/book/src/plugins/to-add-optional-features.md index 7b4c85ac802..d6d53a06ccf 100644 --- a/docs/book/src/plugins/to-add-optional-features.md +++ b/docs/book/src/plugins/to-add-optional-features.md @@ -7,9 +7,11 @@ The following plugins are useful to generate code and take advantage of optional | [autoupdate.kubebuilder.io/v1-alpha][autoupdate] | `autoupdate/v1-alpha` | Optional helper which scaffolds a scheduled worker that helps keep your project updated with changes in the ecosystem, significantly reducing the burden of manual maintenance. | | [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). | | [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. | -| [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 | +| [helm.kubebuilder.io/v1-alpha][helm-v1alpha] (deprecated) | `helm/v1-alpha` | **Deprecated** - Optional helper plugin which can be used to scaffold a Helm Chart to distribute the project under the `dist` directory. Use v2-alpha instead. | +| [helm.kubebuilder.io/v2-alpha][helm-v2alpha] | `helm/v2-alpha` | Optional helper plugin which dynamically generates Helm charts from kustomize output, preserving all customizations | [grafana]: ./available/grafana-v1-alpha.md [deploy]: ./available/deploy-image-plugin-v1-alpha.md -[helm]: ./available/helm-v1-alpha.md +[helm-v1alpha]: ./available/helm-v1-alpha.md +[helm-v2alpha]: ./available/helm-v2-alpha.md [autoupdate]: ./available/autoupdate-v1-alpha.md \ No newline at end of file diff --git a/go.mod b/go.mod index b6b121aac61..2ae94efba99 100644 --- a/go.mod +++ b/go.mod @@ -13,21 +13,29 @@ require ( golang.org/x/mod v0.28.0 golang.org/x/text v0.29.0 golang.org/x/tools v0.37.0 + gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.19.0 + k8s.io/apimachinery v0.34.0 sigs.k8s.io/yaml v1.6.0 ) require ( github.com/Masterminds/semver/v3 v3.4.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 // indirect github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/kr/pretty v0.3.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pkg/errors v0.9.1 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect + github.com/x448/float16 v0.8.4 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect @@ -35,4 +43,10 @@ require ( golang.org/x/sync v0.17.0 // indirect golang.org/x/sys v0.36.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect + sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect ) diff --git a/go.sum b/go.sum index 1b85e5fc320..8ab454f4f3e 100644 --- a/go.sum +++ b/go.sum @@ -8,14 +8,19 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4= github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY= github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U= github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE= @@ -24,6 +29,10 @@ github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslC github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -31,6 +40,12 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/onsi/ginkgo/v2 v2.25.3 h1:Ty8+Yi/ayDAGtk4XxmmfUy4GabvM+MegeB4cDLRi6nw= @@ -59,38 +74,82 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= helm.sh/helm/v3 v3.19.0 h1:krVyCGa8fa/wzTZgqw0DUiXuRT5BPdeqE/sQXujQ22k= helm.sh/helm/v3 v3.19.0/go.mod h1:Lk/SfzN0w3a3C3o+TdAKrLwJ0wcZ//t1/SDXAvfgDdc= +k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0= +k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/pkg/cli/alpha/internal/generate.go b/pkg/cli/alpha/internal/generate.go index 8de380ba7ef..1f984a79c93 100644 --- a/pkg/cli/alpha/internal/generate.go +++ b/pkg/cli/alpha/internal/generate.go @@ -34,6 +34,7 @@ import ( autoupdate "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/autoupdate/v1alpha" "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha" hemlv1alpha "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha" + hemlv2alpha "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v2alpha" ) // Generate store the required info for the command @@ -111,8 +112,8 @@ func (opts *Generate) Generate() error { return fmt.Errorf("error migrating AutoUpdate plugin: %w", err) } - if hasHelmPlugin(projectConfig) { - if err = kubebuilderHelmEdit(); err != nil { + if hasHelm, isV2Alpha := hasHelmPlugin(projectConfig); hasHelm && isV2Alpha { + if err = kubebuilderHelmEditWithConfig(projectConfig); err != nil { return fmt.Errorf("error editing Helm plugin: %w", err) } } @@ -125,7 +126,7 @@ func (opts *Generate) Generate() error { // These steps are performed on a best-effort basis: if any of the targets fail, // we slog a warning to inform the user, but we do not stop the process or return an error. // This is to avoid blocking the migration flow due to non-critical issues during setup. - targets := []string{"manifests", "generate", "fmt", "vet", "lint-fix"} + targets := []string{"fmt", "vet", "lint-fix"} for _, target := range targets { err := util.RunCmd(fmt.Sprintf("Running make %s", target), "make", target) if err != nil { @@ -490,7 +491,8 @@ func copyFile(src, des string) error { func grafanaConfigMigrate(src, des string) error { grafanaConfig := fmt.Sprintf("%s/grafana/custom-metrics/config.yaml", src) if _, err := os.Stat(grafanaConfig); os.IsNotExist(err) { - return fmt.Errorf("grafana config path %s does not exist: %w", grafanaConfig, err) + slog.Info("Grafana config file not found, skipping file migration", "path", grafanaConfig) + return nil // Don't fail if config files don't exist } return copyFile(grafanaConfig, fmt.Sprintf("%s/grafana/custom-metrics/config.yaml", des)) } @@ -504,31 +506,75 @@ func kubebuilderGrafanaEdit() error { return nil } +// Edits the project to include the Helm plugin with tracked configuration. +func kubebuilderHelmEditWithConfig(s store.Store) error { + var cfg struct { + ManifestsFile string `json:"manifests,omitempty"` + OutputDir string `json:"output,omitempty"` + } + err := s.Config().DecodePluginConfig(plugin.KeyFor(hemlv2alpha.Plugin{}), &cfg) + if errors.As(err, &config.PluginKeyNotFoundError{}) { + // No previous configuration, use defaults + return kubebuilderHelmEdit(true) + } else if err != nil { + return fmt.Errorf("failed to decode helm plugin config: %w", err) + } + + // Use tracked configuration values + pluginKey := plugin.KeyFor(hemlv2alpha.Plugin{}) + args := []string{"edit", "--plugins", pluginKey} + if cfg.ManifestsFile != "" { + args = append(args, "--manifests", cfg.ManifestsFile) + } + if cfg.OutputDir != "" { + args = append(args, "--output-dir", cfg.OutputDir) + } + + 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 +} + // Edits the project to include the Helm plugin. -func kubebuilderHelmEdit() error { - args := []string{"edit", "--plugins", plugin.KeyFor(hemlv1alpha.Plugin{})} +func kubebuilderHelmEdit(isV2Alpha bool) error { + var pluginKey string + if isV2Alpha { + pluginKey = plugin.KeyFor(hemlv2alpha.Plugin{}) + } else { + pluginKey = plugin.KeyFor(hemlv1alpha.Plugin{}) + } + + args := []string{"edit", "--plugins", pluginKey} 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 { +// hasHelmPlugin checks if any Helm plugin (v1alpha or v2alpha) is present by inspecting +// the plugin chain or configuration. +func hasHelmPlugin(cfg store.Store) (bool, bool) { var pluginConfig map[string]interface{} - // Decode the Helm plugin configuration to check if it's present - err := cfg.Config().DecodePluginConfig(plugin.KeyFor(hemlv1alpha.Plugin{}), &pluginConfig) + // Check for v2alpha first (preferred) + err := cfg.Config().DecodePluginConfig(plugin.KeyFor(hemlv2alpha.Plugin{}), &pluginConfig) + if err == nil { + return true, true // has helm plugin, is v2alpha + } + + // Check for v1alpha + err = cfg.Config().DecodePluginConfig(plugin.KeyFor(hemlv1alpha.Plugin{}), &pluginConfig) if err != nil { - // If the Helm plugin is not found, return false + // If neither Helm plugin is found, return false if errors.As(err, &config.PluginKeyNotFoundError{}) { - return false + return false, false } // slog other errors if needed slog.Error("error decoding Helm plugin config", "error", err) - return false + return false, false } - // Helm plugin is present - return true + // v1alpha Helm plugin is present + return true, false // has helm plugin, is not v2alpha } diff --git a/pkg/plugins/golang/v4/scaffolds/internal/templates/readme.go b/pkg/plugins/golang/v4/scaffolds/internal/templates/readme.go index 078e3cb088b..5511c9be69a 100644 --- a/pkg/plugins/golang/v4/scaffolds/internal/templates/readme.go +++ b/pkg/plugins/golang/v4/scaffolds/internal/templates/readme.go @@ -58,7 +58,7 @@ func (f *Readme) SetTemplateDefaults() error { codeFence("make build-installer IMG=/{{ .ProjectName }}:tag"), codeFence("kubectl apply -f https://raw.githubusercontent.com//{{ .ProjectName }}/"+ "/dist/install.yaml"), - codeFence(fmt.Sprintf("%s edit --plugins=helm/v1-alpha", f.CommandName)), + codeFence(fmt.Sprintf("%s edit --plugins=helm/v2-alpha", f.CommandName)), ) return nil diff --git a/pkg/plugins/optional/helm/v1alpha/plugin.go b/pkg/plugins/optional/helm/v1alpha/plugin.go index c56b7c559b8..231a15860c1 100644 --- a/pkg/plugins/optional/helm/v1alpha/plugin.go +++ b/pkg/plugins/optional/helm/v1alpha/plugin.go @@ -55,5 +55,6 @@ func (p Plugin) GetEditSubcommand() plugin.EditSubcommand { return &p.editSubcom // DeprecationWarning define the deprecation message or return empty when plugin is not deprecated func (p Plugin) DeprecationWarning() string { - return "" + return "helm/v1-alpha plugin is deprecated, use helm/v2-alpha instead which " + + "provides dynamic Helm chart generation from kustomize output" } diff --git a/pkg/plugins/optional/helm/v2alpha/edit.go b/pkg/plugins/optional/helm/v2alpha/edit.go new file mode 100644 index 00000000000..87d9e1b778e --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/edit.go @@ -0,0 +1,217 @@ +/* +Copyright 2025 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 v2alpha + +import ( + "errors" + "fmt" + "log/slog" + "os" + "path/filepath" + + "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/plugin/util" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v2alpha/scaffolds" +) + +const ( + // DefaultManifestsFile is the default path for kustomize output manifests + DefaultManifestsFile = "dist/install.yaml" + // DefaultOutputDir is the default output directory for Helm charts + DefaultOutputDir = "dist" +) + +var _ plugin.EditSubcommand = &editSubcommand{} + +type editSubcommand struct { + config config.Config + force bool + manifestsFile string + outputDir string +} + +//nolint:lll +func (p *editSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) { + subcmdMeta.Description = `Generate a Helm chart from your project's kustomize output. + +This plugin dynamically generates Helm chart templates by parsing the output of 'make build-installer' +(dist/install.yaml by default). The generated chart preserves all customizations made to your kustomize +configuration including environment variables, labels, and annotations. + +The chart structure mirrors your config/ directory organization for easy maintenance.` + + subcmdMeta.Examples = fmt.Sprintf(`# Generate Helm chart from default manifests (dist/install.yaml) to default output (dist/) + %[1]s edit --plugins=%[2]s + +# Generate Helm chart and overwrite existing files (useful for updates) + %[1]s edit --plugins=%[2]s --force + +# Generate Helm chart from a custom manifests file + %[1]s edit --plugins=%[2]s --manifests=path/to/custom-install.yaml + +# Generate Helm chart to a custom output directory + %[1]s edit --plugins=%[2]s --output-dir=charts + +# Generate from custom manifests to custom output directory + %[1]s edit --plugins=%[2]s --manifests=manifests/install.yaml --output-dir=helm-charts + +# Typical workflow: + make build-installer # Generate dist/install.yaml with latest changes + %[1]s edit --plugins=%[2]s # Generate/update Helm chart in dist/chart/ + +**NOTE**: The plugin preserves customizations in values.yaml, Chart.yaml, _helpers.tpl, and .helmignore +unless --force is used. All template files are regenerated to match your current kustomize output. + +The generated chart structure mirrors your config/ directory: +/chart/ +├── Chart.yaml +├── values.yaml +├── .helmignore +└── templates/ + ├── _helpers.tpl + ├── rbac/ + ├── manager/ + ├── webhook/ + └── ... +`, cliMeta.CommandName, plugin.KeyFor(Plugin{})) +} + +func (p *editSubcommand) BindFlags(fs *pflag.FlagSet) { + fs.BoolVar(&p.force, "force", false, "if true, regenerates all the files") + fs.StringVar(&p.manifestsFile, "manifests", DefaultManifestsFile, + "path to the YAML file containing Kubernetes manifests from kustomize output") + fs.StringVar(&p.outputDir, "output-dir", DefaultOutputDir, "output directory for the generated Helm chart") +} + +func (p *editSubcommand) InjectConfig(c config.Config) error { + p.config = c + return nil +} + +func (p *editSubcommand) Scaffold(fs machinery.Filesystem) error { + // If using default manifests file, ensure it exists by running make build-installer + if p.manifestsFile == DefaultManifestsFile { + if err := p.ensureManifestsExist(); err != nil { + slog.Warn("Failed to generate default manifests file", "error", err, "file", p.manifestsFile) + } + } + + scaffolder := scaffolds.NewKustomizeHelmScaffolder(p.config, p.force, p.manifestsFile, p.outputDir) + scaffolder.InjectFS(fs) + err := scaffolder.Scaffold() + if err != nil { + return fmt.Errorf("error scaffolding Helm chart: %w", err) + } + + // Track the plugin configuration following a declarative approach + cfg := pluginConfig{} + if err = p.config.DecodePluginConfig(pluginKey, &cfg); errors.As(err, &config.UnsupportedFieldError{}) { + // Skip tracking as the config doesn't support per-plugin configuration + return nil + } else if err != nil && !errors.As(err, &config.PluginKeyNotFoundError{}) { + // Fail unless the key wasn't found, which just means it is the first time tracking + return fmt.Errorf("error decoding plugin configuration: %w", err) + } + + // Update configuration with current parameters + cfg.ManifestsFile = p.manifestsFile + cfg.OutputDir = p.outputDir + + if err = p.config.EncodePluginConfig(pluginKey, cfg); err != nil { + return fmt.Errorf("error encoding plugin configuration: %w", err) + } + + return nil +} + +// ensureManifestsExist runs make build-installer to generate the default manifests file +func (p *editSubcommand) ensureManifestsExist() error { + slog.Info("Generating default manifests file", "file", p.manifestsFile) + + // Run the required make targets to generate the manifests file + targets := []string{"manifests", "generate", "build-installer"} + for _, target := range targets { + if err := util.RunCmd(fmt.Sprintf("Running make %s", target), "make", target); err != nil { + return fmt.Errorf("make %s failed: %w", target, err) + } + } + + // Verify the file was created + if _, err := os.Stat(p.manifestsFile); err != nil { + return fmt.Errorf("manifests file %s was not created: %w", p.manifestsFile, err) + } + + slog.Info("Successfully generated manifests file", "file", p.manifestsFile) + return nil +} + +// PostScaffold automatically uncomments cert-manager installation when webhooks are present +func (p *editSubcommand) PostScaffold() error { + hasWebhooks := hasWebhooksWith(p.config) + + if hasWebhooks { + workflowFile := filepath.Join(".github", "workflows", "test-chart.yml") + if _, err := os.Stat(workflowFile); err != nil { + slog.Info( + "Workflow file not found, unable to uncomment cert-manager installation", + "error", err, + "file", workflowFile, + ) + return nil + } + target := ` +# - name: Install cert-manager via Helm (wait for readiness) +# run: | +# helm repo add jetstack https://charts.jetstack.io +# helm repo update +# helm install cert-manager jetstack/cert-manager \ +# --namespace cert-manager \ +# --create-namespace \ +# --set crds.enabled=true \ +# --wait \ +# --timeout 300s` + if err := util.UncommentCode(workflowFile, target, "#"); err != nil { + hasUncommented, errCheck := util.HasFileContentWith(workflowFile, "- name: Install cert-manager via Helm") + if !hasUncommented || errCheck != nil { + slog.Warn("Failed to uncomment cert-manager installation in workflow file", "error", err, "file", workflowFile) + } + } else { + target = `# TODO: Uncomment if cert-manager is enabled` + _ = util.ReplaceInFile(workflowFile, target, "") + } + } + return nil +} + +func hasWebhooksWith(c config.Config) bool { + resources, err := c.GetResources() + if err != nil { + return false + } + + for _, res := range resources { + if res.HasDefaultingWebhook() || res.HasValidationWebhook() || res.HasConversionWebhook() { + return true + } + } + + return false +} diff --git a/pkg/plugins/optional/helm/v2alpha/edit_test.go b/pkg/plugins/optional/helm/v2alpha/edit_test.go new file mode 100644 index 00000000000..f17d1c75f36 --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/edit_test.go @@ -0,0 +1,168 @@ +/* +Copyright 2025 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 v2alpha + +import ( + "path/filepath" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/spf13/afero" + "github.com/spf13/pflag" + + "sigs.k8s.io/kubebuilder/v4/pkg/config" + "sigs.k8s.io/kubebuilder/v4/pkg/config/store/yaml" + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" + "sigs.k8s.io/kubebuilder/v4/pkg/plugin" +) + +var _ = Describe("editSubcommand", func() { + var ( + editCmd *editSubcommand + cfg config.Config + fs machinery.Filesystem + ) + + BeforeEach(func() { + // Create test config + memFs := afero.NewMemMapFs() + fs = machinery.Filesystem{FS: memFs} + store := yaml.New(fs) + + // Create a basic PROJECT file + projectContent := `domain: example.com +layout: +- go.kubebuilder.io/v4 +projectName: test-project +repo: example.com/test-project +version: "3" +` + err := afero.WriteFile(memFs, "PROJECT", []byte(projectContent), 0o644) + Expect(err).NotTo(HaveOccurred()) + + err = store.LoadFrom("PROJECT") + Expect(err).NotTo(HaveOccurred()) + + cfg = store.Config() + + // Create edit subcommand + editCmd = &editSubcommand{ + config: cfg, + } + }) + + Context("UpdateMetadata", func() { + It("should set correct metadata", func() { + cliMeta := plugin.CLIMetadata{CommandName: "kubebuilder"} + meta := plugin.SubcommandMetadata{} + editCmd.UpdateMetadata(cliMeta, &meta) + + Expect(meta.Description).To(ContainSubstring("Generate a Helm chart")) + Expect(meta.Description).To(ContainSubstring("kustomize")) + Expect(meta.Examples).NotTo(BeEmpty()) + }) + }) + + Context("BindFlags", func() { + It("should bind flags correctly", func() { + flagSet := pflag.NewFlagSet("test", pflag.ContinueOnError) + editCmd.BindFlags(flagSet) + + // Check that flags were added + manifestsFlag := flagSet.Lookup("manifests") + Expect(manifestsFlag).NotTo(BeNil()) + Expect(manifestsFlag.DefValue).To(Equal(DefaultManifestsFile)) + + outputFlag := flagSet.Lookup("output-dir") + Expect(outputFlag).NotTo(BeNil()) + Expect(outputFlag.DefValue).To(Equal(DefaultOutputDir)) + + forceFlag := flagSet.Lookup("force") + Expect(forceFlag).NotTo(BeNil()) + }) + }) + + Context("InjectConfig", func() { + It("should inject config correctly", func() { + err := editCmd.InjectConfig(cfg) + Expect(err).NotTo(HaveOccurred()) + Expect(editCmd.config).To(Equal(cfg)) + }) + }) + + Context("hasWebhooksWith", func() { + It("should return false for config without webhooks", func() { + result := hasWebhooksWith(cfg) + Expect(result).To(BeFalse()) + }) + }) + + Context("PostScaffold", func() { + BeforeEach(func() { + // Create the directory structure + err := fs.FS.MkdirAll(".github/workflows", 0o755) + Expect(err).NotTo(HaveOccurred()) + }) + + It("should not modify workflow file when no webhooks present", func() { + // Create test workflow file + workflowContent := `name: Test Chart +on: + push: + branches: [main] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + +# - name: Install cert-manager via Helm +# run: | +# helm repo add jetstack https://charts.jetstack.io +# helm repo update +# helm install cert-manager jetstack/cert-manager \ +# --namespace cert-manager --create-namespace --set crds.enabled=true +# +# - name: Wait for cert-manager to be ready +# run: | +# kubectl wait --namespace cert-manager --for=condition=available \ +# --timeout=300s deployment/cert-manager +# kubectl wait --namespace cert-manager --for=condition=available \ +# --timeout=300s deployment/cert-manager-cainjector +# kubectl wait --namespace cert-manager --for=condition=available \ +# --timeout=300s deployment/cert-manager-webhook +` + workflowPath := filepath.Join(".github", "workflows", "test-chart.yml") + err := afero.WriteFile(fs.FS, workflowPath, []byte(workflowContent), 0o644) + Expect(err).NotTo(HaveOccurred()) + + err = editCmd.PostScaffold() + Expect(err).NotTo(HaveOccurred()) + + // Content should remain unchanged + content, err := afero.ReadFile(fs.FS, workflowPath) + Expect(err).NotTo(HaveOccurred()) + Expect(string(content)).To(ContainSubstring("# - name: Install cert-manager via Helm")) + }) + + It("should handle missing workflow file gracefully", func() { + editCmd.config = cfg + err := editCmd.PostScaffold() + Expect(err).NotTo(HaveOccurred()) // Should not error even if file doesn't exist + }) + }) +}) diff --git a/pkg/plugins/optional/helm/v2alpha/plugin.go b/pkg/plugins/optional/helm/v2alpha/plugin.go new file mode 100644 index 00000000000..3f5fd9e2e25 --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/plugin.go @@ -0,0 +1,63 @@ +/* +Copyright 2025 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 v2alpha + +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: 2, Stage: stage.Alpha} + supportedProjectVersions = []config.Version{cfgv3.Version} + pluginKey = plugin.KeyFor(Plugin{}) +) + +// Plugin implements the plugin.Full interface +type Plugin struct { + editSubcommand +} + +var _ plugin.Edit = Plugin{} + +// PluginConfig defines the structure that will be used to track the data +type pluginConfig struct { + ManifestsFile string `json:"manifests,omitempty"` + OutputDir string `json:"output,omitempty"` +} + +// Name returns the name of the plugin +func (Plugin) Name() string { return pluginName } + +// Version returns the version of the Helm 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 } + +// GetEditSubcommand will return the subcommand which is responsible for adding and/or edit a helm chart +func (p Plugin) GetEditSubcommand() plugin.EditSubcommand { return &p.editSubcommand } + +// DeprecationWarning define the deprecation message or return empty when plugin is not deprecated +func (p Plugin) DeprecationWarning() string { + return "" +} diff --git a/pkg/plugins/optional/helm/v2alpha/plugin_test.go b/pkg/plugins/optional/helm/v2alpha/plugin_test.go new file mode 100644 index 00000000000..06cf0607035 --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/plugin_test.go @@ -0,0 +1,68 @@ +/* +Copyright 2025 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 v2alpha + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "sigs.k8s.io/kubebuilder/v4/pkg/config" +) + +var _ = Describe("Plugin", func() { + var p Plugin + + BeforeEach(func() { + p = Plugin{} + }) + + Context("Name", func() { + It("should return the correct plugin name", func() { + Expect(p.Name()).To(Equal("helm.kubebuilder.io")) + }) + }) + + Context("Version", func() { + It("should return version 2-alpha", func() { + version := p.Version() + Expect(version.Number).To(Equal(2)) + Expect(version.Stage.String()).To(Equal("alpha")) + }) + }) + + Context("SupportedProjectVersions", func() { + It("should support project version 3", func() { + versions := p.SupportedProjectVersions() + expectedVersion := config.Version{Number: 3} + Expect(versions).To(ContainElement(expectedVersion)) + }) + }) + + Context("GetEditSubcommand", func() { + It("should return an edit subcommand", func() { + subcommand := p.GetEditSubcommand() + Expect(subcommand).NotTo(BeNil()) + }) + }) + + Context("DeprecationWarning", func() { + It("should return empty string since v2-alpha is not deprecated", func() { + warning := p.DeprecationWarning() + Expect(warning).To(BeEmpty()) + }) + }) +}) diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/edit_kustomize.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/edit_kustomize.go new file mode 100644 index 00000000000..24c3537aa84 --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/edit_kustomize.go @@ -0,0 +1,194 @@ +/* +Copyright 2025 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" + "log/slog" + "os" + "os/exec" + "path/filepath" + "strings" + + "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/v2alpha/scaffolds/internal/kustomize" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates" + charttemplates "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/chart-templates" + "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/github" +) + +const ( + defaultManifestsFile = "dist/install.yaml" +) + +var _ plugins.Scaffolder = &editKustomizeScaffolder{} + +type editKustomizeScaffolder struct { + config config.Config + fs machinery.Filesystem + force bool + manifestsFile string + outputDir string +} + +// NewKustomizeHelmScaffolder returns a new Scaffolder for HelmPlugin using kustomize output +func NewKustomizeHelmScaffolder(cfg config.Config, force bool, manifestsFile, outputDir string) plugins.Scaffolder { + return &editKustomizeScaffolder{ + config: cfg, + force: force, + manifestsFile: manifestsFile, + outputDir: outputDir, + } +} + +// InjectFS implements cmdutil.Scaffolder +func (s *editKustomizeScaffolder) InjectFS(fs machinery.Filesystem) { + s.fs = fs +} + +// Scaffold generates the complete Helm chart from kustomize output +func (s *editKustomizeScaffolder) Scaffold() error { + slog.Info("Generating Helm Chart from kustomize output") + + // Ensure chart directory structure exists + if err := s.ensureChartDirectoryExists(); err != nil { + return fmt.Errorf("failed to create chart directory: %w", err) + } + + // Generate fresh kustomize output if using default file + if s.manifestsFile == defaultManifestsFile { + if err := s.generateKustomizeOutput(); err != nil { + return fmt.Errorf("failed to generate kustomize output: %w", err) + } + } + + // Parse the kustomize output into organized resource groups + parser := kustomize.NewParser(s.manifestsFile) + resources, err := parser.Parse() + if err != nil { + return fmt.Errorf("failed to parse kustomize output from %s: %w", s.manifestsFile, err) + } + + // Analyze resources to determine chart features + hasWebhooks := len(resources.WebhookConfigurations) > 0 || len(resources.Certificates) > 0 + // Prometheus is enabled when ServiceMonitor resources exist (../prometheus enabled) + hasPrometheus := len(resources.ServiceMonitors) > 0 + // Metrics are enabled either when ServiceMonitor exists or when a metrics service is present + hasMetrics := hasPrometheus + if !hasMetrics { + for _, svc := range resources.Services { + if strings.Contains(svc.GetName(), "metrics") { + hasMetrics = true + break + } + } + } + + // When Prometheus is enabled via kustomize, ensure any previously-generated + // generic ServiceMonitor file is removed to avoid duplicates in the chart. + if hasPrometheus { + staleSM := filepath.Join(s.outputDir, "chart", "templates", "monitoring", "servicemonitor.yaml") + if rmErr := s.fs.FS.Remove(staleSM); rmErr != nil && !os.IsNotExist(rmErr) { + // Not fatal; log and continue + slog.Warn("failed to remove stale generic ServiceMonitor", "path", staleSM, "error", rmErr) + } + } + chartConverter := kustomize.NewChartConverter(resources, s.config.GetProjectName(), s.outputDir) + deploymentConfig := chartConverter.ExtractDeploymentConfig() + + // Create scaffold for standard Helm chart files + scaffold := machinery.NewScaffold(s.fs, machinery.WithConfig(s.config)) + + // Define the standard Helm chart files to generate + chartFiles := []machinery.Builder{ + &github.HelmChartCI{}, // GitHub Actions workflow for chart testing + &templates.HelmChart{OutputDir: s.outputDir}, // Chart.yaml metadata + &templates.HelmValuesBasic{ // values.yaml with dynamic config + HasWebhooks: hasWebhooks, + HasMetrics: hasMetrics, + DeploymentConfig: deploymentConfig, + OutputDir: s.outputDir, + Force: s.force, + }, + &templates.HelmIgnore{OutputDir: s.outputDir}, // .helmignore file + &charttemplates.HelmHelpers{OutputDir: s.outputDir}, // _helpers.tpl template functions + } + + // Only scaffold the generic ServiceMonitor when the project does NOT already + // provide one via kustomize (../prometheus). This avoids duplicate objects + // with the same name within the Helm chart. + if !hasPrometheus { + chartFiles = append(chartFiles, &charttemplates.ServiceMonitor{OutputDir: s.outputDir}) + } + + // Generate template files from kustomize output + if writeErr := chartConverter.WriteChartFiles(s.fs); writeErr != nil { + return fmt.Errorf("failed to write chart template files: %w", writeErr) + } + + // Generate standard Helm chart files + if err = scaffold.Execute(chartFiles...); err != nil { + return fmt.Errorf("failed to generate Helm chart files: %w", err) + } + + slog.Info("Helm Chart generation completed successfully") + return nil +} + +// generateKustomizeOutput runs make build-installer to generate the manifests file +func (s *editKustomizeScaffolder) generateKustomizeOutput() error { + slog.Info("Generating kustomize output with make build-installer") + + // Check if Makefile exists + if _, err := os.Stat("Makefile"); os.IsNotExist(err) { + return fmt.Errorf("makefile not found in current directory") + } + + // Run make build-installer + cmd := exec.Command("make", "build-installer") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if err := cmd.Run(); err != nil { + return fmt.Errorf("failed to run make build-installer: %w", err) + } + + // Verify that the manifests file was created + if _, err := os.Stat(defaultManifestsFile); os.IsNotExist(err) { + return fmt.Errorf("%s was not generated by make build-installer", defaultManifestsFile) + } + + return nil +} + +// ensureChartDirectoryExists creates the chart directory structure if it doesn't exist +func (s *editKustomizeScaffolder) ensureChartDirectoryExists() error { + dirs := []string{ + filepath.Join(s.outputDir, "chart"), + filepath.Join(s.outputDir, "chart", "templates"), + } + + for _, dir := range dirs { + if err := os.MkdirAll(dir, 0o755); err != nil { + return fmt.Errorf("failed to create directory %s: %w", dir, err) + } + } + + return nil +} diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/chart_converter.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/chart_converter.go new file mode 100644 index 00000000000..b7d7c1b264a --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/chart_converter.go @@ -0,0 +1,161 @@ +/* +Copyright 2025 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 kustomize + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +// ChartConverter orchestrates the conversion of kustomize output to Helm chart templates +type ChartConverter struct { + resources *ParsedResources + projectName string + outputDir string + + // Components for conversion + organizer *ResourceOrganizer + templater *HelmTemplater + writer *ChartWriter +} + +// NewChartConverter creates a new chart converter with all necessary components +func NewChartConverter(resources *ParsedResources, projectName, outputDir string) *ChartConverter { + organizer := NewResourceOrganizer(resources) + templater := NewHelmTemplater(projectName) + writer := NewChartWriter(templater, outputDir) + + return &ChartConverter{ + resources: resources, + projectName: projectName, + outputDir: outputDir, + organizer: organizer, + templater: templater, + writer: writer, + } +} + +// WriteChartFiles converts all resources to Helm chart templates and writes them to the filesystem +func (c *ChartConverter) WriteChartFiles(fs machinery.Filesystem) error { + // Organize resources by their logical function + resourceGroups := c.organizer.OrganizeByFunction() + + // Write each group to appropriate template files + for groupName, resources := range resourceGroups { + if len(resources) > 0 { + // De-duplicate exact resources by (apiVersion, kind, namespace, name) + deduped := dedupeResources(resources) + if err := c.writer.WriteResourceGroup(fs, groupName, deduped); err != nil { + return fmt.Errorf("failed to write %s resources: %w", groupName, err) + } + } + } + + return nil +} + +// dedupeResources removes exact duplicate resources by keying on +// apiVersion, kind, namespace (optional), and name. +func dedupeResources(resources []*unstructured.Unstructured) []*unstructured.Unstructured { + seen := make(map[string]struct{}) + out := make([]*unstructured.Unstructured, 0, len(resources)) + for _, r := range resources { + if r == nil { + continue + } + key := r.GetAPIVersion() + "|" + r.GetKind() + "|" + r.GetNamespace() + "|" + r.GetName() + if _, exists := seen[key]; exists { + continue + } + seen[key] = struct{}{} + out = append(out, r) + } + return out +} + +// ExtractDeploymentConfig extracts configuration values from the deployment for values.yaml +func (c *ChartConverter) ExtractDeploymentConfig() map[string]interface{} { + if c.resources.Deployment == nil { + return make(map[string]interface{}) + } + + config := make(map[string]interface{}) + + // Extract from deployment spec + spec, found, err := unstructured.NestedFieldNoCopy(c.resources.Deployment.Object, "spec", "template", "spec") + if !found || err != nil { + return config + } + + specMap, ok := spec.(map[string]interface{}) + if !ok { + return config + } + + // Extract pod security context + if podSecurityContext, podSecFound, podSecErr := unstructured.NestedFieldNoCopy(specMap, + "securityContext"); podSecFound && podSecErr == nil { + if podSecMap, podSecOk := podSecurityContext.(map[string]interface{}); podSecOk && len(podSecMap) > 0 { + config["podSecurityContext"] = podSecurityContext + } + } + + // Extract container configuration + containers, found, err := unstructured.NestedFieldNoCopy(specMap, "containers") + if !found || err != nil { + return config + } + + containersList, ok := containers.([]interface{}) + if !ok || len(containersList) == 0 { + return config + } + + // Use the first container (manager container) + firstContainer, ok := containersList[0].(map[string]interface{}) + if !ok { + return config + } + + // Extract environment variables + if env, envFound, envErr := unstructured.NestedFieldNoCopy(firstContainer, "env"); envFound && envErr == nil { + if envList, envOk := env.([]interface{}); envOk && len(envList) > 0 { + config["env"] = envList + } + } + + // Extract resources + if resources, resFound, resErr := unstructured.NestedFieldNoCopy(firstContainer, + "resources"); resFound && resErr == nil { + if resourcesMap, resOk := resources.(map[string]interface{}); resOk && len(resourcesMap) > 0 { + config["resources"] = resources + } + } + + // Extract container security context + if securityContext, secFound, secErr := unstructured.NestedFieldNoCopy(firstContainer, + "securityContext"); secFound && secErr == nil { + if secMap, secOk := securityContext.(map[string]interface{}); secOk && len(secMap) > 0 { + config["securityContext"] = securityContext + } + } + + return config +} diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/chart_converter_test.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/chart_converter_test.go new file mode 100644 index 00000000000..ca889be0cd0 --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/chart_converter_test.go @@ -0,0 +1,168 @@ +/* +Copyright 2025 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 kustomize + +import ( + "path/filepath" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/spf13/afero" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ = Describe("ChartConverter", func() { + var ( + converter *ChartConverter + resources *ParsedResources + fs machinery.Filesystem + ) + + BeforeEach(func() { + // Create test resources + resources = &ParsedResources{} + + // Add a test deployment + deployment := &unstructured.Unstructured{} + deployment.SetAPIVersion("apps/v1") + deployment.SetKind("Deployment") + deployment.SetName("test-controller") + deployment.SetNamespace("test-system") + + // Set deployment spec + err := unstructured.SetNestedField(deployment.Object, int64(1), "spec", "replicas") + Expect(err).NotTo(HaveOccurred()) + + resources.Deployment = deployment + + // Create filesystem + fs = machinery.Filesystem{FS: afero.NewMemMapFs()} + + // Create converter + converter = NewChartConverter(resources, "test-project", "dist") + }) + + Context("NewChartConverter", func() { + It("should create a converter with correct properties", func() { + Expect(converter.resources).To(Equal(resources)) + Expect(converter.projectName).To(Equal("test-project")) + Expect(converter.outputDir).To(Equal("dist")) + }) + }) + + Context("WriteChartFiles", func() { + It("should write chart files to filesystem", func() { + // Add some resources to test with + serviceAccount := &unstructured.Unstructured{} + serviceAccount.SetAPIVersion("v1") + serviceAccount.SetKind("ServiceAccount") + serviceAccount.SetName("test-sa") + serviceAccount.SetNamespace("test-system") + resources.ServiceAccount = serviceAccount + + // Add RBAC resources to test rbac directory creation + clusterRole := &unstructured.Unstructured{} + clusterRole.SetAPIVersion("rbac.authorization.k8s.io/v1") + clusterRole.SetKind("ClusterRole") + clusterRole.SetName("test-role") + resources.ClusterRoles = []*unstructured.Unstructured{clusterRole} + + err := converter.WriteChartFiles(fs) + Expect(err).NotTo(HaveOccurred()) + + exists, err := afero.Exists(fs.FS, "dist/chart/templates/manager") + Expect(err).NotTo(HaveOccurred()) + Expect(exists).To(BeTrue()) + + exists, err = afero.Exists(fs.FS, "dist/chart/templates/rbac") + Expect(err).NotTo(HaveOccurred()) + Expect(exists).To(BeTrue()) + }) + + It("should deduplicate identical resources within a group", func() { + // Prepare two identical Services in the metrics group + metricsSvc1 := &unstructured.Unstructured{} + metricsSvc1.SetAPIVersion("v1") + metricsSvc1.SetKind("Service") + metricsSvc1.SetName("test-project-controller-manager-metrics-service") + metricsSvc1.SetNamespace("test-system") + + metricsSvc2 := &unstructured.Unstructured{} + metricsSvc2.SetAPIVersion("v1") + metricsSvc2.SetKind("Service") + metricsSvc2.SetName("test-project-controller-manager-metrics-service") + metricsSvc2.SetNamespace("test-system") + + // Add both to resources; organizer will place them into the metrics group + resources.Services = append(resources.Services, metricsSvc1, metricsSvc2) + + // Write chart files + err := converter.WriteChartFiles(fs) + Expect(err).NotTo(HaveOccurred()) + + // Expect only one file to be written for the metrics service after de-duplication + metricsDir := filepath.Join("dist", "chart", "templates", "metrics") + files, err := afero.ReadDir(fs.FS, metricsDir) + Expect(err).NotTo(HaveOccurred()) + Expect(files).To(HaveLen(1), "expected only one metrics service file after deduplication") + }) + }) + + Context("ExtractDeploymentConfig", func() { + It("should extract deployment configuration correctly", func() { + // Set up deployment with environment variables + containers := []interface{}{ + map[string]interface{}{ + "name": "manager", + "image": "controller:latest", + "env": []interface{}{ + map[string]interface{}{ + "name": "TEST_ENV", + "value": "test-value", + }, + }, + "resources": map[string]interface{}{ + "limits": map[string]interface{}{ + "cpu": "100m", + "memory": "128Mi", + }, + }, + }, + } + + err := unstructured.SetNestedSlice( + resources.Deployment.Object, + containers, + "spec", "template", "spec", "containers", + ) + Expect(err).NotTo(HaveOccurred()) + + config := converter.ExtractDeploymentConfig() + + Expect(config).NotTo(BeNil()) + Expect(config).To(HaveKey("env")) + Expect(config).To(HaveKey("resources")) + }) + + It("should handle deployment without containers", func() { + config := converter.ExtractDeploymentConfig() + Expect(config).To(BeEmpty()) + }) + }) +}) diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/chart_writer.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/chart_writer.go new file mode 100644 index 00000000000..6ed109e9da9 --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/chart_writer.go @@ -0,0 +1,190 @@ +/* +Copyright 2025 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 kustomize + +import ( + "bytes" + "fmt" + "path/filepath" + "strings" + + "github.com/spf13/afero" + "gopkg.in/yaml.v3" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +// ChartWriter handles writing Helm chart template files +type ChartWriter struct { + templater *HelmTemplater + outputDir string +} + +// NewChartWriter creates a new chart writer +func NewChartWriter(templater *HelmTemplater, outputDir string) *ChartWriter { + return &ChartWriter{ + templater: templater, + outputDir: outputDir, + } +} + +// WriteResourceGroup writes a group of resources to a Helm template file +func (w *ChartWriter) WriteResourceGroup(fs machinery.Filesystem, groupName string, + resources []*unstructured.Unstructured, +) error { + // Special handling for namespace - write as single file + if groupName == "namespace" { + return w.writeNamespaceFile(fs, resources[0]) + } + + // For CRDs, certificates, and other resources that should be split, write individual files + if w.shouldSplitFiles(groupName) { + return w.writeSplitFiles(fs, groupName, resources) + } + + // For other groups, write as directory-based template files + return w.writeGroupDirectory(fs, groupName, resources) +} + +// writeNamespaceFile writes the namespace as a single file in templates/ +func (w *ChartWriter) writeNamespaceFile(fs machinery.Filesystem, namespace *unstructured.Unstructured) error { + // Apply Helm templating + yamlContent := w.convertToYAML(namespace) + yamlContent = w.templater.ApplyHelmSubstitutions(yamlContent, namespace) + + // Write to templates/namespace.yaml + filePath := filepath.Join(w.outputDir, "chart", "templates", "namespace.yaml") + return w.writeFileWithNewline(fs, filePath, yamlContent) +} + +// writeGroupDirectory writes resources as files in a group-specific directory +func (w *ChartWriter) writeGroupDirectory(fs machinery.Filesystem, groupName string, + resources []*unstructured.Unstructured, +) error { + var finalContent bytes.Buffer + + // Convert each resource to YAML and apply templating + for i, resource := range resources { + if i > 0 { + finalContent.WriteString("---\n") + } + + yamlContent := w.convertToYAML(resource) + yamlContent = w.templater.ApplyHelmSubstitutions(yamlContent, resource) + finalContent.WriteString(yamlContent) + } + + // Write to templates/{groupName}/{groupName}.yaml + dirPath := filepath.Join(w.outputDir, "chart", "templates", groupName) + filePath := filepath.Join(dirPath, groupName+".yaml") + + return w.writeFileWithNewline(fs, filePath, finalContent.String()) +} + +// convertToYAML converts an unstructured object to YAML string +func (w *ChartWriter) convertToYAML(resource *unstructured.Unstructured) string { + yamlBytes, err := yaml.Marshal(resource.Object) + if err != nil { + return fmt.Sprintf("# Error converting to YAML: %v\n", err) + } + return string(yamlBytes) +} + +// shouldSplitFiles determines if resources in a group should be written as individual files +func (w *ChartWriter) shouldSplitFiles(groupName string) bool { + return groupName == "crd" || groupName == "cert-manager" || groupName == "webhook" || + groupName == "prometheus" || groupName == "rbac" || groupName == "metrics" +} + +// writeSplitFiles writes each resource in the group to its own file +func (w *ChartWriter) writeSplitFiles(fs machinery.Filesystem, groupName string, + resources []*unstructured.Unstructured, +) error { + // Create the group directory + groupDir := filepath.Join(w.outputDir, "chart", "templates", groupName) + if err := fs.FS.MkdirAll(groupDir, 0o755); err != nil { + return fmt.Errorf("creating group directory %s: %w", groupDir, err) + } + + // Write each resource to its own file + for i, resource := range resources { + fileName := w.generateFileName(resource, i) + filePath := filepath.Join(groupDir, fileName) + + yamlContent := w.convertToYAML(resource) + yamlContent = w.templater.ApplyHelmSubstitutions(yamlContent, resource) + + if err := w.writeFileWithNewline(fs, filePath, yamlContent); err != nil { + return fmt.Errorf("writing resource file %s: %w", filePath, err) + } + } + + return nil +} + +// generateFileName creates a unique filename for a resource based on its metadata +func (w *ChartWriter) generateFileName(resource *unstructured.Unstructured, index int) string { + // Try to use the resource name if available + if name := resource.GetName(); name != "" { + // Remove project prefix from the filename for cleaner file names + projectPrefix := w.templater.projectName + "-" + fileName := name + if strings.HasPrefix(name, projectPrefix) { + fileName = strings.TrimPrefix(name, projectPrefix) + } + + // Handle special cases where filename might be empty after prefix removal + if fileName == "" { + fileName = resource.GetKind() + if fileName == "" { + fileName = "resource" + } + } + + // Replace dots and other special characters with underscores for filename safety + fileName = filepath.Base(fileName) // Remove any path separators + return fmt.Sprintf("%s.yaml", fileName) + } + + // Fall back to kind + index if no name + kind := resource.GetKind() + if kind == "" { + kind = "resource" + } + return fmt.Sprintf("%s-%d.yaml", kind, index) +} + +// writeFileWithNewline ensures the file ends with a newline +func (w *ChartWriter) writeFileWithNewline(fs machinery.Filesystem, filePath, content string) error { + // Ensure content ends with newline + if content != "" && content[len(content)-1] != '\n' { + content += "\n" + } + + // Create directory if it doesn't exist + dir := filepath.Dir(filePath) + if err := fs.FS.MkdirAll(dir, 0o755); err != nil { + return fmt.Errorf("creating directory %s: %w", dir, err) + } + + // Use afero to write directly through the filesystem + if err := afero.WriteFile(fs.FS, filePath, []byte(content), 0o644); err != nil { + return fmt.Errorf("writing file %s: %w", filePath, err) + } + return nil +} diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/helm_templater.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/helm_templater.go new file mode 100644 index 00000000000..d32ce64523b --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/helm_templater.go @@ -0,0 +1,594 @@ +/* +Copyright 2025 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 kustomize + +import ( + "fmt" + "regexp" + "strings" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +const ( + kindNamespace = "Namespace" + kindCertificate = "Certificate" + kindService = "Service" + kindServiceAccount = "ServiceAccount" + kindRole = "Role" + kindClusterRole = "ClusterRole" + kindRoleBinding = "RoleBinding" + kindClusterRoleBinding = "ClusterRoleBinding" + kindServiceMonitor = "ServiceMonitor" + kindIssuer = "Issuer" + kindValidatingWebhook = "ValidatingWebhookConfiguration" + kindMutatingWebhook = "MutatingWebhookConfiguration" + + // API versions + apiVersionCertManager = "cert-manager.io/v1" + apiVersionMonitoring = "monitoring.coreos.com/v1" + + chartNameTemplate = "chart.name" +) + +// HelmTemplater handles converting YAML content to Helm templates +type HelmTemplater struct { + projectName string +} + +// NewHelmTemplater creates a new Helm templater +func NewHelmTemplater(projectName string) *HelmTemplater { + return &HelmTemplater{ + projectName: projectName, + } +} + +// ApplyHelmSubstitutions converts YAML content to use Helm template syntax +func (t *HelmTemplater) ApplyHelmSubstitutions(yamlContent string, resource *unstructured.Unstructured) string { + // Apply conditional wrappers first + yamlContent = t.addConditionalWrappers(yamlContent, resource) + + // Apply general project name substitutions + yamlContent = t.substituteProjectNames(yamlContent, resource) + + // Apply namespace substitutions + yamlContent = t.substituteNamespace(yamlContent, resource) + + // Template ServiceMonitor metadata.name to be chart.name-scoped for consistency + yamlContent = t.templateServiceMonitorNames(yamlContent, resource) + + // Apply cert-manager and webhook-specific templating AFTER other substitutions + yamlContent = t.substituteCertManagerReferences(yamlContent, resource) + + // Apply labels and annotations from Helm chart + yamlContent = t.addHelmLabelsAndAnnotations(yamlContent, resource) + + // Apply resource-specific substitutions + yamlContent = t.substituteRBACValues(yamlContent) + + // Apply deployment-specific templating + if resource.GetKind() == "Deployment" { + yamlContent = t.templateDeploymentFields(yamlContent) + + // Apply conditional logic for cert-manager related fields in deployments + yamlContent = t.makeContainerArgsConditional(yamlContent) + yamlContent = t.makeWebhookVolumeMountsConditional(yamlContent) + yamlContent = t.makeWebhookVolumesConditional(yamlContent) + yamlContent = t.makeMetricsVolumeMountsConditional(yamlContent) + yamlContent = t.makeMetricsVolumesConditional(yamlContent) + } + + // Final tidy-up: avoid accidental blank lines after Helm if-block starts + // Some replacements may introduce an empty line between a `{{- if ... }}` + // and the following content; collapse that to ensure consistent formatting. + yamlContent = t.collapseBlankLineAfterIf(yamlContent) + + return yamlContent +} + +// substituteProjectNames keeps original YAML as much as possible - only add Helm templating +func (t *HelmTemplater) substituteProjectNames(yamlContent string, _ *unstructured.Unstructured) string { + return yamlContent +} + +// substituteNamespace replaces hardcoded namespace references with Release.Namespace +func (t *HelmTemplater) substituteNamespace(yamlContent string, resource *unstructured.Unstructured) string { + hardcodedNamespace := t.projectName + "-system" + namespaceTemplate := "{{ .Release.Namespace }}" + + // Replace hardcoded namespace references everywhere, including in the Namespace resource + // so that metadata.name becomes the Helm release namespace. + yamlContent = strings.ReplaceAll(yamlContent, hardcodedNamespace, namespaceTemplate) + + // Replace service DNS name placeholders in certificates + if resource.GetKind() == kindCertificate { + yamlContent = t.substituteCertificateDNSNames(yamlContent, resource) + } + + return yamlContent +} + +// substituteCertificateDNSNames replaces hardcoded DNS names in certificates with proper service templates +func (t *HelmTemplater) substituteCertificateDNSNames(yamlContent string, resource *unstructured.Unstructured) string { + name := resource.GetName() + + // Replace service names with templated ones based on certificate type + if strings.Contains(name, "metrics-cert") || strings.Contains(name, "metrics") { + // Metrics certificates should point to metrics service + // Use chart.name based service naming for consistency + metricsServiceTemplate := "{{ include \"chart.serviceName\" " + + "(dict \"suffix\" \"controller-manager-metrics-service\" \"context\" .) }}" + metricsServiceFQDN := metricsServiceTemplate + ".{{ include \"chart.namespaceName\" . }}.svc" + metricsServiceFQDNCluster := metricsServiceTemplate + + ".{{ include \"chart.namespaceName\" . }}.svc.cluster.local" + + // Replace placeholders + yamlContent = strings.ReplaceAll(yamlContent, "SERVICE_NAME.SERVICE_NAMESPACE.svc", metricsServiceFQDN) + yamlContent = strings.ReplaceAll(yamlContent, + "SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local", metricsServiceFQDNCluster) + + // Also replace hardcoded service names + hardcodedMetricsService := t.projectName + "-controller-manager-metrics-service" + yamlContent = strings.ReplaceAll(yamlContent, hardcodedMetricsService, metricsServiceTemplate) + } + + // Replace hardcoded issuer reference with templated one + hardcodedIssuer := t.projectName + "-selfsigned-issuer" + templatedIssuer := "{{ include \"" + chartNameTemplate + "\" . }}-selfsigned-issuer" + yamlContent = strings.ReplaceAll(yamlContent, hardcodedIssuer, templatedIssuer) + + return yamlContent +} + +// substituteCertManagerReferences applies cert-manager and webhook-specific template substitutions +func (t *HelmTemplater) substituteCertManagerReferences(yamlContent string, _ *unstructured.Unstructured) string { + return yamlContent +} + +// templateServiceNames ensures Service metadata.name uses Helm helpers for release-scoped naming. +// It converts hardcoded names like "-webhook-service" or +// "-controller-manager-metrics-service" to: +// +// name: {{ include "chart.serviceName" (dict "suffix" "" "context" .) }} +// NOTE: Service names are intentionally left as project-scoped (no release prefix) +// to match existing samples and e2e tests that refer to fixed service names. + +// templateServiceMonitorNames ensures ServiceMonitor metadata.name uses chart.name-based naming for consistency +// with existing tests and samples. It converts names like "controller-manager-metrics-monitor" or +// "-controller-manager-metrics-monitor" to: +// +// name: {{ include "chart.name" . }}-controller-manager-metrics-monitor +func (t *HelmTemplater) templateServiceMonitorNames(yamlContent string, resource *unstructured.Unstructured) string { + if resource.GetKind() != kindServiceMonitor { + return yamlContent + } + + origName := resource.GetName() + if origName == "" { + return yamlContent + } + + // Normalize suffix by stripping the project prefix if present + suffix := origName + prefix := t.projectName + "-" + if strings.HasPrefix(origName, prefix) { + suffix = strings.TrimPrefix(origName, prefix) + } + + // Only template if the intended target follows the conventional suffix + // This keeps any custom user-provided names intact + // For default scaffolding, suffix is typically "controller-manager-metrics-monitor" + templated := "{{ include \"chart.name\" . }}-" + suffix + + nameRe := regexp.MustCompile("(?m)^([\t ]*)name:\\s*" + regexp.QuoteMeta(origName) + "\\s*$") + yamlContent = nameRe.ReplaceAllString(yamlContent, "${1}name: "+templated) + + return yamlContent +} + +// addHelmLabelsAndAnnotations replaces kustomize managed-by labels with Helm equivalents +func (t *HelmTemplater) addHelmLabelsAndAnnotations(yamlContent string, _ *unstructured.Unstructured) string { + // Replace app.kubernetes.io/managed-by: kustomize with Helm template + // Use regex to handle different whitespace patterns + managedByRegex := regexp.MustCompile(`(\s*)app\.kubernetes\.io/managed-by:\s+kustomize`) + yamlContent = managedByRegex.ReplaceAllString(yamlContent, "${1}app.kubernetes.io/managed-by: {{ .Release.Service }}") + + return yamlContent +} + +// substituteRBACValues applies RBAC-specific template substitutions +func (t *HelmTemplater) substituteRBACValues(yamlContent string) string { + return yamlContent +} + +// templateDeploymentFields converts deployment-specific fields to Helm templates +func (t *HelmTemplater) templateDeploymentFields(yamlContent string) string { + // Template configuration fields + yamlContent = t.templateImageReference(yamlContent) + yamlContent = t.templateEnvironmentVariables(yamlContent) + yamlContent = t.templateResources(yamlContent) + yamlContent = t.templateSecurityContexts(yamlContent) + yamlContent = t.templateVolumeMounts(yamlContent) + yamlContent = t.templateVolumes(yamlContent) + + return yamlContent +} + +// templateEnvironmentVariables preserves environment variables from kustomize output +func (t *HelmTemplater) templateEnvironmentVariables(yamlContent string) string { + // Environment variables are preserved as-is from the kustomize output to maintain + // the exact configuration generated by the project's customizations + return yamlContent +} + +// templateResources converts resource sections to Helm templates +func (t *HelmTemplater) templateResources(yamlContent string) string { + // This ensures that volumeMounts, volumes, and other fields are preserved + // The resources will remain as-is from the kustomize output and can be templated later + return yamlContent +} + +// templateSecurityContexts preserves security contexts from kustomize output +func (t *HelmTemplater) templateSecurityContexts(yamlContent string) string { + // Security contexts are preserved as-is from the kustomize output to maintain + // the exact security configuration without interfering with other container fields + return yamlContent +} + +// templateVolumeMounts converts volumeMounts sections to keep them as-is since they're webhook-specific +func (t *HelmTemplater) templateVolumeMounts(yamlContent string) string { + // For webhook volumeMounts, we keep them as-is since they're required for webhook functionality + // They will be conditionally included based on webhook configuration + return yamlContent +} + +// templateVolumes converts volumes sections to keep them as-is since they're webhook-specific +func (t *HelmTemplater) templateVolumes(yamlContent string) string { + // For webhook volumes, we keep them as-is since they're required for webhook functionality + // They will be conditionally included based on webhook configuration + return yamlContent +} + +// templateImageReference converts hardcoded image references to Helm templates +func (t *HelmTemplater) templateImageReference(yamlContent string) string { + // Replace hardcoded controller image with Helm template + // This handles the common case where kustomize outputs "controller:latest" + // or other hardcoded image references + imagePattern := regexp.MustCompile(`(\s+)image:\s+controller:latest`) + yamlContent = imagePattern.ReplaceAllString(yamlContent, + `${1}image: "{{ .Values.controllerManager.image.repository }}:{{ .Values.controllerManager.image.tag }}"`) + + // Also handle any other common image patterns that might appear + imagePattern2 := regexp.MustCompile(`(\s+)image:\s+([^"'\s]+):(latest|[\w\.\-]+)`) + yamlContent = imagePattern2.ReplaceAllStringFunc(yamlContent, func(match string) string { + // Only replace if it looks like a controller image (contains "controller" or "manager") + if strings.Contains(match, "controller") || strings.Contains(match, "manager") { + indentMatch := regexp.MustCompile(`^(\s+)`) + indent := indentMatch.FindString(match) + return fmt.Sprintf( + `%simage: "{{ .Values.controllerManager.image.repository }}:{{ .Values.controllerManager.image.tag }}"`, indent) + } + return match + }) + + return yamlContent +} + +// makeWebhookAnnotationsConditional makes only cert-manager annotations conditional, not the entire webhook +func (t *HelmTemplater) makeWebhookAnnotationsConditional(yamlContent string) string { + // Find cert-manager.io/inject-ca-from annotation and make it conditional + if strings.Contains(yamlContent, "cert-manager.io/inject-ca-from") { + // Replace the cert-manager annotation with conditional wrapper + certManagerPattern := regexp.MustCompile(`(\s+)cert-manager\.io/inject-ca-from:\s*[^\n]+`) + yamlContent = certManagerPattern.ReplaceAllStringFunc(yamlContent, func(match string) string { + // Extract the indentation + indentMatch := regexp.MustCompile(`^(\s+)`).FindStringSubmatch(match) + indent := "" + if len(indentMatch) > 1 { + indent = indentMatch[1] + } + + // Extract the annotation line with proper indentation + annotationLine := strings.TrimSpace(match) + + return fmt.Sprintf("%s{{- if .Values.certManager.enable }}\n%s%s\n%s{{- end }}", + indent, indent, annotationLine, indent) + }) + } + + return yamlContent +} + +// makeContainerArgsConditional makes webhook-cert-path and metrics-cert-path args conditional on certManager.enable +func (t *HelmTemplater) makeContainerArgsConditional(yamlContent string) string { + // Make webhook-cert-path arg conditional on certManager.enable + if strings.Contains(yamlContent, "--webhook-cert-path") { + // Match only spaces/tabs for indent to avoid consuming the newline + webhookArgPattern := regexp.MustCompile(`([ \t]+)-\s*--webhook-cert-path=[^\n]*`) + yamlContent = webhookArgPattern.ReplaceAllStringFunc(yamlContent, func(match string) string { + indentMatch := regexp.MustCompile(`^(\s+)`).FindStringSubmatch(match) + indent := "" + if len(indentMatch) > 1 { + indent = indentMatch[1] + } + + argLine := strings.TrimSpace(match) + return fmt.Sprintf("%s{{- if .Values.certManager.enable }}\n%s%s\n%s{{- end }}", + indent, indent, argLine, indent) + }) + } + + // Make metrics-cert-path arg conditional on certManager.enable AND metrics.enable + if strings.Contains(yamlContent, "--metrics-cert-path") { + // Match only spaces/tabs for indent to avoid consuming the newline + metricsArgPattern := regexp.MustCompile(`([ \t]+)-\s*--metrics-cert-path=[^\n]*`) + yamlContent = metricsArgPattern.ReplaceAllStringFunc(yamlContent, func(match string) string { + indentMatch := regexp.MustCompile(`^(\s+)`).FindStringSubmatch(match) + indent := "" + if len(indentMatch) > 1 { + indent = indentMatch[1] + } + + argLine := strings.TrimSpace(match) + return fmt.Sprintf("%s{{- if and .Values.certManager.enable .Values.metrics.enable }}\n%s%s\n%s{{- end }}", + indent, indent, argLine, indent) + }) + } + + return yamlContent +} + +// makeWebhookVolumesConditional makes webhook volumes conditional on certManager.enable +func (t *HelmTemplater) makeWebhookVolumesConditional(yamlContent string) string { + // Make webhook volumes conditional on certManager.enable + if strings.Contains(yamlContent, "webhook-certs") && strings.Contains(yamlContent, "secretName: webhook-server-cert") { + // Match only spaces/tabs for indent to avoid consuming the newline + volumePattern := regexp.MustCompile(`([ \t]+)-\s*name:\s*webhook-certs[\s\S]*?secretName:\s*webhook-server-cert`) + yamlContent = volumePattern.ReplaceAllStringFunc(yamlContent, func(match string) string { + lines := strings.Split(match, "\n") + if len(lines) > 0 { + indent := "" + if len(lines[0]) > 0 && lines[0][0] == ' ' { + // Count leading spaces + for _, char := range lines[0] { + if char == ' ' { + indent += " " + } else { + break + } + } + } + + // Reconstruct the block with conditional wrapper + result := fmt.Sprintf("%s{{- if .Values.certManager.enable }}\n", indent) + for _, line := range lines { + result += line + "\n" + } + result += fmt.Sprintf("%s{{- end }}", indent) + return result + } + return match + }) + } + + return yamlContent +} + +// makeWebhookVolumeMountsConditional makes webhook volumeMounts conditional on certManager.enable +func (t *HelmTemplater) makeWebhookVolumeMountsConditional(yamlContent string) string { + // Make webhook volumeMounts conditional on certManager.enable + webhookCertsPath := "/tmp/k8s-webhook-server/serving-certs" + if strings.Contains(yamlContent, "webhook-certs") && strings.Contains(yamlContent, webhookCertsPath) { + // Match only spaces/tabs for indent to avoid consuming the newline + mountPattern := regexp.MustCompile( + `([ \t]+)-\s*mountPath:\s*/tmp/k8s-webhook-server/serving-certs[\s\S]*?readOnly:\s*true`) + yamlContent = mountPattern.ReplaceAllStringFunc(yamlContent, func(match string) string { + lines := strings.Split(match, "\n") + if len(lines) > 0 { + indent := "" + if len(lines[0]) > 0 && lines[0][0] == ' ' { + // Count leading spaces + for _, char := range lines[0] { + if char == ' ' { + indent += " " + } else { + break + } + } + } + + // Reconstruct the block with conditional wrapper + result := fmt.Sprintf("%s{{- if .Values.certManager.enable }}\n", indent) + for _, line := range lines { + result += line + "\n" + } + result += fmt.Sprintf("%s{{- end }}", indent) + return result + } + return match + }) + } + + return yamlContent +} + +// makeMetricsVolumesConditional makes metrics volumes conditional on certManager.enable AND metrics.enable +func (t *HelmTemplater) makeMetricsVolumesConditional(yamlContent string) string { + // Make metrics volumes conditional on certManager.enable AND metrics.enable + if strings.Contains(yamlContent, "metrics-certs") && strings.Contains(yamlContent, "secretName: metrics-server-cert") { + // Match only spaces/tabs for indent to avoid consuming the newline + volumePattern := regexp.MustCompile(`([ \t]+)-\s*name:\s*metrics-certs[\s\S]*?secretName:\s*metrics-server-cert`) + yamlContent = volumePattern.ReplaceAllStringFunc(yamlContent, func(match string) string { + lines := strings.Split(match, "\n") + if len(lines) > 0 { + indent := "" + if len(lines[0]) > 0 && lines[0][0] == ' ' { + // Count leading spaces + for _, char := range lines[0] { + if char == ' ' { + indent += " " + } else { + break + } + } + } + + // Reconstruct the block with conditional wrapper + result := fmt.Sprintf("%s{{- if and .Values.certManager.enable .Values.metrics.enable }}\n", indent) + for _, line := range lines { + result += line + "\n" + } + result += fmt.Sprintf("%s{{- end }}", indent) + return result + } + return match + }) + } + + return yamlContent +} + +// injectCommonLabels adds a Helm template snippet to append user-provided common labels +// (.Values.commonLabels) to every metadata.labels block while preserving indentation. +// It avoids duplicate insertion by checking for an existing snippet nearby. +// no common labels injection; labels come from kustomize manifests + +// makeMetricsVolumeMountsConditional makes metrics volumeMounts conditional on certManager.enable AND metrics.enable +func (t *HelmTemplater) makeMetricsVolumeMountsConditional(yamlContent string) string { + // Make metrics volumeMounts conditional on certManager.enable AND metrics.enable + metricsCertsPath := "/tmp/k8s-metrics-server/metrics-certs" + if strings.Contains(yamlContent, "metrics-certs") && strings.Contains(yamlContent, metricsCertsPath) { + // Match only spaces/tabs for indent to avoid consuming the newline + mountPattern := regexp.MustCompile( + `([ \t]+)-\s*mountPath:\s*/tmp/k8s-metrics-server/metrics-certs[\s\S]*?readOnly:\s*true`) + yamlContent = mountPattern.ReplaceAllStringFunc(yamlContent, func(match string) string { + lines := strings.Split(match, "\n") + if len(lines) > 0 { + indent := "" + if len(lines[0]) > 0 && lines[0][0] == ' ' { + // Count leading spaces + for _, char := range lines[0] { + if char == ' ' { + indent += " " + } else { + break + } + } + } + + // Reconstruct the block with conditional wrapper + result := fmt.Sprintf("%s{{- if and .Values.certManager.enable .Values.metrics.enable }}\n", indent) + for _, line := range lines { + result += line + "\n" + } + result += fmt.Sprintf("%s{{- end }}", indent) + return result + } + return match + }) + } + + return yamlContent +} + +// addConditionalWrappers adds conditional Helm logic based on resource type +func (t *HelmTemplater) addConditionalWrappers(yamlContent string, resource *unstructured.Unstructured) string { + kind := resource.GetKind() + apiVersion := resource.GetAPIVersion() + name := resource.GetName() + + switch { + case kind == kindNamespace: + return "" + case kind == "CustomResourceDefinition": + // CRDs need crd.enable condition + return fmt.Sprintf("{{- if .Values.crd.enable }}\n%s{{- end }}\n", yamlContent) + case kind == kindCertificate && apiVersion == apiVersionCertManager: + // Handle different certificate types + if strings.Contains(name, "metrics-cert") || strings.Contains(name, "metrics") { + // Metrics certificates need both certManager and metrics enabled + return fmt.Sprintf("{{- if and .Values.certManager.enable .Values.metrics.enable }}\n%s{{- end }}\n", + yamlContent) + } + // Other certificates (webhook serving certs) only need certManager enabled + return fmt.Sprintf("{{- if .Values.certManager.enable }}\n%s{{- end }}", yamlContent) + case kind == kindIssuer && apiVersion == apiVersionCertManager: + // All cert-manager issuers need certManager enabled + return fmt.Sprintf("{{- if .Values.certManager.enable }}\n%s{{- end }}", yamlContent) + case kind == kindServiceMonitor && apiVersion == apiVersionMonitoring: + // ServiceMonitors need prometheus enabled + return fmt.Sprintf("{{- if .Values.prometheus.enable }}\n%s{{- end }}", yamlContent) + case kind == kindServiceAccount || kind == kindRole || kind == kindClusterRole || + kind == kindRoleBinding || kind == kindClusterRoleBinding: + // Distinguish between essential RBAC and helper RBAC + if strings.Contains(name, "admin-role") || strings.Contains(name, "editor-role") || + strings.Contains(name, "viewer-role") { + // Helper RBAC roles (admin/editor/viewer) - convenience roles for CRD management + return fmt.Sprintf("{{- if .Values.rbacHelpers.enable }}\n%s{{- end }}\n", yamlContent) + } + if strings.Contains(name, "metrics") { + // Metrics RBAC depends on metrics being enabled + return fmt.Sprintf("{{- if .Values.metrics.enable }}\n%s{{- end }}\n", yamlContent) + } + // Essential RBAC (controller-manager, leader-election, manager roles) - always enabled + // These are required for the controller to function properly + return yamlContent + case kind == kindValidatingWebhook || kind == kindMutatingWebhook: + // Webhook configurations should always exist if project has webhooks + // Only the cert-manager annotations should be conditional + return t.makeWebhookAnnotationsConditional(yamlContent) + case kind == kindService: + // Services need conditional logic based on their purpose + if strings.Contains(name, "metrics") { + // Metrics services need metrics enabled + return fmt.Sprintf("{{- if .Values.metrics.enable }}\n%s{{- end }}\n", yamlContent) + } + // Other services (webhook service, etc.) don't need conditionals - they're essential + return yamlContent + default: + // No conditional wrapper needed for other resources (Deployment, Namespace) + return yamlContent + } +} + +// collapseBlankLineAfterIf removes a single empty line that may appear +// immediately after a Helm if directive line, e.g. `{{- if ... }}`. +// This keeps templates compact and matches expected formatting in tests. +func (t *HelmTemplater) collapseBlankLineAfterIf(yamlContent string) string { + lines := strings.Split(yamlContent, "\n") + if len(lines) == 0 { + return yamlContent + } + out := make([]string, 0, len(lines)) + for i := 0; i < len(lines); i++ { + line := lines[i] + // If current line is an if, and next line is blank, skip the blank + if strings.Contains(line, "{{- if ") { + out = append(out, line) + if i+1 < len(lines) && strings.TrimSpace(lines[i+1]) == "" { + i++ // skip one blank line after if + } + continue + } + // If current line is blank, and next line is an end, skip the blank + if strings.TrimSpace(line) == "" && i+1 < len(lines) && strings.Contains(lines[i+1], "{{- end }}") { + continue + } + out = append(out, line) + } + return strings.Join(out, "\n") +} diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/helm_templater_test.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/helm_templater_test.go new file mode 100644 index 00000000000..ca66eb15682 --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/helm_templater_test.go @@ -0,0 +1,431 @@ +/* +Copyright 2025 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 kustomize + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +var _ = Describe("HelmTemplater", func() { + var templater *HelmTemplater + + BeforeEach(func() { + templater = &HelmTemplater{ + projectName: "test-project", + } + }) + + // No global labels injection is performed by v2-alpha + + Context("basic template processing", func() { + It("should replace kustomize managed-by labels with Helm equivalents", func() { + deploymentResource := &unstructured.Unstructured{} + deploymentResource.SetAPIVersion("apps/v1") + deploymentResource.SetKind("Deployment") + deploymentResource.SetName("test-project-controller-manager") + + content := `apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/name: test-project + control-plane: controller-manager + name: test-project-controller-manager + namespace: test-project-system +spec: + template: + metadata: + labels: + control-plane: controller-manager` + + result := templater.ApplyHelmSubstitutions(content, deploymentResource) + + // Should replace kustomize managed-by with Helm template + Expect(result).To(ContainSubstring("app.kubernetes.io/managed-by: {{ .Release.Service }}")) + Expect(result).To(ContainSubstring("app.kubernetes.io/name: test-project")) + Expect(result).To(ContainSubstring("control-plane: controller-manager")) + + // Should substitute namespace + Expect(result).To(ContainSubstring("namespace: {{ .Release.Namespace }}")) + + // Should NOT add extra Helm metadata injection + Expect(result).NotTo(ContainSubstring(`{{- include "chart.labels"`)) + Expect(result).NotTo(ContainSubstring(`{{- include "chart.annotations"`)) + }) + + It("should handle cert-manager annotations with proper indentation", func() { + resource := &unstructured.Unstructured{} + resource.SetAPIVersion("admissionregistration.k8s.io/v1") + resource.SetKind("ValidatingWebhookConfiguration") + resource.SetName("test-project-validating-webhook-configuration") + + content := `apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: test-project-system/test-project-serving-cert + name: test-project-validating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1` + + result := templater.ApplyHelmSubstitutions(content, resource) + + // Should have proper conditional formatting without extra spaces + Expect(result).To(ContainSubstring("{{- if .Values.certManager.enable }}")) + Expect(result).To(ContainSubstring("cert-manager.io/inject-ca-from:")) + Expect(result).To(ContainSubstring("{{- end }}")) + + // Should NOT have extra blank lines or improper indentation + Expect(result).NotTo(ContainSubstring("{{- if .Values.certManager.enable }}\n\n")) + Expect(result).NotTo(ContainSubstring("cert-manager.io/inject-ca-from:\n\n")) + }) + + It("should handle container args with proper indentation", func() { + deploymentResource := &unstructured.Unstructured{} + deploymentResource.SetAPIVersion("apps/v1") + deploymentResource.SetKind("Deployment") + deploymentResource.SetName("test-project-controller-manager") + + content := `apiVersion: apps/v1 +kind: Deployment +spec: + template: + spec: + containers: + - args: + - --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs/tls.crt + - --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs/tls.crt + - --leader-elect + name: manager` + + result := templater.ApplyHelmSubstitutions(content, deploymentResource) + + // Should have proper conditional formatting for webhook cert path + Expect(result).To(ContainSubstring("{{- if .Values.certManager.enable }}")) + Expect(result).To(ContainSubstring("- --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs/tls.crt")) + + // Should have proper conditional formatting for metrics cert path + Expect(result).To(ContainSubstring("{{- if and .Values.certManager.enable .Values.metrics.enable }}")) + Expect(result).To(ContainSubstring("- --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs/tls.crt")) + + // Should NOT have extra blank lines + Expect(result).NotTo(ContainSubstring("{{- if .Values.certManager.enable }}\n\n")) + }) + + It("should handle volume mounts with proper indentation", func() { + deploymentResource := &unstructured.Unstructured{} + deploymentResource.SetAPIVersion("apps/v1") + deploymentResource.SetKind("Deployment") + deploymentResource.SetName("test-project-controller-manager") + + content := `apiVersion: apps/v1 +kind: Deployment +spec: + template: + spec: + containers: + - volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: webhook-certs + readOnly: true + - mountPath: /tmp/k8s-metrics-server/metrics-certs + name: metrics-certs + readOnly: true` + + result := templater.ApplyHelmSubstitutions(content, deploymentResource) + + // Should have conditional blocks for webhook certs + Expect(result).To(ContainSubstring("{{- if .Values.certManager.enable }}")) + Expect(result).To(ContainSubstring("mountPath: /tmp/k8s-webhook-server/serving-certs")) + + // Should have conditional blocks for metrics certs + Expect(result).To(ContainSubstring("{{- if and .Values.certManager.enable .Values.metrics.enable }}")) + Expect(result).To(ContainSubstring("mountPath: /tmp/k8s-metrics-server/metrics-certs")) + }) + + It("should handle namespace substitution correctly", func() { + serviceResource := &unstructured.Unstructured{} + serviceResource.SetAPIVersion("v1") + serviceResource.SetKind("Service") + serviceResource.SetName("test-project-webhook-service") + + content := `apiVersion: v1 +kind: Service +metadata: + name: test-project-webhook-service + namespace: test-project-system +spec: + type: ClusterIP` + + result := templater.ApplyHelmSubstitutions(content, serviceResource) + + // Should substitute namespace with Helm template + Expect(result).To(ContainSubstring("namespace: {{ .Release.Namespace }}")) + Expect(result).NotTo(ContainSubstring("namespace: test-project-system")) + }) + + It("should preserve annotations without modification", func() { + webhookResource := &unstructured.Unstructured{} + webhookResource.SetAPIVersion("admissionregistration.k8s.io/v1") + webhookResource.SetKind("ValidatingWebhookConfiguration") + webhookResource.SetName("test-project-validating-webhook-configuration") + + content := `apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + cert-manager.io/inject-ca-from: test-system/test-serving-cert + name: test-project-validating-webhook-configuration` + + result := templater.ApplyHelmSubstitutions(content, webhookResource) + + // Should preserve existing kustomize annotations as-is + Expect(result).To(ContainSubstring("cert-manager.io/inject-ca-from")) + + // Should NOT add extra Helm metadata injection + Expect(result).NotTo(ContainSubstring(`{{- include "chart.labels"`)) + Expect(result).NotTo(ContainSubstring(`{{- include "chart.annotations"`)) + }) + }) + + Context("conditional wrapping", func() { + It("should add metrics conditional for ServiceMonitor resources", func() { + serviceMonitorResource := &unstructured.Unstructured{} + serviceMonitorResource.SetAPIVersion("monitoring.coreos.com/v1") + serviceMonitorResource.SetKind("ServiceMonitor") + serviceMonitorResource.SetName("test-project-controller-manager-metrics-monitor") + + content := `apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: test-project-controller-manager-metrics-monitor` + + result := templater.ApplyHelmSubstitutions(content, serviceMonitorResource) + + // Should be wrapped with prometheus enable conditional + Expect(result).To(ContainSubstring("{{- if .Values.prometheus.enable }}")) + Expect(result).To(ContainSubstring("{{- end }}")) + }) + + It("should add metrics conditional for metrics services", func() { + serviceResource := &unstructured.Unstructured{} + serviceResource.SetAPIVersion("v1") + serviceResource.SetKind("Service") + serviceResource.SetName("test-project-controller-manager-metrics-service") + + content := `apiVersion: v1 +kind: Service +metadata: + name: test-project-controller-manager-metrics-service` + + result := templater.ApplyHelmSubstitutions(content, serviceResource) + + // Should be wrapped with metrics enable conditional + Expect(result).To(ContainSubstring("{{- if .Values.metrics.enable }}")) + Expect(result).To(ContainSubstring("{{- end }}")) + }) + + It("should add cert-manager conditional for Certificate resources", func() { + certResource := &unstructured.Unstructured{} + certResource.SetAPIVersion("cert-manager.io/v1") + certResource.SetKind("Certificate") + certResource.SetName("test-project-serving-cert") + + content := `apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: test-project-serving-cert` + + result := templater.ApplyHelmSubstitutions(content, certResource) + + // Should be wrapped with certManager enable conditional + Expect(result).To(ContainSubstring("{{- if .Values.certManager.enable }}")) + Expect(result).To(ContainSubstring("{{- end }}")) + }) + + It("should add combined conditionals for metrics certificates", func() { + certResource := &unstructured.Unstructured{} + certResource.SetAPIVersion("cert-manager.io/v1") + certResource.SetKind("Certificate") + certResource.SetName("test-project-metrics-certs") + + content := `apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: test-project-metrics-certs` + + result := templater.ApplyHelmSubstitutions(content, certResource) + + // Should be wrapped with both metrics and certManager conditionals + Expect(result).To(ContainSubstring("{{- if and .Values.certManager.enable .Values.metrics.enable }}")) + Expect(result).To(ContainSubstring("{{- end }}")) + }) + + It("should NOT add conditionals to essential resources", func() { + // Test essential RBAC + clusterRoleResource := &unstructured.Unstructured{} + clusterRoleResource.SetAPIVersion("rbac.authorization.k8s.io/v1") + clusterRoleResource.SetKind("ClusterRole") + clusterRoleResource.SetName("test-project-manager-role") + + content := `apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: test-project-manager-role` + + result := templater.ApplyHelmSubstitutions(content, clusterRoleResource) + + // Should NOT wrap essential RBAC with conditionals + Expect(result).NotTo(ContainSubstring("{{- if .Values")) + + // Test webhook service (also essential) + serviceResource := &unstructured.Unstructured{} + serviceResource.SetAPIVersion("v1") + serviceResource.SetKind("Service") + serviceResource.SetName("test-project-webhook-service") + + webhookContent := `apiVersion: v1 +kind: Service +metadata: + name: test-project-webhook-service` + + webhookResult := templater.ApplyHelmSubstitutions(webhookContent, serviceResource) + + // Should NOT wrap webhook service with conditionals (it's essential) + Expect(webhookResult).NotTo(ContainSubstring("{{- if .Values")) + }) + + It("should NOT add cert-manager conditionals to webhook configurations", func() { + mutatingWebhookResource := &unstructured.Unstructured{} + mutatingWebhookResource.SetAPIVersion("admissionregistration.k8s.io/v1") + mutatingWebhookResource.SetKind("MutatingWebhookConfiguration") + mutatingWebhookResource.SetName("test-project-mutating-webhook-configuration") + + content := `apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: test-project-mutating-webhook-configuration` + + result := templater.ApplyHelmSubstitutions(content, mutatingWebhookResource) + + // Webhook configurations should NOT be conditional on cert-manager + // (they're essential and cert-manager is optional) + Expect(result).NotTo(ContainSubstring("{{- if .Values.certManager.enable }}")) + }) + }) + + Context("helper RBAC wrapping", func() { + It("should add rbacHelpers conditional for helper RBAC roles", func() { + clusterRoleResource := &unstructured.Unstructured{} + clusterRoleResource.SetAPIVersion("rbac.authorization.k8s.io/v1") + clusterRoleResource.SetKind("ClusterRole") + clusterRoleResource.SetName("test-project-memcached-editor-role") + + content := `apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: test-project-memcached-editor-role` + + result := templater.ApplyHelmSubstitutions(content, clusterRoleResource) + + // Should be wrapped with rbacHelpers conditional + Expect(result).To(ContainSubstring("{{- if .Values.rbacHelpers.enable }}")) + Expect(result).To(ContainSubstring("{{- end }}")) + }) + + It("should add rbacHelpers conditional for helper ClusterRoleBindings", func() { + bindingResource := &unstructured.Unstructured{} + bindingResource.SetAPIVersion("rbac.authorization.k8s.io/v1") + bindingResource.SetKind("ClusterRoleBinding") + bindingResource.SetName("test-project-memcached-viewer-rolebinding") + + content := `apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: test-project-memcached-viewer-rolebinding` + + result := templater.ApplyHelmSubstitutions(content, bindingResource) + + // Should be wrapped with rbacHelpers conditional + Expect(result).To(ContainSubstring("{{- if .Values.rbacHelpers.enable }}")) + Expect(result).To(ContainSubstring("{{- end }}")) + }) + }) + + Context("project name handling", func() { + It("should preserve project names as-is (no templating)", func() { + serviceAccountResource := &unstructured.Unstructured{} + serviceAccountResource.SetAPIVersion("v1") + serviceAccountResource.SetKind("ServiceAccount") + serviceAccountResource.SetName("test-project-controller-manager") + + content := `apiVersion: v1 +kind: ServiceAccount +metadata: + name: test-project-controller-manager + namespace: test-project-system` + + result := templater.ApplyHelmSubstitutions(content, serviceAccountResource) + + // Should keep project name as-is for resource names + Expect(result).To(ContainSubstring("name: test-project-controller-manager")) + Expect(result).NotTo(ContainSubstring("{{ include")) + }) + }) + + Context("edge cases", func() { + It("should handle empty content", func() { + testResource := &unstructured.Unstructured{} + testResource.SetKind("ConfigMap") + + result := templater.ApplyHelmSubstitutions("", testResource) + Expect(result).To(BeEmpty()) + }) + + It("should handle resources without namespace", func() { + clusterRoleResource := &unstructured.Unstructured{} + clusterRoleResource.SetAPIVersion("rbac.authorization.k8s.io/v1") + clusterRoleResource.SetKind("ClusterRole") + clusterRoleResource.SetName("test-project-manager-role") + + content := `apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: test-project-manager-role` + + result := templater.ApplyHelmSubstitutions(content, clusterRoleResource) + + // Should not add namespace substitution for cluster-scoped resources + Expect(result).NotTo(ContainSubstring("namespace:")) + }) + + It("should handle malformed YAML gracefully", func() { + testResource := &unstructured.Unstructured{} + testResource.SetKind("ConfigMap") + + malformedContent := "not: valid: yaml: content:" + result := templater.ApplyHelmSubstitutions(malformedContent, testResource) + + // Should return content as-is for malformed YAML + Expect(result).To(Equal(malformedContent)) + }) + }) +}) diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/parser.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/parser.go new file mode 100644 index 00000000000..488ad64e007 --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/parser.go @@ -0,0 +1,153 @@ +/* +Copyright 2025 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 kustomize + +import ( + "fmt" + "io" + "os" + + "gopkg.in/yaml.v3" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +// ParsedResources holds Kubernetes resources organized by type for Helm chart generation +type ParsedResources struct { + // Core Kubernetes resources + Namespace *unstructured.Unstructured + Deployment *unstructured.Unstructured + Services []*unstructured.Unstructured + + // RBAC resources + ServiceAccount *unstructured.Unstructured + Roles []*unstructured.Unstructured + ClusterRoles []*unstructured.Unstructured + RoleBindings []*unstructured.Unstructured + ClusterRoleBindings []*unstructured.Unstructured + + // CRD and API resources + CustomResourceDefinitions []*unstructured.Unstructured + WebhookConfigurations []*unstructured.Unstructured + + // Cert-manager resources + Certificates []*unstructured.Unstructured + Issuer *unstructured.Unstructured + + // Monitoring resources + ServiceMonitors []*unstructured.Unstructured + + // Other resources not fitting above categories + Other []*unstructured.Unstructured +} + +// Parser parses kustomize output and extracts resources by type +type Parser struct { + filePath string +} + +// NewParser creates a new parser for the given kustomize output file +func NewParser(filePath string) *Parser { + return &Parser{filePath: filePath} +} + +// Parse reads and parses the kustomize output file into organized resource groups +func (p *Parser) Parse() (*ParsedResources, error) { + file, err := os.Open(p.filePath) + if err != nil { + return nil, fmt.Errorf("failed to open file %s: %w", p.filePath, err) + } + defer func() { + _ = file.Close() + }() + + return p.ParseFromReader(file) +} + +// ParseFromReader parses multi-document YAML from a reader and categorizes resources by type +func (p *Parser) ParseFromReader(reader io.Reader) (*ParsedResources, error) { + decoder := yaml.NewDecoder(reader) + resources := &ParsedResources{ + CustomResourceDefinitions: make([]*unstructured.Unstructured, 0), + Roles: make([]*unstructured.Unstructured, 0), + ClusterRoles: make([]*unstructured.Unstructured, 0), + RoleBindings: make([]*unstructured.Unstructured, 0), + ClusterRoleBindings: make([]*unstructured.Unstructured, 0), + Services: make([]*unstructured.Unstructured, 0), + Certificates: make([]*unstructured.Unstructured, 0), + WebhookConfigurations: make([]*unstructured.Unstructured, 0), + ServiceMonitors: make([]*unstructured.Unstructured, 0), + Other: make([]*unstructured.Unstructured, 0), + } + + for { + var doc map[string]interface{} + err := decoder.Decode(&doc) + if err == io.EOF { + break + } + if err != nil { + return nil, fmt.Errorf("failed to decode YAML document: %w", err) + } + + // Skip empty documents + if doc == nil { + continue + } + + obj := &unstructured.Unstructured{Object: doc} + p.categorizeResource(obj, resources) + } + + return resources, nil +} + +// categorizeResource sorts a Kubernetes resource into the appropriate category based on kind and API version +func (p *Parser) categorizeResource(obj *unstructured.Unstructured, resources *ParsedResources) { + kind := obj.GetKind() + apiVersion := obj.GetAPIVersion() + + switch { + case kind == "Namespace": + resources.Namespace = obj + case kind == "CustomResourceDefinition": + resources.CustomResourceDefinitions = append(resources.CustomResourceDefinitions, obj) + case kind == "ServiceAccount": + resources.ServiceAccount = obj + case kind == "Role": + resources.Roles = append(resources.Roles, obj) + case kind == "ClusterRole": + resources.ClusterRoles = append(resources.ClusterRoles, obj) + case kind == "RoleBinding": + resources.RoleBindings = append(resources.RoleBindings, obj) + case kind == "ClusterRoleBinding": + resources.ClusterRoleBindings = append(resources.ClusterRoleBindings, obj) + case kind == "Service": + resources.Services = append(resources.Services, obj) + case kind == "Deployment": + resources.Deployment = obj + case kind == "Certificate" && apiVersion == "cert-manager.io/v1": + resources.Certificates = append(resources.Certificates, obj) + case kind == "Issuer" && apiVersion == "cert-manager.io/v1": + resources.Issuer = obj + case kind == "ValidatingWebhookConfiguration" || kind == "MutatingWebhookConfiguration": + resources.WebhookConfigurations = append(resources.WebhookConfigurations, obj) + case kind == "ServiceMonitor" && apiVersion == "monitoring.coreos.com/v1": + resources.ServiceMonitors = append(resources.ServiceMonitors, obj) + default: + resources.Other = append(resources.Other, obj) + } +} diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/parser_test.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/parser_test.go new file mode 100644 index 00000000000..237adc15495 --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/parser_test.go @@ -0,0 +1,286 @@ +/* +Copyright 2025 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 kustomize + +import ( + "os" + "path/filepath" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Parser", func() { + var ( + parser *Parser + tempFile string + ) + + BeforeEach(func() { + // Create a temporary file for testing + tempDir := GinkgoT().TempDir() + tempFile = filepath.Join(tempDir, "test-manifest.yaml") + }) + + Context("with valid YAML containing various resources", func() { + BeforeEach(func() { + yamlContent := `--- +apiVersion: v1 +kind: Namespace +metadata: + name: test-system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: test-system +spec: + replicas: 1 +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: controller-manager + namespace: test-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: manager-role +rules: +- apiGroups: [""] + resources: ["*"] + verbs: ["*"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: manager-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: test-system +--- +apiVersion: v1 +kind: Service +metadata: + name: controller-manager-metrics-service + namespace: test-system +spec: + ports: + - name: https + port: 8443 + targetPort: 8443 + selector: + control-plane: controller-manager +` + err := os.WriteFile(tempFile, []byte(yamlContent), 0o600) + Expect(err).NotTo(HaveOccurred()) + + parser = NewParser(tempFile) + }) + + It("should parse all resources correctly", func() { + resources, err := parser.Parse() + Expect(err).NotTo(HaveOccurred()) + Expect(resources).NotTo(BeNil()) + + // Check that resources were parsed + Expect(resources.Namespace).NotTo(BeNil()) + Expect(resources.Deployment).NotTo(BeNil()) + Expect(resources.ServiceAccount).NotTo(BeNil()) + + // Check RBAC resources + Expect(resources.ClusterRoles).To(HaveLen(1)) + Expect(resources.ClusterRoleBindings).To(HaveLen(1)) + + // Check Services + Expect(resources.Services).To(HaveLen(1)) + }) + + It("should identify correct resource types", func() { + resources, err := parser.Parse() + Expect(err).NotTo(HaveOccurred()) + + Expect(resources.Namespace.GetKind()).To(Equal("Namespace")) + Expect(resources.Deployment.GetKind()).To(Equal("Deployment")) + Expect(resources.ServiceAccount.GetKind()).To(Equal("ServiceAccount")) + }) + }) + + Context("with webhook configuration", func() { + BeforeEach(func() { + yamlContent := `--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration +webhooks: +- name: test.example.com + clientConfig: + service: + name: webhook-service + namespace: test-system + path: "/validate" +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: serving-cert + namespace: test-system +spec: + dnsNames: + - webhook-service.test-system.svc + - webhook-service.test-system.svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-server-cert +` + err := os.WriteFile(tempFile, []byte(yamlContent), 0o600) + Expect(err).NotTo(HaveOccurred()) + + parser = NewParser(tempFile) + }) + + It("should parse webhook configurations", func() { + resources, err := parser.Parse() + Expect(err).NotTo(HaveOccurred()) + + Expect(resources.WebhookConfigurations).To(HaveLen(1)) + Expect(resources.Certificates).To(HaveLen(1)) + + webhook := resources.WebhookConfigurations[0] + Expect(webhook.GetKind()).To(Equal("ValidatingWebhookConfiguration")) + + cert := resources.Certificates[0] + Expect(cert.GetKind()).To(Equal("Certificate")) + }) + }) + + Context("with ServiceMonitor", func() { + BeforeEach(func() { + yamlContent := `--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: controller-manager-metrics-monitor + namespace: test-system +spec: + endpoints: + - path: /metrics + port: https + selector: + matchLabels: + control-plane: controller-manager +` + err := os.WriteFile(tempFile, []byte(yamlContent), 0o600) + Expect(err).NotTo(HaveOccurred()) + + parser = NewParser(tempFile) + }) + + It("should parse ServiceMonitor", func() { + resources, err := parser.Parse() + Expect(err).NotTo(HaveOccurred()) + + Expect(resources.ServiceMonitors).To(HaveLen(1)) + + monitor := resources.ServiceMonitors[0] + Expect(monitor.GetKind()).To(Equal("ServiceMonitor")) + }) + }) + + Context("with empty or invalid YAML", func() { + It("should handle empty file gracefully", func() { + err := os.WriteFile(tempFile, []byte(""), 0o600) + Expect(err).NotTo(HaveOccurred()) + + parser = NewParser(tempFile) + resources, err := parser.Parse() + Expect(err).NotTo(HaveOccurred()) + Expect(resources).NotTo(BeNil()) + }) + + It("should return error for invalid YAML", func() { + invalidYAML := `invalid: yaml: content: [unclosed` + err := os.WriteFile(tempFile, []byte(invalidYAML), 0o600) + Expect(err).NotTo(HaveOccurred()) + + parser = NewParser(tempFile) + _, err = parser.Parse() + Expect(err).To(HaveOccurred()) + }) + + It("should return error for non-existent file", func() { + parser = NewParser("/non/existent/file.yaml") + _, err := parser.Parse() + Expect(err).To(HaveOccurred()) + }) + }) + + Context("resource organization", func() { + BeforeEach(func() { + yamlContent := `--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tests.example.com +spec: + group: example.com + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer + namespace: test-system +spec: + selfSigned: {} +` + err := os.WriteFile(tempFile, []byte(yamlContent), 0o600) + Expect(err).NotTo(HaveOccurred()) + + parser = NewParser(tempFile) + }) + + It("should organize CRDs and Issuers correctly", func() { + resources, err := parser.Parse() + Expect(err).NotTo(HaveOccurred()) + + Expect(resources.CustomResourceDefinitions).To(HaveLen(1)) + Expect(resources.Issuer).NotTo(BeNil()) + + crd := resources.CustomResourceDefinitions[0] + Expect(crd.GetKind()).To(Equal("CustomResourceDefinition")) + + issuer := resources.Issuer + Expect(issuer.GetKind()).To(Equal("Issuer")) + }) + }) +}) diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/resource_organizer.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/resource_organizer.go new file mode 100644 index 00000000000..6dff347829b --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/resource_organizer.go @@ -0,0 +1,173 @@ +/* +Copyright 2025 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 kustomize + +import ( + "strings" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +// ResourceOrganizer groups Kubernetes resources by their logical function +type ResourceOrganizer struct { + resources *ParsedResources +} + +// NewResourceOrganizer creates a new resource organizer +func NewResourceOrganizer(resources *ParsedResources) *ResourceOrganizer { + return &ResourceOrganizer{ + resources: resources, + } +} + +// OrganizeByFunction groups resources by their logical function matching config/ directory structure +func (o *ResourceOrganizer) OrganizeByFunction() map[string][]*unstructured.Unstructured { + groups := make(map[string][]*unstructured.Unstructured) + + // CRDs - Custom Resource Definitions + if len(o.resources.CustomResourceDefinitions) > 0 { + groups["crd"] = o.resources.CustomResourceDefinitions + } + + // RBAC - Role-Based Access Control resources + rbacResources := o.collectRBACResources() + if len(rbacResources) > 0 { + groups["rbac"] = rbacResources + } + + // Manager - Deployment and related resources + if o.resources.Deployment != nil { + groups["manager"] = []*unstructured.Unstructured{o.resources.Deployment} + } + + // Metrics - Metrics services and related resources + metricsResources := o.collectMetricsResources() + if len(metricsResources) > 0 { + groups["metrics"] = metricsResources + } + + // Webhook - Webhook configurations and webhook services + webhookResources := o.collectWebhookResources() + if len(webhookResources) > 0 { + groups["webhook"] = webhookResources + } + + // Cert-manager - Certificate issuers and related resources + certManagerResources := o.collectCertManagerResources() + if len(certManagerResources) > 0 { + groups["cert-manager"] = certManagerResources + } + + // Prometheus - Prometheus ServiceMonitors and monitoring resources + prometheusResources := o.collectPrometheusResources() + if len(prometheusResources) > 0 { + groups["prometheus"] = prometheusResources + } + + // Other - Any remaining resources + if len(o.resources.Other) > 0 { + groups["other"] = o.resources.Other + } + + return groups +} + +// collectRBACResources gathers all RBAC-related resources +func (o *ResourceOrganizer) collectRBACResources() []*unstructured.Unstructured { + var rbacResources []*unstructured.Unstructured + + // Service account + if o.resources.ServiceAccount != nil { + rbacResources = append(rbacResources, o.resources.ServiceAccount) + } + + // Roles and bindings + rbacResources = append(rbacResources, o.resources.Roles...) + rbacResources = append(rbacResources, o.resources.ClusterRoles...) + rbacResources = append(rbacResources, o.resources.RoleBindings...) + rbacResources = append(rbacResources, o.resources.ClusterRoleBindings...) + + return rbacResources +} + +// collectWebhookResources gathers webhook-related resources +func (o *ResourceOrganizer) collectWebhookResources() []*unstructured.Unstructured { + var webhookResources []*unstructured.Unstructured + + // Webhook configurations (ValidatingWebhookConfiguration, MutatingWebhookConfiguration) + webhookResources = append(webhookResources, o.resources.WebhookConfigurations...) + + // Webhook services (services containing "webhook" in the name) + for _, service := range o.resources.Services { + if o.isWebhookService(service) { + webhookResources = append(webhookResources, service) + } + } + + return webhookResources +} + +// collectCertManagerResources gathers cert-manager related resources +func (o *ResourceOrganizer) collectCertManagerResources() []*unstructured.Unstructured { + var certManagerResources []*unstructured.Unstructured + + // Certificate issuers + if o.resources.Issuer != nil { + certManagerResources = append(certManagerResources, o.resources.Issuer) + } + + // Certificates (both webhook and metrics certificates are cert-manager resources) + certManagerResources = append(certManagerResources, o.resources.Certificates...) + + return certManagerResources +} + +// collectMetricsResources gathers metrics-related resources +func (o *ResourceOrganizer) collectMetricsResources() []*unstructured.Unstructured { + var metricsResources []*unstructured.Unstructured + + // Metrics services (services containing "metrics" in the name) + for _, service := range o.resources.Services { + if o.isMetricsService(service) { + metricsResources = append(metricsResources, service) + } + } + + return metricsResources +} + +// collectPrometheusResources gathers prometheus related resources +func (o *ResourceOrganizer) collectPrometheusResources() []*unstructured.Unstructured { + var prometheusResources []*unstructured.Unstructured + + // ServiceMonitors + prometheusResources = append(prometheusResources, o.resources.ServiceMonitors...) + + return prometheusResources +} + +// isWebhookService determines if a service is webhook-related +func (o *ResourceOrganizer) isWebhookService(service *unstructured.Unstructured) bool { + serviceName := service.GetName() + return strings.Contains(serviceName, "webhook") +} + +// isMetricsService determines if a service is metrics-related +func (o *ResourceOrganizer) isMetricsService(service *unstructured.Unstructured) bool { + serviceName := service.GetName() + return strings.Contains(serviceName, "metrics") +} diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/suite_test.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/suite_test.go new file mode 100644 index 00000000000..7a9924df56a --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/kustomize/suite_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2025 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 kustomize + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestKustomize(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Kustomize Suite") +} diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go new file mode 100644 index 00000000000..c610f87303c --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/chart-templates/helpers_tpl.go @@ -0,0 +1,132 @@ +/* +Copyright 2025 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 charttemplates + +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 + + // OutputDir specifies the output directory for the chart + OutputDir string +} + +// SetTemplateDefaults sets the default template configuration +func (f *HelmHelpers) SetTemplateDefaults() error { + if f.Path == "" { + outputDir := f.OutputDir + if outputDir == "" { + outputDir = "dist" + } + f.Path = filepath.Join(outputDir, "chart", "templates", "_helpers.tpl") + } + + f.TemplateBody = helmHelpersTemplate + + f.IfExistsAction = machinery.SkipFile + + return nil +} + +const helmHelpersTemplate = `{{` + "`" + `{{/* +Chart name based on project name. +Truncated to 63 characters for Kubernetes compatibility. +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.name" -}}` + "`" + `}} +{{` + "`" + `{{- if .Chart }}` + "`" + `}} + {{` + "`" + `{{- if .Chart.Name }}` + "`" + `}} + {{` + "`" + `{{- .Chart.Name | trunc 63 | trimSuffix "-" }}` + "`" + `}} + {{` + "`" + `{{- else }}` + "`" + `}} + {{ .ProjectName }} + {{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{- else }}` + "`" + `}} + {{ .ProjectName }} +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{` + "`" + `{{/* +Full name of the chart (with release name prefix). +Combines release name with chart name. +Truncated to 63 characters for Kubernetes compatibility. +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.fullname" -}}` + "`" + `}} +{{` + "`" + `{{- $name := include "chart.name" . }}` + "`" + `}} +{{` + "`" + `{{- if contains $name .Release.Name }}` + "`" + `}} +{{` + "`" + `{{- .Release.Name | trunc 63 | trimSuffix "-" }}` + "`" + `}} +{{` + "`" + `{{- else }}` + "`" + `}} +{{` + "`" + `{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{` + "`" + `{{/* +Namespace for generated references. +Always uses the Helm release namespace. +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.namespaceName" -}}` + "`" + `}} +{{` + "`" + `{{ .Release.Namespace }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + + + +{{` + "`" + `{{/* +Service name with proper truncation for Kubernetes 63-character limit. +Takes a context with .suffix for the service type (e.g., "webhook-service"). +If fullname + suffix exceeds 63 chars, truncates fullname to 45 chars. +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.serviceName" -}}` + "`" + `}} +{{` + "`" + `{{- $fullname := include "chart.fullname" .context -}}` + "`" + `}} +{{` + "`" + `{{- if gt (len $fullname) 45 -}}` + "`" + `}} +{{` + "`" + `{{- printf "%s-%s" (trunc 45 $fullname | trimSuffix "-") .suffix ` + + `| trunc 63 | trimSuffix "-" -}}` + "`" + `}} +{{` + "`" + `{{- else -}}` + "`" + `}} +{{` + "`" + `{{- printf "%s-%s" $fullname .suffix | trunc 63 | trimSuffix "-" -}}` + "`" + `}} +{{` + "`" + `{{- end -}}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{` + "`" + `{{/* +Common labels for Helm charts. +Includes app version, chart version, app name, instance, and managed-by labels. +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.labels" -}}` + "`" + `}} +{{` + "`" + `{{- if .Chart.AppVersion -}}` + "`" + `}} +app.kubernetes.io/version: {{` + "`" + `{{ .Chart.AppVersion | quote }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +{{` + "`" + `{{- if .Chart.Version }}` + "`" + `}} +helm.sh/chart: {{` + "`" + `{{ .Chart.Version | quote }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +app.kubernetes.io/name: {{` + "`" + `{{ include "chart.name" . }}` + "`" + `}} +app.kubernetes.io/instance: {{` + "`" + `{{ .Release.Name }}` + "`" + `}} +app.kubernetes.io/managed-by: {{` + "`" + `{{ .Release.Service }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} + +{{` + "`" + `{{/* +Selector labels for matching pods and services. +Only includes name and instance for consistent selection. +*/}}` + "`" + `}} +{{` + "`" + `{{- define "chart.selectorLabels" -}}` + "`" + `}} +app.kubernetes.io/name: {{` + "`" + `{{ include "chart.name" . }}` + "`" + `}} +app.kubernetes.io/instance: {{` + "`" + `{{ .Release.Name }}` + "`" + `}} +{{` + "`" + `{{- end }}` + "`" + `}} +` diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/chart-templates/servicemonitor.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/chart-templates/servicemonitor.go new file mode 100644 index 00000000000..55e82a0e36a --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/chart-templates/servicemonitor.go @@ -0,0 +1,94 @@ +/* +Copyright 2025 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 charttemplates + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +const defaultOutputDir = "dist" + +var _ machinery.Template = &ServiceMonitor{} + +// ServiceMonitor scaffolds a ServiceMonitor for Prometheus monitoring in the Helm chart +type ServiceMonitor struct { + machinery.TemplateMixin + machinery.ProjectNameMixin + + // OutputDir specifies the output directory for the chart + OutputDir string +} + +// SetTemplateDefaults implements machinery.Template +func (f *ServiceMonitor) SetTemplateDefaults() error { + if f.Path == "" { + outputDir := f.OutputDir + if outputDir == "" { + outputDir = defaultOutputDir + } + f.Path = filepath.Join(outputDir, "chart", "templates", "monitoring", "servicemonitor.yaml") + } + + f.TemplateBody = serviceMonitorTemplate + + f.IfExistsAction = machinery.OverwriteFile + + return nil +} + +const serviceMonitorTemplate = `{{` + "`" + `{{- if .Values.prometheus.enable }}` + "`" + `}} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + {{ "{{- include \"chart.labels\" . | nindent 4 }}" }} + control-plane: controller-manager + name: {{ .ProjectName }}-controller-manager-metrics-monitor + namespace: {{ "{{ .Release.Namespace }}" }} +spec: + endpoints: + - path: /metrics + port: https + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + {{ "{{- if .Values.certManager.enable }}" }} + serverName: {{ .ProjectName }}-controller-manager-metrics-service.{{ "{{ .Release.Namespace }}" }}.svc + # Apply secure TLS configuration with cert-manager + insecureSkipVerify: false + ca: + secret: + name: metrics-server-cert + key: ca.crt + cert: + secret: + name: metrics-server-cert + key: tls.crt + keySecret: + name: metrics-server-cert + key: tls.key + {{ "{{- else }}" }} + # Development/Test mode (insecure configuration) + insecureSkipVerify: true + {{ "{{- end }}" }} + selector: + matchLabels: + control-plane: controller-manager +{{` + "`" + `{{- end }}` + "`" + `}} +` diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/chart.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/chart.go new file mode 100644 index 00000000000..94ea490c3aa --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/chart.go @@ -0,0 +1,62 @@ +/* +Copyright 2025 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" +) + +const defaultOutputDir = "dist" + +var _ machinery.Template = &HelmChart{} + +// HelmChart scaffolds a file that defines the Helm chart structure +type HelmChart struct { + machinery.TemplateMixin + machinery.ProjectNameMixin + + // OutputDir specifies the output directory for the chart + OutputDir string +} + +// SetTemplateDefaults implements machinery.Template +func (f *HelmChart) SetTemplateDefaults() error { + if f.Path == "" { + outputDir := f.OutputDir + if outputDir == "" { + outputDir = defaultOutputDir + } + f.Path = filepath.Join(outputDir, "chart", "Chart.yaml") + } + + f.TemplateBody = helmChartTemplate + + f.IfExistsAction = machinery.SkipFile + + return nil +} + +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/v2alpha/scaffolds/internal/templates/github/test_chart.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/github/test_chart.go new file mode 100644 index 00000000000..e7b55992edc --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/github/test_chart.go @@ -0,0 +1,120 @@ +/* +Copyright 2025 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 github + +import ( + "path/filepath" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &HelmChartCI{} + +// HelmChartCI scaffolds the GitHub Action for testing Helm charts +type HelmChartCI struct { + machinery.TemplateMixin + machinery.ProjectNameMixin +} + +// SetTemplateDefaults implements machinery.Template +func (f *HelmChartCI) SetTemplateDefaults() error { + if f.Path == "" { + f.Path = filepath.Join(".github", "workflows", "test-chart.yml") + } + + f.TemplateBody = testChartTemplate + + f.IfExistsAction = machinery.SkipFile + + return nil +} + +const testChartTemplate = `name: Test Chart + +on: + push: + pull_request: + +jobs: + test-e2e: + name: Run on Ubuntu + runs-on: ubuntu-latest + steps: + - name: Clone the code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + + - 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 {{ .ProjectName }} + run: | + go mod tidy + make docker-build IMG={{ .ProjectName }}:v0.1.0 + kind load docker-image {{ .ProjectName }}: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 + run: | + helm lint ./dist/chart + +# TODO: Uncomment if cert-manager is enabled +# - name: Install cert-manager via Helm (wait for readiness) +# run: | +# helm repo add jetstack https://charts.jetstack.io +# helm repo update +# helm install cert-manager jetstack/cert-manager \ +# --namespace cert-manager \ +# --create-namespace \ +# --set crds.enabled=true \ +# --wait \ +# --timeout 300s + +# TODO: Uncomment if Prometheus is enabled +# - name: Install Prometheus Operator CRDs +# run: | +# helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +# helm repo update +# helm install prometheus-crds prometheus-community/prometheus-operator-crds + + - name: Install Helm chart for project + run: | + helm install my-release ./dist/chart --create-namespace --namespace {{ .ProjectName }}-system + + - name: Check Helm release status + run: | + helm status my-release --namespace {{ .ProjectName }}-system +` diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/helmignore.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/helmignore.go new file mode 100644 index 00000000000..d11a4a6459f --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/helmignore.go @@ -0,0 +1,77 @@ +/* +Copyright 2025 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 + + // OutputDir specifies the output directory for the chart + OutputDir string +} + +// SetTemplateDefaults implements machinery.Template +func (f *HelmIgnore) SetTemplateDefaults() error { + if f.Path == "" { + outputDir := f.OutputDir + if outputDir == "" { + outputDir = "dist" + } + f.Path = filepath.Join(outputDir, "chart", ".helmignore") + } + + f.TemplateBody = helmIgnoreTemplate + + f.IfExistsAction = machinery.SkipFile + + return nil +} + +const helmIgnoreTemplate = `# Patterns to ignore when building Helm packages. +# 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/v2alpha/scaffolds/internal/templates/values_basic.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/values_basic.go new file mode 100644 index 00000000000..b72f2214099 --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/values_basic.go @@ -0,0 +1,274 @@ +/* +Copyright 2025 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 ( + "bytes" + "path/filepath" + + "gopkg.in/yaml.v3" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ machinery.Template = &HelmValuesBasic{} + +// HelmValuesBasic scaffolds a basic values.yaml based on detected features +type HelmValuesBasic struct { + machinery.TemplateMixin + machinery.ProjectNameMixin + + // DeploymentConfig stores extracted deployment configuration (env, resources, security contexts) + DeploymentConfig map[string]interface{} + // OutputDir specifies the output directory for the chart + OutputDir string + // Force if true allows overwriting the scaffolded file + Force bool + // HasWebhooks is true when webhooks were found in the config + HasWebhooks bool + // HasMetrics is true when metrics service/monitor were found in the config + HasMetrics bool +} + +// SetTemplateDefaults implements machinery.Template +func (f *HelmValuesBasic) SetTemplateDefaults() error { + if f.Path == "" { + outputDir := f.OutputDir + if outputDir == "" { + outputDir = "dist" + } + f.Path = filepath.Join(outputDir, "chart", "values.yaml") + } + + f.TemplateBody = f.generateBasicValues() + + if f.Force { + f.IfExistsAction = machinery.OverwriteFile + } else { + f.IfExistsAction = machinery.SkipFile + } + + return nil +} + +// generateBasicValues creates a basic values.yaml based on detected features +func (f *HelmValuesBasic) generateBasicValues() string { + var buf bytes.Buffer + + // Controller Manager configuration + buf.WriteString(`# Configure the controller manager deployment +controllerManager: + replicas: 1 + + image: + repository: controller + tag: latest + pullPolicy: IfNotPresent + +`) + + // Add extracted deployment configuration + f.addDeploymentConfig(&buf) + + // RBAC configuration + buf.WriteString(`# Essential RBAC permissions (required for controller operation) +# These include ServiceAccount, controller permissions, leader election, and metrics access +# Note: Essential RBAC is always enabled as it's required for the controller to function + +# Helper RBAC roles for managing custom resources +# These provide convenient admin/editor/viewer roles for each CRD type +# Useful for giving users different levels of access to your custom resources +rbacHelpers: + enable: false # Install convenience admin/editor/viewer roles for CRDs + +`) + + // CRD configuration + buf.WriteString(`# Custom Resource Definitions +crd: + enable: true # Install CRDs with the chart + keep: true # Keep CRDs when uninstalling + +`) + + // Metrics configuration (enable if metrics artifacts detected in kustomize output) + if f.HasMetrics { + buf.WriteString(`# Controller metrics endpoint. +# Enable to expose /metrics endpoint with RBAC protection. +metrics: + enable: true + +`) + } else { + buf.WriteString(`# Controller metrics endpoint. +# Enable to expose /metrics endpoint with RBAC protection. +metrics: + enable: false + +`) + } + + // Cert-manager configuration - only if certificates/webhooks are present + if f.HasWebhooks { + buf.WriteString(`# Cert-manager integration for TLS certificates. +# Required for webhook certificates and metrics endpoint certificates. +certManager: + enable: true + +`) + } + + // Prometheus configuration + buf.WriteString(`# Prometheus ServiceMonitor for metrics scraping. +# Requires prometheus-operator to be installed in the cluster. +prometheus: + enable: false +`) + + buf.WriteString("\n") + return buf.String() +} + +// addDeploymentConfig adds extracted deployment configuration to the values +func (f *HelmValuesBasic) addDeploymentConfig(buf *bytes.Buffer) { + if f.DeploymentConfig == nil { + // Add default sections with examples + f.addDefaultDeploymentSections(buf) + return + } + + // Add environment variables if they exist + if env, exists := f.DeploymentConfig["env"]; exists && env != nil { + buf.WriteString(" # Environment variables\n") + buf.WriteString(" env:\n") + if envYaml, err := yaml.Marshal(env); err == nil { + // Indent the YAML properly + lines := bytes.Split(envYaml, []byte("\n")) + for _, line := range lines { + if len(line) > 0 { + buf.WriteString(" ") + buf.Write(line) + buf.WriteString("\n") + } + } + } else { + buf.WriteString(" []\n") + } + buf.WriteString("\n") + } else { + buf.WriteString(" # Environment variables\n") + buf.WriteString(" env: []\n\n") + } + + // Add podSecurityContext + if podSecCtx, exists := f.DeploymentConfig["podSecurityContext"]; exists && podSecCtx != nil { + buf.WriteString(" # Pod-level security settings\n") + buf.WriteString(" podSecurityContext:\n") + if secYaml, err := yaml.Marshal(podSecCtx); err == nil { + lines := bytes.Split(secYaml, []byte("\n")) + for _, line := range lines { + if len(line) > 0 { + buf.WriteString(" ") + buf.Write(line) + buf.WriteString("\n") + } + } + } + buf.WriteString("\n") + } else { + f.addDefaultPodSecurityContext(buf) + } + + // Add securityContext + if secCtx, exists := f.DeploymentConfig["securityContext"]; exists && secCtx != nil { + buf.WriteString(" # Container-level security settings\n") + buf.WriteString(" securityContext:\n") + if secYaml, err := yaml.Marshal(secCtx); err == nil { + lines := bytes.Split(secYaml, []byte("\n")) + for _, line := range lines { + if len(line) > 0 { + buf.WriteString(" ") + buf.Write(line) + buf.WriteString("\n") + } + } + } + buf.WriteString("\n") + } else { + f.addDefaultSecurityContext(buf) + } + + // Add resources + if resources, exists := f.DeploymentConfig["resources"]; exists && resources != nil { + buf.WriteString(" # Resource limits and requests\n") + buf.WriteString(" resources:\n") + if resYaml, err := yaml.Marshal(resources); err == nil { + lines := bytes.Split(resYaml, []byte("\n")) + for _, line := range lines { + if len(line) > 0 { + buf.WriteString(" ") + buf.Write(line) + buf.WriteString("\n") + } + } + } + buf.WriteString("\n") + } else { + f.addDefaultResources(buf) + } +} + +// addDefaultDeploymentSections adds default sections when no deployment config is available +func (f *HelmValuesBasic) addDefaultDeploymentSections(buf *bytes.Buffer) { + buf.WriteString(" # Environment variables\n") + buf.WriteString(" env: []\n\n") + + f.addDefaultPodSecurityContext(buf) + f.addDefaultSecurityContext(buf) + f.addDefaultResources(buf) +} + +// addDefaultPodSecurityContext adds default podSecurityContext section +func (f *HelmValuesBasic) addDefaultPodSecurityContext(buf *bytes.Buffer) { + buf.WriteString(" # Pod-level security settings\n") + buf.WriteString(" podSecurityContext: {}\n") + buf.WriteString(" # fsGroup: 2000\n\n") +} + +// addDefaultSecurityContext adds default securityContext section +func (f *HelmValuesBasic) addDefaultSecurityContext(buf *bytes.Buffer) { + buf.WriteString(" # Container-level security settings\n") + buf.WriteString(" securityContext: {}\n") + buf.WriteString(" # capabilities:\n") + buf.WriteString(" # drop:\n") + buf.WriteString(" # - ALL\n") + buf.WriteString(" # readOnlyRootFilesystem: true\n") + buf.WriteString(" # runAsNonRoot: true\n") + buf.WriteString(" # runAsUser: 1000\n\n") +} + +// addDefaultResources adds default resources section +func (f *HelmValuesBasic) addDefaultResources(buf *bytes.Buffer) { + buf.WriteString(" # Resource limits and requests\n") + buf.WriteString(" resources: {}\n") + buf.WriteString(" # limits:\n") + buf.WriteString(" # cpu: 100m\n") + buf.WriteString(" # memory: 128Mi\n") + buf.WriteString(" # requests:\n") + buf.WriteString(" # cpu: 100m\n") + buf.WriteString(" # memory: 128Mi\n\n") +} diff --git a/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/values_basic_test.go b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/values_basic_test.go new file mode 100644 index 00000000000..e8cfbab712b --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/scaffolds/internal/templates/values_basic_test.go @@ -0,0 +1,168 @@ +/* +Copyright 2025 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 ( + "strings" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "sigs.k8s.io/kubebuilder/v4/pkg/machinery" +) + +var _ = Describe("HelmValuesBasic", func() { + var valuesTemplate *HelmValuesBasic + + Context("when project has webhooks", func() { + BeforeEach(func() { + valuesTemplate = &HelmValuesBasic{ + HasWebhooks: true, + DeploymentConfig: map[string]interface{}{}, + } + valuesTemplate.InjectProjectName("test-project") + err := valuesTemplate.SetTemplateDefaults() + Expect(err).NotTo(HaveOccurred()) + }) + + It("should include certManager configuration", func() { + content := valuesTemplate.GetBody() + + Expect(content).To(ContainSubstring("certManager:")) + Expect(content).To(ContainSubstring("enable: true")) + }) + + It("should include all basic sections", func() { + content := valuesTemplate.GetBody() + + Expect(content).To(ContainSubstring("replicaCount:")) + Expect(content).To(ContainSubstring("metrics:")) + Expect(content).To(ContainSubstring("prometheus:")) + Expect(content).To(ContainSubstring("rbacHelpers:")) + }) + }) + + Context("when project has no webhooks", func() { + BeforeEach(func() { + valuesTemplate = &HelmValuesBasic{ + HasWebhooks: false, + DeploymentConfig: map[string]interface{}{}, + } + valuesTemplate.InjectProjectName("test-project") + err := valuesTemplate.SetTemplateDefaults() + Expect(err).NotTo(HaveOccurred()) + }) + + It("should not include certManager configuration", func() { + content := valuesTemplate.GetBody() + + Expect(content).NotTo(ContainSubstring("certManager:")) + Expect(content).NotTo(ContainSubstring("enable: true")) + }) + + It("should still include other basic sections", func() { + content := valuesTemplate.GetBody() + + Expect(content).To(ContainSubstring("replicaCount:")) + Expect(content).To(ContainSubstring("metrics:")) + Expect(content).To(ContainSubstring("prometheus:")) + Expect(content).To(ContainSubstring("rbacHelpers:")) + }) + }) + + Context("template path and content", func() { + BeforeEach(func() { + valuesTemplate = &HelmValuesBasic{ + OutputDir: "dist", + } + valuesTemplate.InjectProjectName("test-project") + err := valuesTemplate.SetTemplateDefaults() + Expect(err).NotTo(HaveOccurred()) + }) + + It("should have correct path", func() { + Expect(valuesTemplate.GetPath()).To(Equal("dist/chart/values.yaml")) + }) + + It("should implement Builder interface", func() { + var builder machinery.Builder = valuesTemplate + Expect(builder).NotTo(BeNil()) + }) + + It("should have correct file permissions", func() { + info := valuesTemplate.GetIfExistsAction() + Expect(info).To(Equal(machinery.OverwriteFile)) + }) + }) + + Context("with deployment configuration", func() { + BeforeEach(func() { + deploymentConfig := map[string]interface{}{ + "env": []interface{}{ + map[string]interface{}{ + "name": "TEST_ENV", + "value": "test-value", + }, + }, + "resources": map[string]interface{}{ + "limits": map[string]interface{}{ + "cpu": "100m", + "memory": "128Mi", + }, + }, + } + + valuesTemplate = &HelmValuesBasic{ + HasWebhooks: false, + DeploymentConfig: deploymentConfig, + } + valuesTemplate.InjectProjectName("test-project") + err := valuesTemplate.SetTemplateDefaults() + Expect(err).NotTo(HaveOccurred()) + }) + + It("should include deployment configuration", func() { + content := valuesTemplate.GetBody() + Expect(content).To(ContainSubstring("manager:")) + }) + }) + + Context("rbacHelpers configuration", func() { + BeforeEach(func() { + valuesTemplate = &HelmValuesBasic{ + HasWebhooks: false, + } + valuesTemplate.InjectProjectName("test-project") + err := valuesTemplate.SetTemplateDefaults() + Expect(err).NotTo(HaveOccurred()) + }) + + It("should have rbacHelpers disabled by default", func() { + content := valuesTemplate.GetBody() + lines := strings.Split(content, "\n") + var rbacHelpersIndex int + for i, line := range lines { + if strings.Contains(line, "rbacHelpers:") { + rbacHelpersIndex = i + break + } + } + Expect(rbacHelpersIndex).To(BeNumerically(">", 0)) + Expect(lines[rbacHelpersIndex+1]).To(ContainSubstring("enable: false")) + }) + }) +}) diff --git a/pkg/plugins/optional/helm/v2alpha/suite_test.go b/pkg/plugins/optional/helm/v2alpha/suite_test.go new file mode 100644 index 00000000000..1765c3bbb4f --- /dev/null +++ b/pkg/plugins/optional/helm/v2alpha/suite_test.go @@ -0,0 +1,29 @@ +/* +Copyright 2025 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 v2alpha + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestHelmV2AlphaPlugin(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Helm v2-alpha Plugin Suite") +} diff --git a/test/e2e/alphagenerate/generate_test.go b/test/e2e/alphagenerate/generate_test.go index f4c8e5c012b..37e68ab4a7e 100644 --- a/test/e2e/alphagenerate/generate_test.go +++ b/test/e2e/alphagenerate/generate_test.go @@ -85,8 +85,11 @@ var _ = Describe("kubebuilder", func() { By("Generate API with Deploy Image plugin") generateAPIWithDeployImage(kbc) + By("build the installer manifest") + Expect(kbc.Make("build-installer")).To(Succeed()) + By("Enabling Helm plugin") - err = kbc.Edit("--plugins", "helm.kubebuilder.io/v1-alpha") + err = kbc.Edit("--plugins", "helm.kubebuilder.io/v2-alpha") Expect(err).NotTo(HaveOccurred(), "Failed to edit project to enable Helm Plugin") By("Re-generating the project with plugins") @@ -354,7 +357,7 @@ func validateHelmPlugin(projectFile string) { By("checking the Helm plugin in the PROJECT file") var helmPluginConfig map[string]interface{} - err := projectConfig.DecodePluginConfig("helm.kubebuilder.io/v1-alpha", &helmPluginConfig) + err := projectConfig.DecodePluginConfig("helm.kubebuilder.io/v2-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/alphagenerate/generate_v4_with_plugins_test.go b/test/e2e/alphagenerate/generate_v4_with_plugins_test.go index 7ca74e0f8be..2e3a7317f9c 100644 --- a/test/e2e/alphagenerate/generate_v4_with_plugins_test.go +++ b/test/e2e/alphagenerate/generate_v4_with_plugins_test.go @@ -23,8 +23,10 @@ import ( . "github.com/onsi/gomega" "sigs.k8s.io/kubebuilder/v4/pkg/model/resource" + "sigs.k8s.io/kubebuilder/v4/pkg/plugin" pluginutil "sigs.k8s.io/kubebuilder/v4/pkg/plugin/util" "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/deploy-image/v1alpha1" + hemlv2alpha "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v2alpha" "sigs.k8s.io/kubebuilder/v4/test/e2e/utils" ) @@ -188,10 +190,12 @@ func validateV4WithPluginsProjectFile(kbc *utils.TestContext, projectFile string Expect(grafanaConfig.Resources).To(BeEmpty(), "Expected zero resource for the Grafana plugin") By("decoding the helm plugin configuration") - var helmConfig v1alpha1.PluginConfig - err = projectConfig.DecodePluginConfig("grafana.kubebuilder.io/v1-alpha", &helmConfig) + var helmConfig map[string]interface{} + // Use the proper plugin key from the plugin package + pluginKey := plugin.KeyFor(hemlv2alpha.Plugin{}) + err = projectConfig.DecodePluginConfig(pluginKey, &helmConfig) Expect(err).NotTo(HaveOccurred(), "Failed to decode Helm plugin configuration") - // Validate the resource configuration - Expect(helmConfig.Resources).To(BeEmpty(), "Expected zero resource for the Helm plugin") + // Validate the helm plugin configuration exists + Expect(helmConfig).NotTo(BeNil(), "Expected Helm plugin configuration to be present") } diff --git a/test/e2e/helm/e2e_suite_test.go b/test/e2e/helm/e2e_suite_test.go index a1f038da53d..c54312bab8e 100644 --- a/test/e2e/helm/e2e_suite_test.go +++ b/test/e2e/helm/e2e_suite_test.go @@ -19,6 +19,9 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + + "sigs.k8s.io/kubebuilder/v4/pkg/plugin/util" + "sigs.k8s.io/kubebuilder/v4/test/e2e/utils" ) // Run e2e tests using the Ginkgo runner. @@ -27,3 +30,32 @@ func TestE2E(t *testing.T) { _, _ = fmt.Fprintf(GinkgoWriter, "Starting helm plugin kubebuilder suite\n") RunSpecs(t, "Kubebuilder helm plugin e2e suite") } + +// BeforeSuite run before any specs are run to perform the required actions for all e2e Go tests. +var _ = BeforeSuite(func() { + var err error + + kbc, err := utils.NewTestContext(util.KubebuilderBinName, "GO111MODULE=on") + Expect(err).NotTo(HaveOccurred()) + Expect(kbc.Prepare()).To(Succeed()) + + By("installing the cert-manager bundle") + Expect(kbc.InstallCertManager()).To(Succeed()) + + By("installing the Prometheus operator") + Expect(kbc.InstallPrometheusOperManager()).To(Succeed()) +}) + +// AfterSuite run after all the specs have run, regardless of whether any tests have failed to ensures that +// all be cleaned up +var _ = AfterSuite(func() { + kbc, err := utils.NewTestContext(util.KubebuilderBinName, "GO111MODULE=on") + Expect(err).NotTo(HaveOccurred()) + Expect(kbc.Prepare()).To(Succeed()) + + By("uninstalling the Prometheus manager bundle") + kbc.UninstallPrometheusOperManager() + + By("uninstalling the cert-manager bundle") + kbc.UninstallCertManager() +}) diff --git a/test/e2e/helm/generate_test.go b/test/e2e/helm/generate_test.go index 18beccf2b5c..4d5a66f9062 100644 --- a/test/e2e/helm/generate_test.go +++ b/test/e2e/helm/generate_test.go @@ -18,6 +18,7 @@ package helm import ( "path/filepath" + "strings" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -28,113 +29,102 @@ import ( "sigs.k8s.io/kubebuilder/v4/pkg/config/store/yaml" "sigs.k8s.io/kubebuilder/v4/pkg/machinery" pluginutil "sigs.k8s.io/kubebuilder/v4/pkg/plugin/util" - helmv1alpha "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha" + helmv2alpha "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v2alpha" "sigs.k8s.io/kubebuilder/v4/test/e2e/utils" ) -var _ = Describe("kubebuilder", func() { - Context("plugin helm/v1-alpha", func() { - var kbc *utils.TestContext +var _ = Describe("Helm v2-alpha Plugin", func() { + var kbc *utils.TestContext - BeforeEach(func() { - var err error - kbc, err = utils.NewTestContext(pluginutil.KubebuilderBinName, "GO111MODULE=on") + BeforeEach(func() { + var err error + kbc, err = utils.NewTestContext(pluginutil.KubebuilderBinName, "GO111MODULE=on") + Expect(err).NotTo(HaveOccurred()) + Expect(kbc.Prepare()).To(Succeed()) + }) + + AfterEach(func() { + kbc.Destroy() + }) + + Describe("Basic Functionality", func() { + It("should generate helm chart with dynamic kustomize-based templates", func() { + By("initializing a basic project") + initBasicProject(kbc) + + By("creating API and controller resources") + createTestResources(kbc) + + By("building installer manifest") + Expect(kbc.Make("build-installer")).To(Succeed()) + + By("applying helm v2-alpha plugin") + err := kbc.EditHelmPlugin() Expect(err).NotTo(HaveOccurred()) - Expect(kbc.Prepare()).To(Succeed()) - }) - AfterEach(func() { - kbc.Destroy() + By("validating generated helm chart structure") + validateBasicHelmChart(kbc) + + By("verifying dynamic template generation") + validateDynamicTemplates(kbc) + + By("checking plugin configuration tracking") + validatePluginConfig(kbc) }) - It("should extend an initialed project with helm plugin", func() { - initTheProject(kbc) + It("should handle webhooks correctly", func() { + By("initializing a project with webhooks") + initBasicProject(kbc) + createTestResources(kbc) + createWebhookResources(kbc) + + By("building installer manifest with webhooks") + Expect(kbc.Make("build-installer")).To(Succeed()) + + By("applying helm v2-alpha plugin") + err := kbc.EditHelmPlugin() + Expect(err).NotTo(HaveOccurred()) - By("extend the project by adding helm plugin") - err := kbc.Edit( - "--plugins", "helm.kubebuilder.io/v1-alpha", - ) - Expect(err).NotTo(HaveOccurred(), "Failed to edit the project") + By("validating webhook templates are generated") + validateWebhookTemplates(kbc) - ensureCommonHelmFilesContent(kbc, false) + By("verifying cert-manager integration") + validateCertManagerIntegration(kbc) }) - // This test is to ensure that the helm plugin can be added to a project - // that has already been initialized with the go/v4 plugin. - // As the project is getting extended with webhooks, - // it is needed to run the `kubebuilder edit --plugins helm.kubebuilder.io/v1-alpha` command - // with ` --force` again to ensure that the webhooks are enabled in the - // values.yaml file. - It("should extend an initialized project with helm plugin and webhooks", func() { - initTheProject(kbc) - - By("extend the project by adding helm plugin") - err := kbc.Edit( - "--plugins", "helm.kubebuilder.io/v1-alpha", - ) - Expect(err).NotTo(HaveOccurred(), "Failed to edit the project") - - ensureCommonHelmFilesContent(kbc, false) - extendProjectWithWebhooks(kbc) - - // after creating webhooks, we want to have the webhooks enabled - // in the values.yaml file, so we need to run `kubebuilder edit` - // with the --force flag for the helm plugin. - By("re-edit the project after creating webhooks") - err = kbc.Edit( - "--plugins", "helm.kubebuilder.io/v1-alpha", "--force", - ) - Expect(err).NotTo(HaveOccurred(), "Failed to edit the project") - - ensureCommonHelmFilesContent(kbc, true) + It("should support custom flags and preserve files", func() { + By("initializing project and building installer") + initBasicProject(kbc) + createTestResources(kbc) + Expect(kbc.Make("build-installer")).To(Succeed()) + + By("applying plugin with custom output directory") + err := kbc.Edit("--plugins", "helm.kubebuilder.io/v2-alpha", "--output-dir", "custom-charts") + Expect(err).NotTo(HaveOccurred()) + + By("verifying chart is generated in custom directory") + validateCustomOutputDir(kbc, "custom-charts") + + By("re-running plugin without --force should preserve existing files") + err = kbc.Edit("--plugins", "helm.kubebuilder.io/v2-alpha", "--output-dir", "custom-charts") + Expect(err).NotTo(HaveOccurred()) + + By("verifying files are preserved when not using --force") + validateFilePreservation(kbc, "custom-charts") }) }) }) -// ensureCommonHelmFilesContent tests common helm-chart files which got -// generated by the helm/v1(-alpha) plugin -func ensureCommonHelmFilesContent(kbc *utils.TestContext, webhookEnabled bool) { - var helmConfig helmv1alpha.Plugin - projectConfig := getConfigFromProjectFile(filepath.Join(kbc.Dir, "PROJECT")) - - By("decoding the helm plugin configuration") - err := projectConfig.DecodePluginConfig("helm.kubebuilder.io/v1-alpha", &helmConfig) - Expect(err).NotTo(HaveOccurred(), "Failed to decode Helm plugin configuration") - - // loading the generated helm chart - chart, err := helmChartLoader.LoadDir(filepath.Join(kbc.Dir, "dist", "chart")) - Expect(err).NotTo(HaveOccurred(), "Failed to load helm chart") - - // validating the helm chart metadata (Chart.yaml) - err = chart.Validate() - Expect(err).NotTo(HaveOccurred(), "Failed to validate helm chart") - - // expect the chart-name equal to the name of the PROJECT - Expect(chart.Name()).To(Equal("e2e-"+kbc.TestSuffix), "Chart name doesn't match") - - // expecting the existence of a manager.yaml file - var matchedFiles int - for _, templateFile := range chart.Templates { - switch templateFile.Name { - case "templates/manager/manager.yaml": - matchedFiles++ - default: - matchedFiles += 0 - } - } - - Expect(matchedFiles).To(BeNumerically("==", 1)) - - // check if webhooks are enabled in the Chart.yaml - if webhookEnabled { - isEnabled := chart.Values["webhook"].(map[string]interface{})["enable"] - Expect(isEnabled).To(Equal(webhookEnabled), "webhook isn't enabled in the Chart.yaml") - } +func initBasicProject(kbc *utils.TestContext) { + err := kbc.Init( + "--plugins", "go/v4", + "--project-version", "3", + "--domain", kbc.Domain, + ) + Expect(err).NotTo(HaveOccurred()) } -// extendProjectWithWebhooks is creating API and scaffolding webhooks in the project -func extendProjectWithWebhooks(kbc *utils.TestContext) { - By("creating API definition") +func createTestResources(kbc *utils.TestContext) { err := kbc.CreateAPI( "--group", kbc.Group, "--version", kbc.Version, @@ -144,10 +134,11 @@ func extendProjectWithWebhooks(kbc *utils.TestContext) { "--controller", "--make=false", ) - Expect(err).NotTo(HaveOccurred(), "Failed to create API") + Expect(err).NotTo(HaveOccurred()) +} - By("scaffolding mutating and validating webhooks") - err = kbc.CreateWebhook( +func createWebhookResources(kbc *utils.TestContext) { + err := kbc.CreateWebhook( "--group", kbc.Group, "--version", kbc.Version, "--kind", kbc.Kind, @@ -155,30 +146,141 @@ func extendProjectWithWebhooks(kbc *utils.TestContext) { "--programmatic-validation", "--make=false", ) - Expect(err).NotTo(HaveOccurred(), "Failed to scaffolding mutating webhook") + Expect(err).NotTo(HaveOccurred()) By("run make manifests") Expect(kbc.Make("manifests")).To(Succeed()) } -// initTheProject initializes a project with the go/v4 plugin and sets the domain. -func initTheProject(kbc *utils.TestContext) { - By("initializing a project") - err := kbc.Init( - "--plugins", "go/v4", - "--project-version", "3", - "--domain", kbc.Domain, - ) - Expect(err).NotTo(HaveOccurred(), "Failed to initialize project") +func validateBasicHelmChart(kbc *utils.TestContext) { + chartPath := filepath.Join(kbc.Dir, "dist", "chart") + + By("verifying Chart.yaml exists and is valid") + chart, err := helmChartLoader.LoadDir(chartPath) + Expect(err).NotTo(HaveOccurred()) + Expect(chart.Validate()).To(Succeed()) + Expect(chart.Name()).To(Equal("e2e-" + kbc.TestSuffix)) + + By("verifying essential files exist") + essentialFiles := []string{ + "Chart.yaml", + "values.yaml", + ".helmignore", + "templates/_helpers.tpl", + } + for _, file := range essentialFiles { + filePath := filepath.Join(chartPath, file) + Expect(filePath).To(BeAnExistingFile()) + } +} + +func validateDynamicTemplates(kbc *utils.TestContext) { + chartPath := filepath.Join(kbc.Dir, "dist", "chart") + + By("verifying templates directory structure matches config/ structure") + expectedDirs := []string{ + "templates/manager", + "templates/rbac", + "templates/crd", + "templates/metrics", + } + for _, dir := range expectedDirs { + dirPath := filepath.Join(chartPath, dir) + Expect(dirPath).To(BeADirectory()) + } + + By("verifying manager deployment template exists") + managerTemplate := filepath.Join(chartPath, "templates", "manager", "manager.yaml") + Expect(managerTemplate).To(BeAnExistingFile()) + + By("verifying CRD templates exist") + crdDir := filepath.Join(chartPath, "templates", "crd") + files, err := afero.ReadDir(afero.NewOsFs(), crdDir) + Expect(err).NotTo(HaveOccurred()) + Expect(files).ToNot(BeEmpty()) +} + +func validateWebhookTemplates(kbc *utils.TestContext) { + chartPath := filepath.Join(kbc.Dir, "dist", "chart") + + By("verifying webhook directory exists") + webhookDir := filepath.Join(chartPath, "templates", "webhook") + Expect(webhookDir).To(BeADirectory()) + + By("verifying webhook configuration files exist") + files, err := afero.ReadDir(afero.NewOsFs(), webhookDir) + Expect(err).NotTo(HaveOccurred()) + Expect(files).ToNot(BeEmpty()) + + By("verifying webhook files contain webhook configurations") + foundValidatingWebhook := false + for _, file := range files { + if file.IsDir() { + continue + } + webhookFile := filepath.Join(webhookDir, file.Name()) + content, err := afero.ReadFile(afero.NewOsFs(), webhookFile) + Expect(err).NotTo(HaveOccurred()) + contentStr := string(content) + if strings.Contains(contentStr, "ValidatingWebhookConfiguration") { + foundValidatingWebhook = true + break + } + } + Expect(foundValidatingWebhook).To(BeTrue(), "Expected to find ValidatingWebhookConfiguration in webhook templates") +} + +func validateCertManagerIntegration(kbc *utils.TestContext) { + chartPath := filepath.Join(kbc.Dir, "dist", "chart") + + By("verifying cert-manager templates exist") + certManagerDir := filepath.Join(chartPath, "templates", "cert-manager") + Expect(certManagerDir).To(BeADirectory()) + + By("verifying cert-manager is enabled in values.yaml") + valuesPath := filepath.Join(chartPath, "values.yaml") + valuesContent, err := afero.ReadFile(afero.NewOsFs(), valuesPath) + Expect(err).NotTo(HaveOccurred()) + Expect(string(valuesContent)).To(ContainSubstring("certManager:")) + Expect(string(valuesContent)).To(ContainSubstring("enable: true")) +} + +func validatePluginConfig(kbc *utils.TestContext) { + By("verifying plugin configuration is tracked in PROJECT file") + projectPath := filepath.Join(kbc.Dir, "PROJECT") + projectConfig := getConfigFromProjectFile(projectPath) + + var helmConfig helmv2alpha.Plugin + err := projectConfig.DecodePluginConfig("helm.kubebuilder.io/v2-alpha", &helmConfig) + Expect(err).NotTo(HaveOccurred()) +} + +func validateCustomOutputDir(kbc *utils.TestContext, outputDir string) { + chartPath := filepath.Join(kbc.Dir, outputDir, "chart") + + By("verifying chart exists in custom directory") + Expect(chartPath).To(BeADirectory()) + + By("verifying Chart.yaml in custom directory") + chartFile := filepath.Join(chartPath, "Chart.yaml") + Expect(chartFile).To(BeAnExistingFile()) +} + +func validateFilePreservation(kbc *utils.TestContext, outputDir string) { + chartPath := filepath.Join(kbc.Dir, outputDir, "chart") + + By("verifying files still exist after re-run") + valuesFile := filepath.Join(chartPath, "values.yaml") + Expect(valuesFile).To(BeAnExistingFile()) + + chartFile := filepath.Join(chartPath, "Chart.yaml") + Expect(chartFile).To(BeAnExistingFile()) } func getConfigFromProjectFile(projectFilePath string) config.Config { - By("loading the PROJECT configuration") fs := afero.NewOsFs() store := yaml.New(machinery.Filesystem{FS: fs}) err := store.LoadFrom(projectFilePath) - Expect(err).NotTo(HaveOccurred(), "Failed to load PROJECT configuration") - - cfg := store.Config() - return cfg + Expect(err).NotTo(HaveOccurred()) + return store.Config() } diff --git a/test/e2e/helm/plugin_cluster_test.go b/test/e2e/helm/plugin_cluster_test.go new file mode 100644 index 00000000000..0665080d4f0 --- /dev/null +++ b/test/e2e/helm/plugin_cluster_test.go @@ -0,0 +1,933 @@ +/* +Copyright 2025 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 helm + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + pluginutil "sigs.k8s.io/kubebuilder/v4/pkg/plugin/util" + "sigs.k8s.io/kubebuilder/v4/test/e2e/utils" +) + +const ( + tokenRequestRawString = `{"apiVersion": "authentication.k8s.io/v1", "kind": "TokenRequest"}` +) + +// tokenRequest is a trimmed down version of the authentication.k8s.io/v1/TokenRequest Type +// that we want to use for extracting the token. +type tokenRequest struct { + Status struct { + Token string `json:"token"` + } `json:"status"` +} + +var _ = Describe("kubebuilder", func() { + Context("plugin helm/v2-alpha", func() { + var kbc *utils.TestContext + + BeforeEach(func() { + var err error + kbc, err = utils.NewTestContext(pluginutil.KubebuilderBinName, "GO111MODULE=on") + Expect(err).NotTo(HaveOccurred()) + Expect(kbc.Prepare()).To(Succeed()) + }) + + AfterEach(func() { + By("removing restricted namespace label") + _ = kbc.RemoveNamespaceLabelToEnforceRestricted() + + By("uninstalling Helm Release (if installed)") + _ = kbc.UninstallHelmRelease() + + By("removing controller image and working dir") + kbc.Destroy() + }) + + It("should generate a runnable project using webhooks and installed with the HelmChart", func() { + generateHelmProject(kbc) + By("installing Helm") + Expect(kbc.InstallHelm()).To(Succeed()) + + runHelm(kbc, true, true, false) + }) + + It("should generate a runnable project without metrics exposed", func() { + generateHelmProjectWithoutMetrics(kbc) + By("installing Helm") + Expect(kbc.InstallHelm()).To(Succeed()) + + runHelm(kbc, true, false, false) + }) + + It("should generate a runnable project with metrics protected by network policies", func() { + generateHelmProjectWithNetworkPoliciesWithoutWebhooks(kbc) + By("installing Helm") + Expect(kbc.InstallHelm()).To(Succeed()) + + runHelm(kbc, false, true, true) + }) + + It("should generate a runnable project with webhooks and metrics protected by network policies", func() { + generateHelmProjectWithNetworkPolicies(kbc) + By("installing Helm") + Expect(kbc.InstallHelm()).To(Succeed()) + + runHelm(kbc, true, true, true) + }) + + It("should generate a runnable project with the manager running as restricted and without webhooks", func() { + generateHelmProjectWithoutWebhooks(kbc) + By("installing Helm") + Expect(kbc.InstallHelm()).To(Succeed()) + + runHelm(kbc, false, true, false) + }) + }) +}) + +// runHelm executes the helm-based deployment and validations similar to go/v4 Run, +// but always installs via the Helm chart generated by the helm/v2-alpha plugin. +func runHelm(kbc *utils.TestContext, hasWebhook, hasMetrics, hasNetworkPolicies bool) { + var controllerPodName string + var err error + + By("creating manager namespace") + err = kbc.CreateManagerNamespace() + Expect(err).NotTo(HaveOccurred()) + + By("labeling the namespace to enforce the restricted security policy") + err = kbc.LabelNamespacesToEnforceRestricted() + Expect(err).NotTo(HaveOccurred()) + + By("updating the go.mod") + err = kbc.Tidy() + Expect(err).NotTo(HaveOccurred()) + + By("run make all") + err = kbc.Make("all") + Expect(err).NotTo(HaveOccurred()) + + By("building the controller image") + err = kbc.Make("docker-build", "IMG="+kbc.ImageName) + Expect(err).NotTo(HaveOccurred()) + + By("loading the controller docker image into the kind cluster") + err = kbc.LoadImageToKindCluster() + Expect(err).NotTo(HaveOccurred()) + + By("building the installer manifest for helm chart generation") + err = kbc.Make("build-installer", "IMG="+kbc.ImageName) + Expect(err).NotTo(HaveOccurred(), "Failed to build installer manifest") + + 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 = pluginutil.ReplaceInFile(values, "repository: controller", "repository: e2e-test/controller-manager") + Expect(err).NotTo(HaveOccurred(), "Failed to edit repository in the chart/values.yaml") + err = pluginutil.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 = pluginutil.ReplaceInFile(values, "prometheus:\n enable: false", "prometheus:\n enable: true") + Expect(err).NotTo(HaveOccurred(), "Failed to enable prometheus in the chart/values.yaml") + + if hasWebhook { + By("updating values to enable cert-manager and cleanup CRDs on uninstall") + // ensure CRDs are not kept on uninstall for cleanup in tests + err = pluginutil.ReplaceInFile(values, "keep: true", "keep: false") + Expect(err).NotTo(HaveOccurred(), "Failed to set keep false in the chart/values.yaml") + } + + By("install with Helm release") + err = kbc.HelmInstallRelease() + Expect(err).NotTo(HaveOccurred(), "Failed to install helm release") + + By("Checking controllerManager and getting the name of the Pod") + controllerPodName = getControllerName(kbc) + + By("Checking if all flags are applied to the manager pod") + podOutput, err := kbc.Kubectl.Get( + true, + "pod", controllerPodName, + "-o", "jsonpath={.spec.containers[0].args}", + ) + Expect(err).NotTo(HaveOccurred()) + Expect(podOutput).To(ContainSubstring("leader-elect"), + "Expected manager pod to have --leader-elect flag") + Expect(podOutput).To(ContainSubstring("health-probe-bind-address"), + "Expected manager pod to have --health-probe-bind-address flag") + + By("validating that the Prometheus manager has provisioned the Service") + Eventually(func(g Gomega) { + _, err = kbc.Kubectl.Get( + false, + "Service", "prometheus-operator") + g.Expect(err).NotTo(HaveOccurred()) + }, time.Minute, time.Second).Should(Succeed()) + + By("validating that the ServiceMonitor for Prometheus is applied in the namespace") + _, err = kbc.Kubectl.Get( + true, + "ServiceMonitor") + Expect(err).NotTo(HaveOccurred()) + + if hasNetworkPolicies { + if hasMetrics { + By("labeling the namespace to allow consume the metrics") + Expect(kbc.Kubectl.Command("label", "namespaces", kbc.Kubectl.Namespace, + "metrics=enabled")).Error().NotTo(HaveOccurred()) + + By("Ensuring the Allow Metrics Traffic NetworkPolicy exists", func() { + var output string + output, err = kbc.Kubectl.Get( + true, + "networkpolicy", fmt.Sprintf("e2e-%s-allow-metrics-traffic", kbc.TestSuffix), + ) + Expect(err).NotTo(HaveOccurred(), "NetworkPolicy allow-metrics-traffic should exist in the namespace") + Expect(output).To( + ContainSubstring("allow-metrics-traffic"), + "NetworkPolicy allow-metrics-traffic should be present in the output", + ) + }) + } + + if hasWebhook { + By("labeling the namespace to allow webhooks traffic") + _, err = kbc.Kubectl.Command("label", "namespaces", kbc.Kubectl.Namespace, + "webhook=enabled") + Expect(err).NotTo(HaveOccurred()) + + By("Ensuring the allow-webhook-traffic NetworkPolicy exists", func() { + var output string + output, err = kbc.Kubectl.Get( + true, + "networkpolicy", fmt.Sprintf("e2e-%s-allow-webhook-traffic", kbc.TestSuffix), + ) + Expect(err).NotTo(HaveOccurred(), "NetworkPolicy allow-webhook-traffic should exist in the namespace") + Expect(output).To( + ContainSubstring("allow-webhook-traffic"), + "NetworkPolicy allow-webhook-traffic should be present in the output", + ) + }) + } + } + + if hasWebhook { + By("validating that cert-manager has provisioned the certificate Secret") + + verifyWebhookCert := func(g Gomega) { + var output string + output, err = kbc.Kubectl.Get( + true, + "secrets", "webhook-server-cert") + g.Expect(err).ToNot(HaveOccurred(), "webhook-server-cert should exist in the namespace") + g.Expect(output).To(ContainSubstring("webhook-server-cert")) + } + + Eventually(verifyWebhookCert, time.Minute, time.Second).Should(Succeed()) + + By("validating that the mutating|validating webhooks have the CA injected") + verifyCAInjection := func(g Gomega) { + var mwhOutput, vwhOutput string + mwhOutput, err = kbc.Kubectl.Get( + false, + "mutatingwebhookconfigurations.admissionregistration.k8s.io", + fmt.Sprintf("e2e-%s-mutating-webhook-configuration", kbc.TestSuffix), + "-o", "go-template={{ range .webhooks }}{{ .clientConfig.caBundle }}{{ end }}") + g.Expect(err).NotTo(HaveOccurred()) + // check that ca should be long enough, because there may be a place holder "\n" + g.Expect(len(mwhOutput)).To(BeNumerically(">", 10)) + + vwhOutput, err = kbc.Kubectl.Get( + false, + "validatingwebhookconfigurations.admissionregistration.k8s.io", + fmt.Sprintf("e2e-%s-validating-webhook-configuration", kbc.TestSuffix), + "-o", "go-template={{ range .webhooks }}{{ .clientConfig.caBundle }}{{ end }}") + g.Expect(err).NotTo(HaveOccurred()) + // check that ca should be long enough, because there may be a place holder "\n" + g.Expect(len(vwhOutput)).To(BeNumerically(">", 10)) + } + + Eventually(verifyCAInjection, time.Minute, time.Second).Should(Succeed()) + } + + By("creating an instance of the CR") + sampleFile := filepath.Join("config", "samples", + fmt.Sprintf("%s_%s_%s.yaml", kbc.Group, kbc.Version, strings.ToLower(kbc.Kind))) + sampleFilePath, err := filepath.Abs(filepath.Join(fmt.Sprintf("e2e-%s", kbc.TestSuffix), sampleFile)) + Expect(err).To(Not(HaveOccurred())) + + f, err := os.OpenFile(sampleFilePath, os.O_APPEND|os.O_WRONLY, 0o644) + Expect(err).To(Not(HaveOccurred())) + defer func() { + err = f.Close() + Expect(err).To(Not(HaveOccurred())) + }() + _, err = f.WriteString(" foo: bar") + Expect(err).To(Not(HaveOccurred())) + + applySample := func(g Gomega) { + _, applyErr := kbc.Kubectl.Apply(true, "-f", sampleFile) + g.Expect(applyErr).NotTo(HaveOccurred()) + } + Eventually(applySample, time.Minute, time.Second).Should(Succeed()) + + By("validating that the controller-manager pod is running as expected") + verifyControllerUp := func(g Gomega) error { + // Get pod name + const podListGoTemplate = "go-template={{ range .items }}" + + "{{ if not .metadata.deletionTimestamp }}" + + "{{ .metadata.name }}" + + "{{ \"\\n\" }}" + + "{{ end }}" + + "{{ end }}" + podOutput, getErr := kbc.Kubectl.Get( + true, + "pods", "-l", "control-plane=controller-manager", + "-o", podListGoTemplate) + g.Expect(getErr).NotTo(HaveOccurred()) + podNames := pluginutil.GetNonEmptyLines(podOutput) + if len(podNames) != 1 { + return fmt.Errorf("expect 1 controller pods running, but got %d", len(podNames)) + } + controllerPodName = podNames[0] + g.Expect(controllerPodName).Should(ContainSubstring("controller-manager")) + + // Validate pod status + status, statusErr := kbc.Kubectl.Get( + true, + "pods", controllerPodName, "-o", "jsonpath={.status.phase}") + g.Expect(statusErr).NotTo(HaveOccurred()) + if status != "Running" { + return fmt.Errorf("controller pod in %s status", status) + } + return nil + } + Eventually(verifyControllerUp, 5*time.Minute, time.Second).Should(Succeed()) + + if hasMetrics { + _ = getMetricsOutput(kbc) + } else { + metricsShouldBeUnavailable(kbc) + } + + if hasWebhook { + By("validating that the CRD conversion was properly configured and works as expected") + + // Ensure CRD conversion webhook has CA injected before testing conversion + By("waiting for CRD conversion CA bundle to be injected") + crdName := fmt.Sprintf("conversiontests.%s.%s", kbc.Group, kbc.Domain) + Eventually(func(g Gomega) { + out, errGet := kbc.Kubectl.Get( + true, + "crd", crdName, + "-o", "jsonpath={.spec.conversion.webhook.clientConfig.caBundle}", + ) + g.Expect(errGet).NotTo(HaveOccurred()) + g.Expect(len(strings.TrimSpace(out))).To(BeNumerically(">", 10)) + }, 2*time.Minute, 2*time.Second).Should(Succeed()) + + // Update the ConversionTest CR sample in v1 to set a specific `size` + By("modifying the ConversionTest CR sample to set `size` for conversion testing") + conversionCRFile := filepath.Join("config", "samples", + fmt.Sprintf("%s_v1_conversiontest.yaml", kbc.Group)) + conversionCRPath := filepath.Join(kbc.Dir, conversionCRFile) + + // Edit the file to include `size` in the spec field for v1 + err = pluginutil.ReplaceInFile(conversionCRPath, "# TODO(user): Add fields here", `size: 3`) + Expect(err).NotTo(HaveOccurred(), "failed to replace spec in ConversionTest CR sample") + + // Apply the ConversionTest Custom Resource in v1 + By("applying the modified ConversionTest CR in v1 for conversion") + _, err = kbc.Kubectl.Apply(true, "-f", conversionCRPath) + Expect(err).NotTo(HaveOccurred(), "failed to apply modified ConversionTest CR") + + By("waiting for the ConversionTest CR to appear") + Eventually(func(g Gomega) { + _, err := kbc.Kubectl.Get(true, "conversiontest", "conversiontest-sample") + g.Expect(err).NotTo(HaveOccurred(), "expected the ConversionTest CR to exist") + }, time.Minute, time.Second).Should(Succeed()) + + By("validating that the converted resource in v2 has replicas == 3") + Eventually(func(g Gomega) { + out, err := kbc.Kubectl.Get( + true, + "conversiontest", "conversiontest-sample", + "-o", "jsonpath={.spec.replicas}", + ) + g.Expect(err).NotTo(HaveOccurred(), "failed to get converted resource in v2") + replicas, err := strconv.Atoi(out) + g.Expect(err).NotTo(HaveOccurred(), "replicas field is not an integer") + g.Expect(replicas).To(Equal(3), "expected replicas to be 3 after conversion") + }, 2*time.Minute, 2*time.Second).Should(Succeed()) + } +} + +func getControllerName(kbc *utils.TestContext) string { + By("validating that the controller-manager pod is running as expected") + var controllerPodName string + verifyControllerUp := func(g Gomega) error { + // Get pod name + const podListGoTemplate = "go-template={{ range .items }}" + + "{{ if not .metadata.deletionTimestamp }}" + + "{{ .metadata.name }}" + + "{{ \"\\n\" }}" + + "{{ end }}" + + "{{ end }}" + podOutput, err := kbc.Kubectl.Get( + true, + "pods", "-l", "control-plane=controller-manager", + "-o", podListGoTemplate) + g.Expect(err).NotTo(HaveOccurred()) + podNames := pluginutil.GetNonEmptyLines(podOutput) + if len(podNames) != 1 { + return fmt.Errorf("expect 1 controller pods running, but got %d", len(podNames)) + } + controllerPodName = podNames[0] + g.Expect(controllerPodName).Should(ContainSubstring("controller-manager")) + + // Validate pod status + status, err := kbc.Kubectl.Get( + true, + "pods", controllerPodName, "-o", "jsonpath={.status.phase}") + g.Expect(err).NotTo(HaveOccurred()) + if status != "Running" { + return fmt.Errorf("controller pod in %s status", status) + } + return nil + } + defer func() { + out, err := kbc.Kubectl.CommandInNamespace("describe", "all") + Expect(err).NotTo(HaveOccurred()) + _, _ = fmt.Fprintln(GinkgoWriter, out) + }() + Eventually(verifyControllerUp, 5*time.Minute, time.Second).Should(Succeed()) + return controllerPodName +} + +// getMetricsOutput return the metrics output from curl pod +func getMetricsOutput(kbc *utils.TestContext) string { + _, err := kbc.Kubectl.Command( + "get", "clusterrolebinding", fmt.Sprintf("metrics-%s", kbc.TestSuffix), + ) + if err != nil && strings.Contains(err.Error(), "NotFound") { + // Create the clusterrolebinding only if it doesn't exist + _, err = kbc.Kubectl.Command( + "create", "clusterrolebinding", fmt.Sprintf("metrics-%s", kbc.TestSuffix), + fmt.Sprintf("--clusterrole=e2e-%s-metrics-reader", kbc.TestSuffix), + fmt.Sprintf("--serviceaccount=%s:%s", kbc.Kubectl.Namespace, kbc.Kubectl.ServiceAccount), + ) + Expect(err).NotTo(HaveOccurred()) + } else { + Expect(err).NotTo(HaveOccurred(), "Failed to check clusterrolebinding existence") + } + + token, err := serviceAccountToken(kbc) + Expect(err).NotTo(HaveOccurred()) + Expect(token).NotTo(BeEmpty()) + + var metricsOutput string + By("validating that the controller-manager service is available") + _, err = kbc.Kubectl.Get( + true, + "service", fmt.Sprintf("e2e-%s-controller-manager-metrics-service", kbc.TestSuffix), + ) + Expect(err).NotTo(HaveOccurred(), "Controller-manager service should exist") + + By("ensuring the service endpoint is ready") + checkServiceEndpoint := func(g Gomega) { + var output string + output, err = kbc.Kubectl.Get( + true, + "endpoints", fmt.Sprintf("e2e-%s-controller-manager-metrics-service", kbc.TestSuffix), + "-o", "jsonpath={.subsets[*].addresses[*].ip}", + ) + g.Expect(err).NotTo(HaveOccurred(), "endpoints should exist") + g.Expect(output).ShouldNot(BeEmpty(), "no endpoints found") + } + Eventually(checkServiceEndpoint, 2*time.Minute, time.Second).Should(Succeed(), + "Service endpoint should be ready") + + // See comment in v4 suite about metrics readiness delay on newer k8s + By("waiting briefly to ensure that the certs are provisioned and metrics are available") + time.Sleep(15 * time.Second) + + By("creating a curl pod to access the metrics endpoint") + cmdOpts := cmdOptsToCreateCurlPod(kbc, token) + _, err = kbc.Kubectl.CommandInNamespace(cmdOpts...) + Expect(err).NotTo(HaveOccurred()) + + By("validating that the controllerManager ServiceAccount exists") + saName := kbc.Kubectl.ServiceAccount + currentSAOutput, err := kbc.Kubectl.Get( + true, + "serviceaccount", saName, + "-o", "jsonpath={.metadata.name}", + ) + Expect(err).NotTo(HaveOccurred(), "Failed to fetch the service account") + Expect(currentSAOutput).To(Equal(saName), "The ServiceAccount in use does not match the expected one") + + By("validating that the metrics endpoint is serving as expected") + getCurlLogs := func(g Gomega) { + metricsOutput, err = kbc.Kubectl.Logs("curl") + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(metricsOutput).Should(ContainSubstring("< HTTP/1.1 200 OK")) + } + Eventually(getCurlLogs, 10*time.Second, time.Second).Should(Succeed()) + removeCurlPod(kbc) + return metricsOutput +} + +func metricsShouldBeUnavailable(kbc *utils.TestContext) { + _, err := kbc.Kubectl.Command( + "create", "clusterrolebinding", fmt.Sprintf("metrics-%s", kbc.TestSuffix), + fmt.Sprintf("--clusterrole=e2e-%s-metrics-reader", kbc.TestSuffix), + fmt.Sprintf("--serviceaccount=%s:%s", kbc.Kubectl.Namespace, kbc.Kubectl.ServiceAccount)) + Expect(err).NotTo(HaveOccurred()) + + token, err := serviceAccountToken(kbc) + Expect(err).NotTo(HaveOccurred()) + Expect(token).NotTo(BeEmpty()) + + By("creating a curl pod to access the metrics endpoint") + cmdOpts := cmdOptsToCreateCurlPod(kbc, token) + _, err = kbc.Kubectl.CommandInNamespace(cmdOpts...) + Expect(err).NotTo(HaveOccurred()) + + By("validating that the curl pod fail as expected") + verifyCurlUp := func(g Gomega) { + status, errCurl := kbc.Kubectl.Get( + true, + "pods", "curl", "-o", "jsonpath={.status.phase}") + g.Expect(errCurl).NotTo(HaveOccurred()) + g.Expect(status).NotTo(Equal("Failed"), + fmt.Sprintf("curl pod in %s status when should fail with an error", status)) + } + Eventually(verifyCurlUp, 240*time.Second, time.Second).Should(Succeed()) + + By("validating that the metrics endpoint is not working as expected") + getCurlLogs := func(g Gomega) { + metricsOutput, err := kbc.Kubectl.Logs("curl") + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(metricsOutput).Should(ContainSubstring("Could not resolve host")) + } + Eventually(getCurlLogs, 10*time.Second, time.Second).Should(Succeed()) + removeCurlPod(kbc) +} + +func cmdOptsToCreateCurlPod(kbc *utils.TestContext, token string) []string { + //nolint:lll + cmdOpts := []string{ + "run", "curl", + "--restart=Never", + "--namespace", kbc.Kubectl.Namespace, + "--image=curlimages/curl:latest", + "--overrides", + fmt.Sprintf(`{ + "spec": { + "containers": [{ + "name": "curl", + "image": "curlimages/curl:latest", + "command": ["/bin/sh", "-c"], + "args": ["curl -v -k -H 'Authorization: Bearer %s' https://e2e-%s-controller-manager-metrics-service.%s.svc.cluster.local:8443/metrics"], + "securityContext": { + "readOnlyRootFilesystem": true, + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": ["ALL"] + }, + "runAsNonRoot": true, + "runAsUser": 1000, + "seccompProfile": { + "type": "RuntimeDefault" + } + } + }], + "serviceAccountName": "%s" + } + }`, token, kbc.TestSuffix, kbc.Kubectl.Namespace, kbc.Kubectl.ServiceAccount), + } + return cmdOpts +} + +func removeCurlPod(kbc *utils.TestContext) { + By("cleaning up the curl pod") + _, err := kbc.Kubectl.Delete(true, "pods/curl", "--grace-period=0", "--force") + Expect(err).NotTo(HaveOccurred()) +} + +// serviceAccountToken provides a helper function that can provide you with a service account +// token that you can use to interact with the service. This function leverages the k8s' +// TokenRequest API in raw format in order to make it generic for all version of the k8s that +// is currently being supported in kubebuilder test infra. +// TokenRequest API returns the token in raw JWT format itself. There is no conversion required. +func serviceAccountToken(kbc *utils.TestContext) (string, error) { + var out string + + secretName := fmt.Sprintf("%s-token-request", kbc.Kubectl.ServiceAccount) + tokenRequestFile := filepath.Join(kbc.Dir, secretName) + if err := os.WriteFile(tokenRequestFile, []byte(tokenRequestRawString), os.FileMode(0o755)); err != nil { + return out, fmt.Errorf("error creating token request file %s: %w", tokenRequestFile, err) + } + getToken := func(g Gomega) { + // Output of this is already a valid JWT token. No need to covert this from base64 to string format + rawJSON, err := kbc.Kubectl.Command( + "create", + "--raw", fmt.Sprintf( + "/api/v1/namespaces/%s/serviceaccounts/%s/token", + kbc.Kubectl.Namespace, + kbc.Kubectl.ServiceAccount, + ), + "-f", tokenRequestFile, + ) + + g.Expect(err).NotTo(HaveOccurred()) + var token tokenRequest + err = json.Unmarshal([]byte(rawJSON), &token) + g.Expect(err).NotTo(HaveOccurred()) + + out = token.Status.Token + } + Eventually(getToken, time.Minute, time.Second).Should(Succeed()) + + return out, nil +} + +// generateHelmProject sets up a go/v4 project with webhooks and conversion webhook enabled, +// and prepares kustomize configs so the helm plugin can generate full charts. +func generateHelmProject(kbc *utils.TestContext) { + initHelmProject(kbc) + createAPI(kbc) + + By("scaffolding mutating and validating webhooks") + err := kbc.CreateWebhook( + "--group", kbc.Group, + "--version", kbc.Version, + "--kind", kbc.Kind, + "--defaulting", + "--programmatic-validation", + "--make=false", + ) + Expect(err).NotTo(HaveOccurred(), "Failed to scaffolding mutating webhook") + + By("implementing the mutating and validating webhooks") + webhookFilePath := filepath.Join( + kbc.Dir, "internal/webhook", kbc.Version, + fmt.Sprintf("%s_webhook.go", strings.ToLower(kbc.Kind))) + err = utils.ImplementWebhooks(webhookFilePath, strings.ToLower(kbc.Kind)) + Expect(err).NotTo(HaveOccurred(), "Failed to implement webhooks") + + scaffoldConversionWebhook(kbc) + + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- ../prometheus", "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "prometheus", "kustomization.yaml"), + monitorTLSPatch, "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + metricsCertPatch, "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + metricsCertReplaces, "#")).To(Succeed()) +} + +func generateHelmProjectWithoutMetrics(kbc *utils.TestContext) { + initHelmProject(kbc) + createAPI(kbc) + + By("scaffolding mutating and validating webhooks") + err := kbc.CreateWebhook( + "--group", kbc.Group, + "--version", kbc.Version, + "--kind", kbc.Kind, + "--defaulting", + "--programmatic-validation", + "--make=false", + ) + Expect(err).NotTo(HaveOccurred(), "Failed to scaffolding mutating webhook") + + By("implementing the mutating and validating webhooks") + webhookFilePath := filepath.Join( + kbc.Dir, "internal/webhook", kbc.Version, + fmt.Sprintf("%s_webhook.go", strings.ToLower(kbc.Kind))) + err = utils.ImplementWebhooks(webhookFilePath, strings.ToLower(kbc.Kind)) + Expect(err).NotTo(HaveOccurred(), "Failed to implement webhooks") + + scaffoldConversionWebhook(kbc) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- ../prometheus", "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.CommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "- metrics_service.yaml", "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.CommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + metricsTarget, "#")).To(Succeed()) +} + +func generateHelmProjectWithNetworkPoliciesWithoutWebhooks(kbc *utils.TestContext) { + initHelmProject(kbc) + createAPI(kbc) + + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- ../prometheus", "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + metricsTarget, "#")).To(Succeed()) + By("uncomment kustomization.yaml to enable network policy") + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- ../network-policy", "#")).To(Succeed()) +} + +func generateHelmProjectWithNetworkPolicies(kbc *utils.TestContext) { + initHelmProject(kbc) + createAPI(kbc) + + By("scaffolding mutating and validating webhooks") + err := kbc.CreateWebhook( + "--group", kbc.Group, + "--version", kbc.Version, + "--kind", kbc.Kind, + "--defaulting", + "--programmatic-validation", + "--make=false", + ) + Expect(err).NotTo(HaveOccurred(), "Failed to scaffolding mutating webhook") + + By("implementing the mutating and validating webhooks") + webhookFilePath := filepath.Join( + kbc.Dir, "internal/webhook", kbc.Version, + fmt.Sprintf("%s_webhook.go", strings.ToLower(kbc.Kind))) + err = utils.ImplementWebhooks(webhookFilePath, strings.ToLower(kbc.Kind)) + Expect(err).NotTo(HaveOccurred(), "Failed to implement webhooks") + + scaffoldConversionWebhook(kbc) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- ../prometheus", "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + metricsTarget, "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + metricsCertPatch, "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + metricsCertReplaces, "#")).To(Succeed()) + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "prometheus", "kustomization.yaml"), + monitorTLSPatch, "#")).To(Succeed()) + + By("uncomment kustomization.yaml to enable network policy") + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- ../network-policy", "#")).To(Succeed()) +} + +func generateHelmProjectWithoutWebhooks(kbc *utils.TestContext) { + initHelmProject(kbc) + createAPI(kbc) + + ExpectWithOffset(1, pluginutil.UncommentCode( + filepath.Join(kbc.Dir, "config", "default", "kustomization.yaml"), + "#- ../prometheus", "#")).To(Succeed()) +} + +func createAPI(kbc *utils.TestContext) { + By("creating API definition") + err := kbc.CreateAPI( + "--group", kbc.Group, + "--version", kbc.Version, + "--kind", kbc.Kind, + "--namespaced", + "--resource", + "--controller", + "--make=false", + ) + Expect(err).NotTo(HaveOccurred(), "Failed to create API") + + By("implementing the API") + ExpectWithOffset(1, pluginutil.InsertCode( + filepath.Join(kbc.Dir, "api", kbc.Version, fmt.Sprintf("%s_types.go", strings.ToLower(kbc.Kind))), + fmt.Sprintf(`type %sSpec struct { +`, kbc.Kind), + "\t// +optional\nCount int `json:\"count,omitempty\"`\n")).Should(Succeed()) +} + +func initHelmProject(kbc *utils.TestContext) { + By("initializing a project") + err := kbc.Init( + "--plugins", "go/v4", + "--project-version", "3", + "--domain", kbc.Domain, + ) + Expect(err).NotTo(HaveOccurred(), "Failed to initialize project") +} + +const metricsTarget = `- path: manager_metrics_patch.yaml + target: + kind: Deployment` + +// scaffoldConversionWebhook sets up conversion webhooks for testing the ConversionTest API +func scaffoldConversionWebhook(kbc *utils.TestContext) { + By("scaffolding conversion webhooks for testing ConversionTest v1 to v2 conversion") + + // Create API for v1 (hub) with conversion enabled + err := kbc.CreateAPI( + "--group", kbc.Group, + "--version", "v1", + "--kind", "ConversionTest", + "--controller=true", + "--resource=true", + "--make=false", + ) + ExpectWithOffset(1, err).NotTo(HaveOccurred(), "failed to create v1 API for conversion testing") + + // Create API for v2 (spoke) without a controller + err = kbc.CreateAPI( + "--group", kbc.Group, + "--version", "v2", + "--kind", "ConversionTest", + "--controller=false", + "--resource=true", + "--make=false", + ) + ExpectWithOffset(1, err).NotTo(HaveOccurred(), "failed to create v2 API for conversion testing") + + // Create the conversion webhook for v1 + By("setting up the conversion webhook for v1") + err = kbc.CreateWebhook( + "--group", kbc.Group, + "--version", "v1", + "--kind", "ConversionTest", + "--conversion", + "--spoke", "v2", + "--make=false", + ) + ExpectWithOffset(1, err).NotTo(HaveOccurred(), "failed to create conversion webhook for v1") + + // Insert Size field in v1 + By("implementing the size spec in v1") + ExpectWithOffset(1, pluginutil.InsertCode( + filepath.Join(kbc.Dir, "api", "v1", "conversiontest_types.go"), + "Foo *string `json:\"foo,omitempty\"`", + "\n\tSize int `json:\"size,omitempty\"` // Number of desired instances", + )).NotTo(HaveOccurred(), "failed to add size spec to conversiontest_types v1") + + // Insert Replicas field in v2 + By("implementing the replicas spec in v2") + ExpectWithOffset(1, pluginutil.InsertCode( + filepath.Join(kbc.Dir, "api", "v2", "conversiontest_types.go"), + "Foo *string `json:\"foo,omitempty\"`", + "\n\tReplicas int `json:\"replicas,omitempty\"` // Number of replicas", + )).NotTo(HaveOccurred(), "failed to add replicas spec to conversiontest_conversion.go v2") + + err = pluginutil.ReplaceInFile(filepath.Join(kbc.Dir, "api/v2/conversiontest_conversion.go"), + "// dst.Spec.Size = src.Spec.Replicas", + "dst.Spec.Size = src.Spec.Replicas") + Expect(err).NotTo(HaveOccurred(), "failed to implement conversion logic from v1 to v2") + + err = pluginutil.ReplaceInFile(filepath.Join(kbc.Dir, "api/v2/conversiontest_conversion.go"), + "// dst.Spec.Replicas = src.Spec.Size", + "dst.Spec.Replicas = src.Spec.Size") + Expect(err).NotTo(HaveOccurred(), "failed to implement conversion logic from v2 to v1") +} + +const monitorTLSPatch = `#patches: +# - path: monitor_tls_patch.yaml +# target: +# kind: ServiceMonitor` + +const metricsCertPatch = `#- path: cert_metrics_manager_patch.yaml +# target: +# kind: Deployment` + +const metricsCertReplaces = `# - source: # Uncomment the following block to enable certificates for metrics +# kind: Service +# version: v1 +# name: controller-manager-metrics-service +# fieldPath: metadata.name +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: metrics-certs +# fieldPaths: +# - spec.dnsNames.0 +# - spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 0 +# create: true +# - select: # Uncomment the following to set the Service name for TLS config in Prometheus ServiceMonitor +# kind: ServiceMonitor +# group: monitoring.coreos.com +# version: v1 +# name: controller-manager-metrics-monitor +# fieldPaths: +# - spec.endpoints.0.tlsConfig.serverName +# options: +# delimiter: '.' +# index: 0 +# create: true + +# - source: +# kind: Service +# version: v1 +# name: controller-manager-metrics-service +# fieldPath: metadata.namespace +# targets: +# - select: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: metrics-certs +# fieldPaths: +# - spec.dnsNames.0 +# - spec.dnsNames.1 +# options: +# delimiter: '.' +# index: 1 +# create: true +# - select: # Uncomment the following to set the Service namespace for TLS in Prometheus ServiceMonitor +# kind: ServiceMonitor +# group: monitoring.coreos.com +# version: v1 +# name: controller-manager-metrics-monitor +# fieldPaths: +# - spec.endpoints.0.tlsConfig.serverName +# options: +# delimiter: '.' +# index: 1 +# create: true` diff --git a/test/e2e/setup.sh b/test/e2e/setup.sh index 231c335127d..c849036bc6a 100755 --- a/test/e2e/setup.sh +++ b/test/e2e/setup.sh @@ -66,4 +66,5 @@ function test_cluster { go test $(dirname "$0")/deployimage $flags -timeout 30m go test $(dirname "$0")/v4 $flags -timeout 30m + go test $(dirname "$0")/helm $flags -timeout 30m } diff --git a/test/e2e/utils/test_context.go b/test/e2e/utils/test_context.go index a06cee0ce1f..b24970b73cb 100644 --- a/test/e2e/utils/test_context.go +++ b/test/e2e/utils/test_context.go @@ -404,9 +404,9 @@ func (t *TestContext) UninstallHelmRelease() error { return nil } -// EditHelmPlugin is for running `kubebuilder edit --plugins=helm.kubebuilder.io/v1-alpha` +// EditHelmPlugin is for running `kubebuilder edit --plugins=helm.kubebuilder.io/v2-alpha` func (t *TestContext) EditHelmPlugin() error { - cmd := exec.Command(t.BinaryName, "edit", "--plugins=helm/v1-alpha") + cmd := exec.Command(t.BinaryName, "edit", "--plugins=helm.kubebuilder.io/v2-alpha") _, 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 2bab11205b5..14940eca73f 100644 --- a/test/e2e/v4/plugin_cluster_test.go +++ b/test/e2e/v4/plugin_cluster_test.go @@ -77,16 +77,6 @@ var _ = Describe("kubebuilder", func() { GenerateV4(kbc) Run(kbc, true, true, false, true, false) }) - It("should generate a runnable project using webhooks and installed with the HelmChart", func() { - 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() { GenerateV4WithoutMetrics(kbc) Run(kbc, true, false, false, false, false) @@ -154,32 +144,6 @@ func Run(kbc *utils.TestContext, hasWebhook, isToUseInstaller, isToUseHelmChart, _, err = kbc.Kubectl.Apply(true, "-f", "dist/install.yaml") Expect(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 enable: false", "prometheus:\n enable: true") - Expect(err).NotTo(HaveOccurred(), "Failed to enable prometheus in the chart/values.yaml") - - By("updating values to set crd.keep false") - err = util.ReplaceInFile(values, "keep: true", "keep: false") - Expect(err).NotTo(HaveOccurred(), "Failed to set keep false in the chart/values.yaml") - - By("install with Helm release") - err = kbc.HelmInstallRelease() - Expect(err).NotTo(HaveOccurred(), "Failed to install helm release") - } - By("Checking controllerManager and getting the name of the Pod") controllerPodName = getControllerName(kbc) diff --git a/test/features.sh b/test/features.sh index f5d48d9a611..be3994429fe 100755 --- a/test/features.sh +++ b/test/features.sh @@ -28,9 +28,6 @@ pushd . >/dev/null header_text "Running Grafana Plugin E2E tests" go test "$(dirname "$0")/e2e/grafana" ${flags:-} -timeout 30m -header_text "Running Helm Plugin E2E tests" -go test "$(dirname "$0")/e2e/helm" ${flags:-} -timeout 30m - header_text "Running Alpha Generate Command E2E tests" go test "$(dirname "$0")/e2e/alphagenerate" ${flags:-} -timeout 30m diff --git a/test/testdata/generate.sh b/test/testdata/generate.sh index d21d7489f32..09b9c167854 100755 --- a/test/testdata/generate.sh +++ b/test/testdata/generate.sh @@ -111,7 +111,7 @@ function scaffold_test_project { if [[ $project =~ with-plugins ]] ; then header_text 'Editing project with Helm plugin ...' - $kb edit --plugins=helm.kubebuilder.io/v1-alpha + $kb edit --plugins=helm.kubebuilder.io/v2-alpha header_text 'Editing project with Auto Update plugin ...' $kb edit --plugins=autoupdate.kubebuilder.io/v1-alpha diff --git a/testdata/project-v4-multigroup/README.md b/testdata/project-v4-multigroup/README.md index 90e3634ccb2..6346b081834 100644 --- a/testdata/project-v4-multigroup/README.md +++ b/testdata/project-v4-multigroup/README.md @@ -97,7 +97,7 @@ kubectl apply -f https://raw.githubusercontent.com//project-v4-multigroup/< 1. Build the chart using the optional helm plugin ```sh -kubebuilder edit --plugins=helm/v1-alpha +kubebuilder edit --plugins=helm/v2-alpha ``` 2. See that a chart was generated under 'dist/chart', and users diff --git a/testdata/project-v4-with-plugins/.github/workflows/test-chart.yml b/testdata/project-v4-with-plugins/.github/workflows/test-chart.yml index 6ea70d29ae5..d2c8ad2ea45 100644 --- a/testdata/project-v4-with-plugins/.github/workflows/test-chart.yml +++ b/testdata/project-v4-with-plugins/.github/workflows/test-chart.yml @@ -46,18 +46,17 @@ jobs: run: | helm lint ./dist/chart -# TODO: Uncomment if cert-manager is enabled - - name: Install cert-manager via Helm + + - name: Install cert-manager via Helm (wait for readiness) run: | helm repo add jetstack https://charts.jetstack.io helm repo update - helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set crds.enabled=true - - - name: Wait for cert-manager to be ready - run: | - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-cainjector - kubectl wait --namespace cert-manager --for=condition=available --timeout=300s deployment/cert-manager-webhook + helm install cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --set crds.enabled=true \ + --wait \ + --timeout 300s # TODO: Uncomment if Prometheus is enabled # - name: Install Prometheus Operator CRDs @@ -65,16 +64,6 @@ jobs: # helm repo add prometheus-community https://prometheus-community.github.io/helm-charts # helm repo update # helm install prometheus-crds prometheus-community/prometheus-operator-crds -# -# - name: Install Prometheus via Helm -# run: | -# helm repo add prometheus-community https://prometheus-community.github.io/helm-charts -# helm repo update -# helm install prometheus prometheus-community/prometheus --namespace monitoring --create-namespace -# -# - name: Wait for Prometheus to be ready -# run: | -# kubectl wait --namespace monitoring --for=condition=available --timeout=300s deployment/prometheus-server - name: Install Helm chart for project run: | @@ -83,8 +72,3 @@ jobs: - name: Check Helm release status run: | helm status my-release --namespace project-v4-with-plugins-system - -# TODO: Uncomment if prometheus.enabled is set to true to confirm that the ServiceMonitor gets created -# - name: Check Presence of ServiceMonitor -# run: | -# kubectl wait --namespace project-v4-with-plugins-system --for=jsonpath='{.kind}'=ServiceMonitor servicemonitor/project-v4-with-plugins-controller-manager-metrics-monitor diff --git a/testdata/project-v4-with-plugins/PROJECT b/testdata/project-v4-with-plugins/PROJECT index aa1079a4d0c..28173926fc2 100644 --- a/testdata/project-v4-with-plugins/PROJECT +++ b/testdata/project-v4-with-plugins/PROJECT @@ -26,7 +26,9 @@ plugins: image: busybox:1.36.1 version: v1alpha1 grafana.kubebuilder.io/v1-alpha: {} - helm.kubebuilder.io/v1-alpha: {} + helm.kubebuilder.io/v2-alpha: + manifests: dist/install.yaml + output: dist projectName: project-v4-with-plugins repo: sigs.k8s.io/kubebuilder/testdata/project-v4-with-plugins resources: diff --git a/testdata/project-v4-with-plugins/README.md b/testdata/project-v4-with-plugins/README.md index 3ad65a5c159..c8b5eefa8b6 100644 --- a/testdata/project-v4-with-plugins/README.md +++ b/testdata/project-v4-with-plugins/README.md @@ -97,7 +97,7 @@ kubectl apply -f https://raw.githubusercontent.com//project-v4-with-plugins 1. Build the chart using the optional helm plugin ```sh -kubebuilder edit --plugins=helm/v1-alpha +kubebuilder edit --plugins=helm/v2-alpha ``` 2. See that a chart was generated under 'dist/chart', and users diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl b/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl index d20eb916b37..689c1a905d6 100644 --- a/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl +++ b/testdata/project-v4-with-plugins/dist/chart/templates/_helpers.tpl @@ -1,9 +1,11 @@ +{{/* +Chart name based on project name. +Truncated to 63 characters for Kubernetes compatibility. +*/}} {{- define "chart.name" -}} {{- if .Chart }} {{- if .Chart.Name }} {{- .Chart.Name | trunc 63 | trimSuffix "-" }} - {{- else if .Values.nameOverride }} - {{ .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- else }} project-v4-with-plugins {{- end }} @@ -12,7 +14,48 @@ {{- end }} {{- end }} +{{/* +Full name of the chart (with release name prefix). +Combines release name with chart name. +Truncated to 63 characters for Kubernetes compatibility. +*/}} +{{- define "chart.fullname" -}} +{{- $name := include "chart.name" . }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Namespace for generated references. +Always uses the Helm release namespace. +*/}} +{{- define "chart.namespaceName" -}} +{{ .Release.Namespace }} +{{- end }} + + + +{{/* +Service name with proper truncation for Kubernetes 63-character limit. +Takes a context with .suffix for the service type (e.g., "webhook-service"). +If fullname + suffix exceeds 63 chars, truncates fullname to 45 chars. +*/}} +{{- define "chart.serviceName" -}} +{{- $fullname := include "chart.fullname" .context -}} +{{- if gt (len $fullname) 45 -}} +{{- printf "%s-%s" (trunc 45 $fullname | trimSuffix "-") .suffix | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" $fullname .suffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end }} +{{/* +Common labels for Helm charts. +Includes app version, chart version, app name, instance, and managed-by labels. +*/}} {{- define "chart.labels" -}} {{- if .Chart.AppVersion -}} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} @@ -25,26 +68,11 @@ app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end }} - +{{/* +Selector labels for matching pods and services. +Only includes name and instance for consistent selection. +*/}} {{- define "chart.selectorLabels" -}} app.kubernetes.io/name: {{ include "chart.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} - - -{{- define "chart.hasMutatingWebhooks" -}} -{{- $hasMutating := false }} -{{- range . }} - {{- if eq .type "mutating" }} - $hasMutating = true }}{{- end }} -{{- end }} -{{ $hasMutating }}}}{{- end }} - - -{{- 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/cert-manager/metrics-certs.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/cert-manager/metrics-certs.yaml new file mode 100644 index 00000000000..e503d5d5e1a --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/cert-manager/metrics-certs.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.certManager.enable .Values.metrics.enable }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-metrics-certs + namespace: {{ .Release.Namespace }} +spec: + dnsNames: + - {{ include "chart.serviceName" (dict "suffix" "controller-manager-metrics-service" "context" .) }}.{{ include "chart.namespaceName" . }}.svc + - {{ include "chart.serviceName" (dict "suffix" "controller-manager-metrics-service" "context" .) }}.{{ include "chart.namespaceName" . }}.svc.cluster.local + issuerRef: + kind: Issuer + name: {{ include "chart.name" . }}-selfsigned-issuer + secretName: metrics-server-cert +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/cert-manager/selfsigned-issuer.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/cert-manager/selfsigned-issuer.yaml new file mode 100644 index 00000000000..4d90c37a01b --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/cert-manager/selfsigned-issuer.yaml @@ -0,0 +1,12 @@ +{{- if .Values.certManager.enable }} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-selfsigned-issuer + namespace: {{ .Release.Namespace }} +spec: + selfSigned: {} +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/cert-manager/serving-cert.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/cert-manager/serving-cert.yaml new file mode 100644 index 00000000000..b0a5d8bfbe0 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/cert-manager/serving-cert.yaml @@ -0,0 +1,18 @@ +{{- if .Values.certManager.enable }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-serving-cert + namespace: {{ .Release.Namespace }} +spec: + dnsNames: + - project-v4-with-plugins-webhook-service.{{ .Release.Namespace }}.svc + - project-v4-with-plugins-webhook-service.{{ .Release.Namespace }}.svc.cluster.local + issuerRef: + kind: Issuer + name: {{ include "chart.name" . }}-selfsigned-issuer + secretName: webhook-server-cert +{{- 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 deleted file mode 100644 index 64066ebc0cd..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/certmanager/certificate.yaml +++ /dev/null @@ -1,60 +0,0 @@ -{{- if .Values.certmanager.enable }} -# Self-signed Issuer -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: selfsigned-issuer - namespace: {{ .Release.Namespace }} -spec: - selfSigned: {} -{{- if .Values.webhook.enable }} ---- -# Certificate for the webhook -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - annotations: - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - name: serving-cert - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} -spec: - dnsNames: - - project-v4-with-plugins.{{ .Release.Namespace }}.svc - - project-v4-with-plugins.{{ .Release.Namespace }}.svc.cluster.local - - project-v4-with-plugins-webhook-service.{{ .Release.Namespace }}.svc - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: webhook-server-cert -{{- end }} -{{- if .Values.metrics.enable }} ---- -# Certificate for the metrics -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - annotations: - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - labels: - {{- include "chart.labels" . | nindent 4 }} - name: metrics-certs - namespace: {{ .Release.Namespace }} -spec: - dnsNames: - - project-v4-with-plugins.{{ .Release.Namespace }}.svc - - project-v4-with-plugins.{{ .Release.Namespace }}.svc.cluster.local - - project-v4-with-plugins-metrics-service.{{ .Release.Namespace }}.svc - issuerRef: - kind: Issuer - name: selfsigned-issuer - secretName: metrics-server-cert -{{- end }} -{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/busyboxes.example.com.testproject.org.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/busyboxes.example.com.testproject.org.yaml new file mode 100644 index 00000000000..c2b5da08914 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/crd/busyboxes.example.com.testproject.org.yaml @@ -0,0 +1,128 @@ +{{- if .Values.crd.enable }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: busyboxes.example.com.testproject.org +spec: + group: example.com.testproject.org + names: + kind: Busybox + listKind: BusyboxList + plural: busyboxes + singular: busybox + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Busybox is the Schema for the busyboxes API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec defines the desired state of Busybox + properties: + size: + default: 1 + description: size defines the number of Busybox instances + format: int32 + minimum: 0 + type: integer + type: object + status: + description: status defines the observed state of Busybox + properties: + conditions: + description: |- + conditions represent the current state of the Busybox resource. + Each condition has a unique type and reflects the status of a specific aspect of the resource. + + Standard condition types include: + - "Available": the resource is fully functional + - "Progressing": the resource is being created or updated + - "Degraded": the resource failed to reach or maintain its desired state + + The status of each condition is one of True, False, or Unknown. + 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 + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_busyboxes.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_busyboxes.yaml deleted file mode 100644 index 4ffd25098f6..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_busyboxes.yaml +++ /dev/null @@ -1,135 +0,0 @@ -{{- if .Values.crd.enable }} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - annotations: - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - controller-gen.kubebuilder.io/version: v0.19.0 - name: busyboxes.example.com.testproject.org -spec: - group: example.com.testproject.org - names: - kind: Busybox - listKind: BusyboxList - plural: busyboxes - singular: busybox - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Busybox is the Schema for the busyboxes API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: spec defines the desired state of Busybox - properties: - size: - default: 1 - description: size defines the number of Busybox instances - format: int32 - minimum: 0 - type: integer - type: object - status: - description: status defines the observed state of Busybox - properties: - conditions: - description: |- - conditions represent the current state of the Busybox resource. - Each condition has a unique type and reflects the status of a specific aspect of the resource. - - Standard condition types include: - - "Available": the resource is fully functional - - "Progressing": the resource is being created or updated - - "Degraded": the resource failed to reach or maintain its desired state - - The status of each condition is one of True, False, or Unknown. - 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 - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_memcacheds.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_memcacheds.yaml deleted file mode 100644 index f9c7d27cb4c..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_memcacheds.yaml +++ /dev/null @@ -1,142 +0,0 @@ -{{- if .Values.crd.enable }} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - annotations: - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - controller-gen.kubebuilder.io/version: v0.19.0 - name: memcacheds.example.com.testproject.org -spec: - group: example.com.testproject.org - names: - kind: Memcached - listKind: MemcachedList - plural: memcacheds - singular: memcached - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: Memcached is the Schema for the memcacheds API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: spec defines the desired state of Memcached - properties: - containerPort: - description: containerPort defines the port that will be used to init - the container with the image - format: int32 - type: integer - size: - default: 1 - description: size defines the number of Memcached instances - format: int32 - minimum: 0 - type: integer - required: - - containerPort - type: object - status: - description: status defines the observed state of Memcached - properties: - conditions: - description: |- - conditions represent the current state of the Memcached resource. - Each condition has a unique type and reflects the status of a specific aspect of the resource. - - Standard condition types include: - - "Available": the resource is fully functional - - "Progressing": the resource is being created or updated - - "Degraded": the resource failed to reach or maintain its desired state - - The status of each condition is one of True, False, or Unknown. - 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 - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_wordpresses.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_wordpresses.yaml deleted file mode 100644 index 24fc9b49770..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/crd/example.com.testproject.org_wordpresses.yaml +++ /dev/null @@ -1,258 +0,0 @@ -{{- if .Values.crd.enable }} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - annotations: - {{- if .Values.certmanager.enable }} - cert-manager.io/inject-ca-from: "{{ .Release.Namespace }}/serving-cert" - {{- end }} - {{- if .Values.crd.keep }} - "helm.sh/resource-policy": keep - {{- end }} - controller-gen.kubebuilder.io/version: v0.19.0 - name: wordpresses.example.com.testproject.org -spec: - {{- if .Values.webhook.enable }} - conversion: - strategy: Webhook - webhook: - clientConfig: - service: - namespace: {{ .Release.Namespace }} - name: project-v4-with-plugins-webhook-service - path: /convert - conversionReviewVersions: - - v1 - {{- end }} - group: example.com.testproject.org - names: - kind: Wordpress - listKind: WordpressList - plural: wordpresses - singular: wordpress - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Wordpress is the Schema for the wordpresses 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: spec defines the desired state of Wordpress - properties: - foo: - description: foo is an example field of Wordpress. Edit wordpress_types.go - to remove/update - type: string - type: object - status: - description: status defines the observed state of Wordpress - properties: - conditions: - description: |- - conditions represent the current state of the Wordpress resource. - Each condition has a unique type and reflects the status of a specific aspect of the resource. - - Standard condition types include: - - "Available": the resource is fully functional - - "Progressing": the resource is being created or updated - - "Degraded": the resource failed to reach or maintain its desired state - - The status of each condition is one of True, False, or Unknown. - 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 - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} - - name: v2 - schema: - openAPIV3Schema: - description: Wordpress is the Schema for the wordpresses 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: spec defines the desired state of Wordpress - properties: - foo: - description: foo is an example field of Wordpress. Edit wordpress_types.go - to remove/update - type: string - type: object - status: - description: status defines the observed state of Wordpress - properties: - conditions: - description: |- - conditions represent the current state of the Wordpress resource. - Each condition has a unique type and reflects the status of a specific aspect of the resource. - - Standard condition types include: - - "Available": the resource is fully functional - - "Progressing": the resource is being created or updated - - "Degraded": the resource failed to reach or maintain its desired state - - The status of each condition is one of True, False, or Unknown. - 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 - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - type: object - required: - - spec - type: object - served: true - storage: false - subresources: - status: {} -{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/memcacheds.example.com.testproject.org.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/memcacheds.example.com.testproject.org.yaml new file mode 100644 index 00000000000..8b26706c561 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/crd/memcacheds.example.com.testproject.org.yaml @@ -0,0 +1,134 @@ +{{- if .Values.crd.enable }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: memcacheds.example.com.testproject.org +spec: + group: example.com.testproject.org + names: + kind: Memcached + listKind: MemcachedList + plural: memcacheds + singular: memcached + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Memcached is the Schema for the memcacheds API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: spec defines the desired state of Memcached + properties: + containerPort: + description: containerPort defines the port that will be used to init the container with the image + format: int32 + type: integer + size: + default: 1 + description: size defines the number of Memcached instances + format: int32 + minimum: 0 + type: integer + required: + - containerPort + type: object + status: + description: status defines the observed state of Memcached + properties: + conditions: + description: |- + conditions represent the current state of the Memcached resource. + Each condition has a unique type and reflects the status of a specific aspect of the resource. + + Standard condition types include: + - "Available": the resource is fully functional + - "Progressing": the resource is being created or updated + - "Degraded": the resource failed to reach or maintain its desired state + + The status of each condition is one of True, False, or Unknown. + 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 + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/crd/wordpresses.example.com.testproject.org.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/crd/wordpresses.example.com.testproject.org.yaml new file mode 100644 index 00000000000..16d09b95b05 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/crd/wordpresses.example.com.testproject.org.yaml @@ -0,0 +1,244 @@ +{{- if .Values.crd.enable }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/project-v4-with-plugins-serving-cert + controller-gen.kubebuilder.io/version: v0.19.0 + name: wordpresses.example.com.testproject.org +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + name: project-v4-with-plugins-webhook-service + namespace: {{ .Release.Namespace }} + path: /convert + conversionReviewVersions: + - v1 + group: example.com.testproject.org + names: + kind: Wordpress + listKind: WordpressList + plural: wordpresses + singular: wordpress + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Wordpress is the Schema for the wordpresses 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: spec defines the desired state of Wordpress + properties: + foo: + description: foo is an example field of Wordpress. Edit wordpress_types.go to remove/update + type: string + type: object + status: + description: status defines the observed state of Wordpress + properties: + conditions: + description: |- + conditions represent the current state of the Wordpress resource. + Each condition has a unique type and reflects the status of a specific aspect of the resource. + + Standard condition types include: + - "Available": the resource is fully functional + - "Progressing": the resource is being created or updated + - "Degraded": the resource failed to reach or maintain its desired state + + The status of each condition is one of True, False, or Unknown. + 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 + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - name: v2 + schema: + openAPIV3Schema: + description: Wordpress is the Schema for the wordpresses 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: spec defines the desired state of Wordpress + properties: + foo: + description: foo is an example field of Wordpress. Edit wordpress_types.go to remove/update + type: string + type: object + status: + description: status defines the observed state of Wordpress + properties: + conditions: + description: |- + conditions represent the current state of the Wordpress resource. + Each condition has a unique type and reflects the status of a specific aspect of the resource. + + Standard condition types include: + - "Available": the resource is fully functional + - "Progressing": the resource is being created or updated + - "Degraded": the resource failed to reach or maintain its desired state + + The status of each condition is one of True, False, or Unknown. + 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 + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + 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 index 814b31c97ef..95df284bbe5 100644 --- a/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/manager/manager.yaml @@ -1,90 +1,87 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: project-v4-with-plugins-controller-manager - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} - control-plane: controller-manager -spec: - replicas: {{ .Values.controllerManager.replicas }} - selector: - matchLabels: - {{- include "chart.selectorLabels" . | nindent 6 }} - control-plane: controller-manager - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - {{- include "chart.labels" . | nindent 8 }} + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins control-plane: controller-manager - {{- if and .Values.controllerManager.pod .Values.controllerManager.pod.labels }} - {{- range $key, $value := .Values.controllerManager.pod.labels }} - {{ $key }}: {{ $value }} - {{- end }} - {{- end }} - spec: - containers: - - name: manager - args: - {{- range .Values.controllerManager.container.args }} - - {{ . }} - {{- end }} - command: - - /manager - image: {{ .Values.controllerManager.container.image.repository }}:{{ .Values.controllerManager.container.image.tag }} - {{- if .Values.controllerManager.container.imagePullPolicy }} - imagePullPolicy: {{ .Values.controllerManager.container.imagePullPolicy }} - {{- end }} - {{- if .Values.controllerManager.container.env }} - env: - {{- range $key, $value := .Values.controllerManager.container.env }} - - name: {{ $key }} - value: {{ $value }} - {{- end }} - {{- end }} - livenessProbe: - {{- toYaml .Values.controllerManager.container.livenessProbe | nindent 12 }} - readinessProbe: - {{- toYaml .Values.controllerManager.container.readinessProbe | nindent 12 }} - {{- if .Values.webhook.enable }} - ports: - - containerPort: 9443 - name: webhook-server - protocol: TCP - {{- end }} - resources: - {{- toYaml .Values.controllerManager.container.resources | nindent 12 }} - securityContext: - {{- toYaml .Values.controllerManager.container.securityContext | nindent 12 }} - {{- if and .Values.certmanager.enable (or .Values.webhook.enable .Values.metrics.enable) }} - volumeMounts: - {{- if and .Values.webhook.enable .Values.certmanager.enable }} - - name: webhook-cert - mountPath: /tmp/k8s-webhook-server/serving-certs - readOnly: true - {{- end }} - {{- if and .Values.metrics.enable .Values.certmanager.enable }} - - name: metrics-certs - mountPath: /tmp/k8s-metrics-server/metrics-certs - readOnly: true - {{- end }} - {{- end }} - securityContext: - {{- toYaml .Values.controllerManager.securityContext | nindent 8 }} - serviceAccountName: {{ .Values.controllerManager.serviceAccountName }} - terminationGracePeriodSeconds: {{ .Values.controllerManager.terminationGracePeriodSeconds }} - {{- if and .Values.certmanager.enable (or .Values.webhook.enable .Values.metrics.enable) }} - volumes: - {{- if and .Values.webhook.enable .Values.certmanager.enable }} - - name: webhook-cert - secret: - secretName: webhook-server-cert - {{- end }} - {{- if and .Values.metrics.enable .Values.certmanager.enable }} - - name: metrics-certs - secret: - secretName: metrics-server-cert - {{- end }} - {{- end }} + name: project-v4-with-plugins-controller-manager + namespace: {{ .Release.Namespace }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: project-v4-with-plugins + control-plane: controller-manager + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + app.kubernetes.io/name: project-v4-with-plugins + control-plane: controller-manager + spec: + containers: + - args: + - --metrics-bind-address=:8443 + - --leader-elect + - --health-probe-bind-address=:8081 + {{- if .Values.certManager.enable }} + - --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs + {{- end }} + command: + - /manager + env: + - name: BUSYBOX_IMAGE + value: busybox:1.36.1 + - name: MEMCACHED_IMAGE + value: memcached:1.6.26-alpine3.19 + image: "{{ .Values.controllerManager.image.repository }}:{{ .Values.controllerManager.image.tag }}" + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + volumeMounts: + {{- if .Values.certManager.enable }} + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: webhook-certs + readOnly: true + {{- end }} + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + serviceAccountName: project-v4-with-plugins-controller-manager + terminationGracePeriodSeconds: 10 + volumes: + {{- if .Values.certManager.enable }} + - name: webhook-certs + secret: + secretName: webhook-server-cert + {{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/metrics/controller-manager-metrics-service.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/metrics/controller-manager-metrics-service.yaml new file mode 100644 index 00000000000..1f98f524ec4 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/metrics/controller-manager-metrics-service.yaml @@ -0,0 +1,20 @@ +{{- if .Values.metrics.enable }} +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + control-plane: controller-manager + name: project-v4-with-plugins-controller-manager-metrics-service + namespace: {{ .Release.Namespace }} +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: 8443 + selector: + app.kubernetes.io/name: project-v4-with-plugins + control-plane: controller-manager +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/metrics/metrics-service.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/metrics/metrics-service.yaml deleted file mode 100644 index d4ea4d3eed5..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/metrics/metrics-service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- if .Values.metrics.enable }} -apiVersion: v1 -kind: Service -metadata: - name: project-v4-with-plugins-controller-manager-metrics-service - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} - control-plane: controller-manager -spec: - ports: - - port: 8443 - targetPort: 8443 - protocol: TCP - name: https - selector: - control-plane: controller-manager -{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/prometheus/monitor.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/monitoring/servicemonitor.yaml similarity index 93% rename from testdata/project-v4-with-plugins/dist/chart/templates/prometheus/monitor.yaml rename to testdata/project-v4-with-plugins/dist/chart/templates/monitoring/servicemonitor.yaml index 522536e7e1e..ce02f448dd7 100644 --- a/testdata/project-v4-with-plugins/dist/chart/templates/prometheus/monitor.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/templates/monitoring/servicemonitor.yaml @@ -1,4 +1,3 @@ -# To integrate with Prometheus. {{- if .Values.prometheus.enable }} apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor @@ -15,7 +14,7 @@ spec: scheme: https bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token tlsConfig: - {{- if .Values.certmanager.enable }} + {{- if .Values.certManager.enable }} serverName: project-v4-with-plugins-controller-manager-metrics-service.{{ .Release.Namespace }}.svc # Apply secure TLS configuration with cert-manager insecureSkipVerify: false 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 deleted file mode 100644 index c1d867c7530..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-metrics-traffic.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.networkPolicy.enable }} -# This NetworkPolicy allows ingress traffic -# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those -# namespaces are able to gather data from the metrics endpoint. -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: allow-metrics-traffic - namespace: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - control-plane: controller-manager - app.kubernetes.io/name: project-v4-with-plugins - 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 deleted file mode 100644 index 998054b8a15..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/network-policy/allow-webhook-traffic.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.networkPolicy.enable }} -# 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: {{ .Release.Namespace }} -spec: - podSelector: - matchLabels: - control-plane: controller-manager - app.kubernetes.io/name: project-v4-with-plugins - 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/rbac/busybox-admin-role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox-admin-role.yaml new file mode 100644 index 00000000000..81ae0435151 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox-admin-role.yaml @@ -0,0 +1,22 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-busybox-admin-role +rules: + - apiGroups: + - example.com.testproject.org + resources: + - busyboxes + verbs: + - '*' + - apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + verbs: + - get +{{- 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 100644 index 00000000000..963a42158ef --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox-editor-role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-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 100644 index 00000000000..a0aaa1440ed --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox-viewer-role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-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/busybox_admin_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_admin_role.yaml deleted file mode 100644 index c149f20460b..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_admin_role.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project-v4-with-plugins itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants full permissions ('*') over example.com.testproject.org. -# This role is intended for users authorized to modify roles and bindings within the cluster, -# enabling them to delegate specific permissions to other users or groups as needed. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: busybox-admin-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes - verbs: - - '*' -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - verbs: - - get -{{- 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 deleted file mode 100644 index f0c7bd2dfbe..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_editor_role.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project-v4-with-plugins itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants permissions to create, update, and delete resources within the example.com.testproject.org. -# This role is intended for users who need to manage these resources -# but should not control RBAC or manage permissions for others. - -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 deleted file mode 100644 index 3866e7bf22a..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/busybox_viewer_role.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project-v4-with-plugins itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants read-only access to example.com.testproject.org resources. -# This role is intended for users who need visibility into these resources -# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. - -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/controller-manager.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/controller-manager.yaml new file mode 100644 index 00000000000..3639b99e784 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/controller-manager.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-controller-manager + namespace: {{ .Release.Namespace }} 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 100644 index 00000000000..e3d15538787 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader-election-role.yaml @@ -0,0 +1,40 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-leader-election-role + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader-election-rolebinding.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader-election-rolebinding.yaml new file mode 100644 index 00000000000..055c2e3eff5 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader-election-rolebinding.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-leader-election-rolebinding + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: project-v4-with-plugins-leader-election-role +subjects: + - kind: ServiceAccount + name: project-v4-with-plugins-controller-manager + namespace: {{ .Release.Namespace }} 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 deleted file mode 100644 index a6a6c59da92..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role.yaml +++ /dev/null @@ -1,42 +0,0 @@ -{{- if .Values.rbac.enable }} -# permissions to do leader election. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - namespace: {{ .Release.Namespace }} - name: project-v4-with-plugins-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 deleted file mode 100644 index 3ab8d4816c1..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/leader_election_role_binding.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - namespace: {{ .Release.Namespace }} - name: project-v4-with-plugins-leader-election-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: project-v4-with-plugins-leader-election-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/manager-role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/manager-role.yaml new file mode 100644 index 00000000000..31c2b0791dd --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/manager-role.yaml @@ -0,0 +1,64 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-v4-with-plugins-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 + - wordpresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - example.com.testproject.org + resources: + - busyboxes/finalizers + - memcacheds/finalizers + - wordpresses/finalizers + verbs: + - update + - apiGroups: + - example.com.testproject.org + resources: + - busyboxes/status + - memcacheds/status + - wordpresses/status + verbs: + - get + - patch + - update diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/manager-rolebinding.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/manager-rolebinding.yaml new file mode 100644 index 00000000000..ffa578f480c --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/manager-rolebinding.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: project-v4-with-plugins-manager-role +subjects: + - kind: ServiceAccount + name: project-v4-with-plugins-controller-manager + namespace: {{ .Release.Namespace }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached-admin-role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached-admin-role.yaml new file mode 100644 index 00000000000..ed711f53db7 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached-admin-role.yaml @@ -0,0 +1,22 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-memcached-admin-role +rules: + - apiGroups: + - example.com.testproject.org + resources: + - memcacheds + verbs: + - '*' + - apiGroups: + - example.com.testproject.org + resources: + - memcacheds/status + verbs: + - get +{{- 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 100644 index 00000000000..214f7e65590 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached-editor-role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-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 100644 index 00000000000..94cc8dd89cf --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached-viewer-role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-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/memcached_admin_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_admin_role.yaml deleted file mode 100644 index 562928a55c2..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_admin_role.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project-v4-with-plugins itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants full permissions ('*') over example.com.testproject.org. -# This role is intended for users authorized to modify roles and bindings within the cluster, -# enabling them to delegate specific permissions to other users or groups as needed. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: memcached-admin-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds - verbs: - - '*' -- apiGroups: - - example.com.testproject.org - resources: - - memcacheds/status - verbs: - - get -{{- 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 deleted file mode 100644 index 995149a58d0..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_editor_role.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project-v4-with-plugins itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants permissions to create, update, and delete resources within the example.com.testproject.org. -# This role is intended for users who need to manage these resources -# but should not control RBAC or manage permissions for others. - -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 deleted file mode 100644 index 7741c22acb2..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/memcached_viewer_role.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project-v4-with-plugins itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants read-only access to example.com.testproject.org resources. -# This role is intended for users who need visibility into these resources -# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. - -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 100644 index 00000000000..640e1cd17de --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics-auth-role.yaml @@ -0,0 +1,19 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-v4-with-plugins-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-rolebinding.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics-auth-rolebinding.yaml new file mode 100644 index 00000000000..1e1b6e7d180 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics-auth-rolebinding.yaml @@ -0,0 +1,14 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: project-v4-with-plugins-metrics-auth-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: project-v4-with-plugins-metrics-auth-role +subjects: + - kind: ServiceAccount + name: project-v4-with-plugins-controller-manager + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics-reader.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics-reader.yaml new file mode 100644 index 00000000000..a1a73d41b1f --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics-reader.yaml @@ -0,0 +1,11 @@ +{{- if .Values.metrics.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: project-v4-with-plugins-metrics-reader +rules: + - nonResourceURLs: + - /metrics + 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 deleted file mode 100644 index 29b3f12404f..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role.yaml +++ /dev/null @@ -1,21 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-v4-with-plugins-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 deleted file mode 100644 index 75ed1b819d8..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_auth_role_binding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-v4-with-plugins-metrics-auth-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-v4-with-plugins-metrics-auth-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.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 deleted file mode 100644 index b45a2bd5d17..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/metrics_reader_role.yaml +++ /dev/null @@ -1,13 +0,0 @@ -{{- if and .Values.rbac.enable .Values.metrics.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-v4-with-plugins-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 deleted file mode 100644 index ec0830f2178..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role.yaml +++ /dev/null @@ -1,69 +0,0 @@ -{{- if .Values.rbac.enable }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-v4-with-plugins-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 - - wordpresses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/finalizers - - memcacheds/finalizers - - wordpresses/finalizers - verbs: - - update -- apiGroups: - - example.com.testproject.org - resources: - - busyboxes/status - - memcacheds/status - - wordpresses/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 deleted file mode 100644 index a6890e55217..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/role_binding.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: project-v4-with-plugins-manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: project-v4-with-plugins-manager-role -subjects: -- kind: ServiceAccount - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.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 deleted file mode 100644 index 93e0a323e1d..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/service_account.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if .Values.rbac.enable }} -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - {{- if and .Values.controllerManager.serviceAccount .Values.controllerManager.serviceAccount.annotations }} - annotations: - {{- range $key, $value := .Values.controllerManager.serviceAccount.annotations }} - {{ $key }}: {{ $value }} - {{- end }} - {{- end }} - name: {{ .Values.controllerManager.serviceAccountName }} - namespace: {{ .Release.Namespace }} -{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress-admin-role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress-admin-role.yaml new file mode 100644 index 00000000000..e0f75c7ff17 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress-admin-role.yaml @@ -0,0 +1,22 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-wordpress-admin-role +rules: + - apiGroups: + - example.com.testproject.org + resources: + - wordpresses + verbs: + - '*' + - apiGroups: + - example.com.testproject.org + resources: + - wordpresses/status + verbs: + - get +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress-editor-role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress-editor-role.yaml new file mode 100644 index 00000000000..0143dd02ce7 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress-editor-role.yaml @@ -0,0 +1,28 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-wordpress-editor-role +rules: + - apiGroups: + - example.com.testproject.org + resources: + - wordpresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - example.com.testproject.org + resources: + - wordpresses/status + verbs: + - get +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress-viewer-role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress-viewer-role.yaml new file mode 100644 index 00000000000..929bc1f780f --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress-viewer-role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbacHelpers.enable }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-wordpress-viewer-role +rules: + - apiGroups: + - example.com.testproject.org + resources: + - wordpresses + verbs: + - get + - list + - watch + - apiGroups: + - example.com.testproject.org + resources: + - wordpresses/status + verbs: + - get +{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_admin_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_admin_role.yaml deleted file mode 100644 index 5eb6793da7a..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_admin_role.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project-v4-with-plugins itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants full permissions ('*') over example.com.testproject.org. -# This role is intended for users authorized to modify roles and bindings within the cluster, -# enabling them to delegate specific permissions to other users or groups as needed. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: wordpress-admin-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - wordpresses - verbs: - - '*' -- apiGroups: - - example.com.testproject.org - resources: - - wordpresses/status - verbs: - - get -{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_editor_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_editor_role.yaml deleted file mode 100644 index a07e4d65591..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_editor_role.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project-v4-with-plugins itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants permissions to create, update, and delete resources within the example.com.testproject.org. -# This role is intended for users who need to manage these resources -# but should not control RBAC or manage permissions for others. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: wordpress-editor-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - wordpresses - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - example.com.testproject.org - resources: - - wordpresses/status - verbs: - - get -{{- end -}} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_viewer_role.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_viewer_role.yaml deleted file mode 100644 index 51cde64879e..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/rbac/wordpress_viewer_role.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.rbac.enable }} -# This rule is not used by the project project-v4-with-plugins itself. -# It is provided to allow the cluster admin to help manage permissions for users. -# -# Grants read-only access to example.com.testproject.org resources. -# This role is intended for users who need visibility into these resources -# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing. - -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - {{- include "chart.labels" . | nindent 4 }} - name: wordpress-viewer-role -rules: -- apiGroups: - - example.com.testproject.org - resources: - - wordpresses - verbs: - - get - - list - - watch -- apiGroups: - - example.com.testproject.org - resources: - - wordpresses/status - verbs: - - get -{{- 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 deleted file mode 100644 index b3b2957e969..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/webhook/service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -{{- if .Values.webhook.enable }} -apiVersion: v1 -kind: Service -metadata: - name: project-v4-with-plugins-webhook-service - namespace: {{ .Release.Namespace }} - labels: - {{- include "chart.labels" . | nindent 4 }} -spec: - ports: - - port: 443 - protocol: TCP - targetPort: 9443 - selector: - control-plane: controller-manager -{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/webhook/validating-webhook-configuration.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/validating-webhook-configuration.yaml new file mode 100644 index 00000000000..028ff044679 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/validating-webhook-configuration.yaml @@ -0,0 +1,29 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + {{- if .Values.certManager.enable }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/project-v4-with-plugins-serving-cert + {{- end }} + name: project-v4-with-plugins-validating-webhook-configuration +webhooks: + - admissionReviewVersions: + - v1 + clientConfig: + service: + name: project-v4-with-plugins-webhook-service + namespace: {{ .Release.Namespace }} + path: /validate-example-com-testproject-org-v1alpha1-memcached + failurePolicy: Fail + name: vmemcached-v1alpha1.kb.io + rules: + - apiGroups: + - example.com.testproject.org + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - memcacheds + sideEffects: None diff --git a/testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhook-service.yaml b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhook-service.yaml new file mode 100644 index 00000000000..00d0f928b87 --- /dev/null +++ b/testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhook-service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/name: project-v4-with-plugins + name: project-v4-with-plugins-webhook-service + namespace: {{ .Release.Namespace }} +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 9443 + selector: + app.kubernetes.io/name: project-v4-with-plugins + 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 deleted file mode 100644 index aa88ccc1991..00000000000 --- a/testdata/project-v4-with-plugins/dist/chart/templates/webhook/webhooks.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- if .Values.webhook.enable }} -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - name: project-v4-with-plugins-validating-webhook-configuration - namespace: {{ .Release.Namespace }} - annotations: - {{- if .Values.certmanager.enable }} - cert-manager.io/inject-ca-from: "{{ $.Release.Namespace }}/serving-cert" - {{- end }} - labels: - {{- include "chart.labels" . | nindent 4 }} -webhooks: - - name: vmemcached-v1alpha1.kb.io - clientConfig: - service: - name: project-v4-with-plugins-webhook-service - namespace: {{ .Release.Namespace }} - 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 -{{- end }} diff --git a/testdata/project-v4-with-plugins/dist/chart/values.yaml b/testdata/project-v4-with-plugins/dist/chart/values.yaml index 93478fc72db..6537a5b735d 100644 --- a/testdata/project-v4-with-plugins/dist/chart/values.yaml +++ b/testdata/project-v4-with-plugins/dist/chart/values.yaml @@ -1,87 +1,69 @@ -# [MANAGER]: Manager Deployment Configurations +# Configure the controller manager deployment controllerManager: replicas: 1 - container: - image: - repository: controller - tag: latest - imagePullPolicy: IfNotPresent - args: - - "--leader-elect" - - "--metrics-bind-address=:8443" - - "--health-probe-bind-address=:8081" - resources: - limits: + + image: + repository: controller + tag: latest + pullPolicy: IfNotPresent + + # Environment variables + env: + - name: BUSYBOX_IMAGE + value: busybox:1.36.1 + - name: MEMCACHED_IMAGE + value: memcached:1.6.26-alpine3.19 + + # Pod-level security settings + podSecurityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + + # Container-level security settings + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + + # Resource limits and requests + resources: + limits: cpu: 500m memory: 128Mi - requests: + 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 - env: - BUSYBOX_IMAGE: busybox:1.36.1 - MEMCACHED_IMAGE: memcached:1.6.26-alpine3.19 - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - "ALL" - securityContext: - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - terminationGracePeriodSeconds: 10 - serviceAccountName: project-v4-with-plugins-controller-manager -# [RBAC]: To enable RBAC (Permissions) configurations -rbac: - enable: true +# Essential RBAC permissions (required for controller operation) +# These include ServiceAccount, controller permissions, leader election, and metrics access +# Note: Essential RBAC is always enabled as it's required for the controller to function -# [CRDs]: To enable the CRDs -crd: - # This option determines whether the CRDs are included - # in the installation process. - enable: true +# Helper RBAC roles for managing custom resources +# These provide convenient admin/editor/viewer roles for each CRD type +# Useful for giving users different levels of access to your custom resources +rbacHelpers: + enable: false # Install convenience admin/editor/viewer roles for CRDs - # Enabling this option adds the "helm.sh/resource-policy": keep - # annotation to the CRD, ensuring it remains installed even when - # the Helm release is uninstalled. - # NOTE: Removing the CRDs will also remove all cert-manager CR(s) - # (Certificates, Issuers, ...) due to garbage collection. - keep: true +# Custom Resource Definitions +crd: + enable: true # Install CRDs with the chart + keep: true # Keep CRDs when uninstalling -# [METRICS]: Set to true to generate manifests for exporting metrics. -# To disable metrics export set false, and ensure that the -# ControllerManager argument "--metrics-bind-address=:8443" is removed. +# Controller metrics endpoint. +# Enable to expose /metrics endpoint with RBAC protection. metrics: enable: true -# [WEBHOOKS]: Webhooks configuration -# The following configuration is automatically generated from the manifests -# generated by controller-gen. To update run 'make manifests' and -# the edit command with the '--force' flag -webhook: +# Cert-manager integration for TLS certificates. +# Required for webhook certificates and metrics endpoint certificates. +certManager: enable: true -# [PROMETHEUS]: To enable a ServiceMonitor to export metrics to Prometheus set true +# Prometheus ServiceMonitor for metrics scraping. +# Requires prometheus-operator to be installed in the cluster. prometheus: enable: false -# [CERT-MANAGER]: To enable cert-manager injection to webhooks set true -certmanager: - enable: true - -# [NETWORK POLICIES]: To enable NetworkPolicies set true -networkPolicy: - enable: false diff --git a/testdata/project-v4/README.md b/testdata/project-v4/README.md index b6e8414c82a..f90221a159f 100644 --- a/testdata/project-v4/README.md +++ b/testdata/project-v4/README.md @@ -97,7 +97,7 @@ kubectl apply -f https://raw.githubusercontent.com//project-v4/