# HG changeset patch
# User Balasankar 'Balu' C <balasankar@gitlab.com>
# Date 1711996371 0
#      Mon Apr 01 18:32:51 2024 +0000
# Node ID 148acfeedb99ad38e676d489071e783cd890583e
# Parent  a03e6c9b33d970ba1e2f06c7e268492b7545ed3c
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>

diff --git a/files/gitlab-cookbooks/gitlab/libraries/redis_helper.rb b/files/gitlab-cookbooks/gitlab/libraries/redis_helper.rb
--- a/files/gitlab-cookbooks/gitlab/libraries/redis_helper.rb
+++ b/files/gitlab-cookbooks/gitlab/libraries/redis_helper.rb
@@ -116,90 +116,6 @@
     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?
diff --git a/files/gitlab-cookbooks/package/libraries/helpers/new_redis_helper/server.rb b/files/gitlab-cookbooks/package/libraries/helpers/new_redis_helper/server.rb
new file mode 100644
--- /dev/null
+++ b/files/gitlab-cookbooks/package/libraries/helpers/new_redis_helper/server.rb
@@ -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
diff --git a/files/gitlab-cookbooks/redis/resources/service.rb b/files/gitlab-cookbooks/redis/resources/service.rb
--- a/files/gitlab-cookbooks/redis/resources/service.rb
+++ b/files/gitlab-cookbooks/redis/resources/service.rb
@@ -4,7 +4,7 @@
 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
 
diff --git a/spec/chef/cookbooks/gitlab/libraries/redis_helper_spec.rb b/spec/chef/cookbooks/gitlab/libraries/redis_helper_spec.rb
--- a/spec/chef/cookbooks/gitlab/libraries/redis_helper_spec.rb
+++ b/spec/chef/cookbooks/gitlab/libraries/redis_helper_spec.rb
@@ -233,139 +233,6 @@
     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 }
 
diff --git a/spec/chef/cookbooks/package/libraries/new_redis_helper/server_spec.rb b/spec/chef/cookbooks/package/libraries/new_redis_helper/server_spec.rb
new file mode 100644
--- /dev/null
+++ b/spec/chef/cookbooks/package/libraries/new_redis_helper/server_spec.rb
@@ -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
diff --git a/spec/chef/cookbooks/redis/recipes/redis_spec.rb b/spec/chef/cookbooks/redis/recipes/redis_spec.rb
--- a/spec/chef/cookbooks/redis/recipes/redis_spec.rb
+++ b/spec/chef/cookbooks/redis/recipes/redis_spec.rb
@@ -74,8 +74,8 @@
     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 @@
 
       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
diff --git a/spec/chef_helper.rb b/spec/chef_helper.rb
--- a/spec/chef_helper.rb
+++ b/spec/chef_helper.rb
@@ -70,8 +70,8 @@
     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')