Move Redis server information to NewRedisHelper

- Continue conversion to the new style redis helper with
  refactors against the redis server functionality methods

Signed-off-by: Balasankar 'Balu' C <balasankar@gitlab.com>
This commit is contained in:
Balasankar 'Balu' C 2024-04-01 18:32:51 +00:00 committed by Robert Marshall
parent 454718e75a
commit be58ec87c6
7 changed files with 242 additions and 224 deletions

View File

@ -116,90 +116,6 @@ class RedisHelper
end
end
def running_version
return unless OmnibusHelper.new(@node).service_up?('redis')
commands = ['/opt/gitlab/embedded/bin/redis-cli']
commands << redis_cli_connect_options
commands << "INFO"
command = commands.join(" ")
command_output = VersionHelper.version(command)
raise "Execution of the command `#{command}` failed" unless command_output
version_match = command_output.match(/redis_version:(?<redis_version>\d*\.\d*\.\d*)/)
raise "Execution of the command `#{command}` generated unexpected output `#{command_output.strip}`" unless version_match
version_match['redis_version']
end
def installed_version
return unless OmnibusHelper.new(@node).service_up?('redis')
command = '/opt/gitlab/embedded/bin/redis-server --version'
command_output = VersionHelper.version(command)
raise "Execution of the command `#{command}` failed" unless command_output
version_match = command_output.match(/Redis server v=(?<redis_version>\d*\.\d*\.\d*)/)
raise "Execution of the command `#{command}` generated unexpected output `#{command_output.strip}`" unless version_match
version_match['redis_version']
end
def redis_cli_connect_options
args = []
if RedisHelper::Checks.is_redis_tcp?
args = redis_cli_tcp_connect_options(args)
else
args << "-s #{redis['unixsocket']}"
end
args << "-a '#{Gitlab['redis']['password']}'" if Gitlab['redis']['password']
args
end
def redis_cli_tcp_connect_options(args)
args << ["-h #{redis['bind']}"]
port = redis['port'].to_i
if port.zero?
args = redis_cli_tls_options(args)
else
args << "-p #{port}"
end
args
end
def redis_cli_tls_options(args)
tls_port = redis['tls_port'].to_i
args << "--tls"
args << "-p #{tls_port}"
args << "--cacert '#{redis['tls_ca_cert_file']}'" if redis['tls_ca_cert_file']
args << "--cacertdir '#{redis['tls_ca_cert_dir']}'" if redis['tls_ca_cert_dir']
return args unless client_certs_required?
raise "Redis TLS client authentication requires redis['tls_cert_file'] and redis['tls_key_file'] options" unless client_cert_and_key_available?
args << "--cert '#{redis['tls_cert_file']}'"
args << "--key '#{redis['tls_key_file']}'"
args
end
def client_certs_required?
redis['tls_auth_clients'] == 'yes'
end
def client_cert_and_key_available?
redis['tls_cert_file'] && !redis['tls_cert_file'].empty? &&
redis['tls_key_file'] && !redis['tls_key_file'].empty?
end
class Checks
class << self
def is_redis_tcp?

View File

