From 3167cbc369075168a40595d0db987303e6ff1207 Mon Sep 17 00:00:00 2001 From: gpongelli Date: Wed, 13 Nov 2024 14:53:03 +0000 Subject: [PATCH] configure redis database number in values.yaml --- .../gitlab/charts/kas/templates/_helpers.tpl | 3 +- .../charts/webservice/templates/_helpers.tpl | 1 + charts/gitlab/templates/_redis.tpl | 13 +++- doc/advanced/external-redis/index.md | 1 + doc/charts/globals.md | 2 + spec/configuration/gitlab_exporter_spec.rb | 23 +++++-- spec/configuration/kas_spec.rb | 55 +++++++++++++++++ spec/configuration/mailroom_spec.rb | 16 ++++- spec/configuration/redis_spec.rb | 20 ++++++ spec/configuration/workhorse_spec.rb | 61 ++++++++++++++++--- templates/_redis.tpl | 2 +- values.yaml | 1 + 12 files changed, 180 insertions(+), 18 deletions(-) diff --git a/charts/gitlab/charts/kas/templates/_helpers.tpl b/charts/gitlab/charts/kas/templates/_helpers.tpl index 0ce08c57d4..72f66b6598 100644 --- a/charts/gitlab/charts/kas/templates/_helpers.tpl +++ b/charts/gitlab/charts/kas/templates/_helpers.tpl @@ -29,7 +29,8 @@ username: {{ .redisMergedConfig.user }} {{- end -}} {{- if .redisMergedConfig.password.enabled }} password_file: /etc/kas/redis/{{ printf "%s-password" (default "redis" .redisConfigName) }} -{{- end -}} +{{- end }} +database_index: {{ .redisMergedConfig.database }} {{- if not .redisMergedConfig.sentinels }} server: address: {{ template "gitlab.redis.host" . }}:{{ template "gitlab.redis.port" . }} diff --git a/charts/gitlab/charts/webservice/templates/_helpers.tpl b/charts/gitlab/charts/webservice/templates/_helpers.tpl index a320e36ee7..21fd7be309 100644 --- a/charts/gitlab/charts/webservice/templates/_helpers.tpl +++ b/charts/gitlab/charts/webservice/templates/_helpers.tpl @@ -268,6 +268,7 @@ Return the workhorse redis configuration. {{- end }} {{- include "gitlab.redis.selectedMergedConfig" . -}} [redis] +DB = {{ .redisMergedConfig.database }} {{- if not .redisMergedConfig.sentinels }} {{- $userinfo := "" }} {{- if .redisMergedConfig.user }} diff --git a/charts/gitlab/templates/_redis.tpl b/charts/gitlab/templates/_redis.tpl index 8f5841e5f0..a026d49847 100644 --- a/charts/gitlab/templates/_redis.tpl +++ b/charts/gitlab/templates/_redis.tpl @@ -31,6 +31,16 @@ to 6379 default {{- default 6379 .redisMergedConfig.port -}} {{- end -}} +{{/* +Return the redis database +If the redis database is provided, it will use that, otherwise it will fallback +to 0 default +*/}} +{{- define "gitlab.redis.database" -}} +{{- include "gitlab.redis.configMerge" . -}} +{{- default 0 .redisMergedConfig.database -}} +{{- end -}} + {{/* Return the redis scheme, or redis. Allowing people to use rediss clusters */}} @@ -49,7 +59,7 @@ Return the redis scheme, or redis. Allowing people to use rediss clusters Return the redis url. */}} {{- define "gitlab.redis.url" -}} -{{ template "gitlab.redis.scheme" . }}://{{ template "gitlab.redis.url.user" . }}{{ template "gitlab.redis.url.password" . }}{{ template "gitlab.redis.host" . }}:{{ template "gitlab.redis.port" . }} +{{ template "gitlab.redis.scheme" . }}://{{ template "gitlab.redis.url.user" . }}{{ template "gitlab.redis.url.password" . }}{{ template "gitlab.redis.host" . }}:{{ template "gitlab.redis.port" . }}/{{ template "gitlab.redis.database" . }} {{- end -}} {{/* @@ -134,6 +144,7 @@ sentinels: {{- if not (kindIs "map" (get $.redisMergedConfig "password")) -}} {{- $_ := set $.redisMergedConfig "password" $.Values.global.redis.auth -}} {{- end -}} +{{- $_ := set $.redisMergedConfig "database" (default 0 .Values.global.redis.database) -}} {{- range $key := keys $.Values.global.redis.auth -}} {{- if not (hasKey $.redisMergedConfig.password $key) -}} {{- $_ := set $.redisMergedConfig.password $key (index $.Values.global.redis.auth $key) -}} diff --git a/doc/advanced/external-redis/index.md b/doc/advanced/external-redis/index.md index c2431d9793..18bad8c961 100644 --- a/doc/advanced/external-redis/index.md +++ b/doc/advanced/external-redis/index.md @@ -28,6 +28,7 @@ You must set the following parameters: Items below can be further customized if you are not using the defaults: - `global.redis.port`: The port the database is available on, defaults to `6379`. +- `global.redis.database`: The database to connect to on the Redis server, defaults to `0`. For example, pass these values via Helm's `--set` flag while deploying: diff --git a/doc/charts/globals.md b/doc/charts/globals.md index 09bac241ac..d516bff969 100644 --- a/doc/charts/globals.md +++ b/doc/charts/globals.md @@ -452,6 +452,7 @@ global: redis: host: redis.example.com serviceName: redis + database: 7 port: 6379 auth: enabled: true @@ -468,6 +469,7 @@ global: | `host` | String | | The hostname of the Redis server with the database to use. This can be omitted in lieu of `serviceName`. | | `serviceName` | String | `redis` | The name of the `service` which is operating the Redis database. If this is present, and `host` is not, the chart will template the hostname of the service (and current `.Release.Name`) in place of the `host` value. This is convenient when using Redis as a part of the overall GitLab chart. | | `port` | Integer | `6379` | The port on which to connect to the Redis server. | +| `database` | Integer | `0` | The database to connect to on the Redis server. | | `user` | String | | The user used to authenticate against Redis (Redis 6.0+). | | `auth.enabled` | Boolean | true | The `auth.enabled` provides a toggle for using a password with the Redis instance. | | `auth.key` | String | | The `auth.key` attribute for Redis defines the name of the key in the secret (below) that contains the password. | diff --git a/spec/configuration/gitlab_exporter_spec.rb b/spec/configuration/gitlab_exporter_spec.rb index d5550ff29f..e694202119 100644 --- a/spec/configuration/gitlab_exporter_spec.rb +++ b/spec/configuration/gitlab_exporter_spec.rb @@ -35,11 +35,26 @@ 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") + expect(sidekiq_config['opts']['redis_url']).to eq("redis://:#{password}@test-redis-master.default.svc:6379/0") expect(sidekiq_config['opts']).not_to include('redis_sentinels') end end + context 'with custom redis database value' do + let(:values) do + YAML.safe_load(%( + global: + redis: + database: 4 + )).deep_merge(default_values) + end + + 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") + end + end + context 'When customer provides additional labels' do let(:values) do YAML.safe_load(%( @@ -103,7 +118,7 @@ describe 'gitlab-exporter configuration' do it 'configures Sentinels' 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_url']).to eq("redis://:#{password}@global.host:6379/0") expect(sidekiq_config['opts']['redis_sentinels']).to eq( [ { 'host' => 'sentinel1.example.com', 'port' => 26379 }, @@ -131,7 +146,7 @@ describe 'gitlab-exporter configuration' do it 'configures Sentinels' 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}@queues.redis.host:6379") + expect(sidekiq_config['opts']['redis_url']).to eq("redis://:#{password}@queues.redis.host:6379/0") expect(sidekiq_config['opts']['redis_sentinels']).to eq( [ { 'host' => 'sentinel1.example.com', 'port' => 26379 }, @@ -164,7 +179,7 @@ describe 'gitlab-exporter configuration' do 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_url']).to eq("redis://:#{password}@global.host:6379/0") expect(sidekiq_config['opts']['redis_sentinel_password']).to eq(RuntimeTemplate::JUNK_PASSWORD) expect(sidekiq_config['opts']['redis_sentinels']).to eq( [ diff --git a/spec/configuration/kas_spec.rb b/spec/configuration/kas_spec.rb index 787a72fc55..f56a56523e 100644 --- a/spec/configuration/kas_spec.rb +++ b/spec/configuration/kas_spec.rb @@ -285,6 +285,19 @@ describe 'kas configuration' do )) end + let(:sentinels_database) do + YAML.safe_load(%( + redis: + host: global.host + database: 6 + sentinels: + - host: sentinel1.example.com + port: 26379 + - host: sentinel2.example.com + port: 26379 + )) + end + context 'when redis is disabled' do let(:kas_values) do default_kas_values.deep_merge!(YAML.safe_load(%( @@ -331,9 +344,28 @@ describe 'kas configuration' do end end + context 'when global redis has database value' do + let(:kas_values) do + default_kas_values.deep_merge!(YAML.safe_load(%( + global: + redis: + database: 3 + ))) + end + + it 'has set url' do + expect(config_yaml_data['redis']).to include(YAML.safe_load(%( + database_index: 3 + server: + address: test-redis-master.default.svc:6379 + ))) + end + end + context 'when no sentinel is setup' do it 'takes the global redis config' do expect(config_yaml_data['redis']).to include(YAML.safe_load(%( + database_index: 0 password_file: /etc/kas/redis/redis-password server: address: test-redis-master.default.svc:6379 @@ -354,6 +386,28 @@ describe 'kas configuration' do it 'takes the global sentinel redis config' do expect(config_yaml_data['redis']).to include(YAML.safe_load(%( + database_index: 0 + sentinel: + addresses: + - sentinel1.example.com:26379 + - sentinel2.example.com:26379 + master_name: global.host + ))) + end + end + + context 'when sentinel and database are setup' do + let(:kas_values) do + vals = default_kas_values + vals['global'].deep_merge!(sentinels_database) + vals.deep_merge!('redis' => { 'install' => false }) + end + + it_behaves_like 'mounts global redis secret' + + it 'takes the global sentinel and database redis config' do + expect(config_yaml_data['redis']).to include(YAML.safe_load(%( + database_index: 6 sentinel: addresses: - sentinel1.example.com:26379 @@ -434,6 +488,7 @@ describe 'kas configuration' do let(:sentinels) { {} } it 'configures a sharedState server config' do expect(config_yaml_data['redis']).to include(YAML.safe_load(%( + database_index: 0 password_file: /etc/kas/redis/sharedState-password server: address: shared.redis:6378 diff --git a/spec/configuration/mailroom_spec.rb b/spec/configuration/mailroom_spec.rb index 1b94ccc49a..fcdaeb5c14 100644 --- a/spec/configuration/mailroom_spec.rb +++ b/spec/configuration/mailroom_spec.rb @@ -330,13 +330,27 @@ describe 'Mailroom configuration' do t = HelmTemplate.new(values) expect(t.exit_code).to eq(0) # configure the external-redis server, port, secret - expect(t.dig('ConfigMap/test-mailroom','data','mail_room.yml')).to include("external-redis:9999") + expect(t.dig('ConfigMap/test-mailroom','data','mail_room.yml')).to include("external-redis:9999/0") projected_volume = t.projected_volume_sources('Deployment/test-mailroom','init-mailroom-secrets') redis_mount = projected_volume.select { |item| item['secret']['name'] == "external-redis-secret" } expect(redis_mount.length).to eq(1) expect(t.dig('ConfigMap/test-mailroom','data','mail_room.yml')).not_to include(":sentinels:") end + it 'Populates configured database host, port, password' do + local = YAML.safe_load(%( + global: + redis: + host: external-redis + port: 9999 + database: 7 + )) + t = HelmTemplate.new(values.deep_merge(local)) + expect(t.exit_code).to eq(0) + # configure the external-redis server, port, secret + expect(t.dig('ConfigMap/test-mailroom','data','mail_room.yml')).to include("external-redis:9999/7") + end + it 'Populates Sentinels, when configured' do local = YAML.safe_load(%( global: diff --git a/spec/configuration/redis_spec.rb b/spec/configuration/redis_spec.rb index dd5db4230b..5f5720c1ea 100644 --- a/spec/configuration/redis_spec.rb +++ b/spec/configuration/redis_spec.rb @@ -45,6 +45,26 @@ describe 'Redis configuration' do 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 diff --git a/spec/configuration/workhorse_spec.rb b/spec/configuration/workhorse_spec.rb index d8c27b5837..7240bf9b34 100644 --- a/spec/configuration/workhorse_spec.rb +++ b/spec/configuration/workhorse_spec.rb @@ -155,18 +155,50 @@ describe 'Workhorse configuration' do context 'configuring dedicated redis' do let(:template) { HelmTemplate.new(values) } + context 'with default redis database' do + let(:values) do + YAML.safe_load(%( + global: + redis: + host: global.redis + auth: + enabled: true + secret: global-secret + redis: + install: false + )).deep_merge(default_values) + end + + it 'renders the 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[URL Password DB]) + expect(redis_config['URL']).to eq('redis://global.redis:6379') + expect(redis_config['DB']).to eq(0) + expect(redis_config['Password']).to eq(global_redis_password) + + expect(template.dig("ConfigMap/test-workhorse-default", 'data', 'workhorse-config.toml.tpl')).to include('redis/redis-password') + expect(template.dig('ConfigMap/test-workhorse-default', 'data', 'configure')).to include('init-config/redis/redis-password') + end + end + context 'with global redis' do let(:values) do YAML.safe_load(%( global: redis: host: global.redis + database: 3 auth: enabled: true secret: global-secret redis: install: false - )).merge(default_values) + )).deep_merge(default_values) end it 'renders the global redis config' do @@ -176,8 +208,9 @@ describe 'Workhorse configuration' do redis_config = toml['redis'] - expect(redis_config.keys).to match_array(%w[URL Password]) + expect(redis_config.keys).to match_array(%w[URL Password DB]) expect(redis_config['URL']).to eq('redis://global.redis:6379') + expect(redis_config['DB']).to eq(3) expect(redis_config['Password']).to eq(global_redis_password) expect(template.dig("ConfigMap/test-workhorse-default", 'data', 'workhorse-config.toml.tpl')).to include('redis/redis-password') @@ -210,8 +243,9 @@ describe 'Workhorse configuration' do 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[URL Password]) + expect(redis_config.keys).to match_array(%w[URL Password DB]) expect(redis_config['URL']).to eq('redis://workhorse.redis:6379') + expect(redis_config['DB']).to eq(0) expect(redis_config['Password']).to eq(workhorse_redis_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') @@ -228,8 +262,9 @@ describe 'Workhorse configuration' do 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[URL]) + expect(redis_config.keys).to match_array(%w[URL DB]) expect(redis_config['URL']).to eq('redis://workhorse.redis:6379') + expect(redis_config['DB']).to eq(0) end end end @@ -254,8 +289,9 @@ describe 'Workhorse configuration' do 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[URL Password]) + expect(redis_config.keys).to match_array(%w[URL Password DB]) expect(redis_config['URL']).to eq('redis://redis-user@workhorse.redis:6379') + expect(redis_config['DB']).to eq(0) expect(redis_config['Password']).to eq(workhorse_redis_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') @@ -269,6 +305,7 @@ describe 'Workhorse configuration' do global: redis: host: global.redis + database: 7 auth: enabled: true secret: global-secret @@ -290,20 +327,22 @@ describe 'Workhorse configuration' do 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[URL Password]) + expect(redis_config.keys).to match_array(%w[URL Password DB]) expect(redis_config['URL']).to eq('redis://workhorse-redis-user@workhorse.redis:6379') + expect(redis_config['DB']).to eq(7) expect(redis_config['Password']).to eq(workhorse_redis_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 - context 'with redis sentinel' do + context 'with redis sentinel and database' do let(:values) do YAML.safe_load(%( global: redis: host: global.redis + database: 9 auth: enabled: true secret: global-secret @@ -334,10 +373,11 @@ describe 'Workhorse configuration' do 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]) + expect(redis_config.keys).to match_array(%w[Password SentinelMaster Sentinel DB]) 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['DB']).to eq(9) 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 @@ -353,7 +393,7 @@ describe 'Workhorse configuration' do 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[SentinelMaster Sentinel]) + expect(redis_config.keys).to match_array(%w[SentinelMaster Sentinel DB]) 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]) end @@ -397,11 +437,12 @@ describe 'Workhorse configuration' do 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.keys).to match_array(%w[Password SentinelMaster Sentinel SentinelPassword DB]) 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(global_redis_sentinel_password) + expect(redis_config['DB']).to eq(0) expect(template.exit_code).to eq(0), "Unexpected error code #{template.exit_code} -- #{template.stderr}" diff --git a/templates/_redis.tpl b/templates/_redis.tpl index 7ba03e59ee..7935acf010 100644 --- a/templates/_redis.tpl +++ b/templates/_redis.tpl @@ -15,7 +15,7 @@ Build a dict of redis configuration {{- if and $.Values.global.redis.redisYmlOverride $.redisConfigName -}} {{- $hasOverrideSecret = (kindIs "map" (dig $.redisConfigName "password" "" $.Values.global.redis.redisYmlOverride)) -}} {{- end -}} -{{- range $want := list "host" "port" "scheme" "user" -}} +{{- range $want := list "host" "port" "scheme" "user" "database" -}} {{- $_ := set $.redisMergedConfig $want (pluck $want (index $.Values.global.redis $.redisConfigName) $.Values.global.redis | first) -}} {{- end -}} {{- if and $hasOverrideSecret $.usingOverride -}} diff --git a/values.yaml b/values.yaml index 6d72bb8658..c070854eaa 100644 --- a/values.yaml +++ b/values.yaml @@ -172,6 +172,7 @@ global: # writeTimeout: 1 # host: redis.hostedsomewhere.else # port: 6379 + # database: 0 # user: webservice # sentinels: # - host: -- GitLab