Skip to content

Commit 27d225c

Browse files
committed
Add new architecture for RedisHelper
Add a new architecture for Redis Helper where each component gets its own class, and a `redis_params` method to provide the Redis related information that is required for it to populate its own config file. Signed-off-by: Balasankar "Balu" C <[email protected]>
1 parent eba053b commit 27d225c

File tree

2 files changed

+185
-0
lines changed

2 files changed

+185
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
require 'cgi'
2+
require_relative '../../../gitlab/libraries/redis_uri'
3+
4+
module NewRedisHelper
5+
class << self
6+
def build_redis_url(ssl:, host:, port:, path:, password:)
7+
scheme = ssl ? 'rediss:/' : 'redis:/'
8+
uri = URI(scheme)
9+
uri.host = host if host
10+
uri.port = port if port
11+
uri.path = path if path
12+
# In case the password has non-alphanumeric passwords, be sure to encode it
13+
uri.password = CGI.escape(password) if password
14+
15+
uri
16+
end
17+
18+
def build_sentinels_urls(sentinels:, password:)
19+
return [] if sentinels.nil? || sentinels.empty?
20+
21+
sentinels.map do |sentinel|
22+
build_redis_url(
23+
ssl: sentinel['ssl'],
24+
host: sentinel['host'],
25+
port: sentinel['port'],
26+
path: '',
27+
password: password
28+
)
29+
end
30+
end
31+
end
32+
end
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
require_relative '../../../../gitlab/libraries/redis_uri'
2+
3+
module NewRedisHelper
4+
class Base
5+
attr_reader :node
6+
7+
def initialize(node)
8+
@node = node
9+
end
10+
11+
def redis_params
12+
# Defined in each component that extends this class. Should return all
13+
# the Redis related information required by the component to populate
14+
# it's own config file
15+
raise NotImplementedError
16+
end
17+
18+
def redis_credentials
19+
params = if has_sentinels?
20+
master = support_sentinel_groupname? ? master_name : master_ip
21+
[master, master_port, redis_password]
22+
else
23+
[redis_host, redis_port, redis_password]
24+
end
25+
26+
{
27+
host: params[0],
28+
port: params[1],
29+
password: params[2]
30+
}
31+
end
32+
33+
def redis_url
34+
socket = if connect_to_redis_over_tcp?
35+
false
36+
else
37+
redis_socket
38+
end
39+
40+
if socket && !has_sentinels?
41+
uri = URI('unix:/')
42+
uri.path = socket
43+
else
44+
params = redis_credentials
45+
46+
uri = NewRedisHelper.build_redis_url(
47+
ssl: redis_ssl,
48+
host: params[:host],
49+
port: params[:port],
50+
password: params[:password],
51+
path: "/#{redis_database}"
52+
)
53+
end
54+
55+
uri.to_s
56+
end
57+
58+
private
59+
60+
def node_access_keys
61+
# List of keys to obtain the attributes of the service from node object.
62+
# For example ['gitlab', 'gitlab_workhorse'] or ['gitlab_kas']
63+
raise NotImplementedError
64+
end
65+
66+
def gitlab_rb_attr
67+
Gitlab[node_access_keys.last]
68+
end
69+
70+
def node_attr
71+
@node.dig(*node_access_keys)
72+
end
73+
74+
def redis
75+
@node['redis']
76+
end
77+
78+
def redis_server_over_tcp?
79+
redis['port']&.positive? || redis['tls_port']&.positive?
80+
end
81+
82+
def connect_to_redis_over_tcp?
83+
gitlab_rb_attr['redis_host']
84+
end
85+
86+
def redis_replica?
87+
redis['master'] == false
88+
end
89+
90+
def sentinel_daemon_enabled?
91+
Services.enabled?('sentinel')
92+
end
93+
94+
def master_name
95+
node_attr['redis_sentinel_master']
96+
end
97+
98+
def master_ip
99+
node_attr['redis_sentinel_master_ip']
100+
end
101+
102+
def master_port
103+
node_attr['redis_sentinel_master_port']
104+
end
105+
106+
def redis_sentinels_password
107+
node_attr['redis_sentinels_password']
108+
end
109+
110+
def redis_socket
111+
node_attr['redis_socket']
112+
end
113+
114+
def redis_host
115+
node_attr['redis_host']
116+
end
117+
118+
def redis_port
119+
node_attr['redis_port']
120+
end
121+
122+
def redis_password
123+
node_attr['redis_password']
124+
end
125+
126+
def redis_sentinels
127+
node_attr['redis_sentinels']
128+
end
129+
130+
def redis_ssl
131+
!!node_attr['redis_ssl']
132+
end
133+
134+
def redis_database
135+
node_attr['redis_database']
136+
end
137+
138+
def has_sentinels?
139+
node_attr['redis_sentinels'] && !node_attr['redis_sentinels'].empty?
140+
end
141+
142+
def sentinel_urls
143+
NewRedisHelper.build_sentinels_urls(sentinels: redis_sentinels, password: redis_sentinels_password)&.map(&:to_s)
144+
end
145+
146+
def support_sentinel_groupname?
147+
# Defined in each component that extends this class. Should denote
148+
# whether the component can connect to the primary Redis using a
149+
# groupname instead of an IP
150+
raise NotImplementedError
151+
end
152+
end
153+
end

0 commit comments

Comments
 (0)