diff --git a/charts/library/common-test/ci/valkey-values.yaml b/charts/library/common-test/ci/valkey-values.yaml new file mode 100644 index 0000000000000..0b5c70dd69886 --- /dev/null +++ b/charts/library/common-test/ci/valkey-values.yaml @@ -0,0 +1,47 @@ +service: + main: + enabled: true + ports: + main: + enabled: true + port: 8080 + +workload: + main: + enabled: true + podSpec: + containers: + main: + enabled: true + args: + - --port + - "8080" + probes: + liveness: + enabled: true + readiness: + enabled: true + startup: + enabled: true + +dependencies: + valkey: + enabled: true + depconfig: + password: "testpassword" + image: + repository: docker.io/bitnamisecure/valkey + pullPolicy: IfNotPresent + tag: latest@sha256:14dc12c4cc5912747b63d41e237512989d958fa6020dbcb1170cc0fe91f48644 + workload: + main: + enabled: true + replicas: 1 + type: StatefulSet + strategy: RollingUpdate + podSpec: + containers: + main: + env: + REDIS_PASSWORD: "testpassword" + diff --git a/charts/library/common-test/tests/dependencies/targetSelector_test.yaml b/charts/library/common-test/tests/dependencies/targetSelector_test.yaml new file mode 100644 index 0000000000000..731c22d8e6fa7 --- /dev/null +++ b/charts/library/common-test/tests/dependencies/targetSelector_test.yaml @@ -0,0 +1,127 @@ +suite: dependencies targetSelector prefix test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should prefix string targetSelector in service + set: + common: + workload: {} + service: {} + workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + dependencies: + db: + enabled: true + workload: + main: + enabled: true + type: StatefulSet + podSpec: + containers: + main: + enabled: true + primary: true + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + service: + main: + enabled: true + targetSelector: main + ports: + main: + enabled: true + port: 5432 + asserts: + - documentIndex: 0 + isKind: + of: Service + - documentIndex: 0 + equal: + path: metadata.name + value: test-release-name-common-test-db-main + - documentIndex: 0 + matchRegex: + path: spec.selector["pod.name"] + pattern: ^db-main$ + + - it: should prefix targetSelector in podDisruptionBudget + set: + common: + workload: {} + podDisruptionBudget: {} + workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + dependencies: + db: + enabled: true + workload: + worker: + enabled: true + type: StatefulSet + podSpec: + containers: + worker: + enabled: true + primary: true + probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false + podDisruptionBudget: + main: + enabled: true + targetSelector: worker + minAvailable: 1 + asserts: + - documentIndex: 0 + isKind: + of: PodDisruptionBudget + - documentIndex: 0 + equal: + path: metadata.name + value: test-release-name-common-test-db-main + - documentIndex: 0 + equal: + path: spec.selector.matchLabels["pod.name"] + value: db-worker diff --git a/charts/library/common-test/tests/dependencies/valkey_basic_test.yaml b/charts/library/common-test/tests/dependencies/valkey_basic_test.yaml new file mode 100644 index 0000000000000..c794e4538c527 --- /dev/null +++ b/charts/library/common-test/tests/dependencies/valkey_basic_test.yaml @@ -0,0 +1,105 @@ +suite: dependencies valkey full structure test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should create service and workload for valkey dependency + set: + common: + workload: {} + service: {} + dependencies: + valkey: + enabled: true + workload: + main: + enabled: true + primary: true + type: StatefulSet + podSpec: + containers: + main: + enabled: true + primary: true + service: + main: + enabled: true + ports: + main: + enabled: true + port: 6379 + workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + asserts: + - documentIndex: 0 + isKind: + of: Service + - documentIndex: 0 + equal: + path: metadata.name + value: test-release-name-common-test-valkey-main + - documentIndex: 2 + isKind: + of: StatefulSet + - documentIndex: 2 + equal: + path: metadata.name + value: test-release-name-common-test-valkey-main + + - it: should create init container for valkey wait + set: + common: + workload: {} + service: {} + dependencies: + valkey: + enabled: true + workload: + main: + enabled: true + type: StatefulSet + podSpec: + containers: + main: + enabled: true + primary: true + service: + main: + enabled: true + ports: + main: + enabled: true + port: 6379 + workload: + main: + enabled: true + primary: true + type: Deployment + podSpec: + containers: + main: + enabled: true + primary: true + asserts: + - documentIndex: 1 + isKind: + of: Deployment + - documentIndex: 1 + isNotEmpty: + path: spec.template.spec.initContainers + - documentIndex: 1 + contains: + path: spec.template.spec.initContainers + content: + name: test-release-name-common-test-system-valkey-wait + diff --git a/charts/library/common/docs/dependencies.md b/charts/library/common/docs/dependencies.md index 1750b6d02ffa2..d53e2a65b6b81 100644 --- a/charts/library/common/docs/dependencies.md +++ b/charts/library/common/docs/dependencies.md @@ -4,8 +4,10 @@ title: Dependencies :::note -- This page is generated from JSON schema. -- See the [Full Examples](/truecharts-common/dependencies#full-examples) section for complete examples. +- This page documents the new dependencies feature that replaces helm-dependencies. +- Dependencies allow you to include complete chart values.yaml structures within your chart. +- Each dependency is merged into the main chart with prefixed resource names to avoid conflicts. +- Dependency configuration (credentials, passwords, etc.) is stored under `depconfig` and not merged. ::: @@ -17,28 +19,218 @@ title: Dependencies ## `dependencies` -Configuration for `dependencies`. +Configuration for chart dependencies. Each dependency should contain a complete chart values.yaml structure. Resources from dependencies are automatically merged into the main chart with prefixed names (e.g., `valkey-main` for a dependency named `valkey` with a workload named `main`). -| Field | Value | -| ---------- | -------------- | -| Key | `dependencies` | -| Type | `map` | -| Required | ❌ | -| Helm `tpl` | ❌ | -| Default | unset | +| Field | Value | +| ---------- | --------------- | +| Key | `dependencies` | +| Type | `map` | +| Required | ❌ | +| Helm `tpl` | ❌ | +| Default | `{}` | + +Example: + +```yaml +dependencies: + valkey: + enabled: true + depconfig: + password: "my-password" + # Generated credentials available at: + # .Values.dependencies.valkey.depconfig.creds.url + # .Values.dependencies.valkey.depconfig.creds.redis-password + # .Values.dependencies.valkey.depconfig.creds.plainhost + image: + repository: docker.io/bitnamisecure/valkey + tag: latest + workload: + main: + enabled: true + type: StatefulSet + podSpec: + containers: + main: + enabled: true + primary: true + env: + REDIS_PASSWORD: "{{ .Values.dependencies.valkey.depconfig.password }}" + service: + main: + enabled: true + ports: + main: + enabled: true + port: 6379 + persistence: + data: + enabled: true + mountPath: /data +``` --- ### `dependencies.$name.enabled` -No description provided. +Enable or disable the dependency. | Field | Value | | ---------- | ---------------------------- | | Key | `dependencies.$name.enabled` | -| Type | `boolean, string` | +| Type | `boolean` | | Required | ✅ | -| Helm `tpl` | ❌ | +| Helm `tpl` | ✅ | | Default | unset | --- + +### `dependencies.$name.depconfig` + +Configuration specific to the dependency that should NOT be merged into the main values tree. This includes: +- Input configuration (like passwords) +- Generated credentials +- Any other metadata about the dependency + +| Field | Value | +| ---------- | ------------------------------ | +| Key | `dependencies.$name.depconfig` | +| Type | `map` | +| Required | ❌ | +| Helm `tpl` | ❌ | +| Default | `{}` | + +Example: + +```yaml +dependencies: + valkey: + enabled: true + depconfig: + password: "secure-password" + # After initialization, credentials are available: + # .Values.dependencies.valkey.depconfig.creds.url + # .Values.dependencies.valkey.depconfig.creds.redis-password + # .Values.dependencies.valkey.depconfig.creds.plainhost + # .Values.dependencies.valkey.depconfig.creds.plainporthost + # .Values.dependencies.valkey.depconfig.creds.plainhostpass +``` + +--- + +## How Dependencies Work + +1. **Complete Chart Values**: Each dependency under `dependencies.$name` should contain a complete chart values.yaml structure with all the resources it needs (workload, service, configmap, etc.) + +2. **Depconfig Exclusion**: The `depconfig` subdict is NOT merged into main values. It contains dependency-specific configuration and generated credentials. + +3. **Universal Resource Prefixing**: When a dependency is enabled, ALL its resources (except excluded keys) are merged into the main chart with prefixed names: + - **Prefixed**: workload, service, configmap, secret, persistence, volumeClaimTemplates, podDisruptionBudget, hpa, vpa, ingress, route, gateway, certificate, serviceAccount, rbac, networkPolicy, storageClass, and any other resource type + - **Excluded from prefixing**: global, securityContext, podOptions, enabled, depconfig, image (handled specially), chartContext, fallbackDefaults, notes, operator + - Examples: + - `workload.main` → `workload.$name-main` + - `service.main` → `service.$name-main` + - `configmap.config` → `configmap.$name-config` + - `volumeClaimTemplates.data` → `volumeClaimTemplates.$name-data` + - Any new resource type automatically gets prefixed + +4. **Image Handling**: The `image` key is handled specially - instead of prefixing resources within it, the key itself is prefixed to `$nameImage` (e.g., `valkeyImage`) + +5. **Automatic Init Containers**: The common chart automatically detects dependency services (like valkey) and creates appropriate init containers to wait for them to be ready. + +6. **Connection Information**: Connection details for dependencies are automatically included in the chart notes. + +7. **Credential Generation**: For database-like dependencies (valkey, mariadb, mongodb, etc.), credentials are automatically generated and stored in `depconfig.creds`. + +--- + +## Full Examples + +### Valkey Dependency + +```yaml +dependencies: + valkey: + enabled: true + depconfig: + password: "secure-password" + image: + repository: docker.io/bitnamisecure/valkey + pullPolicy: IfNotPresent + tag: latest + workload: + main: + enabled: true + replicas: 1 + type: StatefulSet + podSpec: + containers: + main: + enabled: true + primary: true + env: + REDIS_REPLICATION_MODE: master + ALLOW_EMPTY_PASSWORD: "no" + REDIS_PORT: "6379" + REDIS_PASSWORD: "{{ .Values.dependencies.valkey.depconfig.password }}" + probes: + liveness: + enabled: true + type: exec + command: + - sh + - -c + - /health/ping_liveness_local.sh 2 + service: + main: + enabled: true + ports: + main: + enabled: true + port: 6379 + targetPort: 6379 + volumeClaimTemplates: + data: + enabled: true + accessModes: + - ReadWriteOnce + mountPath: "/bitnami/valkey" + +# In your main workload, access credentials: +workload: + main: + podSpec: + containers: + main: + env: + REDIS_URL: "{{ .Values.dependencies.valkey.depconfig.creds.url }}" + REDIS_HOST: "{{ .Values.dependencies.valkey.depconfig.creds.plainhost }}" + REDIS_PASSWORD: "{{ .Values.dependencies.valkey.depconfig.password }}" +``` + +--- + +## Differences from Helm Dependencies + +This dependencies feature differs from traditional helm chart dependencies: + +1. **No Separate Charts**: Dependencies are defined inline in values.yaml, not as separate helm charts in Chart.yaml +2. **Name Prefixing**: All resources get prefixed with the dependency name to avoid conflicts +3. **Single Release**: Everything is deployed as a single helm release +4. **Easier Configuration**: No need to manage separate chart repositories or versions +5. **Automatic Integration**: Init containers and connection information are automatically handled +6. **Depconfig Structure**: Configuration and credentials are stored in `depconfig` subdict and not merged + +--- + +## Notes + +- Dependencies replace the traditional helm-dependencies mechanism +- Each dependency can contain any valid chart values.yaml structure +- ALL resource types are automatically prefixed to prevent naming conflicts (except excluded keys like global, depconfig, etc.) +- New resource types automatically work without code changes - they just get prefixed +- The `enabled` flag is automatically added to resources if not present +- Init containers are automatically created to wait for dependency services to be ready +- Connection information is automatically included in chart notes +- Configuration and credentials are stored under `depconfig` and accessible via `.Values.dependencies.$name.depconfig` +- Credentials for database dependencies are automatically generated and stored in `depconfig.creds` + diff --git a/charts/library/common/schemas/redis.json b/charts/library/common/schemas/redis.json deleted file mode 100644 index 4a923adb7c43a..0000000000000 --- a/charts/library/common/schemas/redis.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "enabled": { - "type": [ - "boolean", - "string" - ], - "description": "Configuration for `redis.enabled`." - }, - "includeCommon": { - "type": "boolean", - "description": "Configuration for `redis.includeCommon`." - }, - "password": { - "type": "string", - "description": "Configuration for `redis.password`." - }, - "creds": { - "type": "object", - "properties": {}, - "additionalProperties": true, - "description": "Configuration for `redis.creds`." - }, - "secret": { - "type": "object", - "properties": { - "credentials": { - "type": "object", - "properties": { - "enabled": { - "type": [ - "boolean", - "string" - ], - "description": "Configuration for `redis.secret.credentials.enabled`." - } - }, - "additionalProperties": true, - "description": "Configuration for `redis.secret.credentials`." - } - }, - "additionalProperties": true, - "description": "Configuration for `redis.secret`." - } - }, - "additionalProperties": true, - "description": "Configuration for `redis`." -} diff --git a/charts/library/common/templates/lib/chart/_notes.tpl b/charts/library/common/templates/lib/chart/_notes.tpl index 5353ea58acd73..1ac860dbee5d7 100644 --- a/charts/library/common/templates/lib/chart/_notes.tpl +++ b/charts/library/common/templates/lib/chart/_notes.tpl @@ -63,12 +63,18 @@ Display connection information for enabled dependencies and addons {{- end -}} {{- end -}} - {{- if .Values.redis -}} - {{- if .Values.redis.enabled -}} - {{- $hasConnections = true -}} - {{- $connections = append $connections (include "tc.v1.common.lib.chart.connections.redis" . | trim) -}} + {{/* Check for valkey service from dependencies */}} + {{- $valkeyServiceExists := false -}} + {{- range $name, $service := .Values.service -}} + {{- if hasPrefix "valkey-" $name -}} + {{- $valkeyServiceExists = true -}} {{- end -}} {{- end -}} + + {{- if $valkeyServiceExists -}} + {{- $hasConnections = true -}} + {{- $connections = append $connections (include "tc.v1.common.lib.chart.connections.valkey" . | trim) -}} + {{- end -}} {{- if .Values.mongodb -}} {{- if .Values.mongodb.enabled -}} @@ -186,26 +192,32 @@ MariaDB connection information {{- end -}} {{/* -Redis connection information +Valkey connection information */}} -{{- define "tc.v1.common.lib.chart.connections.redis" -}} -## Redis Database - {{- if .Values.redis.creds -}} - {{- if .Values.redis.creds.plainhost }} -- Host: {{ .Values.redis.creds.plainhost }} - {{- end -}} - {{- if .Values.redis.creds.plainporthost }} -- Host:Port: {{ .Values.redis.creds.plainporthost }} - {{- end -}} - {{- if .Values.redis.redisDatabase }} -- Database Index: {{ .Values.redis.redisDatabase | default "0" }} - {{- end -}} - {{- if .Values.redis.creds.url }} -- Connection URL: {{ .Values.redis.creds.url }} +{{- define "tc.v1.common.lib.chart.connections.valkey" -}} +{{- $valkeyServiceName := "" -}} +{{- $valkeyPort := "6379" -}} +{{- range $name, $service := .Values.service -}} + {{- if hasPrefix "valkey-" $name -}} + {{- $valkeyServiceName = $name -}} + {{- range $portName, $portConfig := $service.ports -}} + {{- if $portConfig.enabled -}} + {{- $valkeyPort = toString $portConfig.port -}} + {{- end -}} + {{- end -}} {{- end -}} - {{- else }} -- Configuration pending (credentials will be available after initialization) - {{- end }} +{{- end -}} + +{{- if $valkeyServiceName -}} +{{- $hostName := printf "%s-%s" .Release.Name $valkeyServiceName -}} +## Valkey Database +- Host: {{ $hostName }} +- Port: {{ $valkeyPort }} +- Host:Port: {{ $hostName }}:{{ $valkeyPort }} +{{- else }} +## Valkey Database +- Configuration pending (service will be available after initialization) +{{- end -}} {{- end -}} {{/* diff --git a/charts/library/common/templates/lib/dependencies/_dbWait.tpl b/charts/library/common/templates/lib/dependencies/_dbWait.tpl index 7c79e0cd3b744..470ade6245f24 100644 --- a/charts/library/common/templates/lib/dependencies/_dbWait.tpl +++ b/charts/library/common/templates/lib/dependencies/_dbWait.tpl @@ -1,12 +1,20 @@ {{- define "tc.v1.common.lib.deps.wait" -}} - {{- if .Values.redis.enabled -}} - {{- $container := include "tc.v1.common.lib.deps.wait.redis" $ | fromYaml -}} + {{/* Check if valkey service exists from dependencies */}} + {{- $valkeyServiceExists := false -}} + {{- range $name, $service := .Values.service -}} + {{- if hasPrefix "valkey-" $name -}} + {{- $valkeyServiceExists = true -}} + {{- end -}} + {{- end -}} + + {{- if $valkeyServiceExists -}} + {{- $container := include "tc.v1.common.lib.deps.wait.valkey" $ | fromYaml -}} {{- if $container -}} {{- range .Values.workload -}} {{- if not (hasKey .podSpec "initContainers") -}} {{- $_ := set .podSpec "initContainers" dict -}} {{- end -}} - {{- $_ := set .podSpec.initContainers "redis-wait" $container -}} + {{- $_ := set .podSpec.initContainers "valkey-wait" $container -}} {{- end -}} {{- end -}} {{- end -}} @@ -79,7 +87,24 @@ {{- end -}} {{- end -}} -{{- define "tc.v1.common.lib.deps.wait.redis" -}} +{{- define "tc.v1.common.lib.deps.wait.valkey" -}} +{{/* Find the valkey service name */}} +{{- $valkeyServiceName := "" -}} +{{- $valkeyPort := "6379" -}} +{{- range $name, $service := .Values.service -}} + {{- if hasPrefix "valkey-" $name -}} + {{- $valkeyServiceName = $name -}} + {{- range $portName, $portConfig := $service.ports -}} + {{- if or (not (hasKey $portConfig "enabled")) $portConfig.enabled -}} + {{- $valkeyPort = toString $portConfig.port -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- if $valkeyServiceName -}} +{{- $hostName := printf "%s-%s" .Release.Name $valkeyServiceName -}} + enabled: true type: system imageSelector: valkeyClientImage @@ -105,42 +130,37 @@ resources: cpu: 500m memory: 512Mi env: - REDIS_HOST: - secretKeyRef: - expandObjectName: false - name: '{{ printf "%s-%s" .Release.Name "rediscreds" }}' - key: plainhost - REDIS_PASSWORD: "{{ .Values.redis.password }}" - REDIS_PORT: "6379" + VALKEY_HOST: {{ $hostName }} + VALKEY_PORT: {{ $valkeyPort | quote }} command: - "/bin/sh" - "-c" - | /bin/bash <<'EOF' - echo "Executing DB waits..." - [[ -n "$REDIS_PASSWORD" ]] && export REDISCLI_AUTH="$REDIS_PASSWORD"; + echo "Executing Valkey wait..." export LIVE=false; until "$LIVE"; do response=$( timeout -s 3 2 \ valkey-cli \ - -h "$REDIS_HOST" \ - -p "$REDIS_PORT" \ + -h "$VALKEY_HOST" \ + -p "$VALKEY_PORT" \ ping ) - if [ "$response" == "PONG" ] || [ "$response" == "LOADING Redis is loading the dataset in memory" ]; then + if [ "$response" == "PONG" ] || [ "$response" == "LOADING Valkey is loading the dataset in memory" ]; then LIVE=true echo "$response" - echo "Redis Responded, ending initcontainer and starting main container(s)..." + echo "Valkey Responded, ending initcontainer and starting main container(s)..." else echo "$response" - echo "Redis not responding... Sleeping for 10 sec..." + echo "Valkey not responding... Sleeping for 10 sec..." sleep 10 fi; done EOF {{- end -}} +{{- end -}} {{- define "tc.v1.common.lib.deps.wait.mariadb" -}} enabled: true diff --git a/charts/library/common/templates/lib/dependencies/_redisInjector.tpl b/charts/library/common/templates/lib/dependencies/_redisInjector.tpl deleted file mode 100644 index e500b40ac7e91..0000000000000 --- a/charts/library/common/templates/lib/dependencies/_redisInjector.tpl +++ /dev/null @@ -1,48 +0,0 @@ -{{/* -This template generates a random password and ensures it persists across updates/edits to the chart -*/}} -{{- define "tc.v1.common.dependencies.redis.secret" -}} - -{{- if .Values.redis.enabled -}} - {{- $dbIndex := .Values.redis.redisDatabase | default "0" -}} - {{/* Use with custom-set password */}} - {{- $dbPass := .Values.redis.password -}} - - {{- $redisUser := .Values.redis.redisUsername -}} - {{- if not $redisUser -}}{{/* If you try to print a nil value it will print as [nil] */}} - {{- $redisUser = "" -}} - {{- end -}} - {{/* Prepare data */}} - {{- $dbHost := printf "%v-%v" .Release.Name "redis" -}} - {{- $portHost := printf "%v:6379" $dbHost -}} - {{- $url := printf "redis://%v:%v@%v/%v" $redisUser $dbPass $portHost $dbIndex -}} - {{- $hostPass := printf "%v:%v@%v" $redisUser $dbPass $dbHost -}} - - {{/* Append some values to redis.creds, so apps using the dep, can use them */}} - {{- $_ := set .Values.redis.creds "redisPassword" ($dbPass | quote) -}} - {{- $_ := set .Values.redis.creds "plain" ($dbHost | quote) -}} - {{- $_ := set .Values.redis.creds "plainhost" ($dbHost | quote) -}} - {{- $_ := set .Values.redis.creds "plainport" ($portHost | quote) -}} - {{- $_ := set .Values.redis.creds "plainporthost" ($portHost | quote) -}} - {{- $_ := set .Values.redis.creds "plainhostpass" ($hostPass | quote) -}} - {{- $_ := set .Values.redis.creds "url" ($url | quote) -}} - -{{/* Create the secret (Comment also plays a role on correct formatting) */}} -enabled: true -expandObjectName: false -data: - redis-password: {{ $dbPass }} - plain: {{ $dbHost }} - url: {{ $url }} - plainhostpass: {{ $hostPass }} - plainporthost: {{ $portHost }} - plainhost: {{ $dbHost }} - {{- end -}} -{{- end -}} - -{{- define "tc.v1.common.dependencies.redis.injector" -}} - {{- $secret := include "tc.v1.common.dependencies.redis.secret" . | fromYaml -}} - {{- if $secret -}} - {{- $_ := set .Values.secret (printf "%s-%s" .Release.Name "rediscreds") $secret -}} - {{- end -}} -{{- end -}} diff --git a/charts/library/common/templates/lib/dependencies/_valkeyInjector.tpl b/charts/library/common/templates/lib/dependencies/_valkeyInjector.tpl new file mode 100644 index 0000000000000..4ff882d2e8d52 --- /dev/null +++ b/charts/library/common/templates/lib/dependencies/_valkeyInjector.tpl @@ -0,0 +1,62 @@ +{{/* +This template generates valkey credentials and ensures they persist across updates +*/}} +{{- define "tc.v1.common.dependencies.valkey.secret" -}} + +{{- range $depName, $depConfig := .Values.dependencies -}} + {{- if and (eq $depName "valkey") $depConfig $depConfig.enabled -}} + {{/* Use custom-set password or generate one */}} + {{- $dbPass := "" -}} + {{- if $depConfig.depconfig -}} + {{- $dbPass = $depConfig.depconfig.password | default "PLACEHOLDERPASSWORD" -}} + {{- else -}} + {{- $dbPass = "PLACEHOLDERPASSWORD" -}} + {{- end -}} + + {{/* Prepare data - service name is prefixed */}} + {{- $serviceName := printf "%s-main" $depName -}} + {{- $dbHost := printf "%v-%v" $.Release.Name $serviceName -}} + {{- $portHost := printf "%v:6379" $dbHost -}} + {{- $url := printf "redis://:%v@%v/0" $dbPass $portHost -}} + {{- $hostPass := printf "%v:%v" $dbHost $dbPass -}} + + {{/* Initialize depconfig if not exists */}} + {{- if not $depConfig.depconfig -}} + {{- $_ := set $depConfig "depconfig" dict -}} + {{- end -}} + + {{/* Initialize creds under depconfig if not exists */}} + {{- if not $depConfig.depconfig.creds -}} + {{- $_ := set $depConfig.depconfig "creds" dict -}} + {{- end -}} + + {{/* Append values to dependency depconfig.creds for apps to use */}} + {{- $_ := set $depConfig.depconfig.creds "valkey-password" ($dbPass | quote) -}} + {{- $_ := set $depConfig.depconfig.creds "redis-password" ($dbPass | quote) -}} + {{- $_ := set $depConfig.depconfig.creds "plain" ($dbHost | quote) -}} + {{- $_ := set $depConfig.depconfig.creds "plainhost" ($dbHost | quote) -}} + {{- $_ := set $depConfig.depconfig.creds "plainporthost" ($portHost | quote) -}} + {{- $_ := set $depConfig.depconfig.creds "url" ($url | quote) -}} + {{- $_ := set $depConfig.depconfig.creds "plainhostpass" ($hostPass | quote) -}} + +{{/* Create the secret */}} +enabled: true +expandObjectName: false +data: + valkey-password: {{ $dbPass }} + redis-password: {{ $dbPass }} + plain: {{ $dbHost }} + plainhost: {{ $dbHost }} + plainporthost: {{ $portHost }} + url: {{ $url }} + plainhostpass: {{ $hostPass }} + {{- end -}} +{{- end -}} +{{- end -}} + +{{- define "tc.v1.common.dependencies.valkey.injector" -}} + {{- $secret := include "tc.v1.common.dependencies.valkey.secret" . | fromYaml -}} + {{- if $secret -}} + {{- $_ := set .Values.secret (printf "%s-%s" .Release.Name "valkeycreds") $secret -}} + {{- end -}} +{{- end -}} diff --git a/charts/library/common/templates/lib/util/_chartcontext.tpl b/charts/library/common/templates/lib/util/_chartcontext.tpl index 79b7952bbc0e3..1cbdb6e045afb 100644 --- a/charts/library/common/templates/lib/util/_chartcontext.tpl +++ b/charts/library/common/templates/lib/util/_chartcontext.tpl @@ -48,7 +48,10 @@ {{- $selectedIngress := (get $rootCtx.Values.ingress $primaryIngressName) -}} {{- $primaryRouteName := include "tc.v1.common.lib.util.route.primary" (dict "rootCtx" $rootCtx) -}} - {{- $selectedRoute := (get $rootCtx.Values.route $primaryRouteName) -}} + {{- $selectedRoute := dict -}} + {{- if $rootCtx.Values.route -}} + {{- $selectedRoute = (get $rootCtx.Values.route $primaryRouteName) -}} + {{- end -}} {{- with $objectData.targetSelector -}} {{- if .ingress -}} diff --git a/charts/library/common/templates/loader/_init.tpl b/charts/library/common/templates/loader/_init.tpl index 6a2f78eaac1d0..b7f934a667d3f 100644 --- a/charts/library/common/templates/loader/_init.tpl +++ b/charts/library/common/templates/loader/_init.tpl @@ -12,8 +12,8 @@ {{/* Autogenerate postgresql passwords if needed */}} {{- include "tc.v1.common.spawner.cnpg" . }} - {{/* Autogenerate redis passwords if needed */}} - {{- include "tc.v1.common.dependencies.redis.injector" . }} + {{/* Autogenerate valkey passwords and credentials if needed */}} + {{- include "tc.v1.common.dependencies.valkey.injector" . }} {{/* Autogenerate mariadb passwords if needed */}} {{- include "tc.v1.common.dependencies.mariadb.injector" . }} diff --git a/charts/library/common/templates/values/_init.tpl b/charts/library/common/templates/values/_init.tpl index f36747dc37beb..26d75082076db 100644 --- a/charts/library/common/templates/values/_init.tpl +++ b/charts/library/common/templates/values/_init.tpl @@ -9,23 +9,104 @@ {{- $commonValues := mustDeepCopy .Values.common -}} {{- $chartValues := mustDeepCopy (omit .Values "common") -}} {{- $mergedValues := mustMergeOverwrite $commonValues $chartValues -}} - {{- range $name, $dependencyValues := .Values.dependencies -}} + + {{/* Define which keys should NOT be prefixed (exclusions) */}} + {{- $exclusionKeys := list "global" "securityContext" "podOptions" "enabled" "depconfig" "image" "chartContext" "fallbackDefaults" "notes" "operator" -}} + + {{- range $depName, $dependencyValues := .Values.dependencies -}} {{ $enabled := (include "tc.v1.common.lib.util.enabled" (dict "rootCtx" $ "objectData" $dependencyValues - "name" $name "caller" "dependency" + "name" $depName "caller" "dependency" "key" "dependencies")) }} {{- if eq $enabled "true" -}} - {{- $dependencyValues := omit $dependencyValues "global " -}} - {{- $dependencyValues := omit $dependencyValues "securityContext " -}} - {{- $dependencyValues := omit $dependencyValues "podOptions " -}} - {{- $mergedValues = mustMergeOverwrite $mergedValues $dependencyValues -}} - {{- end -}} - {{- range $mergedValues.addons -}} - {{- if .enabled -}} - {{- $mergedValues = mustMergeOverwrite $mergedValues . -}} + {{- $dependencyValues := omit $dependencyValues "global" "securityContext" "podOptions" "enabled" "depconfig" -}} + + {{/* Process each key in the dependency */}} + {{- range $resourceType, $resources := $dependencyValues -}} + {{- if eq $resourceType "image" -}} + {{/* Special handling for image - prefix the key itself */}} + {{- $imageName := printf "%sImage" $depName -}} + {{- $_ := set $mergedValues $imageName $resources -}} + {{- else if and (not (has $resourceType $exclusionKeys)) (kindIs "map" $resources) -}} + {{/* This is a resource collection that needs prefixing */}} + {{- range $resourceName, $resourceConfig := $resources -}} + {{- if kindIs "map" $resourceConfig -}} + {{- $newName := printf "%s-%s" $depName $resourceName -}} + + {{/* Ensure enabled is set if not explicitly defined */}} + {{- if not (hasKey $resourceConfig "enabled") -}} + {{- $_ := set $resourceConfig "enabled" true -}} + {{- end -}} + + {{/* Handle targetSelector prefixing */}} + {{- if $resourceConfig.targetSelector -}} + {{- if kindIs "string" $resourceConfig.targetSelector -}} + {{- $_ := set $resourceConfig "targetSelector" (printf "%s-%s" $depName $resourceConfig.targetSelector) -}} + {{- else if kindIs "slice" $resourceConfig.targetSelector -}} + {{- $newList := list -}} + {{- range $resourceConfig.targetSelector -}} + {{- $newList = append $newList (printf "%s-%s" $depName .) -}} + {{- end -}} + {{- $_ := set $resourceConfig "targetSelector" $newList -}} + {{- else if kindIs "map" $resourceConfig.targetSelector -}} + {{- $newDict := dict -}} + {{- range $key, $value := $resourceConfig.targetSelector -}} + {{- $newKey := printf "%s-%s" $depName $key -}} + {{- $_ := set $newDict $newKey $value -}} + {{- end -}} + {{- $_ := set $resourceConfig "targetSelector" $newDict -}} + {{- end -}} + {{- end -}} + + {{/* Handle objectName prefixing for persistence volumes */}} + {{- if and (eq $resourceType "persistence") $resourceConfig.objectName -}} + {{- if kindIs "string" $resourceConfig.objectName -}} + {{- $_ := set $resourceConfig "objectName" (printf "%s-%s" $depName $resourceConfig.objectName) -}} + {{- end -}} + {{- end -}} + + {{/* Handle nested targetSelectors in ports (for services) */}} + {{- if and (eq $resourceType "service") $resourceConfig.ports -}} + {{- range $portName, $portConfig := $resourceConfig.ports -}} + {{- if and (kindIs "map" $portConfig) $portConfig.targetSelector -}} + {{- if kindIs "string" $portConfig.targetSelector -}} + {{- $_ := set $portConfig "targetSelector" (printf "%s-%s" $depName $portConfig.targetSelector) -}} + {{- else if kindIs "slice" $portConfig.targetSelector -}} + {{- $newList := list -}} + {{- range $portConfig.targetSelector -}} + {{- $newList = append $newList (printf "%s-%s" $depName .) -}} + {{- end -}} + {{- $_ := set $portConfig "targetSelector" $newList -}} + {{- else if kindIs "map" $portConfig.targetSelector -}} + {{- $newDict := dict -}} + {{- range $key, $value := $portConfig.targetSelector -}} + {{- $newKey := printf "%s-%s" $depName $key -}} + {{- $_ := set $newDict $newKey $value -}} + {{- end -}} + {{- $_ := set $portConfig "targetSelector" $newDict -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{/* Merge into values with prefixed name */}} + {{- if not (hasKey $mergedValues $resourceType) -}} + {{- $_ := set $mergedValues $resourceType dict -}} + {{- end -}} + {{- $_ := set (get $mergedValues $resourceType) $newName $resourceConfig -}} + {{- end -}} + {{- end -}} + {{- end -}} {{- end -}} {{- end -}} {{- end -}} + + {{- range $mergedValues.addons -}} + {{- if .enabled -}} + {{- $mergedValues = mustMergeOverwrite $mergedValues . -}} + {{- end -}} + {{- end -}} + {{- $_ := set . "Values" (mustDeepCopy $mergedValues) -}} {{- end -}} {{- end -}} diff --git a/charts/library/common/values.schema.json b/charts/library/common/values.schema.json index 03dbbddeaec77..b7f99a6a3966f 100644 --- a/charts/library/common/values.schema.json +++ b/charts/library/common/values.schema.json @@ -249,10 +249,6 @@ "$ref": "schemas/cnpg/cnpg.json", "description": "Define a CNPG cluster" }, - "redis": { - "$ref": "schemas/redis.json", - "description": "Configuration for `redis`." - }, "mariadb": { "$ref": "schemas/mariadb.json", "description": "Configuration for `mariadb`." diff --git a/charts/library/common/values.yaml b/charts/library/common/values.yaml index 43df390bbe9cd..6fe6a907903f5 100644 --- a/charts/library/common/values.yaml +++ b/charts/library/common/values.yaml @@ -86,6 +86,11 @@ ubuntuImage: tag: "24.04@sha256:3b826c0233182d7c31a9323121178b98976765b9ee03f9a96200ab0c70e2e1e2" pullPolicy: IfNotPresent +valkeyClientImage: + repository: docker.io/bitnamisecure/valkey + tag: latest@sha256:14dc12c4cc5912747b63d41e237512989d958fa6020dbcb1170cc0fe91f48644 + pullPolicy: IfNotPresent + chartContext: appUrl: "" podCIDR: "" @@ -1490,18 +1495,6 @@ cnpg: # -- contains credentials and urls output by generator creds: {} -# -- Redis dependency configuration -# @default -- See below -redis: - enabled: false - includeCommon: false - password: "PLACEHOLDERPASSWORD" - # -- can be used to make an easy accessible note which URLS to use to access the DB. - creds: {} - secret: - credentials: - enabled: false - # -- mariadb dependency configuration # @default -- See below mariadb: @@ -1542,5 +1535,33 @@ solr: # -- can be used to make an easy accessable note which URLS to use to access the DB. creds: {} +# -- Dependency configuration - replaces helm-dependencies +# Each dependency should contain a complete chart values.yaml structure +# Resources from dependencies are merged into the main chart with prefixed names +# @default -- See below +dependencies: {} +# valkey: +# enabled: true +# image: +# repository: docker.io/bitnamisecure/valkey +# tag: latest +# workload: +# main: +# type: StatefulSet +# podSpec: +# containers: +# main: +# env: +# REDIS_PASSWORD: "my-password" +# service: +# main: +# ports: +# main: +# port: 6379 +# persistence: +# data: +# enabled: true +# mountPath: /data + # -- List of extra objects to deploy with the release extraTpl: []