-
-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SentinelsClient: Use the given protocol to connect to sentinels #48
Conversation
@@ -60,7 +60,7 @@ def resolve_master | |||
|
|||
def resolve_slave | |||
@sentinel_endpoints.each do |sentinel_endpoint| | |||
client = Client.new(sentinel_endpoint) | |||
client = Client.new(sentinel_endpoint, protocol: @protocol) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this be testable in some way? Can you think of a test that could check that this was the passed protocol?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested this in Fedora following the instructions from #29.
Launch Redis master and replica as containers:
Master:
podman run --rm --net=host redis --port 6379 --requirepass p4ssW0rd --masterauth p4ssW0rd
Slave:
podman run --rm --net=host redis --port 6380 --requirepass p4ssW0rd --masterauth p4ssW0rd --slaveof localhost 6379
Create three sentinel.conf
files with the next content:
port 26379
sentinel monitor redis-master 127.0.0.1 6379 2
sentinel down-after-milliseconds redis-master 5000
sentinel failover-timeout redis-master 60000
requirepass "p4ssW0rd"
sentinel auth-pass redis-master p4ssW0rd
But with a different port for each file: 26379
, 26380
, 26381
.
Then launch the sentinels:
podman run --rm --net=host -v ./sentinel1:/data:z redis /data/sentinel.conf --port 26379 --sentinel
podman run --rm --net=host -v ./sentinel2:/data:z redis /data/sentinel.conf --port 26380 --sentinel
podman run --rm --net=host -v ./sentinel3:/data:z redis /data/sentinel.conf --port 26381 --sentinel
I created this small script to test the PR. Comment/uncomment the proper gemfile line to see the difference between master
and this PR
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem 'async-redis'
#gem 'async-redis', git: 'https://github.com/jlledom/async-redis', branch: 'sentinel-client-protocol'
end
class AuthenticatedRESP2
def initialize(password)
@password = password
end
def client(stream)
client = Async::Redis::Protocol::RESP2.client(stream)
client.write_request(["AUTH", *@password])
client.read_response # Ignore response.
client
end
end
def main
Async do
sentinels = [{ host: "localhost", port: 26379 },
{ host: "localhost", port: 26380 },
{ host: "localhost", port: 26381 }]
protocol = AuthenticatedRESP2.new('p4ssW0rd')
client = Async::Redis::SentinelsClient.new('redis-master', sentinels, :master, protocol)
while true
begin
sleep 1
result = client.ping 'test'
puts result
rescue StandardError => e
puts e.message
retry
end
end
end
end
main
I am planning to introduce It may provide a better foundation for this functionality. We may wish to introduce |
c53d2ae
to
6ee6d48
Compare
Thanks for your contribution. I'm sorry I did not attend to this PR sooner. However, now it's merged and I'll release it soon. |
Thanks @ioquatix. Note how this PR assumes the password for the sentinels and master is the same, it's reusing the same protocol for both. In order to support different credentials for sentinels and master, I ended up using |
@jlledom Let me make a first pass over it, and then if you can give feedback on the design, that would be great. |
See #51 for the updated sentinels code. |
A few thoughts. Now it's possible to supply endpoints for each sentinel which allows them to have different credentials. However, I'm not sure how TLS would or should work for the actual instances. I suppose what we could do is make the address construction a method, and allow sub-classes to override it, because I'm not sure if there is any general approach here. |
I think that's not allowed. The docs say:
I understood this as: it's mandatory that all instances use the same credentials. Also the example sentinels.conf file in the repo is more clear:
If I understood your code correctly, I don't think there's any other way to connect to TLS protected instances than sending |
Understood, so in any case, the sentinels should all have the same credentials. Regarding I added the documentation here: 6a75f89 In this way, the sentinels could be using TLS but it may also need to be identical, or perhaps it's simply not supported? |
I understand.
Sentinels can be TLS protected. According to the docs, a sentinel will listen in the TLS port only when About how to connect to master from |
I think we should provide some more generic mechanism, like |
I was trying to connect to some sentinels that require password authentication. For that, I created a new protocol as in the example: https://github.com/socketry/async-redis/blob/main/examples/auth/protocol.rb
When
SentinelsClient
is used, it ignores the provided protocol when it tries to resolve address for master and slaves. As a result, password protected sentinels are not supported by async-redis.This PR includes a small change to fix that.
Types of Changes
Contribution