diff --git a/lib/3scale/backend/storage_helpers.rb b/lib/3scale/backend/storage_helpers.rb index 4ca75c71..a135b07c 100644 --- a/lib/3scale/backend/storage_helpers.rb +++ b/lib/3scale/backend/storage_helpers.rb @@ -222,17 +222,24 @@ def cfg_sentinels_handler(options) sentinels = Splitter.split(sentinels) if sentinels.is_a? String + sentinel_user = nil + sentinel_password = nil sentinels = sentinels.map do |sentinel| - if sentinel.is_a? Hash + next if sentinel.nil? + + if sentinel.respond_to? :strip! + sentinel.strip! + # invalid string if it's empty after stripping next if sentinel.empty? - sentinel.fetch(:host) do - raise InvalidURI.new("(sentinel #{sentinel.inspect})", - 'no host given') - end - sentinel - else - sentinel_to_hash sentinel end + + valid_uri_str = to_redis_uri(sentinel) + # it is safe to perform URI parsing now + uri = URI.parse valid_uri_str + + sentinel_user ||= uri.user + sentinel_password ||= uri.password + { host: uri.host, port: uri.port } end.compact return options if sentinels.empty? @@ -244,11 +251,15 @@ def cfg_sentinels_handler(options) # sentinel port options[:sentinels].each do |sentinel| sentinel[:port] ||= DEFAULT_SENTINEL_PORT - sentinel.delete(:password) if sentinel[:password].nil? || sentinel[:password].empty? end # Handle role option when sentinels are validated options[:role] = role if role && !role.empty? + + # Sentinel credentials + options[:sentinel_username] = sentinel_user unless sentinel_user.to_s.strip.empty? + options[:sentinel_password] = sentinel_password unless sentinel_password.to_s.strip.empty? + options end @@ -285,23 +296,6 @@ def cfg_defaults_handler(options, defaults) cfg_with_defaults end - # helper to convert a sentinel object to a Hash - def sentinel_to_hash(sentinel) - return if sentinel.nil? - - if sentinel.respond_to? :strip! - sentinel.strip! - # invalid string if it's empty after stripping - return if sentinel.empty? - end - - valid_uri_str = to_redis_uri(sentinel) - # it is safe to perform URI parsing now - uri = URI.parse valid_uri_str - - { host: uri.host, port: uri.port, password: uri.password } - end - # split a string by a delimiter character with escaping module Splitter def self.split(str, delimiter: ',', escaper: '\\') diff --git a/test/unit/storage_async_test.rb b/test/unit/storage_async_test.rb index 201fb6fa..f9f266b4 100644 --- a/test/unit/storage_async_test.rb +++ b/test/unit/storage_async_test.rb @@ -68,21 +68,6 @@ def test_sentinels_connection_array_strings conn) end - def test_sentinels_connection_array_hashes - config_obj = { - url: 'redis://master-group-name', - sentinels: [{ host: '127.0.0.1', port: 26_379 }, - {}, - { host: '127.0.0.1', port: 36_379 }, - nil] - } - - conn = StorageAsync::Client.send :new, Storage::Helpers.config_with(config_obj) - assert_sentinel_config({ url: config_obj[:url], - sentinels: config_obj[:sentinels].compact.reject(&:empty?) }, - conn) - end - def test_sentinels_malformed_url config_obj = { url: 'redis://master-group-name', @@ -105,24 +90,6 @@ def test_sentinels_simple_url conn) end - def test_sentinels_array_hashes_default_port - default_sentinel_port = Storage::Helpers.singleton_class.const_get(:DEFAULT_SENTINEL_PORT) - config_obj = { - url: 'redis://master-group-name', - sentinels: [{ host: '127.0.0.1' }, { host: '192.168.1.1' }, - { host: '192.168.1.2', port: nil }, - { host: '127.0.0.1', port: 36379 }] - } - - conn = StorageAsync::Client.send :new, Storage::Helpers.config_with(config_obj) - assert_sentinel_config({ url: config_obj[:url], - sentinels: [{ host: '127.0.0.1', port: default_sentinel_port }, - { host: '192.168.1.1', port: default_sentinel_port }, - { host: '192.168.1.2', port: default_sentinel_port }, - { host: '127.0.0.1', port: 36379 }] }, - conn) - end - def test_sentinels_array_strings_default_port default_sentinel_port = Storage::Helpers.singleton_class.const_get(:DEFAULT_SENTINEL_PORT) config_obj = { @@ -180,7 +147,7 @@ def test_role_empty_when_sentinels_does_not_exist end def test_sentinels_empty - [nil, '', ' ', [], [nil], [''], [' '], [{}]].each do |sentinels_val| + [nil, '', ' ', [], [nil], [''], [' ']].each do |sentinels_val| config_obj = { url: 'redis://master-group-name', sentinels: sentinels_val diff --git a/test/unit/storage_sync_test.rb b/test/unit/storage_sync_test.rb index f9ca69f4..3d6d3142 100644 --- a/test/unit/storage_sync_test.rb +++ b/test/unit/storage_sync_test.rb @@ -72,8 +72,10 @@ def test_sentinels_connection_string_escaped conn = StorageSync.send :new, Storage::Helpers.config_with(config_obj) assert_sentinel_config({ url: config_obj[:url], - sentinels: [{ host: '127.0.0.1', port: 26_379, password: 'passw,ord' }, - { host: '127.0.0.1', port: 36_379 }] }, + sentinels: [{ host: '127.0.0.1', port: 26_379}, + { host: '127.0.0.1', port: 36_379 }], + sentinel_username: 'user', + sentinel_password: 'passw,ord'}, conn) end @@ -90,21 +92,6 @@ def test_sentinels_connection_array_strings conn) end - def test_sentinels_connection_array_hashes - config_obj = { - url: 'redis://master-group-name', - sentinels: [{ host: '127.0.0.1', port: 26_379 }, - {}, - { host: '127.0.0.1', port: 36_379 }, - nil] - } - - conn = StorageSync.send :new, Storage::Helpers.config_with(config_obj) - assert_sentinel_config({ url: config_obj[:url], - sentinels: config_obj[:sentinels].compact.reject(&:empty?) }, - conn) - end - def test_sentinels_malformed_url config_obj = { url: 'redis://master-group-name', @@ -127,24 +114,6 @@ def test_sentinels_simple_url conn) end - def test_sentinels_array_hashes_default_port - default_sentinel_port = Storage::Helpers.singleton_class.const_get(:DEFAULT_SENTINEL_PORT) - config_obj = { - url: 'redis://master-group-name', - sentinels: [{ host: '127.0.0.1' }, { host: '192.168.1.1' }, - { host: '192.168.1.2', port: nil }, - { host: '127.0.0.1', port: 36379 }] - } - - conn = StorageSync.send :new, Storage::Helpers.config_with(config_obj) - assert_sentinel_config({ url: config_obj[:url], - sentinels: [{ host: '127.0.0.1', port: default_sentinel_port }, - { host: '192.168.1.1', port: default_sentinel_port }, - { host: '192.168.1.2', port: default_sentinel_port }, - { host: '127.0.0.1', port: 36379 }] }, - conn) - end - def test_sentinels_array_strings_default_port default_sentinel_port = Storage::Helpers.singleton_class.const_get(:DEFAULT_SENTINEL_PORT) config_obj = { @@ -164,22 +133,6 @@ def test_sentinels_array_strings_default_port conn) end - def test_sentinels_array_hashes_password - config_obj = { - url: 'redis://master-group-name', - sentinels: [{ host: '192.168.1.1', port: 3333, password: 'abc' }, - { host: '192.168.1.2', port: 4444, password: '' }, - { host: '192.168.1.3', port: 5555, password: nil }] - } - - conn = StorageSync.send :new, Storage::Helpers.config_with(config_obj) - assert_sentinel_config({ url: config_obj[:url], - sentinels: [{ host: '192.168.1.1', port: 3333, password: 'abc' }, - { host: '192.168.1.2', port: 4444 }, - { host: '192.168.1.3', port: 5555 }] }, - conn) - end - def test_sentinels_array_strings_password config_obj = { url: 'redis://master-group-name', @@ -190,9 +143,10 @@ def test_sentinels_array_strings_password conn = StorageSync.send :new, Storage::Helpers.config_with(config_obj) assert_sentinel_config({ url: config_obj[:url], - sentinels: [{ host: '192.168.1.1', port: 3333, password: 'abc' }, + sentinels: [{ host: '192.168.1.1', port: 3333 }, { host: '192.168.1.2', port: 4444 }, - { host: '192.168.1.3', port: 5555 }] }, + { host: '192.168.1.3', port: 5555 }], + sentinel_password: 'abc'}, conn) end @@ -234,7 +188,7 @@ def test_role_empty_when_sentinels_does_not_exist end def test_sentinels_empty - [nil, '', ' ', [], [nil], [''], [' '], [{}]].each do |sentinels_val| + [nil, '', ' ', [], [nil], [''], [' ']].each do |sentinels_val| config_obj = { url: 'redis://master-group-name', sentinels: sentinels_val @@ -337,8 +291,10 @@ def assert_sentinel_config(conf, client) conf[:sentinels].each_with_index do |s, i| assert_equal s[:host], config.sentinels[i].host assert_equal s[:port], config.sentinels[i].port - assert_equal s[:password], config.sentinels[i].password end + extra_conf = config.instance_variable_get(:@extra_config) + assert_equal conf[:sentinel_username], extra_conf[:username] + assert_equal conf[:sentinel_password], extra_conf[:password] end def url(url)