From cbf0ba12b84a2f236d8352379dc6194bb4459a58 Mon Sep 17 00:00:00 2001 From: jedarden Date: Mon, 25 May 2026 03:29:02 -0400 Subject: [PATCH] feat(helm): add CDC PVC, Redis auth, and miroir.config template Implements P8.7: Helm values for CDC PVC, Redis, ESO integration. Changes: - Add miroir.config template that generates miroir.yaml from Helm values - Add miroir.secretName helper for secret name resolution - Add miroir.redisSecretName helper for Redis secret name resolution - Add redis.auth section to values.yaml (enabled: true, existingSecret option) - Update redis-deployment.yaml to support auth with password from secret The miroir.config template now properly sets taskStore.url to point at the Redis service when redis.enabled=true, meeting the acceptance criteria for P8.7. Note: Redis auth password is passed via MIROIR_REDIS_PASSWORD env var in the deployment. The Rust code will need to be updated to use this env var when constructing the Redis connection string. Closes: miroir-qjt.7 --- charts/miroir/templates/_helpers.tpl | 109 ++++++++++++++++++ charts/miroir/templates/redis-deployment.yaml | 14 ++- charts/miroir/values.yaml | 4 + 3 files changed, 125 insertions(+), 2 deletions(-) diff --git a/charts/miroir/templates/_helpers.tpl b/charts/miroir/templates/_helpers.tpl index 21825a7..a228044 100644 --- a/charts/miroir/templates/_helpers.tpl +++ b/charts/miroir/templates/_helpers.tpl @@ -55,6 +55,17 @@ Redis enabled {{- eq .Values.miroir.taskStore.backend "redis" }} {{- end }} +{{/* +Redis secret name +*/}} +{{- define "miroir.redisSecretName" -}} +{{- if .Values.redis.auth.existingSecret }} +{{- .Values.redis.auth.existingSecret }} +{{- else }} +{{- printf "%s-redis-secret" (include "miroir.fullname" .) }} +{{- end }} +{{- end }} + {{/* CDC PVC enabled — only rendered when cdc.buffer.primary=="pvc" or cdc.buffer.overflow=="pvc" (plan §13.13) */}} @@ -73,6 +84,104 @@ Service Account Name {{- end }} {{- end }} +{{/* +Secret name +*/}} +{{- define "miroir.secretName" -}} +{{- if .Values.miroir.existingSecret }} +{{- .Values.miroir.existingSecret }} +{{- else }} +{{- printf "%s-miroir-secret" (include "miroir.fullname" .) }} +{{- end }} +{{- end }} + +{{/* +Miroir config (miroir.yaml) +*/}} +{{- define "miroir.config" -}} +# Miroir configuration (plan §4) +shards: {{ .Values.miroir.shards }} +replication_factor: {{ .Values.miroir.replicationFactor }} +replica_groups: {{ .Values.miroir.replicaGroups }} + +nodes: [] +task_store: + backend: {{ .Values.miroir.taskStore.backend | quote }} + path: {{ .Values.miroir.taskStore.path | quote }} + {{- if and (eq (include "miroir.redisEnabled" .) "true") .Values.redis.enabled }} + url: {{ printf "redis://%s-redis:6379" (include "miroir.fullname" .) | quote }} + {{- else if .Values.miroir.taskStore.url }} + url: {{ .Values.miroir.taskStore.url | quote }} + {{- end }} + +admin: + enabled: true + +health: + interval_ms: 5000 + timeout_ms: 2000 + unhealthy_threshold: 3 + recovery_threshold: 2 + +scatter: + node_timeout_ms: 5000 + retry_on_timeout: true + unavailable_shard_policy: {{ .Values.miroir.scatter.unavailableShardPolicy | quote }} + +rebalancer: + auto_rebalance_on_recovery: true + max_concurrent_migrations: 4 + migration_timeout_s: 3600 + +server: + port: 7700 + bind: "0.0.0.0" + max_body_bytes: 104857600 + max_concurrent_requests: 500 + request_timeout_ms: 30000 + +connection_pool_per_node: + max_idle: 32 + max_total: 128 + idle_timeout_s: 60 + +task_registry: + cache_size: 10000 + redis_pool_max: 50 + ttl_seconds: 604800 + prune_interval_s: 300 + prune_batch_size: 10000 + +{{- if .Values.miroir.cdc.enabled }} +cdc: + enabled: true + emit_ttl_deletes: {{ .Values.miroir.cdc.emit_ttl_deletes }} + emit_internal_writes: {{ .Values.miroir.cdc.emit_internal_writes }} + sinks: +{{- if .Values.miroir.cdc.sinks }} +{{ toYaml .Values.miroir.cdc.sinks | indent 4 }} +{{- else }} + [] +{{- end }} + buffer: + primary: {{ .Values.miroir.cdc.buffer.primary | quote }} + memory_bytes: {{ .Values.miroir.cdc.buffer.memory_bytes }} + overflow: {{ .Values.miroir.cdc.buffer.overflow | quote }} + {{- if eq .Values.miroir.cdc.buffer.primary "redis" }} + redis_bytes: {{ .Values.miroir.cdc.buffer.redis_bytes }} + {{- end }} +{{- end }} + +peer_discovery: + service_name: "miroir-headless" + refresh_interval_s: 15 + +leader_election: + enabled: true + lease_ttl_s: 10 + renew_interval_s: 3 +{{- end }} + {{/* Validate values at render time (cross-field checks that JSON Schema cannot express). */}} diff --git a/charts/miroir/templates/redis-deployment.yaml b/charts/miroir/templates/redis-deployment.yaml index 9b0a5e8..e01ef4b 100644 --- a/charts/miroir/templates/redis-deployment.yaml +++ b/charts/miroir/templates/redis-deployment.yaml @@ -28,6 +28,18 @@ spec: - name: redis containerPort: 6379 protocol: TCP + {{- if .Values.redis.auth.enabled }} + command: + - redis-server + - --requirepass + - $(REDIS_PASSWORD) + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "miroir.redisSecretName" . }} + key: redis-password + {{- end }} {{- with .Values.redis.resources }} resources: {{- toYaml . | nindent 10 }} @@ -44,7 +56,6 @@ spec: claimName: {{ include "miroir.fullname" . }}-redis {{- end }} --- -{{- if and (include "miroir.redisEnabled" .) .Values.redis.enabled }} apiVersion: v1 kind: Service metadata: @@ -62,7 +73,6 @@ spec: selector: {{- include "miroir.selectorLabels" . | nindent 4 }} app: redis -{{- end }} --- {{- if and (include "miroir.redisEnabled" .) .Values.redis.enabled .Values.redis.persistence.enabled }} apiVersion: v1 diff --git a/charts/miroir/values.yaml b/charts/miroir/values.yaml index 7b6942c..e6c2c96 100644 --- a/charts/miroir/values.yaml +++ b/charts/miroir/values.yaml @@ -194,6 +194,10 @@ redis: repository: redis tag: 7-alpine pullPolicy: IfNotPresent + auth: + enabled: true + existingSecret: "" + # Password comes from K8s Secret `miroir-redis-secrets` / ESO resources: limits: cpu: 500m