Skip to content

Commit 66660c1

Browse files
committed
Support running Redis only over SSL
Changelog: fixed Signed-off-by: Balasankar "Balu" C <[email protected]>
1 parent fe681c0 commit 66660c1

File tree

3 files changed

+119
-33
lines changed

3 files changed

+119
-33
lines changed

files/gitlab-cookbooks/gitlab/libraries/redis.rb

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,27 @@ def parse_redis_daemon!
8080
redis_bind = Gitlab['redis']['bind'] || node['redis']['bind']
8181

8282
Gitlab['gitlab_rails']['redis_host'] ||= redis_bind
83-
Gitlab['gitlab_rails']['redis_port'] ||= Gitlab['redis']['port']
83+
84+
redis_port_config_key = if Gitlab['redis'].key?('port') && !Gitlab['redis']['port'].zero?
85+
# If Redis is specified to run on a non-TLS port
86+
'port'
87+
elsif Gitlab['redis'].key?('tls_port') && !Gitlab['redis']['tls_port'].zero?
88+
# If Redis is specified to run on a TLS port
89+
'tls_port'
90+
else
91+
# If Redis is running on neither ports, then it doesn't matter which
92+
# key we choose as both will return `nil`.
93+
'port'
94+
end
95+
96+
redis_port = Gitlab['redis'][redis_port_config_key]
97+
Gitlab['gitlab_rails']['redis_port'] ||= redis_port
98+
8499
Gitlab['gitlab_rails']['redis_password'] ||= Gitlab['redis']['master_password']
85100

86101
Chef::Log.warn "gitlab-rails 'redis_host' is different than 'bind' value defined for managed redis instance. Are you sure you are pointing to the same redis instance?" if Gitlab['gitlab_rails']['redis_host'] != redis_bind
87102

88-
Chef::Log.warn "gitlab-rails 'redis_port' is different than 'port' value defined for managed redis instance. Are you sure you are pointing to the same redis instance?" if Gitlab['gitlab_rails']['redis_port'] != Gitlab['redis']['port']
103+
Chef::Log.warn "gitlab-rails 'redis_port' is different than '#{redis_port_config_key}' value defined for managed redis instance. Are you sure you are pointing to the same redis instance?" if Gitlab['gitlab_rails']['redis_port'] != redis_port
89104

90105
Chef::Log.warn "gitlab-rails 'redis_password' is different than 'master_password' value defined for managed redis instance. Are you sure you are pointing to the same redis instance?" if Gitlab['gitlab_rails']['redis_password'] != Gitlab['redis']['master_password']
91106
end

files/gitlab-cookbooks/gitlab/libraries/redis_helper.rb

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@ def initialize(node)
99
@node = node
1010
end
1111

12+
def redis
13+
@node['redis']
14+
end
15+
1216
def redis_params(support_sentinel_groupname: true)
1317
gitlab_rails_config = @node['gitlab']['gitlab_rails']
14-
redis_config = @node['redis']
1518

16-
raise 'Redis announce_ip and announce_ip_from_hostname are mutually exclusive, please unset one of them' if redis_config['announce_ip'] && redis_config['announce_ip_from_hostname']
19+
raise 'Redis announce_ip and announce_ip_from_hostname are mutually exclusive, please unset one of them' if redis['announce_ip'] && redis['announce_ip_from_hostname']
1720

1821
params = if RedisHelper::Checks.has_sentinels? && support_sentinel_groupname
19-
[redis_config['master_name'], redis_config['master_port'], redis_config['master_password']]
22+
[redis['master_name'], redis['master_port'], redis['master_password']]
2023
else
2124
host = gitlab_rails_config['redis_host'] || Gitlab['redis']['master_ip']
2225
port = gitlab_rails_config['redis_port'] || Gitlab['redis']['master_port']
@@ -66,8 +69,8 @@ def workhorse_params
6669
url: redis_url,
6770
password: redis_params.last,
6871
sentinels: redis_sentinel_urls('redis_sentinels'),
69-
sentinelMaster: @node['redis']['master_name'],
70-
sentinelPassword: @node['redis']['master_password']
72+
sentinelMaster: redis['master_name'],
73+
sentinelPassword: redis['master_password']
7174
}
7275
end
7376
end
@@ -119,15 +122,7 @@ def running_version
119122
return unless OmnibusHelper.new(@node).service_up?('redis')
120123

121124
commands = ['/opt/gitlab/embedded/bin/redis-cli']
122-
123-
commands << if RedisHelper::Checks.is_redis_tcp?
124-
"-h #{@node['redis']['bind']} -p #{@node['redis']['port']}"
125-
else
126-
"-s #{@node['redis']['unixsocket']}"
127-
end
128-
129-
commands << "-a '#{Gitlab['redis']['password']}'" if Gitlab['redis']['password']
130-
125+
commands << redis_cli_connect_options
131126
commands << "INFO"
132127
command = commands.join(" ")
133128

@@ -154,10 +149,63 @@ def installed_version
154149
version_match['redis_version']
155150
end
156151

152+
def redis_cli_connect_options
153+
args = []
154+
if RedisHelper::Checks.is_redis_tcp?
155+
args = redis_cli_tcp_connect_options(args)
156+
else
157+
args << "-s #{redis['unixsocket']}"
158+
end
159+
160+
args << "-a '#{Gitlab['redis']['password']}'" if Gitlab['redis']['password']
161+
162+
args
163+
end
164+
165+
def redis_cli_tcp_connect_options(args)
166+
args << ["-h #{redis['bind']}"]
167+
port = redis['port'].to_i
168+
169+
if port.zero?
170+
args = redis_cli_tls_options(args)
171+
else
172+
args << "-p #{port}"
173+
end
174+
175+
args
176+
end
177+
178+
def redis_cli_tls_options(args)
179+
tls_port = redis['tls_port'].to_i
180+
181+
args << "--tls"
182+
args << "-p #{tls_port}"
183+
args << "--cacert '#{redis['tls_ca_cert_file']}'" if redis['tls_ca_cert_file']
184+
args << "--cacertdir '#{redis['tls_ca_cert_dir']}'" if redis['tls_ca_cert_dir']
185+
186+
return args unless client_certs_required?
187+
188+
raise "Redis TLS client authentication requires redis['tls_cert_file'] and redis['tls_key_file'] options" unless client_cert_and_key_available?
189+
190+
args << "--cert '#{redis['tls_cert_file']}'"
191+
args << "--key '#{redis['tls_key_file']}'"
192+
193+
args
194+
end
195+
196+
def client_certs_required?
197+
redis['tls_auth_clients'] == 'yes'
198+
end
199+
200+
def client_cert_and_key_available?
201+
redis['tls_cert_file'] && !redis['tls_cert_file'].empty? &&
202+
redis['tls_key_file'] && !redis['tls_key_file'].empty?
203+
end
204+
157205
class Checks
158206
class << self
159207
def is_redis_tcp?
160-
Gitlab['redis']['port'] && Gitlab['redis']['port'].positive?
208+
(Gitlab['redis']['port'] && Gitlab['redis']['port'].positive?) || (Gitlab['redis']['tls_port'] && Gitlab['redis']['tls_port'].positive?)
161209
end
162210

163211
def is_redis_replica?

spec/chef/cookbooks/gitlab/libraries/redis_helper_spec.rb

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -274,40 +274,63 @@
274274
end
275275

276276
context 'over TCP' do
277-
before do
278-
stub_gitlab_rb(
279-
redis: {
280-
bind: '0.0.0.0',
281-
port: 6379
282-
}
283-
)
284-
end
277+
context 'on non-TLS port' do
278+
before do
279+
stub_gitlab_rb(
280+
redis: {
281+
bind: '0.0.0.0',
282+
port: 6379
283+
}
284+
)
285+
end
285286

286-
it 'calls VersionHelper.version with correct arguments' do
287-
expect(VersionHelper).to receive(:version).with('/opt/gitlab/embedded/bin/redis-cli -h 0.0.0.0 -p 6379 INFO')
287+
it 'calls VersionHelper.version with correct arguments' do
288+
expect(VersionHelper).to receive(:version).with('/opt/gitlab/embedded/bin/redis-cli -h 0.0.0.0 -p 6379 INFO')
288289

289-
subject.running_version
290+
subject.running_version
291+
end
290292
end
291293

292-
context 'with a Redis password specified' do
294+
context 'on TLS port' do
293295
before do
294296
stub_gitlab_rb(
295297
redis: {
296298
bind: '0.0.0.0',
297-
port: 6379,
298-
password: 'toomanysecrets'
299+
tls_port: 6380,
300+
tls_cert_file: '/tmp/self_signed.crt',
301+
tls_key_file: '/tmp/self_signed.key',
302+
tls_auth_clients: 'yes'
299303
}
300304
)
301305
end
302306

303-
it 'it passes password to the command' do
304-
expect(VersionHelper).to receive(:version).with("/opt/gitlab/embedded/bin/redis-cli -h 0.0.0.0 -p 6379 -a 'toomanysecrets' INFO")
307+
it 'calls VersionHelper.version with correct arguments' do
308+
expected_args = "-h 0.0.0.0 --tls -p 6380 --cacert '/opt/gitlab/embedded/ssl/certs/cacert.pem' --cacertdir '/opt/gitlab/embedded/ssl/certs/' --cert '/tmp/self_signed.crt' --key '/tmp/self_signed.key'"
309+
expect(VersionHelper).to receive(:version).with("/opt/gitlab/embedded/bin/redis-cli #{expected_args} INFO")
305310

306311
subject.running_version
307312
end
308313
end
309314
end
310315

316+
context 'with a Redis password specified' do
317+
before do
318+
stub_gitlab_rb(
319+
redis: {
320+
bind: '0.0.0.0',
321+
port: 6379,
322+
password: 'toomanysecrets'
323+
}
324+
)
325+
end
326+
327+
it 'it passes password to the command' do
328+
expect(VersionHelper).to receive(:version).with("/opt/gitlab/embedded/bin/redis-cli -h 0.0.0.0 -p 6379 -a 'toomanysecrets' INFO")
329+
330+
subject.running_version
331+
end
332+
end
333+
311334
it 'parses version from redis-cli output properly' do
312335
expect(subject.running_version).to eq('3.2.12')
313336
end

0 commit comments

Comments
 (0)