Repository: sapcc/helm-charts
Pull request #8162: [hermes] move logstash conf to config map, all secrets in secrets
Author: login: notque
Created: 2025-03-10T19:07:49Z | Merged: 2025-03-18T16:16:10Z



Diff:
diff --git a/openstack/hermes/Chart.yaml b/openstack/hermes/Chart.yaml
index b62c3e83326..516eda5875d 100644
--- a/openstack/hermes/Chart.yaml
+++ b/openstack/hermes/Chart.yaml
@@ -4,7 +4,7 @@ description: Helm audit management for Openstack
 maintainers:
   - name: notque
 name: hermes
-version: 0.1.4
+version: 0.1.5
 dependencies:
   - name: linkerd-support
     repository: oci://keppel.eu-de-1.cloud.sap/ccloud-helm
diff --git a/openstack/hermes/README.md b/openstack/hermes/README.md
index 12381b0a299..5eaefbae7dc 100644
--- a/openstack/hermes/README.md
+++ b/openstack/hermes/README.md
@@ -4,7 +4,7 @@
 
 Important Note:
 
-Hermes utilizes Persistent Volumes for ElasticSearch. These PV's are set to RECYCLE, so when they are no longer used, they are deleted and available for other pods.
+Hermes utilizes Persistent Volumes for OpenSearch. These PV's are set to RECYCLE, so when they are no longer used, they are deleted and available for other pods.
 
 Deployment with the --force option will delete all data from the Data Store. Deployment with the --force option should not be used, and care must be taken to validate all data is available.
 
diff --git a/openstack/hermes/templates/etc/_logstash.conf.tpl b/openstack/hermes/templates/etc/_logstash.conf.tpl
index 7adf05c0115..1d853eaf9f2 100644
--- a/openstack/hermes/templates/etc/_logstash.conf.tpl
+++ b/openstack/hermes/templates/etc/_logstash.conf.tpl
@@ -1,21 +1,20 @@
 input {
 
-{{ range $key, $value := .Values.hermes.rabbitmq.targets }}
-{{- $user := $value.user | default $.Values.hermes.rabbitmq.user }}
-{{- $host := printf "%s-rabbitmq.monsoon3.svc.kubernetes.%s.%s" $key $.Values.global.region $.Values.global.tld}}
+{{ range $replica_name, $replica := .Values.hermes.rabbitmq.targets }}
+{{- $host := printf "%s-rabbitmq.monsoon3.svc.kubernetes.%s.%s" $replica_name $.Values.global.region $.Values.global.tld}}
 rabbitmq {
-    id => "{{ printf "logstash_hermes_%s" $key }}"
-    host => "{{ $value.host | default (printf $.Values.hermes.rabbitmq.host_template $key) }}"
-    user => "{{ $user }}"
-    password => "{{ $value.password }}"
+    id => "{{ printf "logstash_hermes_%s" $replica_name }}"
+    host => "{{ $replica.host | default (printf $.Values.hermes.rabbitmq.host_template $replica_name) }}"
+    user => "${RABBITMQ_{{ upper $replica_name }}_USER}"
+    password => "${RABBITMQ_{{ upper $replica_name }}_PASSWORD}"
     port => {{ $.Values.hermes.rabbitmq.port }}
-    queue => "{{ $value.queue_name | default $.Values.hermes.rabbitmq.queue_name }}"
+    queue => "{{ $replica.queue_name | default $.Values.hermes.rabbitmq.queue_name }}"
     subscription_retry_interval_seconds => 60
     automatic_recovery => true
     connection_timeout => 1000
     heartbeat => 5
     connect_retry_interval => 60
-    durable => {{ $value.durable | default false }}
+    durable => {{ $replica.durable | default false }}
   }
 {{ end }}
 }
@@ -287,8 +286,8 @@ filter {
     ]
     staging_directory => "/tmp/logstash/jdbc_static/import_data"
     loader_schedule => "{{ .Values.logstash.jdbc.schedule }}"
-    jdbc_user => "{{ .Values.global.metis.user | default "default" }}"
-    jdbc_password => "{{ .Values.global.metis.password | default "default" }}"
+    jdbc_user => "${METIS_USER}"
+    jdbc_password => "${METIS_PASSWORD}"
     jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
     jdbc_driver_library => ""
     jdbc_connection_string => "jdbc:mysql://{{ .Values.logstash.jdbc.service }}.{{ .Values.logstash.jdbc.namespace }}:3306/{{ .Values.logstash.jdbc.db }}"
@@ -496,8 +495,8 @@ output {
           hosts => ["https://{{.Values.hermes_elasticsearch_host}}.{{.Values.global.region}}.{{.Values.global.tld}}:{{.Values.hermes_elasticsearch_port}}"]
           auth_type => {
             type => 'basic'
-            user => "{{.Values.users.audit.username}}"
-            password => "{{.Values.users.audit.password}}"
+            user => "${OPENSEARCH_USER}"
+            password => "${OPENSEARCH_PASSWORD}"
           }
           retry_max_interval => 10
           validate_after_inactivity => 1000
@@ -516,8 +515,8 @@ output {
           validate_after_inactivity => 1000
           auth_type => {
             type => 'basic'
-            user => "{{.Values.users.audit.username}}"
-            password => "{{.Values.users.audit.password}}"
+            user => "${OPENSEARCH_USER}"
+            password => "${OPENSEARCH_PASSWORD}"
           }
           ssl => true
           ssl_certificate_verification => true
@@ -537,8 +536,8 @@ output {
         validate_after_inactivity => 1000
         auth_type => {
           type => 'basic'
-          user => "{{.Values.users.audit.username}}"
-          password => "{{.Values.users.audit.password}}"
+          user => "${OPENSEARCH_USER}"
+          password => "${OPENSEARCH_PASSWORD}"
         }
         ssl => true
         ssl_certificate_verification => true
@@ -550,8 +549,8 @@ output {
     s3 {
       id => "output_s3_for_swift"
       endpoint => "{{.Values.logstash.endpoint}}"
-      access_key_id => "{{.Values.logstash.access_key_id_conf}}"
-      secret_access_key => "{{.Values.logstash.secret_access_key_conf}}"
+      access_key_id => "${SWIFT_ACCESS_KEY}"
+      secret_access_key => "${SWIFT_SECRET_KEY}"
       region => "{{.Values.logstash.region}}"
       bucket => "{{.Values.logstash.bucket}}"
       prefix => "{{.Values.logstash.prefix}}"
diff --git a/openstack/hermes/templates/logstash-deployment.yaml b/openstack/hermes/templates/logstash-deployment.yaml
index e88b64cdc0a..13ef0c8c7fa 100644
--- a/openstack/hermes/templates/logstash-deployment.yaml
+++ b/openstack/hermes/templates/logstash-deployment.yaml
@@ -57,12 +57,70 @@ spec:
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
+            
             - name: LS_JAVA_OPTS
               value: {{.Values.logstash.javaopts}}
+            
             - name: CONFIG_HASH
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.annotations['logstash-etc-configmap.yaml']
+            
+            # ======================================================
+            # Dynamically add environment variables for *each* RabbitMQ target
+            # ======================================================
+            {{- range $key, $value := .Values.hermes.rabbitmq.targets }}
+            - name: "RABBITMQ_{{ upper $key }}_USER"
+              valueFrom:
+                secretKeyRef:
+                  name: logstash-secret
+                  key: "RABBITMQ_{{ upper $key }}_USER"
+
+            - name: "RABBITMQ_{{ upper $key }}_PASSWORD"
+              valueFrom:
+                secretKeyRef:
+                  name: logstash-secret
+                  key: "RABBITMQ_{{ upper $key }}_PASSWORD"
+            {{- end }}
+
+            # Metis / DB
+            - name: METIS_USER
+              valueFrom:
+                secretKeyRef:
+                  name: logstash-secret
+                  key: METIS_USER
+
+            - name: METIS_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: logstash-secret
+                  key: METIS_PASSWORD
+
+            # Swift / S3
+            - name: SWIFT_ACCESS_KEY
+              valueFrom:
+                secretKeyRef:
+                  name: logstash-secret
+                  key: SWIFT_ACCESS_KEY
+
+            - name: SWIFT_SECRET_KEY
+              valueFrom:
+                secretKeyRef:
+                  name: logstash-secret
+                  key: SWIFT_SECRET_KEY
+
+            # OpenSearch
+            - name: OPENSEARCH_USER
+              valueFrom:
+                secretKeyRef:
+                  name: logstash-secret
+                  key: OPENSEARCH_USER
+
+            - name: OPENSEARCH_PASSWORD
+              valueFrom:
+                secretKeyRef:
+                  name: logstash-secret
+                  key: OPENSEARCH_PASSWORD
           volumeMounts:
             - name: hermes-etc
               mountPath: /hermes-etc
diff --git a/openstack/hermes/templates/logstash-etc-configmap.yaml b/openstack/hermes/templates/logstash-etc-configmap.yaml
index 4b4053b2c5d..693235c6a0b 100644
--- a/openstack/hermes/templates/logstash-etc-configmap.yaml
+++ b/openstack/hermes/templates/logstash-etc-configmap.yaml
@@ -16,6 +16,8 @@ metadata:
 data:
   audit.json: |
 {{ include "hermes/templates/etc/_audit.json.tpl" . | indent 4 }}
+  logstash.conf: |
+{{ include "hermes/templates/etc/_logstash.conf.tpl" . | indent 4 }}
   logstash.yml: |
 {{ include "hermes/templates/etc/_logstash.yml.tpl" . | indent 4 }}
   log4j2.properties: |
diff --git a/openstack/hermes/templates/logstash-secret.yaml b/openstack/hermes/templates/logstash-secret.yaml
index 233b2ce076f..7e8a07b657a 100644
--- a/openstack/hermes/templates/logstash-secret.yaml
+++ b/openstack/hermes/templates/logstash-secret.yaml
@@ -6,5 +6,19 @@ metadata:
   labels:
     system: openstack
     service: audit
+type: Opaque
 data:
-  logstash.conf: {{ include (print .Template.BasePath  "/etc/_logstash.conf.tpl") . | b64enc }}
+  {{- /* For each RabbitMQ target, store user/password as base64. */}}
+  {{- range $key, $value := .Values.hermes.rabbitmq.targets }}
+  RABBITMQ_{{ upper $key }}_USER: {{ printf "%s" ($value.user | default $.Values.hermes.rabbitmq.user) | b64enc }}
+  RABBITMQ_{{ upper $key }}_PASSWORD: {{ printf "%s" ($value.password | default $.Values.hermes.rabbitmq.password) | b64enc }}
+  {{- end }}
+
+  METIS_USER: {{ required "missing .Values.global.metis.user" .Values.global.metis.user | b64enc }}
+  METIS_PASSWORD: {{ required "missing .Values.global.metis.password" .Values.global.metis.password | b64enc }}
+
+  SWIFT_ACCESS_KEY: {{ required "missing .Values.logstash.access_key_id_conf" .Values.logstash.access_key_id_conf | b64enc }}
+  SWIFT_SECRET_KEY: {{ required "missing .Values.logstash.secret_access_key_conf" .Values.logstash.secret_access_key_conf | b64enc }}
+
+  OPENSEARCH_USER: {{ required "missing .Values.users.audit.username" .Values.users.audit.username | b64enc }}
+  OPENSEARCH_PASSWORD: {{ required "missing .Values.users.audit.password" .Values.users.audit.password | b64enc }}


Reviews:
user: login: viennaa
body: Thanks for secreting this chart. Like the idea of using environment vars here.

Two things from my pov inline.
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T09:31:34Z
user: login: viennaa
body: Thanks :) 
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T16:10:03Z

Review comments:
diff_hunk: @@ -4,7 +4,7 @@
 
 Important Note:
 
-Hermes utilizes Persistent Volumes for ElasticSearch. These PV's are set to RECYCLE, so when they are no longer used, they are deleted and available for other pods.
+Hermes utilizes Persistent Volumes for Opensearch. These PV's are set to RECYCLE, so when they are no longer used, they are deleted and available for other pods.
path: openstack/hermes/README.md
user: login: viennaa
body: ```suggestion
Hermes utilizes Persistent Volumes for OpenSearch. These PV's are set to RECYCLE, so when they are no longer used, they are deleted and available for other pods.
```
created_at: 2025-03-18T09:19:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,13 +1,12 @@
 input {
 
 {{ range $key, $value := .Values.hermes.rabbitmq.targets }}
path: openstack/hermes/templates/etc/_logstash.conf.tpl
user: login: viennaa
body: To me $key and $value are not explanatory. Can they be renamed? I've tried to understand what $key is actually holding but there is also no example in the [values.yaml](https://github.com/sapcc/helm-charts/blob/master/openstack/hermes/values.yaml#L23-L28)

Checking in the config repo it is the replica. So maybe this would be a better naming here:

```suggestion
{{ range $replica_name, $replica := .Values.hermes.rabbitmq.targets }}
```

Then the bottom part also would read easier:

```
    user => "${RABBITMQ_{{ upper $replica_name }}_USER}"
    password => "${RABBITMQ_{{ upper $replica_name }}_PASSWORD}"
```
created_at: 2025-03-18T09:29:02Z
author_association: CONTRIBUTOR

PR comments:
user: login: sapcc-bot
created_at: 2025-03-10T19:09:38Z
body: Failed to validate the helm chart. [Details](https://ci1.eu-de-2.cloud.sap/builds/3918293365). [Readme](https://github.com/sapcc/helm-charts/blob/master/ci/README.md).
author_association: CONTRIBUTOR
user: login: sapcc-bot
created_at: 2025-03-10T19:43:15Z
body: Failed to validate the helm chart. [Details](https://ci1.eu-de-2.cloud.sap/builds/3918371677). [Readme](https://github.com/sapcc/helm-charts/blob/master/ci/README.md).
author_association: CONTRIBUTOR
user: login: sapcc-bot
created_at: 2025-03-18T16:03:08Z
body: Failed to validate the helm chart. [Details](https://ci1.eu-de-2.cloud.sap/builds/3946349113). [Readme](https://github.com/sapcc/helm-charts/blob/master/ci/README.md).
author_association: CONTRIBUTOR