P8.7: Conditional Helm templates for CDC PVC, Redis, and ESO integration (plan §6/§9/§13.13)

- PVC template conditional on cdc.buffer.primary=="pvc" or cdc.buffer.overflow=="pvc"
- Redis deployment conditional on redis.enabled with auth via auto-generated or ESO secret
- ESO ExternalSecret example pulling from kv/search/miroir via openbao-backend ClusterSecretStore
- Deployment mounts CDC PVC at /data/cdc and injects Redis password when enabled
- ConfigMap generates taskStore.url and cdc.buffer.pvc_path from helpers

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
jedarden 2026-04-19 13:16:14 -04:00
parent 863bf1c33f
commit 21748edf5e
8 changed files with 153 additions and 26 deletions

View file

@ -0,0 +1,40 @@
# Example: ExternalSecret for Miroir secrets via External Secrets Operator (ESO)
# Pulls from OpenBao KV v2 at kv/search/miroir using the openbao-backend ClusterSecretStore.
#
# Prerequisites:
# - External Secrets Operator installed in the cluster
# - ClusterSecretStore "openbao-backend" configured for OpenBao access
# - KV secrets populated at kv/search/miroir with properties:
# master_key, node_master_key, admin_api_key, redis_password
#
# Usage:
# kubectl apply -f examples/eso-external-secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: miroir-secrets
spec:
refreshInterval: 1h
secretStoreRef:
name: openbao-backend
kind: ClusterSecretStore
target:
name: miroir-secrets
creationPolicy: Owner
data:
- secretKey: masterKey
remoteRef:
key: kv/search/miroir
property: master_key
- secretKey: nodeMasterKey
remoteRef:
key: kv/search/miroir
property: node_master_key
- secretKey: adminApiKey
remoteRef:
key: kv/search/miroir
property: admin_api_key
- secretKey: redis-password
remoteRef:
key: kv/search/miroir
property: redis_password

View file

@ -172,6 +172,9 @@ cdc:
{{- if eq (include "miroir.redisEnabled" .) "true" }}
redis_bytes: {{ .Values.miroir.cdc.buffer.redis_bytes | default 1073741824 }}
{{- end }}
{{- if eq (include "miroir.cdcPvcEnabled" .) "true" }}
pvc_path: /data/cdc
{{- end }}
{{- end }}
{{- end -}}
@ -182,11 +185,23 @@ Return "true" if Redis is enabled, "false" otherwise.
{{- if .Values.redis.enabled -}}true{{- else -}}false{{- end -}}
{{- end -}}
{{/*
Redis auth secret name.
*/}}
{{- define "miroir.redisSecretName" -}}
{{- if .Values.redis.auth.existingSecret -}}
{{- .Values.redis.auth.existingSecret -}}
{{- else -}}
{{- include "miroir.fullname" . }}-redis-secret
{{- end -}}
{{- end -}}
{{/*
Return "true" if CDC PVC should be created, "false" otherwise.
PVC is rendered when cdc.buffer.primary=="pvc" or cdc.buffer.overflow=="pvc".
*/}}
{{- define "miroir.cdcPvcEnabled" -}}
{{- if .Values.cdcPvc.enabled -}}true{{- else -}}false{{- end -}}
{{- if and .Values.miroir.cdc (or (eq .Values.miroir.cdc.buffer.primary "pvc") (eq .Values.miroir.cdc.buffer.overflow "pvc")) -}}true{{- else -}}false{{- end -}}
{{- end -}}
{{/*

View file

@ -86,6 +86,13 @@ spec:
key: adminApiKey
- name: RUST_LOG
value: {{ .Values.miroir.logLevel | default "info" }}
{{- if and (eq (include "miroir.redisEnabled" .) "true") .Values.redis.auth.enabled }}
- name: MIROIR_REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "miroir.redisSecretName" . }}
key: redis-password
{{- end }}
volumeMounts:
- name: config
mountPath: /config
@ -94,7 +101,7 @@ spec:
mountPath: /data
{{- if eq (include "miroir.cdcPvcEnabled" .) "true" }}
- name: cdc-buffer
mountPath: /cdc
mountPath: /data/cdc
{{- end }}
livenessProbe:
httpGet:

View file

@ -1,6 +1,6 @@
{{/*
Miroir CDC Buffer PVC
Only rendered when cdcPvc.enabled=true
Only rendered when cdc.buffer.primary=="pvc" or cdc.buffer.overflow=="pvc"
*/}}
{{- if eq (include "miroir.cdcPvcEnabled" .) "true" }}
apiVersion: v1
@ -15,8 +15,8 @@ spec:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.cdcPvc.size | default "5Gi" }}
{{- if .Values.cdcPvc.storageClass }}
storageClassName: {{ .Values.cdcPvc.storageClass }}
storage: {{ .Values.miroir.cdc.buffer.pvc_size | default "10Gi" }}
{{- if .Values.miroir.cdc.buffer.pvc_storage_class }}
storageClassName: {{ .Values.miroir.cdc.buffer.pvc_storage_class }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,15 @@
{{/*
Redis auth secret (auto-generated when redis.auth.enabled and no existingSecret)
*/}}
{{- if and (eq (include "miroir.redisEnabled" .) "true") .Values.redis.auth.enabled (not .Values.redis.auth.existingSecret) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "miroir.fullname" . }}-redis-secret
labels:
{{- include "miroir.labels" . | nindent 4 }}
app.kubernetes.io/component: redis
type: Opaque
data:
redis-password: {{ randAlphaNum 32 | b64enc }}
{{- end }}

View file

@ -1,5 +1,5 @@
{{/*
Redis Deployment (only when taskStore.backend=redis)
Redis Deployment (only when redis.enabled=true)
*/}}
{{- if eq (include "miroir.redisEnabled" .) "true" }}
apiVersion: apps/v1
@ -40,6 +40,19 @@ spec:
- name: redis
containerPort: 6379
protocol: TCP
{{- if .Values.redis.auth.enabled }}
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "miroir.redisSecretName" . }}
key: redis-password
{{- end }}
args:
{{- if .Values.redis.auth.enabled }}
- --requirepass
- $(REDIS_PASSWORD)
{{- end }}
{{- if .Values.redis.persistence.enabled }}
volumeMounts:
- name: data
@ -47,12 +60,24 @@ spec:
{{- end }}
livenessProbe:
exec:
command: ["redis-cli", "ping"]
command:
- redis-cli
{{- if .Values.redis.auth.enabled }}
- -a
- $(REDIS_PASSWORD)
{{- end }}
- ping
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
exec:
command: ["redis-cli", "ping"]
command:
- redis-cli
{{- if .Values.redis.auth.enabled }}
- -a
- $(REDIS_PASSWORD)
{{- end }}
- ping
initialDelaySeconds: 3
periodSeconds: 5
resources:

View file

@ -43,7 +43,26 @@
},
"nodeSelector": { "type": "object" },
"tolerations": { "type": "array" },
"affinity": { "type": "object" }
"affinity": { "type": "object" },
"cdc": {
"type": "object",
"properties": {
"enabled": { "type": "boolean" },
"emit_ttl_deletes": { "type": "boolean" },
"emit_internal_writes": { "type": "boolean" },
"buffer": {
"type": "object",
"properties": {
"primary": { "type": "string", "enum": ["memory", "pvc", "redis"] },
"overflow": { "type": "string", "enum": ["drop", "pvc", "redis"] },
"pvc_size": { "type": "string" },
"pvc_storage_class": { "type": "string" },
"memory_bytes": { "type": "integer", "minimum": 0 },
"redis_bytes": { "type": "integer", "minimum": 0 }
}
}
}
}
}
},
"taskStore": {
@ -193,17 +212,16 @@
"type": { "type": "string" },
"port": { "type": "integer", "minimum": 1, "maximum": 65535 }
}
},
"auth": {
"type": "object",
"properties": {
"enabled": { "type": "boolean" },
"existingSecret": { "type": "string" }
}
}
}
},
"cdcPvc": {
"type": "object",
"properties": {
"enabled": { "type": "boolean" },
"size": { "type": "string" },
"storageClass": { "type": "string" }
}
},
"search_ui": {
"type": "object",
"properties": {

View file

@ -28,6 +28,16 @@ miroir:
nodeSelector: {}
tolerations: []
affinity: {}
cdc:
enabled: true
emit_ttl_deletes: false
emit_internal_writes: false
buffer:
primary: memory # memory | pvc | redis
overflow: drop # drop | pvc | redis
pvc_size: 10Gi
pvc_storage_class: ""
memory_bytes: 67108864
taskStore:
backend: sqlite # sqlite | redis
@ -109,7 +119,7 @@ redis:
enabled: false # dev default: enable for production
image:
repository: redis
tag: 7-alpine
tag: 7.4-alpine
pullPolicy: IfNotPresent
replicas: 1
podAnnotations: {}
@ -126,17 +136,14 @@ redis:
affinity: {}
persistence:
enabled: true
size: 1Gi
size: 5Gi
storageClass: ""
service:
type: ClusterIP
port: 6379
# PVC for CDC buffer (when cdc.buffer.primary=pvc or overflow=pvc)
cdcPvc:
enabled: false
size: 5Gi
storageClass: ""
auth:
enabled: true
existingSecret: "" # auto-generated as <release>-redis-secret when empty; password comes from K8s Secret or ESO
# Prometheus Operator integration (plan §10 + §14.9)
serviceMonitor: