Skip to content
Snippets Groups Projects
Commit e43c9979b550 authored by Balasankar 'Balu' C's avatar Balasankar 'Balu' C
Browse files

Merge branch 'sh-support-sentinel-requirepass' into 'master'

Add support for enabling requirepass in Sentinel configuration

See merge request https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/6923



Merged-by: default avatarBalasankar 'Balu' C <balasankar@gitlab.com>
Approved-by: default avatarDustin Collins <714871-dustinmm80@users.noreply.gitlab.com>
Approved-by: default avatarBalasankar 'Balu' C <balasankar@gitlab.com>
Co-authored-by: default avatarStan Hu <stanhu@gmail.com>
No related branches found
No related tags found
1 merge request!100Upstream Merge of 16.1 CE branching point
Showing
with 128 additions and 3 deletions
......@@ -2811,6 +2811,9 @@
##! Uncomment to change default port
# sentinel['port'] = 26379
##! Uncomment to require a Sentinel password. This may be different from the Redis master password.
# sentinel['password'] = 'sentinel-password-goes-here'
#### Support to run sentinels in a Docker or NAT environment
#####! Docs: https://redis.io/topics/sentinel#sentinel-docker-nat-and-possible-issues
# In an standard case, Sentinel will run in the same network service as Redis, so the same IP will be announce for Redis and Sentinel
......
......@@ -21,6 +21,7 @@
default['gitlab']['sentinel']['log_directory'] = '/var/log/gitlab/sentinel'
default['gitlab']['sentinel']['ha'] = false
default['gitlab']['sentinel']['port'] = 26379
default['gitlab']['sentinel']['password'] = nil
default['gitlab']['sentinel']['quorum'] = 1
default['gitlab']['sentinel']['announce_ip'] = nil
default['gitlab']['sentinel']['announce_port'] = nil
......
......@@ -30,4 +30,10 @@
return unless OmnibusHelper.new(@node).service_up?('sentinel')
command = "/opt/gitlab/embedded/bin/redis-cli -h #{sentinel['bind']} -p #{sentinel['port']} INFO"
env =
if sentinel['password']
{ 'REDISCLI_AUTH' => sentinel['password'] }
else
{}
end
......@@ -33,5 +39,6 @@
command_output = VersionHelper.version(command)
command_output = VersionHelper.version(command, env: env)
raise "Execution of the command `#{command}` failed" unless command_output
version_match = command_output.match(/redis_version:(?<redis_version>\d*\.\d*\.\d*)/)
......
......@@ -76,6 +76,7 @@
)
notifies :restart, 'runit_service[sentinel]', :immediately if omnibus_helper.should_notify?('redis')
only_if { new_resource.config_path }
sensitive true
end
ruby_block 'warn pending sentinel restart' do
......
......@@ -88,6 +88,21 @@
# Default is 30 seconds.
sentinel down-after-milliseconds <%= @redis['master_name'] %> <%= @sentinel['down_after_milliseconds'] %>
# requirepass <password>
#
# You can configure Sentinel itself to require a password, however when doing
# so Sentinel will try to authenticate with the same password to all the
# other Sentinels. So you need to configure all your Sentinels in a given
# group with the same "requirepass" password. Check the following documentation
# for more info: https://redis.io/topics/sentinel
#
# IMPORTANT NOTE: starting with Redis 6.2 "requirepass" is a compatibility
# layer on top of the ACL system. The option effect will be just setting
# the password for the default user. Clients will still authenticate using
# AUTH <password> as usually, or more explicitly with AUTH default <password>
# if they follow the new protocol: both will work.
<%= %Q(requirepass "#{@sentinel['password']}") if @sentinel['password'] %>
# sentinel parallel-syncs <master-name> <numreplicas>
#
# How many replicas we can reconfigure to point to the new replica simultaneously
......
......@@ -21,6 +21,7 @@
class << self
def parse_variables
parse_redis_settings
parse_redis_sentinel_settings
parse_rename_commands
end
......@@ -49,6 +50,16 @@
raise "redis 'master_password' is not defined" unless Gitlab['redis']['master_password']
end
def parse_redis_sentinel_settings
return unless RedisHelper::Checks.sentinel_daemon_enabled?
Gitlab['gitlab_rails']['redis_sentinels_password'] ||= Gitlab['sentinel']['password']
RedisHelper::REDIS_INSTANCES.each do |instance|
Gitlab['gitlab_rails']["redis_#{instance}_sentinels_password"] ||= Gitlab['sentinel']['password']
end
end
def parse_rename_commands
return unless Gitlab['redis']['rename_commands'].nil?
......
......@@ -2,6 +2,7 @@
require 'cgi'
class RedisHelper
REDIS_INSTANCES = %w[cache queues shared_state trace_chunks rate_limiting sessions repository_cache cluster_rate_limiting].freeze
ALLOWED_REDIS_CLUSTER_INSTANCE = %w[rate_limiting cluster_rate_limiting].freeze
def initialize(node)
......
......@@ -263,7 +263,7 @@
sensitive true
end
%w(cache queues shared_state trace_chunks rate_limiting sessions repository_cache cluster_rate_limiting).each do |instance|
RedisHelper::REDIS_INSTANCES.each do |instance|
filename = "redis.#{instance}.yml"
url = node['gitlab']['gitlab_rails']["redis_#{instance}_instance"]
sentinels = node['gitlab']['gitlab_rails']["redis_#{instance}_sentinels"]
......
......@@ -5,6 +5,48 @@
subject { described_class.new(chef_run.node) }
before { allow(Gitlab).to receive(:[]).and_call_original }
context '#running_version' do
let(:cmd) { '/opt/gitlab/embedded/bin/redis-cli -h 0.0.0.0 -p 26379 INFO' }
let(:status_success) { double("status", stdout: 'redis_version:1.2.3', exitstatus: 0) }
let(:gitlab_rb) do
{
redis: {
master_ip: '127.0.0.1',
master_password: 'masterpass'
},
sentinel: {
enable: true,
password: sentinel_password
}
}
end
before do
allow_any_instance_of(OmnibusHelper).to receive(:service_up?).with('sentinel').and_return(true)
stub_gitlab_rb(gitlab_rb)
end
context 'with a Sentinel password defined' do
let(:sentinel_password) { 'some password' }
it 'sets REDISCLI_AUTH' do
expect(VersionHelper).to receive(:do_shell_out).with(cmd, env: { 'REDISCLI_AUTH' => sentinel_password }).and_return(status_success)
expect(subject.running_version).to eq('1.2.3')
end
end
context 'without a Sentinel password defined' do
let(:sentinel_password) { nil }
it 'does not set REDISCLI_AUTH' do
expect(VersionHelper).to receive(:do_shell_out).with(cmd, env: {}).and_return(status_success)
expect(subject.running_version).to eq('1.2.3')
end
end
end
context '#myid' do
context 'when retrieving from config' do
it 'fails when myid is not 40 hex-characters long' do
......
......@@ -60,6 +60,7 @@
expect(content).to match(%r{sentinel failover-timeout gitlab-redis 60000})
expect(content).to match(%r{sentinel auth-pass gitlab-redis blahblahblah})
expect(content).not_to match(%r{^tls})
expect(content).not_to match(%r{^requirepass})
expect(content).to match(%r{SENTINEL resolve-hostnames no})
expect(content).to match(%r{SENTINEL announce-hostnames no})
}
......@@ -164,6 +165,22 @@
}
end
end
context 'user sets sentinel password' do
before do
stub_gitlab_rb(
sentinel: {
password: 'some pass'
}
)
end
it 'enables requirepass' do
expect(chef_run).to render_file(sentinel_conf).with_content { |content|
expect(content).to match(%r{requirepass "some pass"})
}
end
end
end
context 'with tls settings specified' do
......
......@@ -161,6 +161,33 @@
expect(node['redis']['master_password']).to eq redis_password
end
it 'instance Sentinel passwords are nil' do
RedisHelper::REDIS_INSTANCES.each do |instance|
expect(node['gitlab']['gitlab_rails']["redis_#{instance}_sentinels_password"]).to be_nil
end
end
context 'when sentinel password is defined' do
before do
stub_gitlab_rb(
sentinel: {
enable: true,
password: 'sentinel pass!'
},
redis: {
password: redis_password,
master_ip: '10.0.0.0'
}
)
end
it 'instance Sentinel passwords are autofilled based on Sentinel password' do
RedisHelper::REDIS_INSTANCES.each do |instance|
expect(node['gitlab']['gitlab_rails']["redis_#{instance}_sentinels_password"]).to eq('sentinel pass!')
end
end
end
context 'announce_ip is defined' do
let(:redis_port) { 6379 }
let(:redis_announce_ip) { '10.10.10.10' }
......
......@@ -4,7 +4,7 @@
using RSpec::Parameterized::TableSyntax
let(:chef_run) { ChefSpec::SoloRunner.new(step_into: %w(templatesymlink runit_service)).converge('gitlab::default') }
let(:redis_instances) { %w(cache queues shared_state trace_chunks rate_limiting sessions repository_cache) }
let(:redis_instances) { RedisHelper::REDIS_INSTANCES }
let(:redis_cluster_instances) { %w(cluster_rate_limiting) }
let(:config_dir) { '/var/opt/gitlab/gitlab-rails/etc/' }
let(:default_vars) do
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment