diff --git a/helm/README.md b/helm/README.md index af494f35c2..cc956b4044 100644 --- a/helm/README.md +++ b/helm/README.md @@ -219,9 +219,28 @@ Per-entry `refreshInterval` and `creationPolicy` overrides are also supported; s | `logflare.backend.bigquery.datasetLocation` | `GOOGLE_DATASET_LOCATION` | bigquery only | | `logflare.backend.postgres.schema` | `POSTGRES_BACKEND_SCHEMA` | postgres only | | `logflare.secretRefs` | see [Loading secrets](#loading-secrets) | | +| `logflare.certFilesSecret` | — | Name of a Secret whose keys are cert filenames; mounted as files. See [Certificate files](#certificate-files) | +| `logflare.certFilesMountPath` | `DB_SSL_*_PATH`, `LOGFLARE_TLS_*_PATH` | Mount path for `certFilesSecret`; the chart points the cert path env vars here | +| `logflare.reloader` | — | When `true`, adds the Stakater Reloader annotation so the Deployment rolls on ConfigMap/Secret changes | +| `logflare.extraConfig` | (any) | Map of non-secret env vars rendered verbatim into the ConfigMap | See `values.yaml` for the full set of generic chart values (image, service, ingress, resources, autoscaling, etc.). +### Certificate files + +Unlike the env-var secrets loaded via `envFrom`, Logflare reads its TLS/mTLS +material from files on disk: the internal database SSL certs (when `DB_SSL` is +enabled) and the gRPC TLS cert/key (when `LOGFLARE_ENABLE_GRPC_SSL` is enabled). + +Provide these via a separate Secret whose keys are the exact filenames — +`db-server-ca.pem`, `db-client-cert.pem`, `db-client-key.pem`, `cert.pem`, +`cert.key` — and set `logflare.certFilesSecret` to its name. The chart mounts it +at `logflare.certFilesMountPath` and sets `DB_SSL_CA_CERT_PATH`, +`DB_SSL_CLIENT_CERT_PATH`, `DB_SSL_CLIENT_KEY_PATH`, `LOGFLARE_TLS_CERT_PATH`, +and `LOGFLARE_TLS_KEY_PATH` to point at the mounted files. (The BigQuery service +account key is handled as an env-var secret via `GOOGLE_APPLICATION_CREDENTIALS_JSON`, +not a mounted file.) + ## Verifying a deployment Render the manifests locally before installing: diff --git a/helm/configmap_test.yaml b/helm/configmap_test.yaml index 31ec417310..f47dd569e9 100644 --- a/helm/configmap_test.yaml +++ b/helm/configmap_test.yaml @@ -51,3 +51,18 @@ tests: path: data.PHX_URL_HOST value: "example.com" template: configmap.yaml + + - it: should render extraConfig entries verbatim into the ConfigMap + set: + logflare.extraConfig: + LOGFLARE_LOG_LEVEL: info + SPOOL_MODE: enabled + asserts: + - equal: + path: data.LOGFLARE_LOG_LEVEL + value: "info" + template: configmap.yaml + - equal: + path: data.SPOOL_MODE + value: "enabled" + template: configmap.yaml diff --git a/helm/deployment_test.yaml b/helm/deployment_test.yaml index 97f8cf7704..60fcf8c0b5 100644 --- a/helm/deployment_test.yaml +++ b/helm/deployment_test.yaml @@ -92,3 +92,59 @@ tests: path: spec.template.spec.containers[0].ports[1].containerPort value: 50051 template: deployment.yaml + + - it: should not mount cert files or set cert paths by default + asserts: + - notExists: + path: spec.template.spec.volumes + template: deployment.yaml + - notContains: + path: spec.template.spec.containers[0].env + content: + name: DB_SSL_CA_CERT_PATH + value: /etc/logflare/certs/db-server-ca.pem + template: deployment.yaml + + - it: should mount the cert files Secret and point cert paths at it when set + set: + logflare.certFilesSecret: logflare-cert-files + asserts: + - equal: + path: spec.template.spec.volumes[0].name + value: cert-files + template: deployment.yaml + - equal: + path: spec.template.spec.volumes[0].secret.secretName + value: logflare-cert-files + template: deployment.yaml + - equal: + path: spec.template.spec.containers[0].volumeMounts[0].mountPath + value: /etc/logflare/certs + template: deployment.yaml + - contains: + path: spec.template.spec.containers[0].env + content: + name: DB_SSL_CA_CERT_PATH + value: /etc/logflare/certs/db-server-ca.pem + template: deployment.yaml + - contains: + path: spec.template.spec.containers[0].env + content: + name: LOGFLARE_TLS_CERT_PATH + value: /etc/logflare/certs/cert.pem + template: deployment.yaml + + - it: should add the Reloader annotation only when enabled + asserts: + - notExists: + path: metadata.annotations["reloader.stakater.com/auto"] + template: deployment.yaml + + - it: should add the Reloader annotation when reloader is true + set: + logflare.reloader: true + asserts: + - equal: + path: metadata.annotations["reloader.stakater.com/auto"] + value: "true" + template: deployment.yaml diff --git a/helm/templates/configmap.yaml b/helm/templates/configmap.yaml index 89c39dfdd1..356c33cb47 100644 --- a/helm/templates/configmap.yaml +++ b/helm/templates/configmap.yaml @@ -39,3 +39,6 @@ data: {{- else }} {{- fail (printf "logflare.backend.type must be 'bigquery' or 'postgres', got %q" .Values.logflare.backend.type) }} {{- end }} + {{- range $key, $value := .Values.logflare.extraConfig }} + {{ $key }}: {{ $value | quote }} + {{- end }} diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index d00afdd1f0..475cc065ae 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -2,6 +2,10 @@ apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "logflare.fullname" . }} + {{- if .Values.logflare.reloader }} + annotations: + reloader.stakater.com/auto: "true" + {{- end }} labels: {{- include "logflare.labels" . | nindent 4 }} spec: @@ -58,6 +62,19 @@ spec: fieldRef: fieldPath: status.podIP {{- end }} + {{- if .Values.logflare.certFilesSecret }} + {{- $mount := .Values.logflare.certFilesMountPath }} + - name: DB_SSL_CA_CERT_PATH + value: {{ printf "%s/db-server-ca.pem" $mount | quote }} + - name: DB_SSL_CLIENT_CERT_PATH + value: {{ printf "%s/db-client-cert.pem" $mount | quote }} + - name: DB_SSL_CLIENT_KEY_PATH + value: {{ printf "%s/db-client-key.pem" $mount | quote }} + - name: LOGFLARE_TLS_CERT_PATH + value: {{ printf "%s/cert.pem" $mount | quote }} + - name: LOGFLARE_TLS_KEY_PATH + value: {{ printf "%s/cert.key" $mount | quote }} + {{- end }} envFrom: - configMapRef: name: {{ include "logflare.fullname" . }} @@ -81,13 +98,27 @@ spec: resources: {{- toYaml . | nindent 12 }} {{- end }} - {{- with .Values.volumeMounts }} + {{- if or .Values.logflare.certFilesSecret .Values.volumeMounts }} volumeMounts: + {{- if .Values.logflare.certFilesSecret }} + - name: cert-files + mountPath: {{ .Values.logflare.certFilesMountPath }} + readOnly: true + {{- end }} + {{- with .Values.volumeMounts }} {{- toYaml . | nindent 12 }} + {{- end }} {{- end }} - {{- with .Values.volumes }} + {{- if or .Values.logflare.certFilesSecret .Values.volumes }} volumes: + {{- if .Values.logflare.certFilesSecret }} + - name: cert-files + secret: + secretName: {{ .Values.logflare.certFilesSecret }} + {{- end }} + {{- with .Values.volumes }} {{- toYaml . | nindent 8 }} + {{- end }} {{- end }} {{- with .Values.nodeSelector }} nodeSelector: diff --git a/helm/values.yaml b/helm/values.yaml index 6ac2006c06..396b41eb5e 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -47,6 +47,25 @@ logflare: secretRefs: [] # - logflare-secrets + # Cert/key files (internal DB SSL and gRPC TLS) come from a mounted Secret + # rather than envFrom, because Logflare reads them from disk. Set to the name + # of a Secret you manage yourself whose keys are the cert filenames + # (db-server-ca.pem, db-client-cert.pem, db-client-key.pem, cert.pem, + # cert.key); empty disables the mount. The chart points the matching + # DB_SSL_*_PATH / LOGFLARE_TLS_*_PATH env vars at the mount for you. + certFilesSecret: "" + certFilesMountPath: /etc/logflare/certs + + # Roll the Deployment automatically when its ConfigMap or referenced Secrets + # change. Requires the Stakater Reloader controller to be installed. + reloader: false + + # Free-form non-secret environment variables rendered verbatim into the + # ConfigMap. Use this for configuration not modeled as first-class values + # above (e.g. LOGFLARE_LOG_LEVEL, LIBCLUSTER_TOPOLOGY, SPOOL_*, GOOGLE_*_SA). + extraConfig: {} + # LOGFLARE_LOG_LEVEL: info + # Logflare's own metadata Postgres database (distinct from the optional # "postgres" event-storage backend below). db: