From 32c1219344f880d715269d32dce6f1dfce1c7f84 Mon Sep 17 00:00:00 2001 From: Clemens Beck Date: Tue, 9 Dec 2025 09:48:04 +0100 Subject: [PATCH 1/2] PoC: Replace bundled Redis with Valkey * Replace bundled Redis chart (deploying Redis 7.2) with the official Valkey chart (deploying Valkey 8). * Reuse existing Redis secret used by GitLab and previous Redis. * Replace configuration config checks and notes related to Bitnami Redis chart. This is a breaking change! Closes https://gitlab.com/gitlab-org/charts/gitlab/-/issues/6227 Changelog: changed --- Chart.lock | 10 ++++---- Chart.yaml | 8 +++--- charts/gitlab/templates/_redis.tpl | 9 +------ scripts/ci/autodevops.sh | 3 ++- templates/_checkConfig.tpl | 8 +++--- templates/_helpers.tpl | 14 ----------- templates/_notes.tpl | 4 +-- templates/_removals.tpl | 36 --------------------------- values.yaml | 39 +++++++----------------------- 9 files changed, 27 insertions(+), 104 deletions(-) diff --git a/Chart.lock b/Chart.lock index bf674f5c61..c1b943e2a9 100644 --- a/Chart.lock +++ b/Chart.lock @@ -23,9 +23,9 @@ dependencies: - name: gitlab-runner repository: https://charts.gitlab.io/ version: 0.83.3 -- name: redis - repository: https://charts.bitnami.com/bitnami - version: 18.19.4 +- name: valkey + repository: https://valkey.io/valkey-helm/ + version: 0.8.1 - name: nginx-ingress repository: "" version: '*.*.*' @@ -44,5 +44,5 @@ dependencies: - name: kubernetes-ingress repository: https://haproxytech.github.io/helm-charts version: 1.39.4 -digest: sha256:af1f675b00ae7ee20ec16b72007d9d36f0cec409981f76195b13b3cbdb8748ac -generated: "2025-11-28T23:23:11.015894751Z" +digest: sha256:51fa790f40b8a901d812624cd0c0e50b9662abb1aa80534ba4a76b23737ca37a +generated: "2025-12-09T09:13:05.842029683+01:00" diff --git a/Chart.yaml b/Chart.yaml index 4e58250272..26511cc3c6 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -39,10 +39,10 @@ dependencies: version: 0.83.3 repository: https://charts.gitlab.io/ condition: gitlab-runner.install -- name: redis - version: 18.19.4 - repository: https://charts.bitnami.com/bitnami - condition: redis.install +- name: valkey + version: 0.8.1 + repository: https://valkey.io/valkey-helm/ + condition: installValkey - name: nginx-ingress condition: nginx-ingress.enabled version: "*.*.*" diff --git a/charts/gitlab/templates/_redis.tpl b/charts/gitlab/templates/_redis.tpl index b362648afc..bbe61f9b45 100644 --- a/charts/gitlab/templates/_redis.tpl +++ b/charts/gitlab/templates/_redis.tpl @@ -10,14 +10,7 @@ to the service name {{- if .redisMergedConfig.host -}} {{- .redisMergedConfig.host -}} {{- else -}} -{{- $name := default "redis" (.Values.redis).serviceName -}} -{{- $redisRelease := .Release.Name -}} -{{- if contains $name $redisRelease -}} -{{- $redisRelease = .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $redisRelease = printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- printf "%s-master.%s.svc" $redisRelease .Release.Namespace -}} +{{- printf "%s-valkey.%s.svc.cluster.local" .Release.Name .Release.Namespace -}} {{- end -}} {{- end -}} diff --git a/scripts/ci/autodevops.sh b/scripts/ci/autodevops.sh index 24f1f485e1..766dd1d970 100755 --- a/scripts/ci/autodevops.sh +++ b/scripts/ci/autodevops.sh @@ -140,7 +140,7 @@ CIYAML nginx-ingress: controller: replicaCount: 1 # 2 - redis: + valkey: resources: requests: cpu: 100m @@ -209,6 +209,7 @@ CIYAML --set releaseOverride="$RELEASE_NAME" \ --set global.hosts.hostSuffix="$HOST_SUFFIX" \ --set global.hosts.domain="$KUBE_INGRESS_BASE_DOMAIN" \ + --set valkey.auth.aclUsers.usersExistingSecret="$RELEASE_NAME-redis-secret" \ --set global.ingress.annotations."external-dns\.alpha\.kubernetes\.io/ttl"="10" \ --set global.ingress.tls.secretName=helm-charts-win-tls \ --set global.ingress.configureCertmanager=false \ diff --git a/templates/_checkConfig.tpl b/templates/_checkConfig.tpl index 396408e44f..f8677cf8e1 100644 --- a/templates/_checkConfig.tpl +++ b/templates/_checkConfig.tpl @@ -145,9 +145,9 @@ Ensure that `redis.install: false` if configuring multiple Redis instances {{- $_ := set $x "count" ( add1 $x.count ) -}} {{- end -}} {{- end -}} -{{- if and .Values.redis.install ( lt 0 $x.count ) }} +{{- if and .Values.installValkey ( lt 0 $x.count ) }} redis: - If configuring multiple Redis servers, you can not use the in-chart Redis server. Please see https://docs.gitlab.com/charts/charts/globals#configure-redis-settings + If configuring multiple Redis servers, you can not use the in-chart Redis/Valkey server. Please see https://docs.gitlab.com/charts/charts/globals#configure-redis-settings {{- end -}} {{- end -}} {{/* END gitlab.checkConfig.multipleRedis */}} @@ -156,7 +156,7 @@ redis: Ensure that `redis.install: false` if using redis.yml override */}} {{- define "gitlab.checkConfig.redisYmlOverride" -}} -{{- if and .Values.redis.install ( hasKey .Values.global.redis "redisYmlOverride" ) }} +{{- if and .Values.installValkey ( hasKey .Values.global.redis "redisYmlOverride" ) }} redis: When you override redis.yml you can not use the in-chart Redis server. Please see https://docs.gitlab.com/charts/charts/globals#configure-redis-settings {{- end -}} @@ -167,7 +167,7 @@ redis: Ensure that `global.redis.host: ` is present if `redis.install: false` */}} {{- define "gitlab.checkConfig.hostWhenNoInstall" -}} -{{- if and (not .Values.redis.install) (empty .Values.global.redis.host) (empty .Values.global.redis.redisYmlOverride) }} +{{- if and (not .Values.installValkey) (empty .Values.global.redis.host) (empty .Values.global.redis.redisYmlOverride) }} redis: You've disabled the installation of Redis. When using an external Redis, you must populate `global.redis.host` or `gitlab.redis.redisYmlOverride`. Please see https://docs.gitlab.com/charts/advanced/external-redis/ {{- end -}} diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 219a8c19d1..1a4ee232e3 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -482,20 +482,6 @@ Return true in any other case. {{- end -}} {{- end -}} -{{/* -Override upstream redis chart naming -*/}} -{{- define "redis.secretName" -}} -{{ template "gitlab.redis.password.secret" . }} -{{- end -}} - -{{/* -Override upstream redis secret key name -*/}} -{{- define "redis.secretPasswordKey" -}} -{{ template "gitlab.redis.password.key" . }} -{{- end -}} - {{/* Return the fullname template for shared-secrets job. */}} diff --git a/templates/_notes.tpl b/templates/_notes.tpl index f85a55bdf7..85f9a5527b 100644 --- a/templates/_notes.tpl +++ b/templates/_notes.tpl @@ -7,8 +7,8 @@ charts: - name: PostgreSQL enabled: {{ .Values.postgresql.install }} - - name: Redis - enabled: {{ .Values.redis.install }} + - name: Valkey + enabled: {{ .Values.installValkey }} - name: Gitaly enabled: {{ .Values.global.gitaly.enabled }} - name: Praefect diff --git a/templates/_removals.tpl b/templates/_removals.tpl index 840a520a48..7b68abb501 100644 --- a/templates/_removals.tpl +++ b/templates/_removals.tpl @@ -46,10 +46,7 @@ Due to gotpl scoping, we can't make use of `range`, so we have to add action lin {{- $removals = append $removals (include "gitlab.removal.local.kubectl" .) -}} {{- $removals = append $removals (include "gitlab.removal.gitlab.gitaly.enabled" .) -}} {{- $removals = append $removals (include "gitlab.removal.initContainerImage" .) -}} -{{- $removals = append $removals (include "external.removal.initContainerImage" .) -}} {{- $removals = append $removals (include "external.removal.initContainerPullPolicy" .) -}} -{{- $removals = append $removals (include "gitlab.removal.redis-ha.enabled" .) -}} -{{- $removals = append $removals (include "gitlab.removal.redis.enabled" .) -}} {{- $removals = append $removals (include "gitlab.removal.gitlab.webservice.service.configuration" .) -}} {{- $removals = append $removals (include "gitlab.removal.gitlab.gitaly.serviceName" .) -}} {{- $removals = append $removals (include "gitlab.removal.global.psql.pool" .) -}} @@ -246,21 +243,6 @@ gitlab.{{ $chart }}: {{- end -}} {{/* END gitlab.removal.initContainerImage */}} -{{/* Deprecation behavious for configuration of initContainer images of external charts */}} -{{- define "external.removal.initContainerImage" -}} -{{- range $chart:= list "minio" "registry" "redis" "redis-ha" }} -{{- if hasKey (index $.Values $chart) "init" -}} -{{- with $config := index $.Values $chart "init" -}} -{{- if or (and (hasKey $config "image") (kindIs "string" $config.image)) (hasKey $config "tag") }} -{{ $chart }}: - Configuring image for initContainers using {{ $chart }}.init.image and {{ $chart }}.init.tag has been removed. Please use {{ $chart }}.init.image.repository and {{ $chart }}.init.image.tag for that. -{{- end -}} -{{- end -}} -{{- end -}} -{{- end -}} -{{- end -}} -{{/* END external.removal.initContainerImage */}} - {{/* Deprecation behavious for configuration of initContainer image pull policy of external charts */}} {{- define "external.removal.initContainerPullPolicy" -}} {{- range $chart:= list "minio" "registry" }} @@ -276,24 +258,6 @@ gitlab.{{ $chart }}: {{- end -}} {{/* END external.removal.initContainerPullPolicy*/}} -{{/* Deprecation behaviors for redis-ha.enabled */}} -{{- define "gitlab.removal.redis-ha.enabled" -}} -{{- if hasKey (index .Values "redis-ha") "enabled" -}} -redis-ha: - The `redis-ha.enabled` has been removed. Redis HA is now implemented by the Redis chart. -{{- end -}} -{{- end -}} -{{/* END gitlab.removal.redis-ha.enabled */}} - -{{/* Deprecation behaviors for redis.enabled */}} -{{- define "gitlab.removal.redis.enabled" -}} -{{- if hasKey .Values.redis "enabled" -}} -redis: - The `redis.enabled` has been removed. Please use `redis.install` to install the Redis service. -{{- end -}} -{{- end -}} -{{/* END gitlab.removal.redis.enabled */}} - {{- define "gitlab.removal.gitlab.webservice.service.configuration" -}} {{- range $chart := list "gitaly" "gitlab-shell" -}} {{- if index $.Values.gitlab $chart -}} diff --git a/values.yaml b/values.yaml index e7f6d5f1d0..3bd850f214 100644 --- a/values.yaml +++ b/values.yaml @@ -1293,40 +1293,19 @@ prometheus: - source_labels: [__meta_kubernetes_service_name] target_label: kubernetes_name -## Configuration of Redis +## Configuration of Valkey ## https://docs.gitlab.com/charts/architecture/decisions#redis ## https://docs.gitlab.com/charts/installation/deployment.html#redis -redis: - install: true - image: - repository: bitnamilegacy/redis +installValkey: true +valkey: auth: - existingSecret: gitlab-redis-secret - existingSecretKey: redis-password - usePasswordFiles: true - architecture: standalone - cluster: - enabled: false - metrics: enabled: true - image: - repository: bitnamilegacy/redis-exporter - sentinel: - enabled: false - image: - repository: bitnamilegacy/redis-sentinel - kubectl: - enabled: false - image: - repository: bitnamilegacy/kubectl - sysctl: - enabled: false - image: - repository: bitnamilegacy/os-shell - volumePermissions: - enabled: false - image: - repository: bitnamilegacy/os-shell + # This depends on the chart release name. + usersExistingSecret: gitlab-redis-secret # -redis-secret + aclUsers: + default: + permissions: "~* &* +@all" + passwordKey: secret ## Installation & configuration of stable/postgresql ## See dependencies in Chart.yaml for current version -- GitLab From d2a105c116b4b153e235eefae26d7588bc4e2a20 Mon Sep 17 00:00:00 2001 From: Clemens Beck Date: Tue, 9 Dec 2025 11:11:31 +0100 Subject: [PATCH 2/2] Spec and doc changes --- charts/registry/templates/_redis.tpl | 12 +- doc/advanced/external-redis/_index.md | 8 +- doc/charts/gitlab/migrations/_index.md | 10 +- doc/charts/gitlab/sidekiq/_index.md | 10 +- doc/charts/globals.md | 29 +- doc/development/style_guide.md | 10 +- doc/installation/command-line-options.md | 14 +- examples/redis/cache.yaml | 3 +- examples/redis/multiple.yaml | 3 +- examples/redis/sentinels.yaml | 3 +- examples/ref/10k.yaml | 5 +- examples/ref/25k.yaml | 5 +- examples/ref/2k.yaml | 5 +- examples/ref/3k.yaml | 5 +- examples/ref/50k.yaml | 5 +- examples/ref/5k.yaml | 5 +- scripts/ci/add_dependency_repos.sh | 1 + scripts/ci/autodevops.sh | 2 +- spec/configuration/affinity_spec.rb | 6 +- spec/configuration/annotations_spec.rb | 3 +- spec/configuration/certificates_spec.rb | 2 +- spec/configuration/gitlab_exporter_spec.rb | 7 +- spec/configuration/global_spec.rb | 12 +- spec/configuration/image_pull_spec.rb | 2 +- spec/configuration/kas_spec.rb | 14 +- spec/configuration/labels_spec.rb | 3 +- spec/configuration/mailroom_spec.rb | 5 +- spec/configuration/node_selector_spec.rb | 4 +- spec/configuration/priorityclass_spec.rb | 11 +- spec/configuration/redis_spec.rb | 815 ------------------ spec/configuration/strategy_spec.rb | 2 +- .../topology_spread_constraints_spec.rb | 1 + spec/configuration/workhorse_spec.rb | 21 +- spec/integration/check_config_spec.rb | 10 +- templates/_checkConfig.tpl | 4 +- 35 files changed, 115 insertions(+), 942 deletions(-) delete mode 100644 spec/configuration/redis_spec.rb diff --git a/charts/registry/templates/_redis.tpl b/charts/registry/templates/_redis.tpl index 9513886af9..f2b2c058ba 100644 --- a/charts/registry/templates/_redis.tpl +++ b/charts/registry/templates/_redis.tpl @@ -21,9 +21,9 @@ Expectation: input contents has .sentinels or .cluster, which is a List of Dict {{- define "gitlab.registry.redisCacheSecret.mount" -}} {{- if .Values.redis.cache.password.enabled }} - secret: - name: {{ default (include "redis.secretName" . ) ( .Values.redis.cache.password.secret | quote) }} + name: {{ default (include "gitlab.redis.password.secret" . ) ( .Values.redis.cache.password.secret | quote) }} items: - - key: {{ default (include "redis.secretPasswordKey" . ) ( .Values.redis.cache.password.key | quote) }} + - key: {{ default (include "gitlab.redis.password.key" . ) ( .Values.redis.cache.password.key | quote) }} path: registry/redis-password {{- end }} {{- end -}} @@ -62,9 +62,9 @@ Expectation: input contents has .sentinels or .cluster, which is a List of Dict {{- define "gitlab.registry.redisRateLimitingSecret.mount" -}} {{- if .Values.redis.rateLimiting.password.enabled }} - secret: - name: {{ default (include "redis.secretName" . ) ( .Values.redis.rateLimiting.password.secret | quote) }} + name: {{ default (include "gitlab.redis.password.secret" . ) ( .Values.redis.rateLimiting.password.secret | quote) }} items: - - key: {{ default (include "redis.secretPasswordKey" . ) ( .Values.redis.rateLimiting.password.key | quote) }} + - key: {{ default (include "gitlab.redis.password.key" . ) ( .Values.redis.rateLimiting.password.key | quote) }} path: registry/redis-rateLimiting-password {{- end }} {{- end -}} @@ -72,9 +72,9 @@ Expectation: input contents has .sentinels or .cluster, which is a List of Dict {{- define "gitlab.registry.redisLoadBalancingSecret.mount" -}} {{- if .Values.redis.loadBalancing.password.enabled }} - secret: - name: {{ default (include "redis.secretName" . ) ( .Values.redis.loadBalancing.password.secret | quote) }} + name: {{ default (include "gitlab.redis.password.secret" . ) ( .Values.redis.loadBalancing.password.secret | quote) }} items: - - key: {{ default (include "redis.secretPasswordKey" . ) ( .Values.redis.loadBalancing.password.key | quote) }} + - key: {{ default (include "gitlab.redis.password.key" . ) ( .Values.redis.loadBalancing.password.key | quote) }} path: registry/redis-loadBalancing-password {{- end }} {{- end -}} diff --git a/doc/advanced/external-redis/_index.md b/doc/advanced/external-redis/_index.md index 98b90f7312..5d6d453f9e 100644 --- a/doc/advanced/external-redis/_index.md +++ b/doc/advanced/external-redis/_index.md @@ -14,11 +14,11 @@ For details about currently supported Redis versions, see [Installation system r ## Configure the chart -Disable the `redis` chart and the Redis service it provides, and point the other services to the external service. +Disable the `valkey` chart and the Valkey/Redis service it provides, and point the other services to the external service. You must set the following parameters: -- `redis.install`: Set to `false` to disable including the Redis chart. +- `installValkey`: Set to `false` to disable including the Redis chart. - `global.redis.host`: Set to the hostname of the external Redis, can be a domain or an IP address. - `global.redis.auth.enabled`: Set to `false` if the external Redis does not require a password. - `global.redis.auth.secret`: The name of the [secret which contains the token for authentication](../../installation/secrets.md#redis-password). @@ -33,7 +33,7 @@ For example, pass these values via Helm's `--set` flag while deploying: ```shell helm install gitlab gitlab/gitlab \ - --set redis.install=false \ + --set installValkey=false \ --set global.redis.host=redis.example \ --set global.redis.auth.secret=gitlab-redis \ --set global.redis.auth.key=redis-password \ @@ -73,7 +73,7 @@ you can do so by defining values under key will be rendered into `redis.yml` as-is. The `global.redis.redisYmlOverride` setting is intended for use with -external Redis services. You must set `redis.install` to `false`. See +external Redis services. You must set `installValkey` to `false`. See [configure Redis settings](../../charts/globals.md#configure-redis-settings) for further details. diff --git a/doc/charts/gitlab/migrations/_index.md b/doc/charts/gitlab/migrations/_index.md index de5f21f7f7..7a4cf6dfdb 100644 --- a/doc/charts/gitlab/migrations/_index.md +++ b/doc/charts/gitlab/migrations/_index.md @@ -224,11 +224,11 @@ The sub keys describe each Sentinel connection. {{< alert type="note" >}} -The current Redis Sentinel support only supports Sentinels that have -been deployed separately from the GitLab chart. As a result, the Redis -deployment through the GitLab chart should be disabled with `redis.install=false`. -The Secret containing the Redis password will need to be manually created -before deploying the GitLab chart. +The current Valkey/Redis Sentinel support only supports Sentinels that have +been deployed separately from the GitLab chart. As a result, the Valkey +deployment through the GitLab chart should be disabled with `installValkey=false`. +The Kubernetes Secret containing the Valkey/Redis password will need to be manually +created before deploying the GitLab chart. {{< /alert >}} diff --git a/doc/charts/gitlab/sidekiq/_index.md b/doc/charts/gitlab/sidekiq/_index.md index 0cea655dca..5befeabecd 100644 --- a/doc/charts/gitlab/sidekiq/_index.md +++ b/doc/charts/gitlab/sidekiq/_index.md @@ -364,11 +364,11 @@ redis: {{< alert type="note" >}} -The current Redis Sentinel support only supports Sentinels that have -been deployed separately from the GitLab chart. As a result, the Redis -deployment through the GitLab chart should be disabled with `redis.install=false`. -The Secret containing the Redis password needs to be manually created -before deploying the GitLab chart. +The current Valkey/Redis Sentinel support only supports Sentinels that have +been deployed separately from the GitLab chart. As a result, the Valkey +deployment through the GitLab chart should be disabled with `installValkey=false`. +The Kubernetes Secret containing the Valkey/Redis password will need to be manually +created before deploying the GitLab chart. {{< /alert >}} diff --git a/doc/charts/globals.md b/doc/charts/globals.md index 462a64c9a1..bd16e322f6 100644 --- a/doc/charts/globals.md +++ b/doc/charts/globals.md @@ -429,7 +429,7 @@ The GitLab global Redis settings are located under the `global.redis` key. By default we use an single, non-replicated Redis instance. If a highly available Redis is required, we recommend using an external Redis instance. -You can bring an external Redis instance by setting `redis.install=false`, and +You can bring an external Redis instance by setting `installValkey=false`, and following our [advanced documentation](../advanced/external-redis/_index.md) for configuration. @@ -476,26 +476,19 @@ redis: tag: x.y.z ``` -### Redis Sentinel support +### Valkey/Redis Sentinel support -The current Redis Sentinel support only supports Sentinels that have -been deployed separately from the GitLab chart. As a result, the Redis -deployment through the GitLab chart should be disabled with `redis.install=false`. -The Kubernetes Secret containing the Redis password will need to be manually created -before deploying the GitLab chart. +The current Valkey/Redis Sentinel support only supports Sentinels that have +been deployed separately from the GitLab chart. As a result, the Valkey +deployment through the GitLab chart should be disabled with `installValkey=false`. +The Kubernetes Secret containing the Valkey/Redis password will need to be manually +created before deploying the GitLab chart. -The installation of an HA Redis cluster from the GitLab chart does not -support using sentinels. If sentinel support is desired, a Redis cluster -needs to be created separately from the GitLab chart install. This can be -done inside or outside the Kubernetes cluster. - -An issue to track the -[supporting of sentinels in a GitLab deployed Redis cluster](https://gitlab.com/gitlab-org/charts/gitlab/-/issues/1810) has -been created for tracking purposes. +To support Sentinel a Valkey/Redis cluster needs to be created separately from the +GitLab chart install. This can be done inside or outside the Kubernetes cluster. ```yaml -redis: - install: false +installValkey: false global: redis: host: redis.example.com @@ -692,7 +685,7 @@ classes that have not been separated. Each instance definition may also use Redis Sentinel support. Sentinel configurations **are not shared** and needs to be specified for each -instance that uses Sentinels. Please refer to the [Sentinel configuration](#redis-sentinel-support) +instance that uses Sentinels. Please refer to the [Sentinel configuration](#valkeyredis-sentinel-support) for the attributes that are used to configure Sentinel servers. ### Specify secure Redis scheme (SSL) diff --git a/doc/development/style_guide.md b/doc/development/style_guide.md index 2497c7b506..d8516f4b75 100644 --- a/doc/development/style_guide.md +++ b/doc/development/style_guide.md @@ -47,11 +47,11 @@ redis: - `sentinels.[].host` - defines the hostname of Redis Sentinel server for a Redis HA setup. - `sentinels.[].port` - defines the port on which to connect to the Redis Sentinel server. Defaults to `26379`. -_Note:_ The current Redis Sentinel support only supports Sentinels that have -been deployed separately from the GitLab chart. As a result, the Redis -deployment through the GitLab chart should be disabled with `redis.install=false`. -The Secret containing the Redis password must be manually created -before deploying the GitLab chart. +_Note:_ The current Valkey/Redis Sentinel support only supports Sentinels that have +been deployed separately from the GitLab chart. As a result, the Valkey +deployment through the GitLab chart should be disabled with `installValkey=false`. +The Kubernetes Secret containing the Valkey/Redis password will need to be manually +created before deploying the GitLab chart. ### Sharing secrets diff --git a/doc/installation/command-line-options.md b/doc/installation/command-line-options.md index eaa3388dcf..768df5ce75 100644 --- a/doc/installation/command-line-options.md +++ b/doc/installation/command-line-options.md @@ -244,16 +244,16 @@ Prefix NGINX Ingress values with `nginx-ingress`. For example, set the controlle See [`nginx-ingress` chart](../charts/nginx/_index.md). -## Advanced in-cluster Redis configuration +## Advanced in-cluster Valkey configuration -| Parameter | Default | Description | -|---------------------------|-----------------------|-------------| -| `redis.install` | `true` | Install the `bitnami/redis` chart | -| `redis.existingSecret` | `gitlab-redis-secret` | Specify the Secret for Redis servers to use | -| `redis.existingSecretKey` | `redis-password` | Secret key where password is stored | +| Parameter | Default | Description | +|--------------------------------------------|-----------------------|-------------| +| `installValkey` | `true` | Install the [valkey](https://github.com/valkey-io/valkey-helm) chart | +| `valkey.auth.aclUsers.usersExistingSecret` | `gitlab-redis-secret` | Specify the Secret for Valkey/Redis servers to use | +| `valkey.auth.aclUsers.passwordKey` | `redis-password` | Secret key where the password of the default user is stored | Any additional configuration of the Redis service should use the configuration -settings from the [Redis chart](https://github.com/bitnami/charts/tree/main/bitnami/redis). +settings from the [Valkey chart documentation](https://github.com/valkey-io/valkey-helm). ## Advanced registry configuration diff --git a/examples/redis/cache.yaml b/examples/redis/cache.yaml index c65bf8effd..64ce5f24c1 100644 --- a/examples/redis/cache.yaml +++ b/examples/redis/cache.yaml @@ -1,5 +1,4 @@ -redis: - install: false +installValkey: false global: redis: host: redis.example diff --git a/examples/redis/multiple.yaml b/examples/redis/multiple.yaml index 2e735ba482..8d34f9a01e 100644 --- a/examples/redis/multiple.yaml +++ b/examples/redis/multiple.yaml @@ -1,5 +1,4 @@ -redis: - install: false +installValkey: false global: redis: host: redis.example diff --git a/examples/redis/sentinels.yaml b/examples/redis/sentinels.yaml index a6ded9dc6a..a968ad5109 100644 --- a/examples/redis/sentinels.yaml +++ b/examples/redis/sentinels.yaml @@ -1,5 +1,4 @@ -redis: - install: false +installValkey: false global: redis: host: redis.example diff --git a/examples/ref/10k.yaml b/examples/ref/10k.yaml index 86c8ca798c..f0a4962a2f 100644 --- a/examples/ref/10k.yaml +++ b/examples/ref/10k.yaml @@ -151,9 +151,8 @@ registry: key: registry-config secret: gcs-secret-example -# Run Redis outside of cluster -redis: - install: false +# Run Valkey/Redis outside of cluster +installValkey: false # Database run outside of cluster postgresql: diff --git a/examples/ref/25k.yaml b/examples/ref/25k.yaml index 5494692e34..d81685e7a8 100644 --- a/examples/ref/25k.yaml +++ b/examples/ref/25k.yaml @@ -151,9 +151,8 @@ registry: key: registry-config secret: gcs-secret-example -# Run Redis outside of cluster -redis: - install: false +# Run Valkey/Redis outside of cluster +installValkey: false # Database run outside of cluster postgresql: diff --git a/examples/ref/2k.yaml b/examples/ref/2k.yaml index 16245cd300..0ca5576cfa 100644 --- a/examples/ref/2k.yaml +++ b/examples/ref/2k.yaml @@ -138,9 +138,8 @@ registry: key: registry-config secret: gcs-secret-example -# Run Redis outside of cluster -redis: - install: false +# Run Valkey/Redis outside of cluster +installValkey: false # Database run outside of cluster postgresql: diff --git a/examples/ref/3k.yaml b/examples/ref/3k.yaml index 51f6e7c8c3..35bb90b579 100644 --- a/examples/ref/3k.yaml +++ b/examples/ref/3k.yaml @@ -142,9 +142,8 @@ registry: key: registry-config secret: gcs-secret-example -# Run Redis outside of cluster -redis: - install: false +# Run Valkey/Redis outside of cluster +installValkey: false # Database run outside of cluster postgresql: diff --git a/examples/ref/50k.yaml b/examples/ref/50k.yaml index e5815cbdab..63fe397030 100644 --- a/examples/ref/50k.yaml +++ b/examples/ref/50k.yaml @@ -151,9 +151,8 @@ registry: key: registry-config secret: gcs-secret-example -# Run Redis outside of cluster -redis: - install: false +# Run Valkey/Redis outside of cluster +installValkey: false # Database run outside of cluster postgresql: diff --git a/examples/ref/5k.yaml b/examples/ref/5k.yaml index d1f253472f..3aacd0712e 100644 --- a/examples/ref/5k.yaml +++ b/examples/ref/5k.yaml @@ -142,9 +142,8 @@ registry: key: registry-config secret: gcs-secret-example -# Run Redis outside of cluster -redis: - install: false +# Run Valkey/Redis outside of cluster +installValkey: false # Database run outside of cluster postgresql: diff --git a/scripts/ci/add_dependency_repos.sh b/scripts/ci/add_dependency_repos.sh index 4ad83177bf..f7cc84995b 100644 --- a/scripts/ci/add_dependency_repos.sh +++ b/scripts/ci/add_dependency_repos.sh @@ -8,3 +8,4 @@ helm repo add bitnami https://charts.bitnami.com/bitnami helm repo add gitlab https://charts.gitlab.io/ helm repo add traefik https://helm.traefik.io/traefik helm repo add haproxy https://haproxytech.github.io/helm-charts +helm repo add valkey https://valkey.io/valkey-helm/ diff --git a/scripts/ci/autodevops.sh b/scripts/ci/autodevops.sh index 766dd1d970..8a7dde2613 100755 --- a/scripts/ci/autodevops.sh +++ b/scripts/ci/autodevops.sh @@ -209,7 +209,6 @@ CIYAML --set releaseOverride="$RELEASE_NAME" \ --set global.hosts.hostSuffix="$HOST_SUFFIX" \ --set global.hosts.domain="$KUBE_INGRESS_BASE_DOMAIN" \ - --set valkey.auth.aclUsers.usersExistingSecret="$RELEASE_NAME-redis-secret" \ --set global.ingress.annotations."external-dns\.alpha\.kubernetes\.io/ttl"="10" \ --set global.ingress.tls.secretName=helm-charts-win-tls \ --set global.ingress.configureCertmanager=false \ @@ -221,6 +220,7 @@ CIYAML --set global.extraEnv.GITLAB_LICENSE_MODE="test" \ --set global.extraEnv.CUSTOMER_PORTAL_URL="https://customers.staging.gitlab.com" \ --set global.gitlab.license.secret="$RELEASE_NAME-gitlab-license" \ + --set valkey.auth.usersExistingSecret="$RELEASE_NAME-redis-secret" \ --namespace="$NAMESPACE" \ "${gitlab_version_args[@]}" \ --version="$CI_PIPELINE_ID-$CI_JOB_ID" \ diff --git a/spec/configuration/affinity_spec.rb b/spec/configuration/affinity_spec.rb index 85cebbc459..57245a8f30 100644 --- a/spec/configuration/affinity_spec.rb +++ b/spec/configuration/affinity_spec.rb @@ -36,7 +36,8 @@ describe 'global affinity configuration' do 'Deployment/test-minio', 'Deployment/test-nginx-ingress-controller', 'Deployment/test-prometheus-server', - 'Deployment/test-gitlab-exporter' + 'Deployment/test-gitlab-exporter', + 'Deployment/test-valkey' ].freeze end @@ -116,7 +117,8 @@ describe 'local affinity configuration' do 'Deployment/test-minio', 'Deployment/test-nginx-ingress-controller', 'Deployment/test-prometheus-server', - 'Deployment/test-gitlab-exporter' + 'Deployment/test-gitlab-exporter', + 'Deployment/test-valkey' ].freeze end diff --git a/spec/configuration/annotations_spec.rb b/spec/configuration/annotations_spec.rb index c8bb6bd64e..d0a2d1f988 100644 --- a/spec/configuration/annotations_spec.rb +++ b/spec/configuration/annotations_spec.rb @@ -26,7 +26,8 @@ describe 'Annotations configuration' do 'Deployment/test-certmanager-webhook', 'Deployment/test-certmanager', 'Deployment/test-gitlab-runner', - 'Deployment/test-prometheus-server' + 'Deployment/test-prometheus-server', + 'Deployment/test-valkey' ] end diff --git a/spec/configuration/certificates_spec.rb b/spec/configuration/certificates_spec.rb index 7aa77d2a6c..2e54695231 100644 --- a/spec/configuration/certificates_spec.rb +++ b/spec/configuration/certificates_spec.rb @@ -7,7 +7,7 @@ describe 'Certificates configuration' do # we're skipping anything not using this feature let(:skip_items) do [ - 'minio', 'nginx', 'postgresql', 'redis', + 'minio', 'nginx', 'postgresql', 'valkey', 'gitlab-runner', 'test-kas', # cert-manager Pods (2) diff --git a/spec/configuration/gitlab_exporter_spec.rb b/spec/configuration/gitlab_exporter_spec.rb index e694202119..bc8cdfe674 100644 --- a/spec/configuration/gitlab_exporter_spec.rb +++ b/spec/configuration/gitlab_exporter_spec.rb @@ -35,7 +35,7 @@ describe 'gitlab-exporter configuration' do it 'configures Redis' do expect(template.exit_code).to eq(0), "Unexpected error code #{template.exit_code} -- #{template.stderr}" - expect(sidekiq_config['opts']['redis_url']).to eq("redis://:#{password}@test-redis-master.default.svc:6379/0") + expect(sidekiq_config['opts']['redis_url']).to eq("redis://:#{password}@test-valkey.default.svc.cluster.local:6379/0") expect(sidekiq_config['opts']).not_to include('redis_sentinels') end end @@ -51,7 +51,7 @@ describe 'gitlab-exporter configuration' do it 'configures Redis' do expect(template.exit_code).to eq(0), "Unexpected error code #{template.exit_code} -- #{template.stderr}" - expect(sidekiq_config['opts']['redis_url']).to eq("redis://:#{password}@test-redis-master.default.svc:6379/4") + expect(sidekiq_config['opts']['redis_url']).to eq("redis://:#{password}@test-valkey.default.svc.cluster.local:6379/4") end end @@ -129,8 +129,7 @@ describe 'gitlab-exporter configuration' do context 'when Redis Sentinel is defined for the queues config' do let(:values) do YAML.safe_load(%( - redis: - install: false + installValkey: false global: redis: host: global.host diff --git a/spec/configuration/global_spec.rb b/spec/configuration/global_spec.rb index f75e9ca406..123bb8dcce 100644 --- a/spec/configuration/global_spec.rb +++ b/spec/configuration/global_spec.rb @@ -363,14 +363,14 @@ describe 'global configuration' do [ 'Deployment/test-gitlab-runner', 'Deployment/test-prometheus-server', - 'Deployment/test-minio' + 'Deployment/test-minio', + 'Deployment/test-valkey' ] end let(:ignored_statefulsets) do [ - 'StatefulSet/test-postgresql', - 'StatefulSet/test-redis-master' + 'StatefulSet/test-postgresql' ] end @@ -438,14 +438,14 @@ describe 'global configuration' do 'Deployment/test-minio', 'Deployment/test-certmanager', 'Deployment/test-certmanager-cainjector', - 'Deployment/test-certmanager-webhook' + 'Deployment/test-certmanager-webhook', + 'Deployment/test-valkey' ] end let(:ignored_statefulsets) do [ - 'StatefulSet/test-postgresql', - 'StatefulSet/test-redis-master' + 'StatefulSet/test-postgresql' ] end diff --git a/spec/configuration/image_pull_spec.rb b/spec/configuration/image_pull_spec.rb index 1b77319cc0..e26f15854b 100644 --- a/spec/configuration/image_pull_spec.rb +++ b/spec/configuration/image_pull_spec.rb @@ -5,7 +5,7 @@ require 'yaml' TARGET_KINDS = %w[Deployment StatefulSet Job].freeze CONTAINER_TYPES = %w[initContainers containers].freeze EXTERNAL_CHARTS = %w[ - certmanager gitlab-runner postgresql prometheus redis nginx-ingress + certmanager gitlab-runner postgresql prometheus valkey nginx-ingress ].freeze def targeted_resource_kind?(resource) diff --git a/spec/configuration/kas_spec.rb b/spec/configuration/kas_spec.rb index 13e60491b6..0a760c5506 100644 --- a/spec/configuration/kas_spec.rb +++ b/spec/configuration/kas_spec.rb @@ -366,6 +366,8 @@ describe 'kas configuration' do describe 'redis config' do shared_examples 'mounts global redis secret' do it do + t = kas_enabled_template + expect(t.exit_code).to eq(0), "Unexpected error code #{t.exit_code} -- #{t.stderr}" kas_secret = kas_enabled_template.projected_volume_sources( 'Deployment/test-kas', 'init-etc-kas' @@ -455,7 +457,7 @@ describe 'kas configuration' do expect(config_yaml_data['redis']).to include(YAML.safe_load(%( database_index: 3 server: - address: test-redis-master.default.svc:6379 + address: test-valkey.default.svc.cluster.local:6379 ))) end end @@ -466,7 +468,7 @@ describe 'kas configuration' do database_index: 0 password_file: /etc/kas/redis/redis-password server: - address: test-redis-master.default.svc:6379 + address: test-valkey.default.svc.cluster.local:6379 ))) end @@ -477,7 +479,7 @@ describe 'kas configuration' do let(:kas_values) do vals = default_kas_values vals['global'].deep_merge!(sentinels) - vals.deep_merge!('redis' => { 'install' => false }) + vals.deep_merge!('installValkey' => false) end it_behaves_like 'mounts global redis secret' @@ -498,7 +500,7 @@ describe 'kas configuration' do let(:kas_values) do vals = default_kas_values vals['global'].deep_merge!(sentinels_database) - vals.deep_merge!('redis' => { 'install' => false }) + vals.deep_merge!('installValkey' => false) end it_behaves_like 'mounts global redis secret' @@ -519,7 +521,7 @@ describe 'kas configuration' do let(:kas_values) do vals = default_kas_values vals['global'].deep_merge!(sentinels) - vals.deep_merge!('redis' => { 'install' => false }) + vals.deep_merge!('installValkey' => false) vals.deep_merge!(YAML.safe_load(%( global: @@ -560,7 +562,7 @@ describe 'kas configuration' do vals = default_kas_values vals['global'].deep_merge!(redis_shared_state_config) vals['global'].deep_merge!(redis_kas_config) - vals.deep_merge!('redis' => { 'install' => false }) + vals.deep_merge!('installValkey' => false) end let(:redis_kas_config) { {} } diff --git a/spec/configuration/labels_spec.rb b/spec/configuration/labels_spec.rb index c6b87f43a8..98cd79c33c 100644 --- a/spec/configuration/labels_spec.rb +++ b/spec/configuration/labels_spec.rb @@ -22,9 +22,10 @@ describe 'Labels configuration' do 'Deployment/test-gitlab-runner', 'Deployment/test-prometheus-server', 'Deployment/test-minio', + 'Deployment/test-valkey', 'Deployment/test-nginx-ingress-controller', 'Deployment/test-nginx-ingress-default-backend', - # not included, StatefulSet: postgresql, redis, gitlab/gitaly + # not included, StatefulSet: postgresql, gitlab/gitaly ] end diff --git a/spec/configuration/mailroom_spec.rb b/spec/configuration/mailroom_spec.rb index fcdaeb5c14..82d5b16d1c 100644 --- a/spec/configuration/mailroom_spec.rb +++ b/spec/configuration/mailroom_spec.rb @@ -36,7 +36,7 @@ describe 'Mailroom configuration' do t = HelmTemplate.new(default_values) expect(t.exit_code).to eq(0) # check the default service name & password are used - expect(t.dig('ConfigMap/test-mailroom','data','mail_room.yml')).to include("test-redis-master.default.svc:6379") + expect(t.dig('ConfigMap/test-mailroom','data','mail_room.yml')).to include("test-valkey.default.svc.cluster.local:6379") # check the default secret is mounted projected_volume = t.projected_volume_sources('Deployment/test-mailroom','init-mailroom-secrets') redis_mount = projected_volume.select { |item| item['secret']['name'] == "test-redis-secret" } @@ -428,8 +428,7 @@ describe 'Mailroom configuration' do password: secret: redis-queues-secret key: redis-queues-key - redis: - install: false + installValkey: false )).deep_merge(default_values) end diff --git a/spec/configuration/node_selector_spec.rb b/spec/configuration/node_selector_spec.rb index 9e993f70d4..d37125a727 100644 --- a/spec/configuration/node_selector_spec.rb +++ b/spec/configuration/node_selector_spec.rb @@ -52,8 +52,8 @@ describe 'Node Selector configuration' do 'Job/test-certmanager-startupapicheck', 'Deployment/test-gitlab-runner', 'Deployment/test-prometheus-server', - 'StatefulSet/test-postgresql', - 'StatefulSet/test-redis-master' + 'Deployment/test-valkey', + 'StatefulSet/test-postgresql' ] end diff --git a/spec/configuration/priorityclass_spec.rb b/spec/configuration/priorityclass_spec.rb index 30d501654c..dee7456b66 100644 --- a/spec/configuration/priorityclass_spec.rb +++ b/spec/configuration/priorityclass_spec.rb @@ -6,6 +6,12 @@ require 'yaml' require 'hash_deep_merge' describe 'global priorityClass configuration' do + let(:ignored_deployments) do + [ + "Deployment/test-valkey" + ] + end + let(:default_values) do HelmTemplate.with_defaults(%( global: @@ -30,7 +36,7 @@ describe 'global priorityClass configuration' do t = HelmTemplate.new(default_values) expect(t.exit_code).to eq(0) - deployments = t.resources_by_kind('Deployment') + deployments = t.resources_by_kind('Deployment').reject { |key, _| ignored_deployments.include? key } deployments.each do |key, _| expect(t.dig(key, 'spec', 'template', 'spec', 'priorityClassName')).to eq('system-cluster-critical') @@ -176,7 +182,8 @@ describe 'local priorityClass configuration' do [ 'Deployment/test-certmanager', 'Deployment/test-certmanager-cainjector', - 'Deployment/test-certmanager-webhook' + 'Deployment/test-certmanager-webhook', + 'Deployment/test-valkey' ] end diff --git a/spec/configuration/redis_spec.rb b/spec/configuration/redis_spec.rb deleted file mode 100644 index 00ef31cc92..0000000000 --- a/spec/configuration/redis_spec.rb +++ /dev/null @@ -1,815 +0,0 @@ -require 'spec_helper' -require 'helm_template_helper' -require 'runtime_template_helper' -require 'yaml' - -describe 'Redis configuration' do - let(:default_values) do - HelmTemplate.defaults - end - - let(:template) { HelmTemplate.new(values) } - let(:resque_yml_erb) { template.dig('ConfigMap/test-webservice', 'data', 'resque.yml.erb') } - let(:resque_yml) { render_erb(resque_yml_erb) } - - def render_erb(raw_template) - yaml = RuntimeTemplate.erb(raw_template: raw_template, files: RuntimeTemplate.mock_files) - YAML.safe_load(yaml, aliases: true) - end - - describe 'global.redis.{connect,read,write}Timeout' do - context 'default values' do - let(:values) { default_values } - - it 'renders no timeout values' do - expect(template.exit_code).to eq(0), "Unexpected error code #{template.exit_code} -- #{template.stderr}" - expect(resque_yml["production"].keys).not_to include("connect_timeout", "read_timeout", "write_timeout") - end - end - - context 'timeouts set' do - let(:values) do - YAML.safe_load(%( - global: - redis: - connectTimeout: 3 - readTimeout: 4 - writeTimeout: 5 - )).deep_merge!(default_values) - end - - it 'renders {connect,read,write}_timeout values' do - expect(template.exit_code).to eq(0), "Unexpected error code #{template.exit_code} -- #{template.stderr}" - expect(resque_yml.dig('production', 'connect_timeout')).to eq(3) - expect(resque_yml.dig('production', 'read_timeout')).to eq(4) - expect(resque_yml.dig('production', 'write_timeout')).to eq(5) - end - end - - context 'custom redis database value' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - port: 6379 - database: 4 - redis: - install: false - )).deep_merge!(default_values) - end - - it 'configures Redis' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0), "Unexpected error code #{template.exit_code} -- #{template.stderr}" - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("resque.redis:6379/4") - end - end - end - - describe 'global.redis.auth.enabled' do - let(:values) do - YAML.safe_load(%( - global: - redis: - auth: - enabled: true - )).deep_merge!(default_values) - end - - context 'when true' do - it 'populate password' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("redis/redis-password") - end - end - - context 'when false' do - let(:values) do - YAML.safe_load(%( - global: - redis: - auth: - enabled: false - )).deep_merge!(default_values) - end - - it 'do not populate password' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).not_to include("redis/redis-password") - end - end - end - - describe 'global.redis.sentinelAuth.enabled' do - let(:values) do - YAML.safe_load(%( - global: - redis: - sentinelAuth: - enabled: true - )).deep_merge!(default_values) - end - - context 'when true' do - it 'populate password' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("redis-sentinel/redis-sentinel-password") - end - end - - context 'when false' do - let(:values) do - YAML.safe_load(%( - global: - redis: - senntinelAuth: - enabled: false - )).deep_merge!(default_values) - end - - it 'do not populate password' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).not_to include("redis-sentinel/redis-sentinel-password") - end - end - end - - describe 'redis.yml override' do - context 'when redisYmlOverride is set' do - context 'when redisYmlOverrideSecrets contains invalid secrets' do - let(:values) do - YAML.safe_load(%( - global: - redis: - redisYmlOverride: - chat: - secret: gitlab-redis-chat-credential-v2 - cache: - password: - enabled: true - secret: gitlab-redis-cache-credential-v2 - key: password - - redis: - install: false - )).deep_merge!(default_values) - end - - it 'skips render only for invalid secret' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - - projected_volume = t.projected_volume_sources('Deployment/test-webservice-default', 'init-webservice-secrets') - chat_mount = projected_volume.select { |item| item['secret']['name'] == "gitlab-redis-chat-credential-v2" } - cache_mount = projected_volume.select { |item| item['secret']['name'] == "gitlab-redis-cache-credential-v2" } - - expect(chat_mount.size).to eq(0) - expect(cache_mount.size).to eq(1) - - chat_mount = projected_volume.select { |item| item['secret']['name'] == "test-redis-secret" } - test_redis_secrets = YAML.safe_load(%( - - secret: - name: test-redis-secret - items: - - key: secret - path: redis/chat-override-password - - secret: - name: test-redis-secret - items: - - key: secret - path: redis/redis-password - )) - expect(chat_mount).to eq(test_redis_secrets) - end - end - - context 'when using both global.redis.redisYmlOverride.xxx and global.redis.xxx to define secrets' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: placeholder - cache: - host: gstg-redis-cache - password: - enabled: true - secret: gitlab-redis-cache-credential-v2 - key: password - redisYmlOverride: - cache: - host: gstg-redis-cache - password: - enabled: true - secret: gitlab-redis-cache-credential-v3 - key: password - redis: - install: false - )).deep_merge!(default_values) - end - - it 'renders both secret without namespace clash' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - - projected_volume = t.projected_volume_sources('Deployment/test-webservice-default', 'init-webservice-secrets') - cache_mount = projected_volume.select { |item| item['secret']['name'] == "gitlab-redis-cache-credential-v2" } - override_mount = projected_volume.select { |item| item['secret']['name'] == "gitlab-redis-cache-credential-v3" } - - # 2 mounts to different paths but same secret key to avoid user having to repeatedly define secrets - expect(cache_mount.size).to eq(1) - expect(override_mount.size).to eq(1) - expect(cache_mount.first['secret']['items'].first['path']).to eq("redis/cache-password") - expect(override_mount.first['secret']['items'].first['path']).to eq("redis/cache-override-password") - end - end - - context 'when redisYmlOverride contains disabled secrets' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: placeholder - cache: - host: gstg-redis-cache - password: - enabled: true - secret: gitlab-redis-cache-credential-v2 - key: password - redisYmlOverride: - dbLoadBalancing: - password: - enabled: false - secret: gitlab-redis-db-loadbalancing-rails-credential-v2 - key: password - chat: - password: - enabled: true - secret: gitlab-redis-cluster-chat-cache-rails-credential-v2 - key: password - redis: - install: false - )).deep_merge!(default_values) - end - - it 'renders custom enabled secrets as a volume alongside other secrets' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - - projected_volume = t.projected_volume_sources('Deployment/test-webservice-default', 'init-webservice-secrets') - cache_mount = projected_volume.select { |item| item['secret']['name'] == "gitlab-redis-cache-credential-v2" } - chat_mount = projected_volume.select { |item| item['secret']['name'] == "gitlab-redis-cluster-chat-cache-rails-credential-v2" } - dblb_mount = projected_volume.select { |item| item['secret']['name'] == "gitlab-redis-db-loadbalancing-rails-credential-v2" } - - expect(cache_mount.size).to eq(1) # override secrets show up in the same location - expect(chat_mount.size).to eq(1) # enabled secret - expect(dblb_mount.size).to eq(0) # disabled secret - - dblb_secret = projected_volume.select { |item| item['secret']['items'].first['path'] == "redis/dbLoadBalancing-override-password" } - expect(dblb_secret.size).to eq(0) # there should be no secret mounted to this path, because password is disabled - end - end - - context 'when rendering redis.yml.erb' do - let(:values) do - YAML.safe_load(%( - global: - redis: - redisYmlOverride: - queues: - host: gprd-redis-queues - password: <%= ERB::Util::url_encode(File.read(\"/etc/gitlab/redis/some-password\").strip) %> - chat: - host: gprd-redis-chat - password: - enabled: false - secret: gitlab-redis-chat-credentials-v2 - key: password - cache: - host: gprd-redis-cache - other_keys: - - node1 - - node2 - password: - enabled: true - secret: gitlab-redis-cache-credentials-v2 - key: password - - redis: - install: false - )).deep_merge!(default_values) - end - - it 'replaces password with ERB string where required' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - - actual = YAML.safe_load(t.dig('ConfigMap/test-webservice','data','redis.yml.erb')) - expect(actual).to eq( - { - 'production' => { - # enabled secret - 'cache' => { - 'host' => 'gprd-redis-cache', - 'password' => "<%= ERB::Util::url_encode(File.read(\"/etc/gitlab/redis/cache-override-password\").strip) %>", - 'other_keys' => %w[node1 node2] - }, - # disabled secret - 'chat' => { - 'host' => 'gprd-redis-chat' - }, - # password being a string - 'queues' => { - 'host' => 'gprd-redis-queues', - 'password' => "<%= ERB::Util::url_encode(File.read(\"/etc/gitlab/redis/some-password\").strip) %>" - } - } - }) - end - end - end - - context 'when redisYmlOverride is not set' do - let(:values) { default_values } - - it 'does not render a file' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - expect(t.dig('ConfigMap/test-webservice','data')).not_to include('redis.yml.erb') - end - end - - context 'When redis.install is true' do - let(:values) do - YAML.safe_load(%( - global: - redis: - redisYmlOverride: - foo: bar - redis: - install: true - )).deep_merge!(default_values) - end - - it 'fails to template (checkConfig)' do - t = HelmTemplate.new(values) - expect(t.exit_code).not_to eq(0) - end - end - - context 'when redis.install is false' do - let(:values) do - YAML.safe_load(%( - global: - redis: - redisYmlOverride: - foo: - bar: baz - bar: - baz: [1, 2, 3] - deeply: - nested: value - # ERB should pass through Helm without being evaluated - some: - password: <%= File.read('/path/to/password').chomp %> - redis: - install: false - )).deep_merge!(default_values) - end - - it 'renders arbitrary values' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - actual = YAML.safe_load(t.dig('ConfigMap/test-webservice','data','redis.yml.erb')) - expect(actual).to eq( - { - 'production' => values["global"]["redis"]["redisYmlOverride"] - } - ) - end - end - end - - describe 'Split Redis queues' do - context 'When redis.install is true' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - cache: - host: cache.redis - redis: - install: true - )).deep_merge!(default_values) - end - - it 'fails to template (checkConfig)' do - t = HelmTemplate.new(values) - expect(t.exit_code).not_to eq(0) - end - end - - context 'When sub-queue does not define password' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - auth: - secret: rspec-resque - cache: - host: cache.redis - redis: - install: false - )).deep_merge!(default_values) - end - - it 'sub-queue inherits all of password from global.redis' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("redis/redis-password") - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("resque.redis") - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).to include("redis/cache-password") - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).to include("cache.redis") - secret_mounts = t.projected_volume_sources('Deployment/test-webservice-default','init-webservice-secrets').select { |item| - item['secret']['name'] == 'rspec-resque' - } - expect(secret_mounts.length).to eq(2) - end - end - - context 'When sub-queue defines password.secret, but not password.enabled' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - auth: - secret: rspec-resque - cache: - host: cache.redis - password: - secret: rspec-cache - redis: - install: false - )).deep_merge!(default_values) - end - - it 'sub-queue inherits from global' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - projected_volume = t.projected_volume_sources('Deployment/test-webservice-default','init-webservice-secrets') - redis_mount = projected_volume.select { |item| item['secret']['name'] == "rspec-resque" } - cache_mount = projected_volume.select { |item| item['secret']['name'] == "rspec-cache" } - # check that it gets consumed - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("redis/redis-password") - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).to include("redis/cache-password") - # check that they are individually mounted. - expect(redis_mount.length).to eq(1) - expect(cache_mount.length).to eq(1) - end - end - - context 'When sub-queue defines password.enabled true, and redis.password.enabled is false' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - auth: - enabled: false - secret: rspec-resque - cache: - host: cache.redis - password: - enabled: true - secret: rspec-cache - redis: - install: false - )).deep_merge!(default_values) - end - - it 'sub-queue uses password, global does not' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - projected_volume = t.projected_volume_sources('Deployment/test-webservice-default','init-webservice-secrets') - redis_mount = projected_volume.select { |item| item['secret']['name'] == "rspec-resque" } - cache_mount = projected_volume.select { |item| item['secret']['name'] == "rspec-cache" } - # check that it gets consumed - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).not_to include("redis/redis-password") - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).to include("redis/cache-password") - # check that they are individually mounted. - expect(redis_mount.length).to eq(0) - expect(cache_mount.length).to eq(1) - end - end - - context 'When sub-queue defines password.enabled false, and redis.password.enabled is true' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - auth: - enabled: true - secret: rspec-resque - cache: - host: cache.redis - password: - enabled: false - secret: rspec-cache - redis: - install: false - )).deep_merge!(default_values) - end - - it 'sub-queue does not use password, global does' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - projected_volume = t.projected_volume_sources('Deployment/test-webservice-default','init-webservice-secrets') - redis_mount = projected_volume.select { |item| item['secret']['name'] == "rspec-resque" } - cache_mount = projected_volume.select { |item| item['secret']['name'] == "rspec-cache" } - # check that it gets consumed - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("redis/redis-password") - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).not_to include("redis/cache-password") - # check that they are individually mounted. - expect(redis_mount.length).to eq(1) - expect(cache_mount.length).to eq(0) - end - end - - context 'When global defines user' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - user: resque-user - auth: - enabled: true - secret: rspec-resque - cache: - host: cache.redis - redis: - install: false - )).deep_merge!(default_values) - end - - it 'global uses user' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - # check that it gets correct hosts & port are used - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("resque-user") - end - end - - context 'When sub-queue defines port, but not host' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - port: 6379 - cache: - port: 9999 - redis: - install: false - )).deep_merge!(default_values) - end - - it 'sub-queue uses port, global host' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - # check that it gets correct hosts & port are used - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("resque.redis:6379") - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).to include("resque.redis:9999") - end - end - - context 'When global and sub-queue defines Sentinels' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - port: 6379 - sentinels: - - host: s1.resque.redis - port: 26379 - - host: s2.resque.redis - port: 26379 - cache: - host: cache.redis - sentinels: - - host: s1.cache.redis - port: 26379 - - host: s2.cache.redis - port: 26379 - redis: - install: false - )).deep_merge!(default_values) - end - - it 'separate sentinels are populated' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - # check that it they consumed only in sub-queue - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("sentinels:") - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("s1.resque.redis") - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).to include("sentinels:") - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).to include("s1.cache.redis") - end - end - - context 'When only sub-queue defines Sentinels' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - port: 6379 - cache: - host: cache.redis - sentinels: - - host: s1.cache.redis - port: 26379 - - host: s2.cache.redis - port: 26379 - redis: - install: false - )).deep_merge!(default_values) - end - - it 'sub-queue sentinels are populated' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - # check that it they consumed only in sub-queue - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).not_to include("sentinels:") - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).to include("sentinels:") - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).to include("s1.cache.redis") - end - end - end - - describe 'Redis Cluster' do - context 'When only nested redis defines cluster' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - cache: - host: cache.redis - sentinels: - - host: s1.cache.redis - - host: s2.cache.redis - clusterCache: - cluster: - - host: s1.cluster-cache.redis - - host: s2.cluster-cache.redis - redis: - install: false - )).deep_merge!(default_values) - end - - it 'Only nested redis cluster is populated' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).to include("sentinels:") - expect(t.dig('ConfigMap/test-webservice','data','redis.cache.yml.erb')).to include("s1.cache.redis") - expect(t.dig('ConfigMap/test-webservice','data','redis.cluster_cache.yml.erb')).to include("cluster:") - expect(t.dig('ConfigMap/test-webservice','data','redis.cluster_cache.yml.erb')).to include("s1.cluster-cache.redis") - end - end - - context 'When only nested redis defines cluster, user, and password' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - auth: - enabled: false - clusterCache: - user: cluster-cache-user - password: - enabled: true - cluster: - - host: s1.cluster-cache.redis - - host: s2.cluster-cache.redis - redis: - install: false - )).deep_merge!(default_values) - end - - it 'Only nested redis cluster is populated' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).not_to include("cluster-cache-user") - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).not_to include("redis/redis-password") - expect(t.dig('ConfigMap/test-webservice','data','redis.cluster_cache.yml.erb')).to include("cluster:") - expect(t.dig('ConfigMap/test-webservice','data','redis.cluster_cache.yml.erb')).to include("s1.cluster-cache.redis") - expect(t.dig('ConfigMap/test-webservice','data','redis.cluster_cache.yml.erb')).to include("cluster-cache-user") - expect(t.dig('ConfigMap/test-webservice','data','redis.cluster_cache.yml.erb')).to include("redis/clusterCache-password") - end - end - - context 'When timeouts are defined' do - let(:values) do - YAML.safe_load(%( - global: - redis: - connectTimeout: 3 - readTimeout: 4 - writeTimeout: 5 - host: resque.redis - auth: - enabled: false - clusterCache: - user: cluster-cache-user - password: - enabled: true - cluster: - - host: s1.cluster-cache.redis - - host: s2.cluster-cache.redis - redis: - install: false - )).deep_merge!(default_values) - end - - let(:redis_cluster_yml_erb) { template.dig('ConfigMap/test-webservice', 'data', 'redis.cluster_cache.yml.erb') } - let(:redis_cluster_yml) { render_erb(redis_cluster_yml_erb) } - - it 'timeouts are populated' do - expect(template.exit_code).to eq(0), "Unexpected error code #{template.exit_code} -- #{template.stderr}" - expect(redis_cluster_yml.dig('production', 'connect_timeout')).to eq(3) - expect(redis_cluster_yml.dig('production', 'read_timeout')).to eq(4) - expect(redis_cluster_yml.dig('production', 'write_timeout')).to eq(5) - end - end - - context 'When top level user and password are defined' do - let(:values) do - YAML.safe_load(%( - global: - redis: - host: resque.redis - user: resque-user - auth: - enabled: true - clusterCache: - cluster: - - host: s1.cluster-cache.redis - - host: s2.cluster-cache.redis - redis: - install: false - )).deep_merge!(default_values) - end - - it 'No values are inherited by nested redis cluster' do - t = HelmTemplate.new(values) - expect(t.exit_code).to eq(0) - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("resque-user") - expect(t.dig('ConfigMap/test-webservice','data','resque.yml.erb')).to include("redis/redis-password") - expect(t.dig('ConfigMap/test-webservice','data','redis.cluster_cache.yml.erb')).to include("cluster:") - expect(t.dig('ConfigMap/test-webservice','data','redis.cluster_cache.yml.erb')).to include("s1.cluster-cache.redis") - expect(t.dig('ConfigMap/test-webservice','data','redis.cluster_cache.yml.erb')).not_to include("resque-user") - expect(t.dig('ConfigMap/test-webservice','data','redis.cluster_cache.yml.erb')).not_to include("redis/redis-password") - expect(t.dig('ConfigMap/test-webservice','data','redis.cluster_cache.yml.erb')).not_to include("redis/cluster-cache-password") - end - end - end - - describe 'Generated Kubernetes object names' do - context 'Helm release name does not include "redis"' do - it 'Objects are suffixed with "-redis", references match' do - # run template, default release name is 'test' - t = HelmTemplate.new(default_values) - expect(t.exit_code).to eq(0) - # check that Services are -redis-master - expect(t.dig('Service/test-master')).to be_falsey - expect(t.dig('Service/test-redis-master')).to be_truthy - # check resque.yml - expect(t.dig('ConfigMap/test-toolbox','data','resque.yml.erb')).to include('test-redis-master') - end - end - - context 'Helm release name includes "redis"' do - it 'Objects are suffixed without "-redis", references match' do - # run template, pass release name with "redis" in it - t = HelmTemplate.new(default_values,'redis-test') - expect(t.exit_code).to eq(0) - # check that Services are -master - expect(t.dig('Service/redis-test-master')).to be_truthy - expect(t.dig('Service/redis-test-redis-master')).to be_falsey - # check resque.yml is pointing to the right service. - expect(t.dig('ConfigMap/redis-test-toolbox','data','resque.yml.erb')).to include('redis-test-master') - end - end - end -end diff --git a/spec/configuration/strategy_spec.rb b/spec/configuration/strategy_spec.rb index 6bcfa82dc4..349f33e268 100644 --- a/spec/configuration/strategy_spec.rb +++ b/spec/configuration/strategy_spec.rb @@ -105,7 +105,7 @@ describe 'Strategy configuration' do 'Deployment/test-toolbox', 'Deployment/test-minio', 'Deployment/test-gitlab-runner', - 'StatefulSet/test-redis-master', + 'Deployment/test-valkey', 'StatefulSet/test-postgresql' ] end diff --git a/spec/configuration/topology_spread_constraints_spec.rb b/spec/configuration/topology_spread_constraints_spec.rb index 25cf825bb5..6c4451b359 100644 --- a/spec/configuration/topology_spread_constraints_spec.rb +++ b/spec/configuration/topology_spread_constraints_spec.rb @@ -20,6 +20,7 @@ describe 'local topologySpreadConstraints configuration' do 'Deployment/test-cert-manager-webhook', 'Deployment/test-gitlab-runner', 'Deployment/test-minio', + 'Deployment/test-valkey', 'Deployment/test-nginx-ingress-controller', 'Deployment/test-prometheus-server', 'Deployment/test-gitlab-exporter' diff --git a/spec/configuration/workhorse_spec.rb b/spec/configuration/workhorse_spec.rb index 91294f9d0f..88a9df5a07 100644 --- a/spec/configuration/workhorse_spec.rb +++ b/spec/configuration/workhorse_spec.rb @@ -190,8 +190,7 @@ CFG auth: enabled: true secret: global-secret - redis: - install: false + installValkey: false )).deep_merge!(default_values) end @@ -222,8 +221,7 @@ CFG auth: enabled: true secret: global-secret - redis: - install: false + installValkey: false )).deep_merge!(default_values) end @@ -258,8 +256,7 @@ CFG password: enabled: true secret: workhorse - redis: - install: false + installValkey: false )).deep_merge!(default_values) end @@ -305,8 +302,7 @@ CFG enabled: true secret: global-secret user: redis-user - redis: - install: false + installValkey: false )).deep_merge!(default_values) it "adds the username to the URL" do @@ -342,8 +338,7 @@ CFG enabled: true secret: workhorse user: workhorse-redis-user - redis: - install: false + installValkey: false )).deep_merge!(default_values) end @@ -382,8 +377,7 @@ CFG password: enabled: true secret: workhorse - redis: - install: false + installValkey: false )).deep_merge!(default_values) end @@ -467,8 +461,7 @@ CFG enabled: true secret: workhorse-redis-sentinel-secret key: password - redis: - install: false + installValkey: false )).deep_merge!(default_values) end diff --git a/spec/integration/check_config_spec.rb b/spec/integration/check_config_spec.rb index 3068c65c2b..f9afb18b4c 100644 --- a/spec/integration/check_config_spec.rb +++ b/spec/integration/check_config_spec.rb @@ -16,18 +16,16 @@ describe 'checkConfig template' do error_description: 'when unset' end - describe 'multipleRedis' do + describe 'multiple Valkey/Redis' do let(:success_values) do YAML.safe_load(%( - redis: - install: true + installValkey: true )).deep_merge!(default_required_values) end let(:error_values) do YAML.safe_load(%( - redis: - install: true + installValkey: true global: redis: cache: @@ -35,7 +33,7 @@ describe 'checkConfig template' do )).deep_merge!(default_required_values) end - let(:error_output) { 'If configuring multiple Redis servers, you can not use the in-chart Redis server' } + let(:error_output) { 'If configuring multiple Redis servers, you can not use the in-chart Valkey/Redis server' } include_examples 'config validation', success_description: 'when Redis is set to install with a single Redis instance', diff --git a/templates/_checkConfig.tpl b/templates/_checkConfig.tpl index f8677cf8e1..6bc02b7c6c 100644 --- a/templates/_checkConfig.tpl +++ b/templates/_checkConfig.tpl @@ -147,7 +147,7 @@ Ensure that `redis.install: false` if configuring multiple Redis instances {{- end -}} {{- if and .Values.installValkey ( lt 0 $x.count ) }} redis: - If configuring multiple Redis servers, you can not use the in-chart Redis/Valkey server. Please see https://docs.gitlab.com/charts/charts/globals#configure-redis-settings + If configuring multiple Redis servers, you can not use the in-chart Valkey/Redis server. Please see https://docs.gitlab.com/charts/charts/globals#configure-redis-settings {{- end -}} {{- end -}} {{/* END gitlab.checkConfig.multipleRedis */}} @@ -158,7 +158,7 @@ Ensure that `redis.install: false` if using redis.yml override {{- define "gitlab.checkConfig.redisYmlOverride" -}} {{- if and .Values.installValkey ( hasKey .Values.global.redis "redisYmlOverride" ) }} redis: - When you override redis.yml you can not use the in-chart Redis server. Please see https://docs.gitlab.com/charts/charts/globals#configure-redis-settings + When you override redis.yml you can not use the in-chart Valkey/Redis server. Please see https://docs.gitlab.com/charts/charts/globals#configure-redis-settings {{- end -}} {{- end -}} {{/* END gitlab.checkConfig.redisYmlOverride */}} -- GitLab