@ -0,0 +1,93 @@
# frozen_string_literal: true
require_relative '../version_helper'
module NewRedisHelper
class Server < NewRedisHelper::Base
def installed_version
return unless OmnibusHelper.new(@node).service_up?('redis')
command = '/opt/gitlab/embedded/bin/redis-server --version'
command_output = VersionHelper.version(command)
raise "Execution of the command `#{command}` failed" unless command_output
version_match = command_output.match(/Redis server v=(?<redis_version>\d*\.\d*\.\d*)/)
raise "Execution of the command `#{command}` generated unexpected output `#{command_output.strip}`" unless version_match
version_match['redis_version']
end
def running_version
return unless OmnibusHelper.new(@node).service_up?('redis')
commands = ['/opt/gitlab/embedded/bin/redis-cli']
commands << redis_cli_connect_options
commands << "INFO"
command = commands.join(" ")
command_output = VersionHelper.version(command)
raise "Execution of the command `#{command}` failed" unless command_output
version_match = command_output.match(/redis_version:(?<redis_version>\d*\.\d*\.\d*)/)
raise "Execution of the command `#{command}` generated unexpected output `#{command_output.strip}`" unless version_match
version_match['redis_version']
end
private
def redis_cli_connect_options
args = []
if redis_server_over_tcp?
args = redis_cli_tcp_connect_options(args)
else
args << "-s #{redis['unixsocket']}"
end
args << "-a '#{redis['password']}'" if redis['password']
args
end
def redis_cli_tcp_connect_options(args)
args << ["-h #{redis['bind']}"]
port = redis['port'].to_i
if port.zero?
args = redis_cli_tls_options(args)
else
args << "-p #{port}"
end
args
end
def redis_cli_tls_options(args)
tls_port = redis['tls_port'].to_i
args << "--tls"
args << "-p #{tls_port}"
args << "--cacert '#{redis['tls_ca_cert_file']}'" if redis['tls_ca_cert_file']
args << "--cacertdir '#{redis['tls_ca_cert_dir']}'" if redis['tls_ca_cert_dir']
return args unless client_certs_required?
raise "Redis TLS client authentication requires redis['tls_cert_file'] and redis['tls_key_file'] options" unless client_cert_and_key_available?
args << "--cert '#{redis['tls_cert_file']}'"
args << "--key '#{redis['tls_key_file']}'"
args
end
def client_certs_required?
redis['tls_auth_clients'] == 'yes'
end
def client_cert_and_key_available?
redis['tls_cert_file'] && !redis['tls_cert_file'].empty? &&
redis['tls_key_file'] && !redis['tls_key_file'].empty?
end
end
end

View File

@ -4,7 +4,7 @@ property :socket_group, String
property :dir, String, default: lazy { node['redis']['dir'] }
property :account_helper, default: lazy { AccountHelper.new(node) }, sensitive: true
property :omnibus_helper, default: lazy { OmnibusHelper.new(node) }, sensitive: true
property :redis_helper, default: lazy { RedisHelper.new(node) }, sensitive: true
property :redis_helper, default: lazy { NewRedisHelper::Server.new(node) }, sensitive: true
property :runit_sv_timeout, [Integer, nil], default: lazy { node['redis']['runit_sv_timeout'] }
property :logfiles_helper, default: lazy { LogfilesHelper.new(node) }, sensitive: true

View File

