diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a47c97d..0a1b958 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -29,9 +29,67 @@ jobs: run: make docker-build docker-push IMG=${{ env.REGISTRY }}/${{ env.REPOSITORY_NAME }}:${GITHUB_REF##*/} - name: Create install.yaml file - run: make build/install.yaml IMG=${{ env.REGISTRY }}/${{ env.REPOSITORY_NAME }}:${GITHUB_REF##*/} + run: make build-installer IMG=${{ env.REGISTRY }}/${{ env.REPOSITORY_NAME }}:${GITHUB_REF##*/} - name: Upload install.yaml file uses: softprops/action-gh-release@v2 with: - files: ./build/install.yaml \ No newline at end of file + files: dist/install.yaml + + package-and-push-helm-chart: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + + - name: Set up Helm + uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 + with: + version: v3.12.0 + + - name: Set chart name + id: chart-name + run: echo "value=${{ github.event.repository.name }}" >> "$GITHUB_OUTPUT" + + - name: Set OCI registry name + id: oci-registry-name + run: echo "value=ghcr.io/${{ github.repository_owner }}/helm-charts" >> "$GITHUB_OUTPUT" + + - name: Set OCI chart name + id: oci-chart-name + run: echo "value=${{ steps.oci-registry-name.outputs.value }}/${{ steps.chart-name.outputs.value }}" >> "$GITHUB_OUTPUT" + + - name: Helm lint + run: helm lint charts/${{ steps.chart-name.outputs.value }} + + - name: Trim prefix from version + id: version + run: echo "value=$(echo ${{ github.ref_name }} | sed 's/release-//')" >> "$GITHUB_OUTPUT" + + - name: Helm package + id: build + run: | + helm package charts/${{ steps.chart-name.outputs.value }} --version ${{ steps.version.outputs.value }} --app-version ${{ steps.version.outputs.value }} + echo "package=${{ steps.chart-name.outputs.value }}-${{ steps.version.outputs.value }}.tgz" >> "$GITHUB_OUTPUT" + - name: Upload chart as artifact + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 + with: + name: "[${{ github.job }}] Helm chart" + path: ${{ steps.build.outputs.package }} + + - name: Log in to the Container registry + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Helm push + run: helm push ${{ steps.build.outputs.package }} oci://${{ steps.oci-registry-name.outputs.value }} + env: + HELM_REGISTRY_CONFIG: ~/.docker/config.json \ No newline at end of file diff --git a/Makefile b/Makefile index 33c3988..fe710b9 100644 --- a/Makefile +++ b/Makefile @@ -148,16 +148,9 @@ deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. $(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f - -.PHONY: build/install.yaml -build/install.yaml: manifests kustomize - mkdir -p $(dir $@) && \ - rm -rf build/kustomize && \ - mkdir -p build/kustomize && \ - cd build/kustomize && \ - $(KUSTOMIZE) create --resources ../../config/default && \ - $(KUSTOMIZE) edit set image controller=${IMG} && \ - cd ${CURDIR} && \ - $(KUSTOMIZE) build build/kustomize > $@ +.PHONY: doc-chart +doc-chart: helm-docs helm + $(HELM_DOCS) charts/ ##@ Dependencies @@ -172,12 +165,15 @@ KUSTOMIZE ?= $(LOCALBIN)/kustomize-$(KUSTOMIZE_VERSION) CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen-$(CONTROLLER_TOOLS_VERSION) ENVTEST ?= $(LOCALBIN)/setup-envtest-$(ENVTEST_VERSION) GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION) +HELM_DOCS ?= $(LOCALBIN)/helm-docs-$(HELM_DOCS_VERSION) +HELM_URL ?= https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 ## Tool Versions KUSTOMIZE_VERSION ?= v5.3.0 -CONTROLLER_TOOLS_VERSION ?= v0.14.0 +CONTROLLER_TOOLS_VERSION ?= v0.16.2 ENVTEST_VERSION ?= latest -GOLANGCI_LINT_VERSION ?= v1.54.2 +GOLANGCI_LINT_VERSION ?= v1.60.3 +HELM_DOCS_VERSION ?= v1.14.2 .PHONY: kustomize kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. @@ -199,6 +195,17 @@ golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. $(GOLANGCI_LINT): $(LOCALBIN) $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,${GOLANGCI_LINT_VERSION}) +.PHONY: helm +helm: + wget -O $(LOCALBIN)/get-helm.sh $(HELM_URL) + chmod 700 $(LOCALBIN)/get-helm.sh + $(LOCALBIN)/get-helm.sh + +.PHONY: helm-docs +helm-docs: $(HELM_DOCS) +$(HELM_DOCS): $(LOCALBIN) + $(call go-install-tool,$(HELM_DOCS),github.com/norwoodj/helm-docs/cmd/helm-docs,$(HELM_DOCS_VERSION)) + # go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist # $1 - target path with name of binary (ideally with version) # $2 - package url which can be installed diff --git a/README.md b/README.md index 3c4048e..7a05336 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,16 @@ spec: $ make deploy IMG=ghcr.io/dana-team/env-route-ns-mutator: ``` +### Install with Helm + +Helm chart docs are available on `charts/env-route-ns-mutator` directory. + +Make sure `cert-manager` is [installed](https://cert-manager.io/docs/installation/helm/) as a prerequisite. + +``` +$ helm upgrade --install env-route-ns-mutator --namespace env-route-ns-mutator-system --create-namespace oci://ghcr.io/dana-team/helm-charts/env-route-ns-mutator --version +``` + #### Build your own image ```bash diff --git a/charts/env-route-ns-mutator/.helmignore b/charts/env-route-ns-mutator/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/env-route-ns-mutator/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/env-route-ns-mutator/Chart.yaml b/charts/env-route-ns-mutator/Chart.yaml new file mode 100644 index 0000000..1451f15 --- /dev/null +++ b/charts/env-route-ns-mutator/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +name: env-route-ns-mutator +description: A Helm chart for Kubernetes +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/charts/env-route-ns-mutator/README.md b/charts/env-route-ns-mutator/README.md new file mode 100644 index 0000000..283db43 --- /dev/null +++ b/charts/env-route-ns-mutator/README.md @@ -0,0 +1,62 @@ +# env-route-ns-mutator + +![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.1.0](https://img.shields.io/badge/AppVersion-0.1.0-informational?style=flat-square) + +A Helm chart for Kubernetes + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | Node affinity rules for scheduling pods. Allows you to specify advanced node selection constraints. | +| config | object | `{"environments":["env1","env2"],"name":"operator-config"}` | Name of the ConfigMap used for configuration. | +| fullnameOverride | string | `""` | | +| image.kubeRbacProxy.pullPolicy | string | `"IfNotPresent"` | The pull policy for the image. | +| image.kubeRbacProxy.repository | string | `"gcr.io/kubebuilder/kube-rbac-proxy"` | The repository of the kube-rbac-proxy container image. | +| image.kubeRbacProxy.tag | string | `"v0.16.0"` | The tag of the kube-rbac-proxy container image. | +| image.manager.pullPolicy | string | `"IfNotPresent"` | The pull policy for the image. | +| image.manager.repository | string | `"ghcr.io/dana-team/env-route-ns-mutator"` | The repository of the manager container image. | +| image.manager.tag | string | `""` | The tag of the manager container image. | +| kubeRbacProxy | object | `{"args":["--secure-listen-address=0.0.0.0:8443","--upstream=http://127.0.0.1:8080/","--logtostderr=true","--v=0"],"ports":{"https":{"containerPort":8443,"name":"https","protocol":"TCP"}},"resources":{"limits":{"cpu":"500m","memory":"128Mi"},"requests":{"cpu":"5m","memory":"64Mi"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}}}` | Configuration for the kube-rbac-proxy container. | +| kubeRbacProxy.args | list | `["--secure-listen-address=0.0.0.0:8443","--upstream=http://127.0.0.1:8080/","--logtostderr=true","--v=0"]` | Command-line arguments passed to the kube-rbac-proxy container. | +| kubeRbacProxy.ports | object | `{"https":{"containerPort":8443,"name":"https","protocol":"TCP"}}` | Port configurations for the kube-rbac-proxy container. | +| kubeRbacProxy.ports.https.containerPort | int | `8443` | The port for the HTTPS endpoint. | +| kubeRbacProxy.ports.https.name | string | `"https"` | The name of the HTTPS port. | +| kubeRbacProxy.ports.https.protocol | string | `"TCP"` | The protocol used by the HTTPS endpoint. | +| kubeRbacProxy.resources | object | `{"limits":{"cpu":"500m","memory":"128Mi"},"requests":{"cpu":"5m","memory":"64Mi"}}` | Resource requests and limits for the kube-rbac-proxy container. | +| kubeRbacProxy.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}}` | Security settings for the kube-rbac-proxy container. | +| livenessProbe | object | `{"initialDelaySeconds":15,"periodSeconds":20,"port":8081}` | Configuration for the liveness probe. | +| livenessProbe.initialDelaySeconds | int | `15` | The initial delay before the liveness probe is initiated. | +| livenessProbe.periodSeconds | int | `20` | The frequency (in seconds) with which the probe will be performed. | +| livenessProbe.port | int | `8081` | The port for the health check endpoint. | +| manager | object | `{"args":["--leader-elect","--health-probe-bind-address=:8081","--metrics-bind-address=127.0.0.1:8080"],"command":["/manager"],"ports":{"health":{"containerPort":8081,"name":"health","protocol":"TCP"},"webhook":{"containerPort":9443,"name":"webhook-server","protocol":"TCP"}},"resources":{"limits":{"cpu":"500m","memory":"128Mi"},"requests":{"cpu":"10m","memory":"64Mi"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}},"volumeMounts":[{"mountPath":"/tmp/k8s-webhook-server/serving-certs","name":"cert","readOnly":true}],"webhookServer":{"defaultMode":420,"secretName":"webhook-server-cert"}}` | Configuration for the manager container. | +| manager.args | list | `["--leader-elect","--health-probe-bind-address=:8081","--metrics-bind-address=127.0.0.1:8080"]` | Command-line arguments passed to the manager container. | +| manager.command | list | `["/manager"]` | Command-line commands passed to the manager container. | +| manager.ports | object | `{"health":{"containerPort":8081,"name":"health","protocol":"TCP"},"webhook":{"containerPort":9443,"name":"webhook-server","protocol":"TCP"}}` | Port configurations for the manager container. | +| manager.ports.health.containerPort | int | `8081` | The port for the health check endpoint. | +| manager.ports.health.name | string | `"health"` | The name of the health check port. | +| manager.ports.health.protocol | string | `"TCP"` | The protocol used by the health check endpoint. | +| manager.ports.webhook.containerPort | int | `9443` | The port for the webhook server. | +| manager.ports.webhook.name | string | `"webhook-server"` | The name of the webhook port. | +| manager.ports.webhook.protocol | string | `"TCP"` | The protocol used by the webhook server. | +| manager.resources | object | `{"limits":{"cpu":"500m","memory":"128Mi"},"requests":{"cpu":"10m","memory":"64Mi"}}` | Resource requests and limits for the manager container. | +| manager.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}}` | Security settings for the manager container. | +| manager.volumeMounts | list | `[{"mountPath":"/tmp/k8s-webhook-server/serving-certs","name":"cert","readOnly":true}]` | Volume mounts for the manager container. | +| manager.webhookServer.defaultMode | int | `420` | The default mode for the secret. | +| manager.webhookServer.secretName | string | `"webhook-server-cert"` | The name of the secret containing the webhook server certificate. | +| nameOverride | string | `""` | | +| nodeSelector | object | `{}` | Node selector for scheduling pods. Allows you to specify node labels for pod assignment. | +| readinessProbe | object | `{"initialDelaySeconds":5,"periodSeconds":10,"port":8081}` | Configuration for the readiness probe. | +| readinessProbe.initialDelaySeconds | int | `5` | The initial delay before the readiness probe is initiated. | +| readinessProbe.periodSeconds | int | `10` | The frequency (in seconds) with which the probe will be performed. | +| readinessProbe.port | int | `8081` | The port for the readiness check endpoint. | +| replicaCount | int | `1` | The number of replicas for the deployment. | +| securityContext | object | `{}` | Pod-level security context for the entire pod. | +| service | object | `{"httpsPort":8443,"protocol":"TCP","targetPort":"https"}` | Service configuration for the operator. | +| service.httpsPort | int | `8443` | The port for the HTTPS endpoint. | +| service.protocol | string | `"TCP"` | The protocol used by the HTTPS endpoint. | +| service.targetPort | string | `"https"` | The name of the target port. | +| tolerations | list | `[]` | Node tolerations for scheduling pods. Allows the pods to be scheduled on nodes with matching taints. | +| volumes | list | `[{"name":"cert","secret":{"defaultMode":420,"secretName":"webhook-server-cert"}}]` | Configuration for the volumes used in the deployment. | +| webhookService | object | `{"ports":{"port":443,"protocol":"TCP","targetPort":9443},"type":"ClusterIP"}` | Configuration for the webhook service. | + diff --git a/charts/env-route-ns-mutator/templates/_helpers.tpl b/charts/env-route-ns-mutator/templates/_helpers.tpl new file mode 100644 index 0000000..b29f84f --- /dev/null +++ b/charts/env-route-ns-mutator/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "env-route-ns-mutator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "env-route-ns-mutator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "env-route-ns-mutator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "env-route-ns-mutator.labels" -}} +helm.sh/chart: {{ include "env-route-ns-mutator.chart" . }} +{{ include "env-route-ns-mutator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "env-route-ns-mutator.selectorLabels" -}} +app.kubernetes.io/name: {{ include "env-route-ns-mutator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "env-route-ns-mutator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "env-route-ns-mutator.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/env-route-ns-mutator/templates/config.yaml b/charts/env-route-ns-mutator/templates/config.yaml new file mode 100644 index 0000000..be24c25 --- /dev/null +++ b/charts/env-route-ns-mutator/templates/config.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.config.name }} + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +data: + environments: {{ join "," .Values.config.environments }} \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/deployment.yaml b/charts/env-route-ns-mutator/templates/deployment.yaml new file mode 100644 index 0000000..c4c6fb3 --- /dev/null +++ b/charts/env-route-ns-mutator/templates/deployment.yaml @@ -0,0 +1,104 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-controller-manager + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + control-plane: controller-manager + template: + metadata: + labels: + control-plane: controller-manager + {{- include "env-route-ns-mutator.selectorLabels" . | nindent 8 }} + annotations: + kubectl.kubernetes.io/default-container: manager + spec: + securityContext: + {{- toYaml .Values.securityContext | nindent 8 }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + tolerations: + {{- toYaml .Values.tolerations | nindent 8 }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + containers: + - name: manager + image: {{ .Values.image.manager.repository }}:{{ .Values.image.manager.tag | default .Chart.AppVersion }} + imagePullPolicy: {{ .Values.image.manager.pullPolicy }} + command: + {{- range .Values.manager.command }} + - {{ . }} + {{- end }} + args: + {{- range .Values.manager.args }} + - {{ . }} + {{- end }} + envFrom: + - configMapRef: + name: {{ .Values.config.name }} + securityContext: + {{- toYaml .Values.manager.securityContext | nindent 12 }} + livenessProbe: + httpGet: + path: /healthz + port: {{ .Values.livenessProbe.port }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + readinessProbe: + httpGet: + path: /readyz + port: {{ .Values.readinessProbe.port }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + resources: + limits: + cpu: {{ .Values.manager.resources.limits.cpu }} + memory: {{ .Values.manager.resources.limits.memory }} + requests: + cpu: {{ .Values.manager.resources.requests.cpu }} + memory: {{ .Values.manager.resources.requests.memory }} + ports: + - containerPort: {{ .Values.manager.ports.health.containerPort }} + name: {{ .Values.manager.ports.health.name }} + protocol: {{ .Values.manager.ports.health.protocol }} + - containerPort: {{ .Values.manager.ports.webhook.containerPort }} + name: {{ .Values.manager.ports.webhook.name }} + protocol: {{ .Values.manager.ports.webhook.protocol }} + volumeMounts: + {{- range .Values.manager.volumeMounts }} + - mountPath: {{ .mountPath }} + name: {{ .name }} + readOnly: {{ .readOnly }} + {{- end }} + - name: kube-rbac-proxy + image: {{ .Values.image.kubeRbacProxy.repository }}:{{ .Values.image.kubeRbacProxy.tag }} + imagePullPolicy: {{ .Values.image.kubeRbacProxy.pullPolicy }} + args: + {{- range .Values.kubeRbacProxy.args }} + - {{ . }} + {{- end }} + securityContext: + {{- toYaml .Values.kubeRbacProxy.securityContext | nindent 12 }} + ports: + - containerPort: {{ .Values.kubeRbacProxy.ports.https.containerPort }} + protocol: {{ .Values.kubeRbacProxy.ports.https.protocol }} + name: {{ .Values.kubeRbacProxy.ports.https.name }} + resources: + limits: + cpu: {{ .Values.kubeRbacProxy.resources.limits.cpu }} + memory: {{ .Values.kubeRbacProxy.resources.limits.memory }} + requests: + cpu: {{ .Values.kubeRbacProxy.resources.requests.cpu }} + memory: {{ .Values.kubeRbacProxy.resources.requests.memory }} + serviceAccountName: {{ include "env-route-ns-mutator.fullname" . }}-controller-manager + volumes: + {{- range .Values.volumes }} + - name: {{ .name }} + secret: + secretName: {{ .secret.secretName }} + defaultMode: {{ .secret.defaultMode }} + {{- end }} \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/leader-election-rbac-role-binding.yaml b/charts/env-route-ns-mutator/templates/leader-election-rbac-role-binding.yaml new file mode 100644 index 0000000..3911c9a --- /dev/null +++ b/charts/env-route-ns-mutator/templates/leader-election-rbac-role-binding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-leader-election-rolebinding + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "env-route-ns-mutator.fullname" . }}-leader-election-role +subjects: +- kind: ServiceAccount + name: {{ include "env-route-ns-mutator.fullname" . }}-controller-manager + namespace: {{ .Release.Namespace }} \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/leader-election-rbac-role.yaml b/charts/env-route-ns-mutator/templates/leader-election-rbac-role.yaml new file mode 100644 index 0000000..00b9e91 --- /dev/null +++ b/charts/env-route-ns-mutator/templates/leader-election-rbac-role.yaml @@ -0,0 +1,38 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-leader-election-role + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +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 \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/manager-rbac-cluster-role.yaml b/charts/env-route-ns-mutator/templates/manager-rbac-cluster-role.yaml new file mode 100644 index 0000000..6332456 --- /dev/null +++ b/charts/env-route-ns-mutator/templates/manager-rbac-cluster-role.yaml @@ -0,0 +1,37 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-manager-role + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - namespaces + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - config.openshift.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - create + - get + - list + - patch + - update + - watch \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/manager-rbac-cluster-rolebinding.yaml b/charts/env-route-ns-mutator/templates/manager-rbac-cluster-rolebinding.yaml new file mode 100644 index 0000000..f381f36 --- /dev/null +++ b/charts/env-route-ns-mutator/templates/manager-rbac-cluster-rolebinding.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-manager-rolebinding + labels: + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: env-route-ns-mutator + app.kubernetes.io/part-of: env-route-ns-mutator + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "env-route-ns-mutator.fullname" . }}-manager-role +subjects: +- kind: ServiceAccount + name: {{ include "env-route-ns-mutator.fullname" . }}-controller-manager + namespace: {{ .Release.Namespace }} \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/metrics-reader-rbac.yaml b/charts/env-route-ns-mutator/templates/metrics-reader-rbac.yaml new file mode 100644 index 0000000..5e387bc --- /dev/null +++ b/charts/env-route-ns-mutator/templates/metrics-reader-rbac.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-metrics-reader + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +rules: +- nonResourceURLs: + - /metrics + verbs: + - get \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/metrics-service.yaml b/charts/env-route-ns-mutator/templates/metrics-service.yaml new file mode 100644 index 0000000..480e4ce --- /dev/null +++ b/charts/env-route-ns-mutator/templates/metrics-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-metrics-service + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +spec: + ports: + - name: https + port: {{ .Values.service.httpsPort }} + protocol: {{ .Values.service.protocol }} + targetPort: {{ .Values.service.targetPort }} + selector: + control-plane: controller-manager \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/mutating-webhook-configuration.yaml b/charts/env-route-ns-mutator/templates/mutating-webhook-configuration.yaml new file mode 100644 index 0000000..64bed0f --- /dev/null +++ b/charts/env-route-ns-mutator/templates/mutating-webhook-configuration.yaml @@ -0,0 +1,51 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "env-route-ns-mutator.fullname" . }}-serving-cert + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +webhooks: +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: {{ include "env-route-ns-mutator.fullname" . }}-webhook-service + namespace: {{ .Release.Namespace }} + path: /mutate-v1-namespace + failurePolicy: Ignore + name: namespace.dana.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - namespaces + sideEffects: None +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: {{ include "env-route-ns-mutator.fullname" . }}-webhook-service + namespace: {{ .Release.Namespace }} + path: /mutate-v1-route + failurePolicy: Ignore + name: route.dana.io + rules: + - apiGroups: + - route.openshift.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - routes + sideEffects: None \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/proxy-rbac-cluster-rolebinding.yaml b/charts/env-route-ns-mutator/templates/proxy-rbac-cluster-rolebinding.yaml new file mode 100644 index 0000000..5eea741 --- /dev/null +++ b/charts/env-route-ns-mutator/templates/proxy-rbac-cluster-rolebinding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-proxy-rolebinding + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "env-route-ns-mutator.fullname" . }}-proxy-role +subjects: +- kind: ServiceAccount + name: {{ include "env-route-ns-mutator.fullname" . }}-controller-manager + namespace: {{ .Release.Namespace }} \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/proxy-rbac.yaml b/charts/env-route-ns-mutator/templates/proxy-rbac.yaml new file mode 100644 index 0000000..faabe95 --- /dev/null +++ b/charts/env-route-ns-mutator/templates/proxy-rbac.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-proxy-role + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/selfsigned-issuer.yaml b/charts/env-route-ns-mutator/templates/selfsigned-issuer.yaml new file mode 100644 index 0000000..96bcd20 --- /dev/null +++ b/charts/env-route-ns-mutator/templates/selfsigned-issuer.yaml @@ -0,0 +1,8 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-selfsigned-issuer + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +spec: + selfSigned: {} \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/serviceaccount.yaml b/charts/env-route-ns-mutator/templates/serviceaccount.yaml new file mode 100644 index 0000000..5b57e67 --- /dev/null +++ b/charts/env-route-ns-mutator/templates/serviceaccount.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-controller-manager + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/serving-cert.yaml b/charts/env-route-ns-mutator/templates/serving-cert.yaml new file mode 100644 index 0000000..95ec859 --- /dev/null +++ b/charts/env-route-ns-mutator/templates/serving-cert.yaml @@ -0,0 +1,14 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-serving-cert + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +spec: + dnsNames: + - {{ include "env-route-ns-mutator.fullname" . }}-webhook-service.{{ .Release.Namespace }}.svc + - {{ include "env-route-ns-mutator.fullname" . }}-webhook-service.{{ .Release.Namespace }}.svc.{{ .Values.kubernetesClusterDomain }} + issuerRef: + kind: Issuer + name: {{ include "env-route-ns-mutator.fullname" . }}-selfsigned-issuer + secretName: webhook-server-cert \ No newline at end of file diff --git a/charts/env-route-ns-mutator/templates/webhook-service.yaml b/charts/env-route-ns-mutator/templates/webhook-service.yaml new file mode 100644 index 0000000..27aeead --- /dev/null +++ b/charts/env-route-ns-mutator/templates/webhook-service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "env-route-ns-mutator.fullname" . }}-webhook-service + labels: + {{- include "env-route-ns-mutator.labels" . | nindent 4 }} +spec: + ports: + - port: {{ .Values.webhookService.ports.port }} + protocol: {{ .Values.webhookService.ports.protocol }} + targetPort: {{ .Values.webhookService.ports.targetPort }} + selector: + control-plane: controller-manager \ No newline at end of file diff --git a/charts/env-route-ns-mutator/values.yaml b/charts/env-route-ns-mutator/values.yaml new file mode 100644 index 0000000..5e4aa66 --- /dev/null +++ b/charts/env-route-ns-mutator/values.yaml @@ -0,0 +1,172 @@ +# Default values for env-route-ns-mutator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +image: + manager: + # -- The repository of the manager container image. + repository: ghcr.io/dana-team/env-route-ns-mutator + # -- The tag of the manager container image. + tag: "" + # -- The pull policy for the image. + pullPolicy: IfNotPresent + + kubeRbacProxy: + # -- The repository of the kube-rbac-proxy container image. + repository: gcr.io/kubebuilder/kube-rbac-proxy + # -- The tag of the kube-rbac-proxy container image. + tag: v0.16.0 + # -- The pull policy for the image. + pullPolicy: IfNotPresent + +# Override the name of the deployment +nameOverride: "" + +# Override the full name of the deployment +fullnameOverride: "" + +# -- The number of replicas for the deployment. +replicaCount: 1 + +# -- Node selector for scheduling pods. Allows you to specify node labels for pod assignment. +nodeSelector: {} + +# -- Node tolerations for scheduling pods. Allows the pods to be scheduled on nodes with matching taints. +tolerations: [] + +# -- Node affinity rules for scheduling pods. Allows you to specify advanced node selection constraints. +affinity: {} + +# -- Configuration for the liveness probe. +livenessProbe: + # -- The port for the health check endpoint. + port: 8081 + # -- The initial delay before the liveness probe is initiated. + initialDelaySeconds: 15 + # -- The frequency (in seconds) with which the probe will be performed. + periodSeconds: 20 + +# -- Configuration for the readiness probe. +readinessProbe: + # -- The port for the readiness check endpoint. + port: 8081 + # -- The initial delay before the readiness probe is initiated. + initialDelaySeconds: 5 + # -- The frequency (in seconds) with which the probe will be performed. + periodSeconds: 10 + +# -- Configuration for the manager container. +manager: + # -- Command-line commands passed to the manager container. + command: + - /manager + # -- Command-line arguments passed to the manager container. + args: + - --leader-elect + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + # -- Port configurations for the manager container. + ports: + health: + # -- The port for the health check endpoint. + containerPort: 8081 + # -- The protocol used by the health check endpoint. + protocol: TCP + # -- The name of the health check port. + name: health + webhook: + # -- The port for the webhook server. + containerPort: 9443 + # -- The protocol used by the webhook server. + protocol: TCP + # -- The name of the webhook port. + name: webhook-server + # -- Security settings for the manager container. + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + # -- Resource requests and limits for the manager container. + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + # -- Volume mounts for the manager container. + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + webhookServer: + # -- The name of the secret containing the webhook server certificate. + secretName: webhook-server-cert + # -- The default mode for the secret. + defaultMode: 420 + +# -- Configuration for the kube-rbac-proxy container. +kubeRbacProxy: + # -- Command-line arguments passed to the kube-rbac-proxy container. + args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + # -- Port configurations for the kube-rbac-proxy container. + ports: + https: + # -- The port for the HTTPS endpoint. + containerPort: 8443 + # -- The protocol used by the HTTPS endpoint. + protocol: TCP + # -- The name of the HTTPS port. + name: https + # -- Security settings for the kube-rbac-proxy container. + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + # -- Resource requests and limits for the kube-rbac-proxy container. + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + +# -- Pod-level security context for the entire pod. +securityContext: {} + +# -- Name of the ConfigMap used for configuration. +config: + name: operator-config + environments: + - env1 + - env2 +# -- Service configuration for the operator. +service: + # -- The port for the HTTPS endpoint. + httpsPort: 8443 + # -- The protocol used by the HTTPS endpoint. + protocol: TCP + # -- The name of the target port. + targetPort: https + +# -- Configuration for the webhook service. +webhookService: + type: ClusterIP + ports: + port: 443 + protocol: TCP + targetPort: 9443 + +# -- Configuration for the volumes used in the deployment. +volumes: + - name: cert + secret: + secretName: webhook-server-cert + defaultMode: 420 \ No newline at end of file