diff --git a/charts/gitlab/charts/kas/templates/_helpers.tpl b/charts/gitlab/charts/kas/templates/_helpers.tpl index 4c758fcdf43e3d422e4e3c2afe83e2c0daca263c..48aeff95738f84dca6921f921d3c1bcd5a051e42 100644 --- a/charts/gitlab/charts/kas/templates/_helpers.tpl +++ b/charts/gitlab/charts/kas/templates/_helpers.tpl @@ -12,3 +12,25 @@ if there is a shared tls secret for all ingresses. {{- end -}} {{- pluck "secretName" .Values.ingress.tls .Values.global.ingress.tls $defaultName | first -}} {{- end -}} + +{{/* +Build Redis config for KAS +*/}} +{{- define "kas.redis" -}} +{{- if .Values.global.redis.sharedState -}} +{{- $_ := set $ "redisConfigName" "sharedState" -}} +{{- end -}} +{{- include "gitlab.redis.selectedMergedConfig" . -}} +password_file: /etc/kas/redis/{{ printf "%s-password" (default "redis" .redisConfigName) }} +{{- if not .redisMergedConfig.sentinels }} +server: + address: {{ template "gitlab.redis.host" . }}:{{ template "gitlab.redis.port" . }} +{{- else }} +sentinel: + addresses: + {{- range $i, $entry := .redisMergedConfig.sentinels }} + - {{ quote (print (trim $entry.host) ":" ( default 26379 $entry.port | int ) ) -}} + {{ end }} + master_name: {{ template "gitlab.redis.host" . }} +{{- end -}} +{{- end -}} \ No newline at end of file diff --git a/charts/gitlab/charts/kas/templates/configmap.yaml b/charts/gitlab/charts/kas/templates/configmap.yaml index 546fc4073ed70d966fd597252c8474d2720bcad9..1d88697d64d7fbcec6f855f321528e876ac68150 100644 --- a/charts/gitlab/charts/kas/templates/configmap.yaml +++ b/charts/gitlab/charts/kas/templates/configmap.yaml @@ -13,6 +13,8 @@ data: {{- if .Values.customConfig }} {{- .Values.customConfig | toYaml | nindent 4 }} {{- else }} + redis: + {{- include "kas.redis" . | nindent 6 }} agent: listen: address: ":{{ .Values.service.internalPort }}" diff --git a/charts/gitlab/charts/kas/templates/deployment.yaml b/charts/gitlab/charts/kas/templates/deployment.yaml index a605bc75c1f744a67f335ade742f03800b127ffe..b165b84cd4559e665a0e73fc4d762c45b98d0e5a 100644 --- a/charts/gitlab/charts/kas/templates/deployment.yaml +++ b/charts/gitlab/charts/kas/templates/deployment.yaml @@ -88,4 +88,5 @@ spec: items: - key: {{ template "gitlab.kas.key" . }} path: .gitlab_kas_secret + {{- include "gitlab.redis.secrets" . | nindent 12 }} {{- end }} diff --git a/charts/gitlab/charts/kas/values.yaml b/charts/gitlab/charts/kas/values.yaml index 8bef432dd34c3b70ed1601c86765d4955df589e8..febbfa37051b04946b84704a42c40cd381ae5414 100644 --- a/charts/gitlab/charts/kas/values.yaml +++ b/charts/gitlab/charts/kas/values.yaml @@ -6,6 +6,9 @@ annotations: {} global: kas: enabled: false + redis: + # host: '0.0.0.0' + password: {} # hosts: # kas: # name: kas.example.com @@ -57,3 +60,10 @@ securityContext: runAsUser: 65532 runAsGroup: 65532 fsGroup: 65532 +redis: +# sentinel: +# addresses: + # - localhost:6661 # required +# server: +# address: "localhost:6379" + password: {} \ No newline at end of file diff --git a/charts/gitlab/templates/_redis.tpl b/charts/gitlab/templates/_redis.tpl index 6fc3a89bd6786db13ca0b54efb238c6db11bf2e4..5c6c7e37fd1df2a64cda00db30470e86e7f7422d 100644 --- a/charts/gitlab/templates/_redis.tpl +++ b/charts/gitlab/templates/_redis.tpl @@ -64,11 +64,7 @@ Return the password section of the Redis URI, if needed. Build the structure describing sentinels */}} {{- define "gitlab.redis.sentinels" -}} -{{- if .redisConfigName }} -{{- $_ := set . "redisMergedConfig" ( index .Values.global.redis .redisConfigName ) -}} -{{- else -}} -{{- $_ := set . "redisMergedConfig" .Values.global.redis -}} -{{- end -}} +{{- include "gitlab.redis.selectedMergedConfig" . -}} {{- if .redisMergedConfig.sentinels -}} sentinels: {{- range $i, $entry := .redisMergedConfig.sentinels }} @@ -78,6 +74,15 @@ sentinels: {{- end -}} {{- end -}} +{{/*Set redisMergedConfig*/}} +{{- define "gitlab.redis.selectedMergedConfig" -}} +{{- if .redisConfigName }} +{{- $_ := set . "redisMergedConfig" ( index .Values.global.redis .redisConfigName ) -}} +{{- else -}} +{{- $_ := set . "redisMergedConfig" .Values.global.redis -}} +{{- end -}} +{{- end -}} + {{/* Return Sentinel list in format for Workhorse Note: Workhorse only uses the primary Redis (global.redis) diff --git a/spec/configuration/kas_spec.rb b/spec/configuration/kas_spec.rb index ed377ad4bac1fe90c6af8286df70f345b65a5078..9591744c77bd2533c55a67f9ad8a320054f0617f 100644 --- a/spec/configuration/kas_spec.rb +++ b/spec/configuration/kas_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true - require 'spec_helper' +require 'hash_deep_merge' require 'helm_template_helper' require 'yaml' @@ -15,7 +15,7 @@ describe 'kas configuration' do let(:custom_secret_name) { 'kas_custom_secret_name' } let(:custom_config) { {} } - let(:kas_values) do + let(:default_kas_values) do { 'gitlab' => { 'kas' => { @@ -34,6 +34,8 @@ describe 'kas configuration' do } end + let(:kas_values) { default_kas_values } + let(:required_resources) do %w[Deployment ConfigMap Ingress Service HorizontalPodAutoscaler PodDisruptionBudget] end @@ -187,6 +189,94 @@ describe 'kas configuration' do expect(config_yaml_data).to eq(custom_config) end end + + describe 'redis config' do + let(:sentinels) do + { + 'redis' => { + 'host' => 'global.host', + 'sentinels' => [ + { 'host' => 'sentinel1.example.com', 'port' => 26379 }, + { 'host' => 'sentinel2.example.com', 'port' => 26379 } + ] + } + } + end + + context 'when redisConfigName is empty' do + context 'when no sentinel is setup' do + it 'takes the global redis config' do + expect(config_yaml_data['redis']).to include( + "password_file" => "/etc/kas/redis/redis-password", + "server" => { "address" => "test-redis-master.default.svc:6379" }) + end + end + + context 'when sentinel is setup' do + let(:kas_values) do + vals = default_kas_values + vals['global'].deep_merge!(sentinels) + vals.deep_merge!('redis' => { 'install' => false }) + end + + it 'takes the global sentinel redis config' do + expect(config_yaml_data['redis']).to include( + { "sentinel" => { "addresses" => ["sentinel1.example.com:26379", "sentinel2.example.com:26379"], + "master_name" => "global.host" } }) + end + end + end + + context 'when a redis sharedState is setup' do + let(:kas_values) do + vals = default_kas_values + vals['global'].deep_merge!(redis_shared_state_config) + vals.deep_merge!('redis' => { 'install' => false }) + end + let(:redis_shared_state_config) do + { + 'redis' => { + 'host' => "global.host", + 'sharedState' => { + 'host' => "shared.redis", + 'port' => "6378", + 'password' => { + 'enabled' => true, + 'secret' => "shared-secret", + 'key' => "shared-key", + }, + 'sentinels' => sentinels + } + } + } + end + context 'when no sharedState sentinel is setup' do + context 'with no sentinels' do + let(:sentinels) { {} } + it 'configures a sharedState server config' do + expect(config_yaml_data['redis']).to include( + "password_file" => "/etc/kas/redis/sharedState-password", + "server" => { "address" => "shared.redis:6378" }) + end + end + end + + context 'when sharedState sentinel is setup' do + let(:sentinels) do + [ + { 'host' => 'sentinel1.shared.com', 'port' => 26379 }, + { 'host' => 'sentinel2.shared.com', 'port' => 26379 } + ] + end + + it 'configures a sharedState sentinel config' do + expect(config_yaml_data['redis']).to include( + "password_file" => "/etc/kas/redis/sharedState-password", + "sentinel" => { "addresses" => ["sentinel1.shared.com:26379", "sentinel2.shared.com:26379"], "master_name" => "shared.redis" }) + end + end + end + end end end end