From 73588ad0a07599e38572a9ac42c905c6c6a3d26a Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 31 May 2024 14:14:48 -0700 Subject: [PATCH 1/7] First iteration of Sentinel password support --- .../gitlab-exporter/templates/configmap.yaml | 1 + .../gitlab-exporter/templates/deployment.yaml | 1 + .../webservice/templates/deployment.yaml | 1 + charts/gitlab/templates/_redis.tpl | 62 ++++++++++++++++-- spec/configuration/gitlab_exporter_spec.rb | 63 +++++++++++++++++++ spec/runtime_template_helper.rb | 1 + templates/_redis.tpl | 45 +++++++++++++ values.yaml | 4 ++ 8 files changed, 174 insertions(+), 4 deletions(-) diff --git a/charts/gitlab/charts/gitlab-exporter/templates/configmap.yaml b/charts/gitlab/charts/gitlab-exporter/templates/configmap.yaml index ea5e66ba23..68867500fa 100644 --- a/charts/gitlab/charts/gitlab-exporter/templates/configmap.yaml +++ b/charts/gitlab/charts/gitlab-exporter/templates/configmap.yaml @@ -57,6 +57,7 @@ data: {{- if $sentinels }} redis_sentinels: {{- $sentinels | nindent 12 }} + redis_sentinel_password: "{{ include "gitlab.redis.sentinel.password" . }}" {{- end }} ruby: &ruby diff --git a/charts/gitlab/charts/gitlab-exporter/templates/deployment.yaml b/charts/gitlab/charts/gitlab-exporter/templates/deployment.yaml index 70f6581ecb..8dbc8024d6 100644 --- a/charts/gitlab/charts/gitlab-exporter/templates/deployment.yaml +++ b/charts/gitlab/charts/gitlab-exporter/templates/deployment.yaml @@ -153,6 +153,7 @@ spec: {{- include "gitlab.psql.secret" . | nindent 10 }} {{- end }} {{- include "gitlab.redis.secret" . | nindent 10 }} + {{- include "gitlab.redisSentinel.secret" . | nindent 10 }} {{ if .Values.tls.enabled }} - secret: name: {{ template "gitlab.gitlab-exporter.tls.secret" . }} diff --git a/charts/gitlab/charts/webservice/templates/deployment.yaml b/charts/gitlab/charts/webservice/templates/deployment.yaml index 24c24b5d49..38e18ce346 100644 --- a/charts/gitlab/charts/webservice/templates/deployment.yaml +++ b/charts/gitlab/charts/webservice/templates/deployment.yaml @@ -494,6 +494,7 @@ spec: {{- include "gitlab.clickhouse.main.secrets" $ | nindent 10 }} {{- end }} {{- include "gitlab.redis.secrets" (dict "globalContext" $) | nindent 10 }} + {{- include "gitlab.redisSentinel.secrets" (dict "globalContext" $) | nindent 10 }} {{- range $.Values.local.psql }} {{- include "gitlab.psql.secret" . | nindent 10 }} {{- end }} diff --git a/charts/gitlab/templates/_redis.tpl b/charts/gitlab/templates/_redis.tpl index 124f160f2e..1004ca3c2c 100644 --- a/charts/gitlab/templates/_redis.tpl +++ b/charts/gitlab/templates/_redis.tpl @@ -69,6 +69,15 @@ Return the password section of the Redis URI, if needed. {{- if .redisMergedConfig.password.enabled -}}:<%= ERB::Util::url_encode(File.read("/etc/gitlab/redis/{{ $password }}").strip) %>@{{- end -}} {{- end -}} +{{/* +Return the Sentinel password, if available. +*/}} +{{- define "gitlab.redis.sentinel.password" -}} +{{- include "gitlab.redis.configMerge" . -}} +{{- $password := printf "%s-%ssentinel-password" (default "redis" .redisConfigName) (ternary "override-" "" (default false .usingOverride)) -}} +{{- if .redisMergedConfig.sentinelPassword.enabled -}}<%= File.read("/etc/gitlab/redis-sentinel/{{ $password }}").strip %>{{- end -}} +{{- end -}} + {{/* Build the structure describing sentinels */}} @@ -99,12 +108,22 @@ sentinels: {{- end -}} {{- if not (kindIs "map" (get $.redisMergedConfig "password")) -}} {{- $_ := set $.redisMergedConfig "password" $.Values.global.redis.auth -}} -{{- end -}} -{{- range $key := keys $.Values.global.redis.auth -}} -{{- if not (hasKey $.redisMergedConfig.password $key) -}} -{{- $_ := set $.redisMergedConfig.password $key (index $.Values.global.redis.auth $key) -}} +{{- else -}} +{{- range $key := keys $.Values.global.redis.auth -}} +{{- if not (hasKey $.redisMergedConfig.password $key) -}} +{{- $_ := set $.redisMergedConfig.password $key (index $.Values.global.redis.auth $key) -}} +{{- end -}} {{- end -}} {{- end -}} +{{- if not (kindIs "map" (get $.redisMergedConfig "sentinelPassword")) -}} +{{- $_ := set $.redisMergedConfig "sentinelPassword" $.Values.global.redis.sentinelPassword -}} +{{- else -}} +{{- range $key := keys $.Values.global.redis.sentinelPassword -}} +{{- if not (hasKey $.redisMergedConfig.sentinelPassword $key) -}} +{{- $_ := set $.redisMergedConfig.sentinelPassword $key (index $.Values.global.redis.sentinelPassword $key) -}} +{{- end -}} +{{- end -}} +{{- end -}} {{- end -}} {{/* @@ -174,3 +193,38 @@ instances. {{- end }} {{- end -}} +{{/* +Takes a dict with `globalContext` and `instances` as keys. The former specifies +the root context `$`, and the latter a list of instances to mount secrets for. +If instances is not specified, we mount secrets for all enabled Redis +instances. +*/}} +{{- define "gitlab.redisSentinel.secrets" -}} +{{- $ := .globalContext }} +{{- $mountRedisYmlOverrideSecrets := true }} +{{- if hasKey . "mountRedisYmlOverrideSecrets" }} +{{- $mountRedisYmlOverrideSecrets = .mountRedisYmlOverrideSecrets }} +{{- end }} +{{- $redisInstances := list "cache" "clusterCache" "sharedState" "queues" "actioncable" "traceChunks" "rateLimiting" "clusterRateLimiting" "sessions" "repositoryCache" "workhorse" }} +{{- if .instances }} +{{- $redisInstances = splitList " " .instances }} +{{- end }} +{{- range $redis := $redisInstances -}} +{{- if index $.Values.global.redis $redis -}} +{{- $_ := set $ "redisConfigName" $redis }} +{{ include "gitlab.redisSentinel.secret" $ }} +{{- end }} +{{- end -}} +{{- end -}} + +{{- define "gitlab.redisSentinel.secret" -}} +{{- include "gitlab.redis.configMerge" . -}} +{{- if .redisMergedConfig.sentinelPassword.enabled }} +{{- $passwordPath := printf "%s-%ssentinel-password" (default "redis" .redisConfigName) (ternary "override-" "" (default false .usingOverride)) -}} +- secret: + name: {{ template "gitlab.redis.sentinelPassword.secret" . }} + items: + - key: {{ template "gitlab.redis.sentinelPassword.key" . }} + path: redis-sentinel/{{ $passwordPath }} +{{- end }} +{{- end -}} diff --git a/spec/configuration/gitlab_exporter_spec.rb b/spec/configuration/gitlab_exporter_spec.rb index 45dc35ddd9..d78d1ffd86 100644 --- a/spec/configuration/gitlab_exporter_spec.rb +++ b/spec/configuration/gitlab_exporter_spec.rb @@ -107,6 +107,69 @@ describe 'gitlab-exporter configuration' do { 'host' => 'sentinel2.example.com', 'port' => 26379 } ]) end + + context 'with Sentinel password as string' do + let(:sentinel_password) { 'my-sentinel-pass' } + let(:values) do + YAML.safe_load(%( + global: + redis: + host: global.host + sentinels: + - host: sentinel1.example.com + port: 26379 + - host: sentinel2.example.com + port: 26379 + sentinelPassword: #{sentinel_password} + )).deep_merge(default_values) + end + + it 'configures Sentinels with password' 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}@global.host:6379") + expect(sidekiq_config['opts']['redis_sentinels']).to eq( + [ + { 'host' => 'sentinel1.example.com', 'port' => 26379, 'password' => sentinel_password }, + { 'host' => 'sentinel2.example.com', 'port' => 26379, 'password' => sentinel_password } + ]) + end + end + + context 'with Sentinel password as secret' do + let(:values) do + YAML.safe_load(%( + global: + redis: + host: global.host + sentinels: + - host: sentinel1.example.com + port: 26379 + - host: sentinel2.example.com + port: 26379 + sentinelPassword: + enabled: true + secret: test-redis-sentinel-secret + key: password + )).deep_merge(default_values) + end + + let(:volumes) { template.dig('Deployment/test-gitlab-exporter', 'spec', 'template', 'spec', 'volumes') } + let(:secret_volumes) { volumes.find { |volume| volume['name'] == 'init-gitlab-exporter-secrets' } } + let(:secret_names) { secret_volumes.dig('projected', 'sources').map { |source| source['secret'] }.map { |secret| secret['name'] } } + + it 'configures Sentinels with password' 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}@global.host:6379") + expect(sidekiq_config['opts']['redis_sentinel_password']).to eq(RuntimeTemplate::JUNK_PASSWORD) + expect(sidekiq_config['opts']['redis_sentinels']).to eq( + [ + { 'host' => 'sentinel1.example.com', 'port' => 26379 }, + { 'host' => 'sentinel2.example.com', 'port' => 26379 } + ]) + + expect(secret_names).to include('test-redis-sentinel-secret') + end + end end context 'When customer enables TLS' do diff --git a/spec/runtime_template_helper.rb b/spec/runtime_template_helper.rb index 28a2e8cd7b..01448c02bd 100644 --- a/spec/runtime_template_helper.rb +++ b/spec/runtime_template_helper.rb @@ -72,6 +72,7 @@ class RuntimeTemplate "#{path}/postgres/psql-password-main" => JUNK_PASSWORD, "#{path}/postgres/psql-password-ci" => JUNK_PASSWORD, "#{path}/redis/redis-password" => JUNK_PASSWORD, + "#{path}/redis-sentinel/redis-sentinel-password" => JUNK_PASSWORD, "#{path}/gitaly/gitaly_token" => JUNK_TOKEN, # registry notification has a special format ... "#{path}/registry/notificationSecret" => "[#{JUNK_TOKEN}]", diff --git a/templates/_redis.tpl b/templates/_redis.tpl index 17405e25f1..7b9eeecc81 100644 --- a/templates/_redis.tpl +++ b/templates/_redis.tpl @@ -32,6 +32,25 @@ Build a dict of redis configuration {{- $_ := set $.redisMergedConfig.password $key (index $.Values.global.redis.auth $key) -}} {{- end -}} {{- end -}} + +{{- $hasOverrideSentinelSecret := false -}} +{{- if and $.Values.global.redis.redisYmlOverride $.redisConfigName -}} +{{- $hasOverrideSentinelSecret = (kindIs "map" (dig $.redisConfigName "sentinel_password" "" $.Values.global.redis.redisYmlOverride)) -}} +{{- end -}} +{{- if and $hasOverrideSentinelSecret $.usingOverride -}} +{{- $_ := set $.redisMergedConfig "sentinelPassword" (get (index $.Values.global.redis.redisYmlOverride $.redisConfigName) "sentinel_password") -}} +{{- else if kindIs "map" (get (index $.Values.global.redis $.redisConfigName) "sentinelPassword") -}} +{{- $_ := set $.redisMergedConfig "sentinelPassword" (get (index $.Values.global.redis $.redisConfigName) "sentinelPassword") -}} +{{- else if (kindIs "map" (get $.Values.global.redis "sentinelPassword")) -}} +{{- $_ := set $.redisMergedConfig "sentinelPassword" (get $.Values.global.redis "sentinelPassword") -}} +{{- else -}} +{{- $_ := set $.redisMergedConfig "sentinelPassword" $.Values.global.redis.auth -}} +{{- end -}} +{{- range $key := keys $.Values.global.redis.sentinelPassword -}} +{{- if not (hasKey $.redisMergedConfig.sentinelPassword $key) -}} +{{- $_ := set $.redisMergedConfig.sentinelPassword $key (index $.Values.global.redis.sentinelPassword $key) -}} +{{- end -}} +{{- end -}} {{- end -}} {{/* @@ -59,3 +78,29 @@ global.redis.auth.enabled {{- include "gitlab.redis.configMerge" . -}} {{ ternary "true" "" .redisMergedConfig.password.enabled }} {{- end -}} + +{{/* +Return the redis sentinel password secret name +*/}} +{{- define "gitlab.redis.sentinelPassword.secret" -}} +{{- include "gitlab.redis.configMerge" . -}} +{{- default (printf "%s-redis-sentinel-secret" .Release.Name) .redisMergedConfig.sentinelPassword.secret | quote -}} +{{- end -}} + +{{/* +Return the redis password secret key +*/}} +{{- define "gitlab.redis.sentinelPassword.key" -}} +{{- include "gitlab.redis.configMerge" . -}} +{{- default "secret" .redisMergedConfig.sentinelPassword.key | quote -}} +{{- end -}} + +{{/* +Return a merged setting between global.redis.sentinelPassword.enabled, +global.redis.[subkey/"redisConfigName"].sentinelPassword.enabled, or +global.redis.auth.enabled +*/}} +{{- define "gitlab.redis.sentinelPassword.enabled" -}} +{{- include "gitlab.redis.configMerge" . -}} +{{ ternary "true" "" .redisMergedConfig.sentinelPassword.enabled }} +{{- end -}} diff --git a/values.yaml b/values.yaml index b79f3bba78..2803e80943 100644 --- a/values.yaml +++ b/values.yaml @@ -173,6 +173,10 @@ global: # sentinels: # - host: # port: + # sentinelPassword: + # enabled: true + # secret: redis-sentinel-password + # key: password ## https://docs.gitlab.com/charts/charts/globals#configure-gitaly-settings gitaly: -- GitLab From 7c2ba8c68a04eb5008331db9d01c689992e064d2 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 31 May 2024 15:42:31 -0700 Subject: [PATCH 2/7] Rename sentinelPassword to sentinelAuth to be consistent Plus this makes it easier to add `sentinel_username` support later. --- charts/gitlab/templates/_redis.tpl | 19 ++++----- spec/configuration/gitlab_exporter_spec.rb | 29 +------------ templates/_redis.tpl | 49 +++++++++++++--------- values.yaml | 8 ++-- 4 files changed, 43 insertions(+), 62 deletions(-) diff --git a/charts/gitlab/templates/_redis.tpl b/charts/gitlab/templates/_redis.tpl index 1004ca3c2c..1014766468 100644 --- a/charts/gitlab/templates/_redis.tpl +++ b/charts/gitlab/templates/_redis.tpl @@ -75,7 +75,7 @@ Return the Sentinel password, if available. {{- define "gitlab.redis.sentinel.password" -}} {{- include "gitlab.redis.configMerge" . -}} {{- $password := printf "%s-%ssentinel-password" (default "redis" .redisConfigName) (ternary "override-" "" (default false .usingOverride)) -}} -{{- if .redisMergedConfig.sentinelPassword.enabled -}}<%= File.read("/etc/gitlab/redis-sentinel/{{ $password }}").strip %>{{- end -}} +{{- if .redisMergedConfig.sentinelAuth.enabled -}}<%= File.read("/etc/gitlab/redis-sentinel/{{ $password }}").strip %>{{- end -}} {{- end -}} {{/* @@ -115,13 +115,10 @@ sentinels: {{- end -}} {{- end -}} {{- end -}} -{{- if not (kindIs "map" (get $.redisMergedConfig "sentinelPassword")) -}} -{{- $_ := set $.redisMergedConfig "sentinelPassword" $.Values.global.redis.sentinelPassword -}} -{{- else -}} -{{- range $key := keys $.Values.global.redis.sentinelPassword -}} -{{- if not (hasKey $.redisMergedConfig.sentinelPassword $key) -}} -{{- $_ := set $.redisMergedConfig.sentinelPassword $key (index $.Values.global.redis.sentinelPassword $key) -}} -{{- end -}} +{{/* Set redisMergedConfig.sentinelAuth. */}} +{{- range $key := keys $.Values.global.redis.sentinelAuth -}} +{{- if not (hasKey $.redisMergedConfig.sentinelAuth $key) -}} +{{- $_ := set $.redisMergedConfig.sentinelAuth $key (index $.Values.global.redis.sentinelAuth $key) -}} {{- end -}} {{- end -}} {{- end -}} @@ -219,12 +216,12 @@ instances. {{- define "gitlab.redisSentinel.secret" -}} {{- include "gitlab.redis.configMerge" . -}} -{{- if .redisMergedConfig.sentinelPassword.enabled }} +{{- if .redisMergedConfig.sentinelAuth.enabled }} {{- $passwordPath := printf "%s-%ssentinel-password" (default "redis" .redisConfigName) (ternary "override-" "" (default false .usingOverride)) -}} - secret: - name: {{ template "gitlab.redis.sentinelPassword.secret" . }} + name: {{ template "gitlab.redis.sentinelAuth.secret" . }} items: - - key: {{ template "gitlab.redis.sentinelPassword.key" . }} + - key: {{ template "gitlab.redis.sentinelAuth.key" . }} path: redis-sentinel/{{ $passwordPath }} {{- end }} {{- end -}} diff --git a/spec/configuration/gitlab_exporter_spec.rb b/spec/configuration/gitlab_exporter_spec.rb index d78d1ffd86..670534cee4 100644 --- a/spec/configuration/gitlab_exporter_spec.rb +++ b/spec/configuration/gitlab_exporter_spec.rb @@ -108,33 +108,6 @@ describe 'gitlab-exporter configuration' do ]) end - context 'with Sentinel password as string' do - let(:sentinel_password) { 'my-sentinel-pass' } - let(:values) do - YAML.safe_load(%( - global: - redis: - host: global.host - sentinels: - - host: sentinel1.example.com - port: 26379 - - host: sentinel2.example.com - port: 26379 - sentinelPassword: #{sentinel_password} - )).deep_merge(default_values) - end - - it 'configures Sentinels with password' 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}@global.host:6379") - expect(sidekiq_config['opts']['redis_sentinels']).to eq( - [ - { 'host' => 'sentinel1.example.com', 'port' => 26379, 'password' => sentinel_password }, - { 'host' => 'sentinel2.example.com', 'port' => 26379, 'password' => sentinel_password } - ]) - end - end - context 'with Sentinel password as secret' do let(:values) do YAML.safe_load(%( @@ -146,7 +119,7 @@ describe 'gitlab-exporter configuration' do port: 26379 - host: sentinel2.example.com port: 26379 - sentinelPassword: + sentinelAuth: enabled: true secret: test-redis-sentinel-secret key: password diff --git a/templates/_redis.tpl b/templates/_redis.tpl index 7b9eeecc81..f1864e56d3 100644 --- a/templates/_redis.tpl +++ b/templates/_redis.tpl @@ -33,22 +33,33 @@ Build a dict of redis configuration {{- end -}} {{- end -}} +{{/* +Build a dict of Redis Sentinel configuration + +- redisYmlOverride is used by GitLab Rails, which uses the redis-rb gem (https://github.com/redis/redis-rb). +- The code below maps `sentinel_password` to the `sentinelAuth` structure. +- redis-rb v5 specifies `sentinel_password` and `sentinel_username` as parameters. +- Note that both redis-rb v4 and v5 can pass `password` and `username` as parameters in the Sentinel host list as well. +- We use `global.redis.sentinelAuth` to be consistent with `global.redis.auth`. +- Currently GitLab doesn't support Redis usernames, but this will likely be needed in the future. + This could be done by introducing `global.redis.sentinelAuth.usernameKey` and `sentinel_username` in redisYmlOverride. +*/}} {{- $hasOverrideSentinelSecret := false -}} {{- if and $.Values.global.redis.redisYmlOverride $.redisConfigName -}} {{- $hasOverrideSentinelSecret = (kindIs "map" (dig $.redisConfigName "sentinel_password" "" $.Values.global.redis.redisYmlOverride)) -}} {{- end -}} {{- if and $hasOverrideSentinelSecret $.usingOverride -}} -{{- $_ := set $.redisMergedConfig "sentinelPassword" (get (index $.Values.global.redis.redisYmlOverride $.redisConfigName) "sentinel_password") -}} -{{- else if kindIs "map" (get (index $.Values.global.redis $.redisConfigName) "sentinelPassword") -}} -{{- $_ := set $.redisMergedConfig "sentinelPassword" (get (index $.Values.global.redis $.redisConfigName) "sentinelPassword") -}} -{{- else if (kindIs "map" (get $.Values.global.redis "sentinelPassword")) -}} -{{- $_ := set $.redisMergedConfig "sentinelPassword" (get $.Values.global.redis "sentinelPassword") -}} +{{- $_ := set $.redisMergedConfig "sentinelAuth" (get (index $.Values.global.redis.redisYmlOverride $.redisConfigName) "sentinel_password") -}} +{{- else if kindIs "map" (get (index $.Values.global.redis $.redisConfigName) "sentinelAuth") -}} +{{- $_ := set $.redisMergedConfig "sentinelAuth" (get (index $.Values.global.redis $.redisConfigName) "sentinelAuth") -}} +{{- else if (kindIs "map" (get $.Values.global.redis "sentinelAuth")) -}} +{{- $_ := set $.redisMergedConfig "sentinelAuth" (get $.Values.global.redis "sentinelAuth") -}} {{- else -}} -{{- $_ := set $.redisMergedConfig "sentinelPassword" $.Values.global.redis.auth -}} +{{- $_ := set $.redisMergedConfig "sentinelAuth" $.Values.global.redis.sentinelAuth -}} {{- end -}} -{{- range $key := keys $.Values.global.redis.sentinelPassword -}} -{{- if not (hasKey $.redisMergedConfig.sentinelPassword $key) -}} -{{- $_ := set $.redisMergedConfig.sentinelPassword $key (index $.Values.global.redis.sentinelPassword $key) -}} +{{- range $key := keys $.Values.global.redis.sentinelAuth -}} +{{- if not (hasKey $.redisMergedConfig.sentinelAuth $key) -}} +{{- $_ := set $.redisMergedConfig.sentinelAuth $key (index $.Values.global.redis.sentinelAuth $key) -}} {{- end -}} {{- end -}} {{- end -}} @@ -80,27 +91,27 @@ global.redis.auth.enabled {{- end -}} {{/* -Return the redis sentinel password secret name +Return the Redis Sentinel auth secret name */}} -{{- define "gitlab.redis.sentinelPassword.secret" -}} +{{- define "gitlab.redis.sentinelAuth.secret" -}} {{- include "gitlab.redis.configMerge" . -}} -{{- default (printf "%s-redis-sentinel-secret" .Release.Name) .redisMergedConfig.sentinelPassword.secret | quote -}} +{{- default (printf "%s-redis-sentinel-secret" .Release.Name) .redisMergedConfig.sentinelAuth.secret | quote -}} {{- end -}} {{/* -Return the redis password secret key +Return the Redis Sentinel password secret key */}} -{{- define "gitlab.redis.sentinelPassword.key" -}} +{{- define "gitlab.redis.sentinelAuth.key" -}} {{- include "gitlab.redis.configMerge" . -}} -{{- default "secret" .redisMergedConfig.sentinelPassword.key | quote -}} +{{- default "secret" .redisMergedConfig.sentinelAuth.key | quote -}} {{- end -}} {{/* -Return a merged setting between global.redis.sentinelPassword.enabled, -global.redis.[subkey/"redisConfigName"].sentinelPassword.enabled, or +Return a merged setting between global.redis.sentinelAuth.enabled, +global.redis.[subkey/"redisConfigName"].sentinelAuth.enabled, or global.redis.auth.enabled */}} -{{- define "gitlab.redis.sentinelPassword.enabled" -}} +{{- define "gitlab.redis.sentinelAuth.enabled" -}} {{- include "gitlab.redis.configMerge" . -}} -{{ ternary "true" "" .redisMergedConfig.sentinelPassword.enabled }} +{{ ternary "true" "" .redisMergedConfig.sentinelAuth.enabled }} {{- end -}} diff --git a/values.yaml b/values.yaml index 2803e80943..9bcc34ba8c 100644 --- a/values.yaml +++ b/values.yaml @@ -173,10 +173,10 @@ global: # sentinels: # - host: # port: - # sentinelPassword: - # enabled: true - # secret: redis-sentinel-password - # key: password + sentinelAuth: + enabled: false + # secret: redis-sentinel-auth + # key: password ## https://docs.gitlab.com/charts/charts/globals#configure-gitaly-settings gitaly: -- GitLab From ed4c19a5e7ada31d4296fdd623460092f0b6d2a4 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 31 May 2024 22:35:16 -0700 Subject: [PATCH 3/7] Add Sentinel password to Workhorse config files --- .../charts/webservice/templates/_helpers.tpl | 9 ++++ spec/configuration/workhorse_spec.rb | 53 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/charts/gitlab/charts/webservice/templates/_helpers.tpl b/charts/gitlab/charts/webservice/templates/_helpers.tpl index 2e7127ec84..ca5c23a278 100644 --- a/charts/gitlab/charts/webservice/templates/_helpers.tpl +++ b/charts/gitlab/charts/webservice/templates/_helpers.tpl @@ -278,6 +278,10 @@ Sentinel = [ {{ template "gitlab.redis.workhorse.sentinel-list" $ }} ] {{- $passwordPath := printf "%s-password" (default "redis" .redisConfigName) }} Password = {% file.Read "/etc/gitlab/redis/{{ $passwordPath }}" | strings.TrimSpace | data.ToJSON %} {{- end }} +{{- if .redisMergedConfig.sentinelAuth.enabled }} +{{- $passwordPath := printf "%s-sentinel-password" (default "redis" .redisConfigName) }} +SentinelPassword = {% file.Read "/etc/gitlab/redis/{{ $passwordPath }}" | strings.TrimSpace | data.ToJSON %} +{{- end }} {{- $_ := set . "redisConfigName" "" }} {{- end -}} @@ -294,5 +298,10 @@ Return the bash setup commands for redis secrets. mkdir -p /init-secrets-workhorse/redis cp -v -r -L /init-config/redis/{{ $passwordPath }} /init-secrets-workhorse/redis/ {{- end -}} +{{- if .redisMergedConfig.sentinelAuth.enabled -}} +{{- $passwordPath := printf "%s-sentinel-password" (default "redis" .redisConfigName) -}} +mkdir -p /init-secrets-workhorse/redis-sentinel +cp -v -r -L /init-config/redis-sentinel/{{ $passwordPath }} /init-secrets-workhorse/redis-sentinel/ +{{- end -}} {{- $_ := set . "redisConfigName" "" }} {{- end -}} diff --git a/spec/configuration/workhorse_spec.rb b/spec/configuration/workhorse_spec.rb index 9f56f9b557..b44c1a8814 100644 --- a/spec/configuration/workhorse_spec.rb +++ b/spec/configuration/workhorse_spec.rb @@ -12,7 +12,9 @@ describe 'Workhorse configuration' do let(:template) { HelmTemplate.new(default_values) } let(:raw_toml) { template.dig('ConfigMap/test-workhorse-default', 'data', 'workhorse-config.toml.tpl') } let(:global_redis_password) { SecureRandom.hex } + let(:global_redis_sentinel_password) { SecureRandom.hex } let(:workhorse_redis_password) { SecureRandom.hex } + let(:workhorse_redis_sentinel_password) { SecureRandom.hex } def render_toml(raw_template, object_store_config = nil) Dir.mktmpdir do |tmpdir| @@ -25,6 +27,8 @@ describe 'Workhorse configuration' do # Write bogus redis password File.write(File.join(tmpdir, "redis", "redis-password"), global_redis_password) File.write(File.join(tmpdir, "redis", "workhorse-password"), workhorse_redis_password) + File.write(File.join(tmpdir, "redis", "redis-sentinel-password"), global_redis_sentinel_password) + File.write(File.join(tmpdir, "redis", "workhorse-sentinel-password"), workhorse_redis_sentinel_password) File.write(File.join(tmpdir, "objectstorage", "object_store"), object_store_config) if object_store_config cmd = "gomplate --left-delim '{%' --right-delim '%}' --file #{input_file}" @@ -275,6 +279,55 @@ describe 'Workhorse configuration' do expect(redis_config['Sentinel']).to match_array(%w[tcp://s1.workhorse.redis:26379 tcp://s2.workhorse.redis:26379]) end end + + context 'with redis sentinel authentication' do + let(:values) do + YAML.safe_load(%( + global: + redis: + host: global.redis + auth: + enabled: true + secret: global-secret + sentinelAuth: + enabled: true + secret: redis-sentinel-secret + key: password + workhorse: + host: workhorse.redis + sentinels: + - host: s1.workhorse.redis + port: 26379 + - host: s2.workhorse.redis + port: 26379 + password: + enabled: true + secret: workhorse + sentinelAuth: + enabled: true + secret: workhorse-redis-sentinel-secret + key: password + redis: + install: false + )).merge(default_values) + end + + it 'overrides global redis config' do + toml = render_toml(raw_toml) + + expect(toml.keys).to match_array(%w[shutdown_timeout listeners image_resizer redis]) + + redis_config = toml['redis'] + expect(redis_config.keys).to match_array(%w[Password SentinelMaster Sentinel SentinelPassword]) + expect(redis_config['SentinelMaster']).to eq('workhorse.redis') + expect(redis_config['Sentinel']).to match_array(%w[tcp://s1.workhorse.redis:26379 tcp://s2.workhorse.redis:26379]) + expect(redis_config['Password']).to eq(workhorse_redis_password) + expect(redis_config['SentinelPassword']).to eq(workhorse_redis_sentinel_password) + + expect(template.dig("ConfigMap/test-workhorse-default", "data", 'workhorse-config.toml.tpl')).to include('redis/workhorse-password') + expect(template.dig('ConfigMap/test-workhorse-default', 'data', 'configure')).to include('init-config/redis/workhorse-password') + end + end end end -- GitLab From 21cfbc37cb31e9d9daa870793bcf640d639047d0 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sat, 1 Jun 2024 00:59:53 -0700 Subject: [PATCH 4/7] Add sentinel_password to Rails config --- charts/gitlab/templates/_rails.redis.tpl | 1 + charts/gitlab/templates/_redis.tpl | 10 +++++++--- spec/configuration/workhorse_spec.rb | 21 +++++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/charts/gitlab/templates/_rails.redis.tpl b/charts/gitlab/templates/_rails.redis.tpl index f0cbc92f0c..b669571c5a 100644 --- a/charts/gitlab/templates/_rails.redis.tpl +++ b/charts/gitlab/templates/_rails.redis.tpl @@ -17,6 +17,7 @@ Input: dict "context" $ "name" string production: url: {{ template "gitlab.redis.url" .context }} {{- include "gitlab.redis.sentinels" .context | nindent 4 }} + sentinel_password: "{{- include "gitlab.redis.sentinel.password" .context }}" id: {{- if eq .name "cable" }} adapter: redis diff --git a/charts/gitlab/templates/_redis.tpl b/charts/gitlab/templates/_redis.tpl index 1014766468..b81e971ebf 100644 --- a/charts/gitlab/templates/_redis.tpl +++ b/charts/gitlab/templates/_redis.tpl @@ -116,9 +116,13 @@ sentinels: {{- end -}} {{- end -}} {{/* Set redisMergedConfig.sentinelAuth. */}} -{{- range $key := keys $.Values.global.redis.sentinelAuth -}} -{{- if not (hasKey $.redisMergedConfig.sentinelAuth $key) -}} -{{- $_ := set $.redisMergedConfig.sentinelAuth $key (index $.Values.global.redis.sentinelAuth $key) -}} +{{- if not (kindIs "map" (get $.redisMergedConfig "sentinelAuth")) -}} +{{- $_ := set $.redisMergedConfig "sentinelAuth" $.Values.global.redis.sentinelAuth -}} +{{- else -}} +{{- range $key := keys $.Values.global.redis.sentinelAuth -}} +{{- if not (hasKey $.redisMergedConfig.sentinelAuth $key) -}} +{{- $_ := set $.redisMergedConfig.sentinelAuth $key (index $.Values.global.redis.sentinelAuth $key) -}} +{{- end -}} {{- end -}} {{- end -}} {{- end -}} diff --git a/spec/configuration/workhorse_spec.rb b/spec/configuration/workhorse_spec.rb index b44c1a8814..e46c306144 100644 --- a/spec/configuration/workhorse_spec.rb +++ b/spec/configuration/workhorse_spec.rb @@ -4,6 +4,7 @@ require 'helm_template_helper' require 'tomlrb' require 'yaml' require 'hash_deep_merge' +require 'runtime_template_helper' describe 'Workhorse configuration' do let(:default_values) do @@ -41,6 +42,16 @@ describe 'Workhorse configuration' do end end + def render_erb(raw_template) + files = { + '/etc/gitlab/redis/workhorse-password' => workhorse_redis_password, + '/etc/gitlab/redis-sentinel/workhorse-sentinel-password' => workhorse_redis_sentinel_password + } + + yaml = RuntimeTemplate.erb(raw_template: raw_template, files: files) + YAML.safe_load(yaml) + end + it 'renders a TOML configuration file' do toml = render_toml(raw_toml) @@ -249,7 +260,13 @@ describe 'Workhorse configuration' do )).merge(default_values) end + let(:webservice_config) { template.dig('ConfigMap/test-webservice', 'data') } + let(:redis_workhorse_raw_yml) { webservice_config.dig('redis.workhorse.yml.erb') } + let(:redis_workhorse_yml) { render_erb(redis_workhorse_raw_yml) } + it 'overrides global redis config' do + expect(template.exit_code).to eq(0), "Unexpected error code #{template.exit_code} -- #{template.stderr}" + toml = render_toml(raw_toml) expect(toml.keys).to match_array(%w[shutdown_timeout listeners image_resizer redis]) @@ -324,8 +341,12 @@ describe 'Workhorse configuration' do expect(redis_config['Password']).to eq(workhorse_redis_password) expect(redis_config['SentinelPassword']).to eq(workhorse_redis_sentinel_password) + expect(template.exit_code).to eq(0), "Unexpected error code #{template.exit_code} -- #{template.stderr}" + expect(template.dig("ConfigMap/test-workhorse-default", "data", 'workhorse-config.toml.tpl')).to include('redis/workhorse-password') expect(template.dig('ConfigMap/test-workhorse-default', 'data', 'configure')).to include('init-config/redis/workhorse-password') + + expect(redis_workhorse_yml['production']['sentinel_password']).to eq(workhorse_redis_sentinel_password) end end end -- GitLab From 62bcecf345f7377f1f25ffbe7385d8354add01df Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Sun, 2 Jun 2024 19:55:31 -0700 Subject: [PATCH 5/7] Make gitlab-exporter work with Redis Sentinel password --- charts/gitlab/charts/gitlab-exporter/templates/configmap.yaml | 2 +- charts/gitlab/templates/_configure.tpl | 2 +- templates/_redis.tpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/gitlab/charts/gitlab-exporter/templates/configmap.yaml b/charts/gitlab/charts/gitlab-exporter/templates/configmap.yaml index 68867500fa..d43d61024d 100644 --- a/charts/gitlab/charts/gitlab-exporter/templates/configmap.yaml +++ b/charts/gitlab/charts/gitlab-exporter/templates/configmap.yaml @@ -83,6 +83,6 @@ data: <<: *db_common configure: | - {{- include "gitlab.scripts.configure.secrets" (dict "required" "none" "optional" "redis postgres gitlab-exporter") | nindent 4 }} + {{- include "gitlab.scripts.configure.secrets" (dict "required" "none" "optional" "redis redis-sentinel postgres gitlab-exporter") | nindent 4 }} # Leave this here - This line denotes end of block to the parser. {{- end }} diff --git a/charts/gitlab/templates/_configure.tpl b/charts/gitlab/templates/_configure.tpl index 1087913eaa..94b56f21a6 100644 --- a/charts/gitlab/templates/_configure.tpl +++ b/charts/gitlab/templates/_configure.tpl @@ -11,7 +11,7 @@ */}} {{- define "gitlab.scripts.configure.secrets" -}} {{- $required := default "shell gitaly registry rails-secrets gitlab-workhorse" $.required | splitList " " -}} -{{- $optional := default "redis minio objectstorage postgres ldap duo omniauth smtp kas pages oauth-secrets mailroom gitlab-exporter microsoft_graph_mailer suggested_reviewers zoekt clickhouse" $.optional | splitList " " -}} +{{- $optional := default "redis redis-sentinel minio objectstorage postgres ldap duo omniauth smtp kas pages oauth-secrets mailroom gitlab-exporter microsoft_graph_mailer suggested_reviewers zoekt clickhouse" $.optional | splitList " " -}} {{- range (without $required "none") -}} {{- $optional = without $optional . -}} {{- end -}} diff --git a/templates/_redis.tpl b/templates/_redis.tpl index f1864e56d3..a312be627c 100644 --- a/templates/_redis.tpl +++ b/templates/_redis.tpl @@ -109,7 +109,7 @@ Return the Redis Sentinel password secret key {{/* Return a merged setting between global.redis.sentinelAuth.enabled, global.redis.[subkey/"redisConfigName"].sentinelAuth.enabled, or -global.redis.auth.enabled +global.redis.sentinelAuth.enabled */}} {{- define "gitlab.redis.sentinelAuth.enabled" -}} {{- include "gitlab.redis.configMerge" . -}} -- GitLab From 289972c377c002954734c0e22add1b423621bb8d Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 3 Jun 2024 01:07:55 -0700 Subject: [PATCH 6/7] Fix working version of Sentinel password support --- .../geo-logcursor/templates/configmap.yml | 2 +- .../geo-logcursor/templates/deployment.yaml | 1 + .../charts/mailroom/templates/configmap.yaml | 6 ++++- .../charts/mailroom/templates/deployment.yaml | 1 + .../charts/migrations/templates/_jobspec.yaml | 1 + .../charts/sidekiq/templates/deployment.yaml | 1 + .../charts/toolbox/templates/backup-job.yaml | 1 + .../charts/toolbox/templates/deployment.yaml | 1 + .../charts/webservice/templates/_helpers.tpl | 3 ++- charts/gitlab/templates/_rails.redis.tpl | 1 + charts/gitlab/templates/_redis.tpl | 13 ++++++---- templates/_redis.tpl | 26 +++---------------- 12 files changed, 26 insertions(+), 31 deletions(-) diff --git a/charts/gitlab/charts/geo-logcursor/templates/configmap.yml b/charts/gitlab/charts/geo-logcursor/templates/configmap.yml index 366c38bbba..48cf6c15d7 100644 --- a/charts/gitlab/charts/geo-logcursor/templates/configmap.yml +++ b/charts/gitlab/charts/geo-logcursor/templates/configmap.yml @@ -96,7 +96,7 @@ data: - 0.0.0.0/0 sidekiq_exporter: configure: | - {{- include "gitlab.scripts.configure.secrets" (dict "required" "rails-secrets" "optional" "postgres redis") | nindent 4 }} + {{- include "gitlab.scripts.configure.secrets" (dict "required" "rails-secrets" "optional" "postgres redis redis-sentinel") | nindent 4 }} {{- include "gitlab.psql.ssl.initScript" . | nindent 4 }} {{- include "gitlab.geo.psql.ssl.initScript" . | nindent 4 }} diff --git a/charts/gitlab/charts/geo-logcursor/templates/deployment.yaml b/charts/gitlab/charts/geo-logcursor/templates/deployment.yaml index 69d53dcd75..18790920bb 100644 --- a/charts/gitlab/charts/geo-logcursor/templates/deployment.yaml +++ b/charts/gitlab/charts/geo-logcursor/templates/deployment.yaml @@ -189,6 +189,7 @@ spec: - key: secrets.yml path: rails-secrets/secrets.yml {{- include "gitlab.redis.secrets" (dict "globalContext" $) | nindent 10 }} + {{- include "gitlab.redisSentinel.secrets" (dict "globalContext" $) | nindent 10 }} {{- range $.Values.local.psql }} {{- include "gitlab.psql.secret" . | nindent 10 }} {{- end }} diff --git a/charts/gitlab/charts/mailroom/templates/configmap.yaml b/charts/gitlab/charts/mailroom/templates/configmap.yaml index 87ea3a8881..8c8e17a7c1 100644 --- a/charts/gitlab/charts/mailroom/templates/configmap.yaml +++ b/charts/gitlab/charts/mailroom/templates/configmap.yaml @@ -51,6 +51,7 @@ data: :queue: email_receiver :worker: EmailReceiverWorker {{- include "gitlab.mailroom.redis.sentinels" $ | nindent 10 }} + :sentinel_password: "{{ include "gitlab.redis.sentinel.password" . }}" {{- else if eq .deliveryMethod "webhook" }} :delivery_method: postback :delivery_options: @@ -67,6 +68,7 @@ data: :redis_url: {{ include "gitlab.mailroom.redis.url" . }} :namespace: mail_room:gitlab {{- include "gitlab.mailroom.redis.sentinels" . | nindent 10 }} + :sentinel_password: "{{ include "gitlab.redis.sentinel.password" . }}" {{- if .Values.global.appConfig.serviceDeskEmail.enabled }} - {{- with .Values.global.appConfig.serviceDeskEmail }} @@ -106,6 +108,7 @@ data: :queue: service_desk_email_receiver :worker: ServiceDeskEmailReceiverWorker {{- include "gitlab.mailroom.redis.sentinels" $ | nindent 10 }} + :sentinel_password: "{{ include "gitlab.redis.sentinel.password" . }}" {{- else if eq .deliveryMethod "webhook" }} :delivery_method: postback :delivery_options: @@ -122,9 +125,10 @@ data: :redis_url: {{ template "gitlab.redis.url" . }} :namespace: mail_room:gitlab {{- include "gitlab.mailroom.redis.sentinels" . | nindent 10 }} + :sentinel_password: "{{ include "gitlab.redis.sentinel.password" . }}" {{- end }} configure: | - {{- include "gitlab.scripts.configure.secrets" (dict "required" "mailroom" "optional" "redis") | nindent 4 }} + {{- include "gitlab.scripts.configure.secrets" (dict "required" "mailroom" "optional" "redis redis-sentinel") | nindent 4 }} # Leave this here - This line denotes end of block to the parser. {{- end }} diff --git a/charts/gitlab/charts/mailroom/templates/deployment.yaml b/charts/gitlab/charts/mailroom/templates/deployment.yaml index b79f562ce3..34e56ff032 100644 --- a/charts/gitlab/charts/mailroom/templates/deployment.yaml +++ b/charts/gitlab/charts/mailroom/templates/deployment.yaml @@ -125,6 +125,7 @@ spec: defaultMode: 0400 sources: {{- include "gitlab.redis.secret" . | nindent 10 }} + {{- include "gitlab.redisSentinel.secret" . | nindent 10 }} {{- if eq .Values.global.appConfig.incomingEmail.inboxMethod "microsoft_graph" }} - secret: name: {{ .Values.global.appConfig.incomingEmail.clientSecret.secret | required "Missing required secret containing the OAuth2 Client ID for incoming email. Make sure to set `.Values.global.appConfig.incomingEmail.clientSecret.secret`" }} diff --git a/charts/gitlab/charts/migrations/templates/_jobspec.yaml b/charts/gitlab/charts/migrations/templates/_jobspec.yaml index f77599e9c4..04535a4895 100644 --- a/charts/gitlab/charts/migrations/templates/_jobspec.yaml +++ b/charts/gitlab/charts/migrations/templates/_jobspec.yaml @@ -156,6 +156,7 @@ spec: path: rails-secrets/secrets.yml {{- include "gitlab.gitaly.clientSecrets" . | nindent 10 }} {{- include "gitlab.redis.secrets" (dict "globalContext" $) | nindent 10 }} + {{- include "gitlab.redisSentinel.secrets" (dict "globalContext" $) | nindent 10 }} {{- range $.Values.local.psql }} {{- include "gitlab.psql.secret" . | nindent 10 }} {{- end }} diff --git a/charts/gitlab/charts/sidekiq/templates/deployment.yaml b/charts/gitlab/charts/sidekiq/templates/deployment.yaml index f5109df5e7..b77c72cf87 100644 --- a/charts/gitlab/charts/sidekiq/templates/deployment.yaml +++ b/charts/gitlab/charts/sidekiq/templates/deployment.yaml @@ -321,6 +321,7 @@ spec: {{- include "gitlab.clickhouse.main.secrets" $ | nindent 10 }} {{- end }} {{- include "gitlab.redis.secrets" (dict "globalContext" $) | nindent 10 }} + {{- include "gitlab.redisSentinel.secrets" (dict "globalContext" $) | nindent 10 }} {{- range $.Values.local.psql }} {{- include "gitlab.psql.secret" . | nindent 10 }} {{- end }} diff --git a/charts/gitlab/charts/toolbox/templates/backup-job.yaml b/charts/gitlab/charts/toolbox/templates/backup-job.yaml index d2c4b7516d..de68cadb8f 100644 --- a/charts/gitlab/charts/toolbox/templates/backup-job.yaml +++ b/charts/gitlab/charts/toolbox/templates/backup-job.yaml @@ -191,6 +191,7 @@ spec: path: shell/.gitlab_shell_secret {{- include "gitlab.gitaly.clientSecrets" . | nindent 16 }} {{- include "gitlab.redis.secrets" (dict "globalContext" $) | nindent 16 }} + {{- include "gitlab.redisSentinel.secrets" (dict "globalContext" $) | nindent 16 }} {{- range $.Values.local.psql }} {{- include "gitlab.psql.secret" . | nindent 16 }} {{- end }} diff --git a/charts/gitlab/charts/toolbox/templates/deployment.yaml b/charts/gitlab/charts/toolbox/templates/deployment.yaml index cc3dbda926..23f24695b0 100644 --- a/charts/gitlab/charts/toolbox/templates/deployment.yaml +++ b/charts/gitlab/charts/toolbox/templates/deployment.yaml @@ -221,6 +221,7 @@ spec: {{- include "gitlab.clickhouse.main.secrets" $ | nindent 10 }} {{- end }} {{- include "gitlab.redis.secrets" (dict "globalContext" $) | nindent 10 }} + {{- include "gitlab.redisSentinel.secrets" (dict "globalContext" $) | nindent 10 }} {{- range $.Values.local.psql }} {{- include "gitlab.psql.secret" . | nindent 10 }} {{- end }} diff --git a/charts/gitlab/charts/webservice/templates/_helpers.tpl b/charts/gitlab/charts/webservice/templates/_helpers.tpl index ca5c23a278..c1183fde7a 100644 --- a/charts/gitlab/charts/webservice/templates/_helpers.tpl +++ b/charts/gitlab/charts/webservice/templates/_helpers.tpl @@ -280,7 +280,7 @@ Password = {% file.Read "/etc/gitlab/redis/{{ $passwordPath }}" | strings.TrimSp {{- end }} {{- if .redisMergedConfig.sentinelAuth.enabled }} {{- $passwordPath := printf "%s-sentinel-password" (default "redis" .redisConfigName) }} -SentinelPassword = {% file.Read "/etc/gitlab/redis/{{ $passwordPath }}" | strings.TrimSpace | data.ToJSON %} +SentinelPassword = {% file.Read "/etc/gitlab/redis-sentinel/{{ $passwordPath }}" | strings.TrimSpace | data.ToJSON %} {{- end }} {{- $_ := set . "redisConfigName" "" }} {{- end -}} @@ -300,6 +300,7 @@ cp -v -r -L /init-config/redis/{{ $passwordPath }} /init-secrets-workhorse/redis {{- end -}} {{- if .redisMergedConfig.sentinelAuth.enabled -}} {{- $passwordPath := printf "%s-sentinel-password" (default "redis" .redisConfigName) -}} +{{ "\n" -}} mkdir -p /init-secrets-workhorse/redis-sentinel cp -v -r -L /init-config/redis-sentinel/{{ $passwordPath }} /init-secrets-workhorse/redis-sentinel/ {{- end -}} diff --git a/charts/gitlab/templates/_rails.redis.tpl b/charts/gitlab/templates/_rails.redis.tpl index b669571c5a..9acb1d3bd3 100644 --- a/charts/gitlab/templates/_rails.redis.tpl +++ b/charts/gitlab/templates/_rails.redis.tpl @@ -8,6 +8,7 @@ Input: dict "context" $ "name" string {{- if $cluster := include "gitlab.redis.cluster" .context -}} {{ .name }}.yml.erb: | production: + sentinel_password: "{{- include "gitlab.redis.sentinel.password" .context }}" {{- include "gitlab.redis.cluster.user" .context | nindent 4 }} {{- include "gitlab.redis.cluster.password" .context | nindent 4 }} {{- $cluster | nindent 4 }} diff --git a/charts/gitlab/templates/_redis.tpl b/charts/gitlab/templates/_redis.tpl index b81e971ebf..a112b95506 100644 --- a/charts/gitlab/templates/_redis.tpl +++ b/charts/gitlab/templates/_redis.tpl @@ -202,10 +202,7 @@ instances. */}} {{- define "gitlab.redisSentinel.secrets" -}} {{- $ := .globalContext }} -{{- $mountRedisYmlOverrideSecrets := true }} -{{- if hasKey . "mountRedisYmlOverrideSecrets" }} -{{- $mountRedisYmlOverrideSecrets = .mountRedisYmlOverrideSecrets }} -{{- end }} +{{- $_ := set $ "usingOverride" false }} {{- $redisInstances := list "cache" "clusterCache" "sharedState" "queues" "actioncable" "traceChunks" "rateLimiting" "clusterRateLimiting" "sessions" "repositoryCache" "workhorse" }} {{- if .instances }} {{- $redisInstances = splitList " " .instances }} @@ -216,12 +213,18 @@ instances. {{ include "gitlab.redisSentinel.secret" $ }} {{- end }} {{- end -}} +{{/* Include global Redis Sentinel secrets */}} +{{/* reset 'redisConfigName', to get global.redisSentinel.auth's Secret item */}} +{{- $_ := set $ "redisConfigName" "" }} +{{- if eq (include "gitlab.redis.sentinelAuth.enabled" $) "true" }} +{{ include "gitlab.redisSentinel.secret" $ }} +{{- end }} {{- end -}} {{- define "gitlab.redisSentinel.secret" -}} {{- include "gitlab.redis.configMerge" . -}} {{- if .redisMergedConfig.sentinelAuth.enabled }} -{{- $passwordPath := printf "%s-%ssentinel-password" (default "redis" .redisConfigName) (ternary "override-" "" (default false .usingOverride)) -}} +{{- $passwordPath := printf "%s-sentinel-password" (default "redis" .redisConfigName) -}} - secret: name: {{ template "gitlab.redis.sentinelAuth.secret" . }} items: diff --git a/templates/_redis.tpl b/templates/_redis.tpl index a312be627c..5240104e5c 100644 --- a/templates/_redis.tpl +++ b/templates/_redis.tpl @@ -36,31 +36,11 @@ Build a dict of redis configuration {{/* Build a dict of Redis Sentinel configuration -- redisYmlOverride is used by GitLab Rails, which uses the redis-rb gem (https://github.com/redis/redis-rb). -- The code below maps `sentinel_password` to the `sentinelAuth` structure. -- redis-rb v5 specifies `sentinel_password` and `sentinel_username` as parameters. -- Note that both redis-rb v4 and v5 can pass `password` and `username` as parameters in the Sentinel host list as well. -- We use `global.redis.sentinelAuth` to be consistent with `global.redis.auth`. -- Currently GitLab doesn't support Redis usernames, but this will likely be needed in the future. - This could be done by introducing `global.redis.sentinelAuth.usernameKey` and `sentinel_username` in redisYmlOverride. +- For simplicity, we do not allow different Sentinel passwords across types. */}} -{{- $hasOverrideSentinelSecret := false -}} -{{- if and $.Values.global.redis.redisYmlOverride $.redisConfigName -}} -{{- $hasOverrideSentinelSecret = (kindIs "map" (dig $.redisConfigName "sentinel_password" "" $.Values.global.redis.redisYmlOverride)) -}} -{{- end -}} -{{- if and $hasOverrideSentinelSecret $.usingOverride -}} -{{- $_ := set $.redisMergedConfig "sentinelAuth" (get (index $.Values.global.redis.redisYmlOverride $.redisConfigName) "sentinel_password") -}} -{{- else if kindIs "map" (get (index $.Values.global.redis $.redisConfigName) "sentinelAuth") -}} -{{- $_ := set $.redisMergedConfig "sentinelAuth" (get (index $.Values.global.redis $.redisConfigName) "sentinelAuth") -}} -{{- else if (kindIs "map" (get $.Values.global.redis "sentinelAuth")) -}} + +{{- if (kindIs "map" (get $.Values.global.redis "sentinelAuth")) -}} {{- $_ := set $.redisMergedConfig "sentinelAuth" (get $.Values.global.redis "sentinelAuth") -}} -{{- else -}} -{{- $_ := set $.redisMergedConfig "sentinelAuth" $.Values.global.redis.sentinelAuth -}} -{{- end -}} -{{- range $key := keys $.Values.global.redis.sentinelAuth -}} -{{- if not (hasKey $.redisMergedConfig.sentinelAuth $key) -}} -{{- $_ := set $.redisMergedConfig.sentinelAuth $key (index $.Values.global.redis.sentinelAuth $key) -}} -{{- end -}} {{- end -}} {{- end -}} -- GitLab From 000a05409a4228c8c1d1504368af39378b1157a8 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 3 Jun 2024 16:09:31 -0700 Subject: [PATCH 7/7] Make mailroom and KAS work with Redis Sentinel password --- .../gitlab/charts/kas/templates/_helpers.tpl | 1 + .../charts/kas/templates/deployment.yaml | 1 + .../charts/mailroom/templates/_helpers.tpl | 2 +- charts/gitlab/templates/_redis.tpl | 4 ++- spec/configuration/kas_spec.rb | 28 +++++++++++++++++++ 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/charts/gitlab/charts/kas/templates/_helpers.tpl b/charts/gitlab/charts/kas/templates/_helpers.tpl index 9668489af3..e34b1ef038 100644 --- a/charts/gitlab/charts/kas/templates/_helpers.tpl +++ b/charts/gitlab/charts/kas/templates/_helpers.tpl @@ -37,6 +37,7 @@ sentinel: - {{ quote (print (trim $entry.host) ":" ( default 26379 $entry.port | int ) ) -}} {{ end }} master_name: {{ template "gitlab.redis.host" . }} + sentinel_password_file: /etc/kas/redis-sentinel/redis-sentinel-password {{- end -}} {{- if eq (.redisMergedConfig.scheme | default "") "rediss" }} tls: diff --git a/charts/gitlab/charts/kas/templates/deployment.yaml b/charts/gitlab/charts/kas/templates/deployment.yaml index 6842c640f6..f8ff8c0c40 100644 --- a/charts/gitlab/charts/kas/templates/deployment.yaml +++ b/charts/gitlab/charts/kas/templates/deployment.yaml @@ -154,5 +154,6 @@ spec: {{- if .Values.redis.enabled -}} {{- $instance := empty .Values.global.redis.kas | ternary "sharedState" "kas" }} {{- include "gitlab.redis.secrets" (dict "globalContext" $ "instances" $instance "mountRedisYmlOverrideSecrets" false) | nindent 12 }} + {{- include "gitlab.redisSentinel.secrets" (dict "globalContext" $) | nindent 12 }} {{- end }} {{- end }} diff --git a/charts/gitlab/charts/mailroom/templates/_helpers.tpl b/charts/gitlab/charts/mailroom/templates/_helpers.tpl index 4dbefb897a..8183fe3cd1 100644 --- a/charts/gitlab/charts/mailroom/templates/_helpers.tpl +++ b/charts/gitlab/charts/mailroom/templates/_helpers.tpl @@ -18,6 +18,6 @@ If global.redis.queues is present, use this. If not present, use global.redis {{- end -}} {{- $sentinels := include "gitlab.redis.sentinels" . }} {{- if $sentinels -}} -:{{- $sentinels | replace " port:" " :port:" | replace " host:" " :host:" -}} +:{{- $sentinels | replace " port:" " :port:" | replace " host:" " :host:" | replace " password:" " :password:" -}} {{- end -}} {{- end -}} diff --git a/charts/gitlab/templates/_redis.tpl b/charts/gitlab/templates/_redis.tpl index a112b95506..21dcf2b6c9 100644 --- a/charts/gitlab/templates/_redis.tpl +++ b/charts/gitlab/templates/_redis.tpl @@ -74,7 +74,7 @@ Return the Sentinel password, if available. */}} {{- define "gitlab.redis.sentinel.password" -}} {{- include "gitlab.redis.configMerge" . -}} -{{- $password := printf "%s-%ssentinel-password" (default "redis" .redisConfigName) (ternary "override-" "" (default false .usingOverride)) -}} +{{- $password := printf "%s-sentinel-password" (default "redis" .redisConfigName) -}} {{- if .redisMergedConfig.sentinelAuth.enabled -}}<%= File.read("/etc/gitlab/redis-sentinel/{{ $password }}").strip %>{{- end -}} {{- end -}} @@ -84,9 +84,11 @@ Build the structure describing sentinels {{- define "gitlab.redis.sentinelsList" -}} {{- include "gitlab.redis.selectedMergedConfig" . -}} {{- if .redisMergedConfig.sentinels -}} +{{- $password := printf `File.read("/etc/gitlab/redis-sentinel/%s-sentinel-password").strip` (default "redis" .redisConfigName) -}} {{- range $i, $entry := .redisMergedConfig.sentinels }} - host: {{ $entry.host }} port: {{ default 26379 $entry.port }} + password: "<%= {{ $password }} %>" {{- end }} {{- end -}} {{- end -}} diff --git a/spec/configuration/kas_spec.rb b/spec/configuration/kas_spec.rb index c55edd11d7..acad95ac5a 100644 --- a/spec/configuration/kas_spec.rb +++ b/spec/configuration/kas_spec.rb @@ -347,6 +347,34 @@ describe 'kas configuration' do ))) end end + + context 'when sentinel is setup with a password' do + let(:kas_values) do + vals = default_kas_values + vals['global'].deep_merge!(sentinels) + + vals.deep_merge!(YAML.safe_load(%( + global: + redis: + sentinelAuth: + enabled: true + ))) + end + + it_behaves_like 'mounts global redis secret' + + it 'takes the global sentinel redis auth config' do + expect(config_yaml_data['redis']).to include(YAML.safe_load(%( + password_file: /etc/kas/redis/redis-password + sentinel: + addresses: + - sentinel1.example.com:26379 + - sentinel2.example.com:26379 + master_name: global.host + sentinel_password_file: /etc/kas/redis-sentinel/redis-sentinel-password + ))) + end + end end context 'when a redis sharedState is setup' do -- GitLab