@ -233,139 +233,6 @@ RSpec.describe RedisHelper do
end
end
describe '#running_version' do
let(:redis_cli_output) do
<<~MSG
# Server
redis_version:3.2.12
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:e16da30f4a0a7845
redis_mode:standalone
os:Linux 4.15.0-58-generic x86_64
MSG
end
before do
# Un-doing the stub added in chef_helper
allow_any_instance_of(described_class).to receive(:running_version).and_call_original
allow(Gitlab).to receive(:[]).and_call_original
allow(VersionHelper).to receive(:version).with(/redis-cli.*INFO/).and_return(redis_cli_output)
end
context 'when redis is not running' do
it 'returns nil' do
allow_any_instance_of(OmnibusHelper).to receive(:service_up?).with('redis').and_return(false)
expect(subject.running_version).to be_nil
end
end
context 'when redis is running' do
before do
allow_any_instance_of(OmnibusHelper).to receive(:service_up?).with('redis').and_return(true)
end
context 'over socket' do
it 'calls VersionHelper.version with correct arguments' do
expect(VersionHelper).to receive(:version).with('/opt/gitlab/embedded/bin/redis-cli -s /var/opt/gitlab/redis/redis.socket INFO')
subject.running_version
end
end
context 'over TCP' do
context 'on non-TLS port' do
before do
stub_gitlab_rb(
redis: {
bind: '0.0.0.0',
port: 6379
}
)
end
it 'calls VersionHelper.version with correct arguments' do
expect(VersionHelper).to receive(:version).with('/opt/gitlab/embedded/bin/redis-cli -h 0.0.0.0 -p 6379 INFO')
subject.running_version
end
end
context 'on TLS port' do
before do
stub_gitlab_rb(
redis: {
bind: '0.0.0.0',
tls_port: 6380,
tls_cert_file: '/tmp/self_signed.crt',
tls_key_file: '/tmp/self_signed.key',
tls_auth_clients: 'yes'
}
)
end
it 'calls VersionHelper.version with correct arguments' do
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'"
expect(VersionHelper).to receive(:version).with("/opt/gitlab/embedded/bin/redis-cli #{expected_args} INFO")
subject.running_version
end
end
end
context 'with a Redis password specified' do
before do
stub_gitlab_rb(
redis: {
bind: '0.0.0.0',
port: 6379,
password: 'toomanysecrets'
}
)
end
it 'it passes password to the command' do
expect(VersionHelper).to receive(:version).with("/opt/gitlab/embedded/bin/redis-cli -h 0.0.0.0 -p 6379 -a 'toomanysecrets' INFO")
subject.running_version
end
end
it 'parses version from redis-cli output properly' do
expect(subject.running_version).to eq('3.2.12')
end
end
end
describe '#installed_version' do
let(:redis_server_output) { 'Redis server v=3.2.12 sha=00000000:0 malloc=jemalloc-4.0.3 bits=64 build=e16da30f4a0a7845' }
before do
# Un-doing the stub added in chef_helper
allow_any_instance_of(described_class).to receive(:installed_version).and_call_original
allow(Gitlab).to receive(:[]).and_call_original
allow(VersionHelper).to receive(:version).with(/redis-server --version/).and_return(redis_server_output)
end
context 'when redis is not running' do
it 'returns nil' do
allow_any_instance_of(OmnibusHelper).to receive(:service_up?).with('redis').and_return(false)
expect(subject.installed_version).to be_nil
end
end
context 'when redis is running' do
before do
allow_any_instance_of(OmnibusHelper).to receive(:service_up?).with('redis').and_return(true)
end
it 'parses redis-server output properly' do
expect(subject.installed_version).to eq('3.2.12')
end
end
end
describe '#validate_instance_shard_config' do
before { allow(Gitlab).to receive(:[]).and_call_original }

View File

@ -0,0 +1,142 @@
require 'chef_helper'
RSpec.describe NewRedisHelper::Server do
let(:chef_run) { ChefSpec::SoloRunner.new(step_into: %w(templatesymlink)).converge('gitlab::default') }
subject { described_class.new(chef_run.node) }
describe '#running_version' do
let(:redis_cli_output) do
<<~MSG
# Server
redis_version:3.2.12
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:e16da30f4a0a7845
redis_mode:standalone
os:Linux 4.15.0-58-generic x86_64
MSG
end
before do
# Un-doing the stub added in chef_helper
allow_any_instance_of(described_class).to receive(:running_version).and_call_original
allow(Gitlab).to receive(:[]).and_call_original
allow(VersionHelper).to receive(:version).with(/redis-cli.*INFO/).and_return(redis_cli_output)
allow_any_instance_of(OmnibusHelper).to receive(:service_up?).and_call_original
end
context 'when redis is not running' do
it 'returns nil' do
allow_any_instance_of(OmnibusHelper).to receive(:service_up?).with('redis').and_return(false)
expect(subject.running_version).to be_nil
end
end
context 'when redis is running' do
before do
allow_any_instance_of(OmnibusHelper).to receive(:service_up?).with('redis').and_return(true)
end
context 'over socket' do
it 'calls VersionHelper.version with correct arguments' do
expect(VersionHelper).to receive(:version).with('/opt/gitlab/embedded/bin/redis-cli -s /var/opt/gitlab/redis/redis.socket INFO')
subject.running_version
end
end
context 'over TCP' do
context 'on non-TLS port' do
before do
stub_gitlab_rb(
redis: {
bind: '0.0.0.0',
port: 6379
}
)
end
it 'calls VersionHelper.version with correct arguments' do
expect(VersionHelper).to receive(:version).with('/opt/gitlab/embedded/bin/redis-cli -h 0.0.0.0 -p 6379 INFO')
subject.running_version
end
end
context 'on TLS port' do
before do
stub_gitlab_rb(
redis: {
bind: '0.0.0.0',
tls_port: 6380,
tls_cert_file: '/tmp/self_signed.crt',
tls_key_file: '/tmp/self_signed.key',
tls_auth_clients: 'yes'
}
)
end
it 'calls VersionHelper.version with correct arguments' do
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'"
expect(VersionHelper).to receive(:version).with("/opt/gitlab/embedded/bin/redis-cli #{expected_args} INFO")
subject.running_version
end
end
end
context 'with a Redis password specified' do
before do
stub_gitlab_rb(
redis: {
bind: '0.0.0.0',
port: 6379,
password: 'toomanysecrets'
}
)
end
it 'it passes password to the command' do
expect(VersionHelper).to receive(:version).with("/opt/gitlab/embedded/bin/redis-cli -h 0.0.0.0 -p 6379 -a 'toomanysecrets' INFO")
subject.running_version
end
end
it 'parses version from redis-cli output properly' do
expect(subject.running_version).to eq('3.2.12')
end
end
end
describe '#installed_version' do
let(:redis_server_output) { 'Redis server v=3.2.12 sha=00000000:0 malloc=jemalloc-4.0.3 bits=64 build=e16da30f4a0a7845' }
before do
# Un-doing the stub added in chef_helper
allow_any_instance_of(described_class).to receive(:installed_version).and_call_original
allow(Gitlab).to receive(:[]).and_call_original
allow(VersionHelper).to receive(:version).with(/redis-server --version/).and_return(redis_server_output)
allow_any_instance_of(OmnibusHelper).to receive(:service_up?).and_call_original
end
context 'when redis is not running' do
it 'returns nil' do
allow_any_instance_of(OmnibusHelper).to receive(:service_up?).with('redis').and_return(false)
expect(subject.installed_version).to be_nil
end
end
context 'when redis is running' do
before do
allow_any_instance_of(OmnibusHelper).to receive(:service_up?).with('redis').and_return(true)
end
it 'parses redis-server output properly' do
expect(subject.installed_version).to eq('3.2.12')
end
end
end
end

