# HG changeset patch
# User Balasankar 'Balu' C <balasankar@gitlab.com>
# Date 1715800138 0
#      Wed May 15 19:08:58 2024 +0000
# Node ID 859456e3343d302f336da2b8c8132f83e9b3dd85
# Parent  036454d4ba60c13fdf09271f902e0b9c299f63fe
Migrate Gitlab Rails to NewRedisHelper logic

- Moves the Gitlab Rails library to use the new
  redis helper logic code path.

Signed-off-by: Balasankar 'Balu' C <balasankar@gitlab.com>

diff --git a/files/gitlab-cookbooks/gitlab/libraries/gitlab_rails.rb b/files/gitlab-cookbooks/gitlab/libraries/gitlab_rails.rb
--- a/files/gitlab-cookbooks/gitlab/libraries/gitlab_rails.rb
+++ b/files/gitlab-cookbooks/gitlab/libraries/gitlab_rails.rb
@@ -17,7 +17,7 @@
 require_relative 'nginx.rb'
 require_relative '../../gitaly/libraries/gitaly.rb'
 require_relative '../../package/libraries/settings_dsl.rb'
-require_relative 'redis_helper'
+require_relative '../../package/libraries/helpers/new_redis_helper/gitlab_rails'
 
 module GitlabRails
   ALLOWED_DATABASES = %w[main ci geo embedding].freeze
@@ -328,7 +328,7 @@
       # This requires the parse_shared_dir to be executed before
       encrypted_settings_path = Gitlab['gitlab_rails']['encrypted_settings_path'] ||= File.join(Gitlab['gitlab_rails']['shared_path'], 'encrypted_settings')
 
-      RedisHelper::REDIS_INSTANCES.each do |instance|
+      NewRedisHelper::GitlabRails::REDIS_INSTANCES.each do |instance|
         Gitlab['gitlab_rails']["redis_#{instance}_encrypted_settings_file"] ||= Gitlab['gitlab_rails']['redis_encrypted_settings_file'] || File.join(encrypted_settings_path, "redis.#{instance}.yml.enc")
       end
 
@@ -339,7 +339,7 @@
     end
 
     def parse_redis_extra_config_command
-      RedisHelper::REDIS_INSTANCES.each do |instance|
+      NewRedisHelper::GitlabRails::REDIS_INSTANCES.each do |instance|
         Gitlab['gitlab_rails']["redis_#{instance}_extra_config_command"] ||= Gitlab['gitlab_rails']['redis_extra_config_command']
       end
     end
diff --git a/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb b/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb
--- a/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb
+++ b/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb
@@ -19,7 +19,7 @@
 omnibus_helper = OmnibusHelper.new(node)
 consul_helper = ConsulHelper.new(node)
 mailroom_helper = MailroomHelper.new(node)
-redis_helper = RedisHelper.new(node)
+redis_helper = NewRedisHelper::GitlabRails.new(node)
 logfiles_helper = LogfilesHelper.new(node)
 logging_settings = logfiles_helper.logging_settings('gitlab-rails')
 
@@ -189,7 +189,7 @@
   sensitive true
 end
 
-redis_url = redis_helper.redis_url
+redis_url = redis_helper.redis_params[:url]
 redis_sentinels = node['gitlab']['gitlab_rails']['redis_sentinels']
 redis_sentinels_password = node['gitlab']['gitlab_rails']['redis_sentinels_password']
 redis_enable_client = node['gitlab']['gitlab_rails']['redis_enable_client']
@@ -277,7 +277,7 @@
   sensitive true
 end
 
-RedisHelper::REDIS_INSTANCES.each do |instance|
+NewRedisHelper::GitlabRails::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"]
diff --git a/files/gitlab-cookbooks/package/libraries/helpers/new_redis_helper/gitlab_rails.rb b/files/gitlab-cookbooks/package/libraries/helpers/new_redis_helper/gitlab_rails.rb
new file mode 100644
--- /dev/null
+++ b/files/gitlab-cookbooks/package/libraries/helpers/new_redis_helper/gitlab_rails.rb
@@ -0,0 +1,32 @@
+module NewRedisHelper
+  class GitlabRails < NewRedisHelper::Base
+    REDIS_INSTANCES = %w[cache queues shared_state trace_chunks rate_limiting sessions repository_cache cluster_rate_limiting workhorse].freeze
+    ALLOWED_REDIS_CLUSTER_INSTANCE = %w[cache rate_limiting cluster_rate_limiting].freeze
+
+    def redis_params
+      {
+        url: redis_url
+      }
+    end
+
+    def validate_instance_shard_config(instance)
+      sentinels = node_attr["redis_#{instance}_sentinels"]
+      clusters = node_attr["redis_#{instance}_cluster_nodes"]
+
+      return if clusters.empty?
+
+      raise "Both sentinel and cluster configurations are defined for #{instance}" unless sentinels.empty?
+      raise "Cluster mode is not allowed for #{instance}" unless ALLOWED_REDIS_CLUSTER_INSTANCE.include?(instance)
+    end
+
+    private
+
+    def node_access_keys
+      %w[gitlab gitlab_rails]
+    end
+
+    def support_sentinel_groupname?
+      true
+    end
+  end
+end
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
@@ -232,82 +232,4 @@
       end
     end
   end
-
-  describe '#validate_instance_shard_config' do
-    before { allow(Gitlab).to receive(:[]).and_call_original }
-
-    context 'with both sentinels and cluster declared' do
-      before do
-        stub_gitlab_rb(
-          gitlab_rails: {
-            redis_cache_sentinels: [
-              { 'host' => 'sentinel1.example.com', 'port' => '12345' },
-              { 'host' => 'sentinel2.example.com', 'port' => '12345' }
-            ],
-            redis_cache_cluster_nodes: [
-              { 'host' => 'cluster1.example.com', 'port' => '12345' },
-              { 'host' => 'cluster1.example.com', 'port' => '12345' }
-            ]
-          }
-        )
-      end
-
-      it 'raises error' do
-        expect { subject.validate_instance_shard_config('cache') }.to raise_error(RuntimeError)
-      end
-    end
-
-    context 'with only sentinels declared' do
-      before do
-        stub_gitlab_rb(
-          gitlab_rails: {
-            redis_cache_sentinels: [
-              { 'host' => 'sentinel1.example.com', 'port' => '12345' },
-              { 'host' => 'sentinel2.example.com', 'port' => '12345' }
-            ]
-          }
-        )
-      end
-
-      it 'does not raise error' do
-        expect { subject.validate_instance_shard_config('cache') }.not_to raise_error(RuntimeError)
-
-        subject
-      end
-    end
-
-    context 'with only clusters declared' do
-      before do
-        stub_gitlab_rb(
-          gitlab_rails: {
-            redis_rate_limiting_cluster_nodes: [
-              { 'host' => 'cluster1.example.com', 'port' => '12345' },
-              { 'host' => 'cluster1.example.com', 'port' => '12345' }
-            ]
-          }
-        )
-      end
-
-      it 'does not raise error' do
-        expect { subject.validate_instance_shard_config('rate_limiting') }.not_to raise_error(RuntimeError)
-      end
-    end
-
-    context 'with cluster declared for instances outside allowed list' do
-      before do
-        stub_gitlab_rb(
-          gitlab_rails: {
-            redis_sessions_cluster_nodes: [
-              { 'host' => 'cluster1.example.com', 'port' => '12345' },
-              { 'host' => 'cluster1.example.com', 'port' => '12345' }
-            ]
-          }
-        )
-      end
-
-      it 'raises error' do
-        expect { subject.validate_instance_shard_config('sessions') }.to raise_error(RuntimeError)
-      end
-    end
-  end
 end
diff --git a/spec/chef/cookbooks/package/libraries/new_redis_helper/gitlab_rails_spec.rb b/spec/chef/cookbooks/package/libraries/new_redis_helper/gitlab_rails_spec.rb
new file mode 100644
--- /dev/null
+++ b/spec/chef/cookbooks/package/libraries/new_redis_helper/gitlab_rails_spec.rb
@@ -0,0 +1,85 @@
+require 'chef_helper'
+
+RSpec.describe NewRedisHelper::GitlabRails do
+  let(:chef_run) { ChefSpec::SoloRunner.new(step_into: %w(templatesymlink)).converge('gitlab::default') }
+
+  subject { described_class.new(chef_run.node) }
+
+  describe '#validate_instance_shard_config' do
+    before { allow(Gitlab).to receive(:[]).and_call_original }
+
+    context 'with both sentinels and cluster declared' do
+      before do
+        stub_gitlab_rb(
+          gitlab_rails: {
+            redis_cache_sentinels: [
+              { 'host' => 'sentinel1.example.com', 'port' => '12345' },
+              { 'host' => 'sentinel2.example.com', 'port' => '12345' }
+            ],
+            redis_cache_cluster_nodes: [
+              { 'host' => 'cluster1.example.com', 'port' => '12345' },
+              { 'host' => 'cluster1.example.com', 'port' => '12345' }
+            ]
+          }
+        )
+      end
+
+      it 'raises error' do
+        expect { subject.validate_instance_shard_config('cache') }.to raise_error(RuntimeError)
+      end
+    end
+
+    context 'with only sentinels declared' do
+      before do
+        stub_gitlab_rb(
+          gitlab_rails: {
+            redis_cache_sentinels: [
+              { 'host' => 'sentinel1.example.com', 'port' => '12345' },
+              { 'host' => 'sentinel2.example.com', 'port' => '12345' }
+            ]
+          }
+        )
+      end
+
+      it 'does not raise error' do
+        expect { subject.validate_instance_shard_config('cache') }.not_to raise_error(RuntimeError)
+
+        subject
+      end
+    end
+
+    context 'with only clusters declared' do
+      before do
+        stub_gitlab_rb(
+          gitlab_rails: {
+            redis_rate_limiting_cluster_nodes: [
+              { 'host' => 'cluster1.example.com', 'port' => '12345' },
+              { 'host' => 'cluster1.example.com', 'port' => '12345' }
+            ]
+          }
+        )
+      end
+
+      it 'does not raise error' do
+        expect { subject.validate_instance_shard_config('rate_limiting') }.not_to raise_error(RuntimeError)
+      end
+    end
+
+    context 'with cluster declared for instances outside allowed list' do
+      before do
+        stub_gitlab_rb(
+          gitlab_rails: {
+            redis_sessions_cluster_nodes: [
+              { 'host' => 'cluster1.example.com', 'port' => '12345' },
+              { 'host' => 'cluster1.example.com', 'port' => '12345' }
+            ]
+          }
+        )
+      end
+
+      it 'raises error' do
+        expect { subject.validate_instance_shard_config('sessions') }.to raise_error(RuntimeError)
+      end
+    end
+  end
+end