Skip to content

Commit e0a9b07

Browse files
committed
Accept sentinels credentials in the URL (#398)
(cherry picked from commit 470d6be)
1 parent a48c695 commit e0a9b07

File tree

3 files changed

+32
-115
lines changed

3 files changed

+32
-115
lines changed

lib/3scale/backend/storage_helpers.rb

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -222,17 +222,24 @@ def cfg_sentinels_handler(options)
222222

223223
sentinels = Splitter.split(sentinels) if sentinels.is_a? String
224224

225+
sentinel_user = nil
226+
sentinel_password = nil
225227
sentinels = sentinels.map do |sentinel|
226-
if sentinel.is_a? Hash
228+
next if sentinel.nil?
229+
230+
if sentinel.respond_to? :strip!
231+
sentinel.strip!
232+
# invalid string if it's empty after stripping
227233
next if sentinel.empty?
228-
sentinel.fetch(:host) do
229-
raise InvalidURI.new("(sentinel #{sentinel.inspect})",
230-
'no host given')
231-
end
232-
sentinel
233-
else
234-
sentinel_to_hash sentinel
235234
end
235+
236+
valid_uri_str = to_redis_uri(sentinel)
237+
# it is safe to perform URI parsing now
238+
uri = URI.parse valid_uri_str
239+
240+
sentinel_user ||= uri.user
241+
sentinel_password ||= uri.password
242+
{ host: uri.host, port: uri.port }
236243
end.compact
237244

238245
return options if sentinels.empty?
@@ -244,11 +251,15 @@ def cfg_sentinels_handler(options)
244251
# sentinel port
245252
options[:sentinels].each do |sentinel|
246253
sentinel[:port] ||= DEFAULT_SENTINEL_PORT
247-
sentinel.delete(:password) if sentinel[:password].nil? || sentinel[:password].empty?
248254
end
249255

250256
# Handle role option when sentinels are validated
251257
options[:role] = role if role && !role.empty?
258+
259+
# Sentinel credentials
260+
options[:sentinel_username] = sentinel_user unless sentinel_user.to_s.strip.empty?
261+
options[:sentinel_password] = sentinel_password unless sentinel_password.to_s.strip.empty?
262+
252263
options
253264
end
254265

@@ -285,23 +296,6 @@ def cfg_defaults_handler(options, defaults)
285296
cfg_with_defaults
286297
end
287298

288-
# helper to convert a sentinel object to a Hash
289-
def sentinel_to_hash(sentinel)
290-
return if sentinel.nil?
291-
292-
if sentinel.respond_to? :strip!
293-
sentinel.strip!
294-
# invalid string if it's empty after stripping
295-
return if sentinel.empty?
296-
end
297-
298-
valid_uri_str = to_redis_uri(sentinel)
299-
# it is safe to perform URI parsing now
300-
uri = URI.parse valid_uri_str
301-
302-
{ host: uri.host, port: uri.port, password: uri.password }
303-
end
304-
305299
# split a string by a delimiter character with escaping
306300
module Splitter
307301
def self.split(str, delimiter: ',', escaper: '\\')

test/unit/storage_async_test.rb

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,6 @@ def test_sentinels_connection_array_strings
6868
conn)
6969
end
7070

71-
def test_sentinels_connection_array_hashes
72-
config_obj = {
73-
url: 'redis://master-group-name',
74-
sentinels: [{ host: '127.0.0.1', port: 26_379 },
75-
{},
76-
{ host: '127.0.0.1', port: 36_379 },
77-
nil]
78-
}
79-
80-
conn = StorageAsync::Client.send :new, Storage::Helpers.config_with(config_obj)
81-
assert_sentinel_config({ url: config_obj[:url],
82-
sentinels: config_obj[:sentinels].compact.reject(&:empty?) },
83-
conn)
84-
end
85-
8671
def test_sentinels_malformed_url
8772
config_obj = {
8873
url: 'redis://master-group-name',
@@ -105,24 +90,6 @@ def test_sentinels_simple_url
10590
conn)
10691
end
10792

108-
def test_sentinels_array_hashes_default_port
109-
default_sentinel_port = Storage::Helpers.singleton_class.const_get(:DEFAULT_SENTINEL_PORT)
110-
config_obj = {
111-
url: 'redis://master-group-name',
112-
sentinels: [{ host: '127.0.0.1' }, { host: '192.168.1.1' },
113-
{ host: '192.168.1.2', port: nil },
114-
{ host: '127.0.0.1', port: 36379 }]
115-
}
116-
117-
conn = StorageAsync::Client.send :new, Storage::Helpers.config_with(config_obj)
118-
assert_sentinel_config({ url: config_obj[:url],
119-
sentinels: [{ host: '127.0.0.1', port: default_sentinel_port },
120-
{ host: '192.168.1.1', port: default_sentinel_port },
121-
{ host: '192.168.1.2', port: default_sentinel_port },
122-
{ host: '127.0.0.1', port: 36379 }] },
123-
conn)
124-
end
125-
12693
def test_sentinels_array_strings_default_port
12794
default_sentinel_port = Storage::Helpers.singleton_class.const_get(:DEFAULT_SENTINEL_PORT)
12895
config_obj = {
@@ -180,7 +147,7 @@ def test_role_empty_when_sentinels_does_not_exist
180147
end
181148

182149
def test_sentinels_empty
183-
[nil, '', ' ', [], [nil], [''], [' '], [{}]].each do |sentinels_val|
150+
[nil, '', ' ', [], [nil], [''], [' ']].each do |sentinels_val|
184151
config_obj = {
185152
url: 'redis://master-group-name',
186153
sentinels: sentinels_val

test/unit/storage_sync_test.rb

Lines changed: 11 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ def test_sentinels_connection_string_escaped
7272

7373
conn = StorageSync.send :new, Storage::Helpers.config_with(config_obj)
7474
assert_sentinel_config({ url: config_obj[:url],
75-
sentinels: [{ host: '127.0.0.1', port: 26_379, password: 'passw,ord' },
76-
{ host: '127.0.0.1', port: 36_379 }] },
75+
sentinels: [{ host: '127.0.0.1', port: 26_379},
76+
{ host: '127.0.0.1', port: 36_379 }],
77+
sentinel_username: 'user',
78+
sentinel_password: 'passw,ord'},
7779
conn)
7880
end
7981

@@ -90,21 +92,6 @@ def test_sentinels_connection_array_strings
9092
conn)
9193
end
9294

93-
def test_sentinels_connection_array_hashes
94-
config_obj = {
95-
url: 'redis://master-group-name',
96-
sentinels: [{ host: '127.0.0.1', port: 26_379 },
97-
{},
98-
{ host: '127.0.0.1', port: 36_379 },
99-
nil]
100-
}
101-
102-
conn = StorageSync.send :new, Storage::Helpers.config_with(config_obj)
103-
assert_sentinel_config({ url: config_obj[:url],
104-
sentinels: config_obj[:sentinels].compact.reject(&:empty?) },
105-
conn)
106-
end
107-
10895
def test_sentinels_malformed_url
10996
config_obj = {
11097
url: 'redis://master-group-name',
@@ -127,24 +114,6 @@ def test_sentinels_simple_url
127114
conn)
128115
end
129116

130-
def test_sentinels_array_hashes_default_port
131-
default_sentinel_port = Storage::Helpers.singleton_class.const_get(:DEFAULT_SENTINEL_PORT)
132-
config_obj = {
133-
url: 'redis://master-group-name',
134-
sentinels: [{ host: '127.0.0.1' }, { host: '192.168.1.1' },
135-
{ host: '192.168.1.2', port: nil },
136-
{ host: '127.0.0.1', port: 36379 }]
137-
}
138-
139-
conn = StorageSync.send :new, Storage::Helpers.config_with(config_obj)
140-
assert_sentinel_config({ url: config_obj[:url],
141-
sentinels: [{ host: '127.0.0.1', port: default_sentinel_port },
142-
{ host: '192.168.1.1', port: default_sentinel_port },
143-
{ host: '192.168.1.2', port: default_sentinel_port },
144-
{ host: '127.0.0.1', port: 36379 }] },
145-
conn)
146-
end
147-
148117
def test_sentinels_array_strings_default_port
149118
default_sentinel_port = Storage::Helpers.singleton_class.const_get(:DEFAULT_SENTINEL_PORT)
150119
config_obj = {
@@ -164,22 +133,6 @@ def test_sentinels_array_strings_default_port
164133
conn)
165134
end
166135

167-
def test_sentinels_array_hashes_password
168-
config_obj = {
169-
url: 'redis://master-group-name',
170-
sentinels: [{ host: '192.168.1.1', port: 3333, password: 'abc' },
171-
{ host: '192.168.1.2', port: 4444, password: '' },
172-
{ host: '192.168.1.3', port: 5555, password: nil }]
173-
}
174-
175-
conn = StorageSync.send :new, Storage::Helpers.config_with(config_obj)
176-
assert_sentinel_config({ url: config_obj[:url],
177-
sentinels: [{ host: '192.168.1.1', port: 3333, password: 'abc' },
178-
{ host: '192.168.1.2', port: 4444 },
179-
{ host: '192.168.1.3', port: 5555 }] },
180-
conn)
181-
end
182-
183136
def test_sentinels_array_strings_password
184137
config_obj = {
185138
url: 'redis://master-group-name',
@@ -190,9 +143,10 @@ def test_sentinels_array_strings_password
190143

191144
conn = StorageSync.send :new, Storage::Helpers.config_with(config_obj)
192145
assert_sentinel_config({ url: config_obj[:url],
193-
sentinels: [{ host: '192.168.1.1', port: 3333, password: 'abc' },
146+
sentinels: [{ host: '192.168.1.1', port: 3333 },
194147
{ host: '192.168.1.2', port: 4444 },
195-
{ host: '192.168.1.3', port: 5555 }] },
148+
{ host: '192.168.1.3', port: 5555 }],
149+
sentinel_password: 'abc'},
196150
conn)
197151
end
198152

@@ -234,7 +188,7 @@ def test_role_empty_when_sentinels_does_not_exist
234188
end
235189

236190
def test_sentinels_empty
237-
[nil, '', ' ', [], [nil], [''], [' '], [{}]].each do |sentinels_val|
191+
[nil, '', ' ', [], [nil], [''], [' ']].each do |sentinels_val|
238192
config_obj = {
239193
url: 'redis://master-group-name',
240194
sentinels: sentinels_val
@@ -337,8 +291,10 @@ def assert_sentinel_config(conf, client)
337291
conf[:sentinels].each_with_index do |s, i|
338292
assert_equal s[:host], config.sentinels[i].host
339293
assert_equal s[:port], config.sentinels[i].port
340-
assert_equal s[:password], config.sentinels[i].password
341294
end
295+
extra_conf = config.instance_variable_get(:@extra_config)
296+
assert_equal conf[:sentinel_username], extra_conf[:username]
297+
assert_equal conf[:sentinel_password], extra_conf[:password]
342298
end
343299

344300
def url(url)

0 commit comments

Comments
 (0)