View File

@ -74,8 +74,8 @@ redis_socket='/var/opt/gitlab/redis/redis.socket'
describe 'pending restart check' do
context 'when running version is same as installed version' do
before do
allow_any_instance_of(RedisHelper).to receive(:running_version).and_return('3.2.12')
allow_any_instance_of(RedisHelper).to receive(:installed_version).and_return('3.2.12')
allow_any_instance_of(NewRedisHelper::Server).to receive(:running_version).and_return('3.2.12')
allow_any_instance_of(NewRedisHelper::Server).to receive(:installed_version).and_return('3.2.12')
end
it 'does not raise a warning' do
@ -85,8 +85,8 @@ redis_socket='/var/opt/gitlab/redis/redis.socket'
context 'when running version is different than installed version' do
before do
allow_any_instance_of(RedisHelper).to receive(:running_version).and_return('3.2.12')
allow_any_instance_of(RedisHelper).to receive(:installed_version).and_return('5.0.9')
allow_any_instance_of(NewRedisHelper::Server).to receive(:running_version).and_return('3.2.12')
allow_any_instance_of(NewRedisHelper::Server).to receive(:installed_version).and_return('5.0.9')
end
it 'raises a warning' do

View File

@ -70,8 +70,8 @@ RSpec.configure do |config|
allow(VersionHelper).to receive(:version).with('/opt/gitlab/embedded/bin/psql --version').and_return('fake_psql_version')
allow(VersionHelper).to receive(:version).with('cat /opt/gitlab/embedded/service/mattermost/VERSION').and_return('foobar')
allow(VersionHelper).to receive(:version).with(/-[-]?version/).and_return('foobar')
allow_any_instance_of(RedisHelper).to receive(:installed_version).and_return('3.2.12')
allow_any_instance_of(RedisHelper).to receive(:running_version).and_return('3.2.12')
allow_any_instance_of(NewRedisHelper::Server).to receive(:installed_version).and_return('3.2.12')
allow_any_instance_of(NewRedisHelper::Server).to receive(:running_version).and_return('3.2.12')
allow_any_instance_of(ConsulHelper).to receive(:installed_version).and_return('1.9.6')
allow_any_instance_of(ConsulHelper).to receive(:running_version).and_return('1.9.6')
stub_command('/sbin/init --version | grep upstart')