From 20faa538f5258b361d2852521583b98e08d05995 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=B6ran=20P=C3=B6hner?=
 <10630407+groundhog2k@users.noreply.github.com>
Date: Mon, 27 Nov 2023 15:43:35 +0100
Subject: [PATCH] Allows usage of existing secret reference and added network
 policy support (#1284)

---
 charts/mysql/Chart.yaml                   |  9 ++++--
 charts/mysql/README.md                    | 24 +++++++++++++---
 charts/mysql/RELEASENOTES.md              |  1 +
 charts/mysql/templates/_helpers.tpl       |  9 ------
 charts/mysql/templates/networkpolicy.yaml | 25 +++++++++++++++++
 charts/mysql/templates/pvc.yaml           |  4 +--
 charts/mysql/templates/secureconfig.yaml  | 20 ++++++++-----
 charts/mysql/templates/statefulset.yaml   | 34 +++++++++++++++++++----
 charts/mysql/values.yaml                  | 24 ++++++++++++++--
 9 files changed, 117 insertions(+), 33 deletions(-)
 create mode 100644 charts/mysql/templates/networkpolicy.yaml

diff --git a/charts/mysql/Chart.yaml b/charts/mysql/Chart.yaml
index b18b84eb..fff6e9ef 100644
--- a/charts/mysql/Chart.yaml
+++ b/charts/mysql/Chart.yaml
@@ -6,7 +6,12 @@ type: application
 
 maintainers:
   - name: groundhog2k
+    url: https://github.com/groundhog2k/helm-charts
 
-version: "0.3.0"
+keywords:
+  - database
+  - mysql
 
-appVersion: "8.2.0"
+version: "1.0.0"
+
+appVersion: "8.0.35"
diff --git a/charts/mysql/README.md b/charts/mysql/README.md
index 3e16906d..7fb2a688 100644
--- a/charts/mysql/README.md
+++ b/charts/mysql/README.md
@@ -94,6 +94,16 @@ helm uninstall my-release
 | service.loadBalancerIP | string | `nil` | The load balancer ip address (only relevant for type LoadBalancer) |
 | service.annotations | object | `{}` | Additional service annotations |
 
+## Network policies
+
+Allows to define optional network policies for [ingress and egress](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
+The policyTypes will be automatically set
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| networkPolicy.ingress | object | `{}` | Ingress network policies |
+| networkPolicy.egress | object | `{}` | Egress network policies |
+
 ## Storage parameters
 
 | Key | Type | Default | Description |
@@ -111,10 +121,16 @@ helm uninstall my-release
 |-----|------|---------|-------------|
 | useDeployment | bool | `false` | Use Kubernetes Deployment instead of StatefulSet |
 | userDatabase | object | `{}` | Optional MySQL user database |
-| userDatabase.name | string | `""` | Name of the user database |
-| userDatabase.user | string | `""` | User name with full access to user database|
-| userDatabase.password | string | `""` | Password of created user |
-| settings.rootPassword | string | `nil` | MySQL root password |
+| userDatabase.existingSecret | string | `nil` | Optional existing secret with database name, user and password |
+| userDatabase.name.secretKey | string | `""` | Key of the existingSecret with database name |
+| userDatabase.name.value | string | `""` | Name of the user database (if no existingSecret was specified) |
+| userDatabase.user.secretKey | string | `""` | Key of the existingSecret with database user |
+| userDatabase.user.value | string | `""` | User name with full access to user database (if no existingSecret was specified) |
+| userDatabase.password.secretKey | string | `""` | Key of the existingSecret with password of created user |
+| userDatabase.password.value | string | `""` | Password of created user (if no existingSecret was specified) |
+| settings.existingSecret | string | `nil` | Optional existing secret for the root password |
+| settings.rootPassword.secretKey | string | `nil` | Key of existingSecret for the MariaDB root password |
+| settings.rootPassword.value | string | `nil` | MariaDB root password (if no existingSecret was specified) |
 | settings.allowEmptyRootPassword | bool | `false` | Set true to allow an empty root password |
 | settings.skipTZInfo | bool | `false` | Set true to skip loading timezone data during init |
 | settings.arguments | list | `[]` | Additional arguments for mysqld (entrypoint process) |
diff --git a/charts/mysql/RELEASENOTES.md b/charts/mysql/RELEASENOTES.md
index 7460dc10..05f4c19c 100644
--- a/charts/mysql/RELEASENOTES.md
+++ b/charts/mysql/RELEASENOTES.md
@@ -16,4 +16,5 @@
 | 0.1.11 | 8.0.35 | Upgraded MySQL to 8.0.35 |
 | 0.2.0 | 8.1.0 | Upgraded MySQL to 8.1.0 |
 | 0.3.0 | 8.2.0 | Upgraded MySQL to 8.2.0 |
+| 1.0.0 | 8.0.35 | Bumped to stable major chart version - Allows usage of existing secret references and network policies |
 | | | |
diff --git a/charts/mysql/templates/_helpers.tpl b/charts/mysql/templates/_helpers.tpl
index 76d4b207..721a597f 100644
--- a/charts/mysql/templates/_helpers.tpl
+++ b/charts/mysql/templates/_helpers.tpl
@@ -61,12 +61,3 @@ Create the name of the service account to use
 {{- default "default" .Values.serviceAccount.name }}
 {{- end }}
 {{- end }}
-
-{{/*
-Generate secret with configuration
-*/}}
-{{- define "mysql.createSecureConfig" -}}
-  {{- if or (.Values.settings.rootPassword) (.Values.userDatabase) }}
-true
-  {{- end }}
-{{- end }}
diff --git a/charts/mysql/templates/networkpolicy.yaml b/charts/mysql/templates/networkpolicy.yaml
new file mode 100644
index 00000000..ea758833
--- /dev/null
+++ b/charts/mysql/templates/networkpolicy.yaml
@@ -0,0 +1,25 @@
+{{- with .Values.networkPolicy }}
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+  name: {{ include "mysql.fullname" $ }}
+spec:
+  podSelector:
+    matchLabels:
+      {{- include "mysql.selectorLabels" $ | nindent 6 }}
+  policyTypes:
+  {{- if .ingress }}
+    - Ingress
+  {{- end }}
+  {{- if .egress }}
+    - Egress
+  {{- end }}
+  {{- with .ingress }}
+  ingress:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+  {{- with .egress }}
+  egress:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+{{- end }}
diff --git a/charts/mysql/templates/pvc.yaml b/charts/mysql/templates/pvc.yaml
index 37d4ee5d..426e7337 100644
--- a/charts/mysql/templates/pvc.yaml
+++ b/charts/mysql/templates/pvc.yaml
@@ -1,6 +1,5 @@
-{{- if .Values.useDeployment }}
 {{- $createPvc := and (empty .Values.storage.persistentVolumeClaimName) (.Values.storage.requestedSize) }}
-{{- if $createPvc }}
+{{- if and (.Values.useDeployment) ($createPvc) }}
 apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
@@ -24,4 +23,3 @@ spec:
   {{- end }}
   {{- end }}  
 {{- end }}
-{{- end }}
diff --git a/charts/mysql/templates/secureconfig.yaml b/charts/mysql/templates/secureconfig.yaml
index 5da6f91e..c67a303a 100644
--- a/charts/mysql/templates/secureconfig.yaml
+++ b/charts/mysql/templates/secureconfig.yaml
@@ -1,4 +1,6 @@
-{{- if include "mysql.createSecureConfig" . }}
+{{- $rootSet := and (not .Values.settings.existingSecret) ((.Values.settings.rootPassword).value) }}
+{{- $userDatabaseSet := and (.Values.userDatabase) (not .Values.userDatabase.existingSecret) }}
+{{- if or ($rootSet) ($userDatabaseSet) }}
 apiVersion: v1
 kind: Secret
 metadata:
@@ -8,15 +10,19 @@ metadata:
 type: Opaque
 data:
   {{- with .Values.settings }}
-  {{- if .rootPassword }}
-  MYSQL_ROOT_PASSWORD: {{ .rootPassword | b64enc }}
+  {{- if (.rootPassword).value }}
+  MYSQL_ROOT_PASSWORD: {{ .rootPassword.value | b64enc }}
   {{- end }}
   {{- end }}
   {{- with .Values.userDatabase }}
-  MYSQL_DATABASE: {{ required "Values: userDatabase.name is mandatory if userDatabase is specified." .name | b64enc }}
-  {{- if .user }}
-  MYSQL_USER: {{ .user | b64enc }}
-  MYSQL_PASSWORD: {{ required "Values: userDatabase.password is mandatory if userDatabase.user is specified." .password | b64enc }}
+  {{- if not .existingSecret }}
+  {{- $_ := required "Values: userDatabase.name is mandatory if userDatabase is specified without existing secret" .name }}
+  MYSQL_DATABASE: {{ required "Values: userDatabase.name.value is mandatory if userDatabase is specified without existingSecret." .name.value | b64enc }}
+  {{- if (.user).value }}
+  MYSQL_USER: {{ .user.value | b64enc }}
+  {{- $_ := required "Values: userDatabase.password is mandatory if userDatabase is specified without existing secret" .password }}
+  MYSQL_PASSWORD: {{ required "Values: userDatabase.password.value is mandatory if userDatabase.user is specified without existingSecret." .password.value | b64enc }}
+  {{- end }}
   {{- end }}
   {{- end }}
 {{- end }}
diff --git a/charts/mysql/templates/statefulset.yaml b/charts/mysql/templates/statefulset.yaml
index 710a7218..539f282d 100644
--- a/charts/mysql/templates/statefulset.yaml
+++ b/charts/mysql/templates/statefulset.yaml
@@ -186,26 +186,48 @@ spec:
             {{- end }}
           {{- end }}
           env:
+          {{- if or (.Values.settings.existingSecret) ((.Values.settings.rootPassword).value) }}
+            - name: MYSQL_ROOT_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: {{ default (include "mysql.fullname" .) .Values.settings.existingSecret }}
+                  key: {{ default "MYSQL_ROOT_PASSWORD" (.Values.settings.rootPassword).secretKey }}
+          {{- end }}
+          {{- with .Values.userDatabase }}
+            - name: MYSQL_DATABASE
+              valueFrom:
+                secretKeyRef:
+                  name: {{ default (include "mysql.fullname" $) .existingSecret }}
+                  key: {{ default "MYSQL_DATABASE" .name.secretKey }}
+            - name: MYSQL_USER
+              valueFrom:
+                secretKeyRef:
+                  name: {{ default (include "mysql.fullname" $) .existingSecret }}
+                  key: {{ default "MYSQL_USER" .user.secretKey }}
+            - name: MYSQL_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: {{ default (include "mysql.fullname" $) .existingSecret }}
+                  key: {{ default "MYSQL_PASSWORD" .password.secretKey }}
+          {{- end }}
           {{- if .Values.settings.skipTZInfo }}
             - name: MYSQL_INITDB_SKIP_TZINFO
               value: "yes"
           {{- end }}
           {{- if .Values.settings.allowEmptyRootPassword }}
-            - name: MYSQL_ALLOW_EMPTY_ROOT_PASSWORD
+            - name: MYSQL_ALLOW_EMPTY_PASSWORD
               value: "yes"
           {{- end }}
           {{- with .Values.env }}
             {{- toYaml . | nindent 12 }}
           {{- end }}
+          {{- with .Values.extraEnvSecrets }}
           envFrom:
-          {{- if include "mysql.createSecureConfig" . }}
-            - secretRef:
-                name: {{ $fullname }}
-          {{- end }}
-          {{- range .Values.extraEnvSecrets }}
+          {{- range . }}
             - secretRef:
                 name: {{ . }}
           {{- end }}
+          {{- end }}
       {{- with .Values.extraContainers }}
       {{- toYaml . | nindent 8 }}
       {{- end }}
diff --git a/charts/mysql/values.yaml b/charts/mysql/values.yaml
index ea160f69..049c061d 100644
--- a/charts/mysql/values.yaml
+++ b/charts/mysql/values.yaml
@@ -136,6 +136,12 @@ extraContainers: []
 ## Additional environment variables
 env: []
 
+## Network policies
+networkPolicy: {}
+  ## Ingress and Egress policies
+  # ingress: {}
+  # egress: {}
+
 ## Use Kubernetes Deployment instead of StatefulSet
 useDeployment: false
 
@@ -146,8 +152,13 @@ settings:
   #  - --character-set-server=utf8mb4
   #  - --collation-server=utf8mb4_unicode_ci
 
+  ## Optional existing secret for the MariaDB root password
+  existingSecret:
+
   ## The root user password
   rootPassword:
+  #  secretKey:
+  #  value:
 
   ## Set true to allow an empty root password
   allowEmptyRootPassword: false
@@ -157,14 +168,23 @@ settings:
 
 ## Optional user database which is created during first startup with user and password
 userDatabase: {}
+  ## Optional existing secret with database name, user and password
+  # existingSecret:
   ## Name of the user database
   # name:
-
+  ##  Use secretKey when existingSecret was specified otherwise value
+  #   secretKey:
+  #   value:
   ## Database user with full access rights
+  ##  Use secretKey when existingSecret was specified otherwise value
   # user:
-
+  #   secretKey:
+  #   value:
   ## Password of the database user
+  ##  Use secretKey when existingSecret was specified otherwise value
   # password:
+  #   secretKey:
+  #   value:
 
 ## Optional custom configuration block that will be mounted as file in /etc/mysql/conf.d/custom.cnf
 ## For more flexible options see extraSecretConfigs: section
-- 
GitLab