mirror of https://github.com/go-redis/redis.git
feat: add acl auth support for sentinels
This commit is contained in:
parent
7c92957d71
commit
f66582f44f
48
main_test.go
48
main_test.go
|
@ -40,15 +40,27 @@ const (
|
|||
sentinelPort3 = "9128"
|
||||
)
|
||||
|
||||
const (
|
||||
aclSentinelUsername = "sentinel-user"
|
||||
aclSentinelPassword = "sentinel-pass"
|
||||
aclSentinelName = "my_server"
|
||||
aclServerPort = "10001"
|
||||
aclSentinelPort1 = "10002"
|
||||
aclSentinelPort2 = "10003"
|
||||
aclSentinelPort3 = "10004"
|
||||
)
|
||||
|
||||
var (
|
||||
sentinelAddrs = []string{":" + sentinelPort1, ":" + sentinelPort2, ":" + sentinelPort3}
|
||||
aclSentinelAddrs = []string {":" + aclSentinelPort1, ":" + aclSentinelPort2, ":" + aclSentinelPort3}
|
||||
|
||||
processes map[string]*redisProcess
|
||||
|
||||
redisMain *redisProcess
|
||||
redisMain, aclServer *redisProcess
|
||||
ringShard1, ringShard2, ringShard3 *redisProcess
|
||||
sentinelMaster, sentinelSlave1, sentinelSlave2 *redisProcess
|
||||
sentinel1, sentinel2, sentinel3 *redisProcess
|
||||
aclSentinel1, aclSentinel2, aclSentinel3 *redisProcess
|
||||
)
|
||||
|
||||
var cluster = &clusterScenario{
|
||||
|
@ -101,6 +113,18 @@ var _ = BeforeSuite(func() {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(startCluster(ctx, cluster)).NotTo(HaveOccurred())
|
||||
|
||||
aclServer, err = startRedis(aclServerPort)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
aclSentinel1, err = startSentinelWithAcl(aclSentinelPort1, aclSentinelName, aclServerPort)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
aclSentinel2, err = startSentinelWithAcl(aclSentinelPort2, aclSentinelName, aclServerPort)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
aclSentinel3, err = startSentinelWithAcl(aclSentinelPort3, aclSentinelName, aclServerPort)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
var _ = AfterSuite(func() {
|
||||
|
@ -364,6 +388,28 @@ func startSentinel(port, masterName, masterPort string) (*redisProcess, error) {
|
|||
return p, nil
|
||||
}
|
||||
|
||||
func startSentinelWithAcl(port, masterName, masterPort string) (*redisProcess, error) {
|
||||
process, err := startSentinel(port, masterName, masterPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, cmd := range []*redis.StatusCmd{
|
||||
redis.NewStatusCmd(ctx, "ACL", "SETUSER", aclSentinelUsername, "ON", ">" + aclSentinelPassword, "-@all",
|
||||
"+auth", "+client|getname", "+client|id", "+client|setname", "+command", "+hello", "+ping", "+role",
|
||||
"+sentinel|get-master-addr-by-name", "+sentinel|master", "+sentinel|myid", "+sentinel|replicas",
|
||||
"+sentinel|sentinels"),
|
||||
} {
|
||||
process.Client.Process(ctx, cmd)
|
||||
if err := cmd.Err(); err != nil {
|
||||
process.Kill()
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return process, nil
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
type badConnError string
|
||||
|
|
|
@ -23,7 +23,13 @@ type FailoverOptions struct {
|
|||
MasterName string
|
||||
// A seed list of host:port addresses of sentinel nodes.
|
||||
SentinelAddrs []string
|
||||
// Sentinel password from "requirepass <password>" (if enabled) in Sentinel configuration
|
||||
|
||||
// If specified with SentinelPassword, enables ACL-based authentication (via
|
||||
// AUTH <user> <pass>).
|
||||
SentinelUsername string
|
||||
// Sentinel password from "requirepass <password>" (if enabled) in Sentinel
|
||||
// configuration, or, if SentinelUsername is also supplied, used for ACL-based
|
||||
// authentication.
|
||||
SentinelPassword string
|
||||
|
||||
// Allows routing read-only commands to the closest master or slave node.
|
||||
|
@ -109,6 +115,7 @@ func (opt *FailoverOptions) sentinelOptions(addr string) *Options {
|
|||
OnConnect: opt.OnConnect,
|
||||
|
||||
DB: 0,
|
||||
Username: opt.SentinelUsername,
|
||||
Password: opt.SentinelPassword,
|
||||
|
||||
MaxRetries: opt.MaxRetries,
|
||||
|
|
|
@ -212,3 +212,62 @@ var _ = Describe("NewFailoverClusterClient", func() {
|
|||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("SentinelAclAuth", func() {
|
||||
var client *redis.Client
|
||||
var server *redis.Client
|
||||
var sentinel *redis.SentinelClient
|
||||
|
||||
BeforeEach(func() {
|
||||
client = redis.NewFailoverClient(&redis.FailoverOptions{
|
||||
MasterName: aclSentinelName,
|
||||
SentinelAddrs: aclSentinelAddrs,
|
||||
MaxRetries: -1,
|
||||
SentinelUsername: aclSentinelUsername,
|
||||
SentinelPassword: aclSentinelPassword,
|
||||
})
|
||||
|
||||
Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred())
|
||||
|
||||
sentinel = redis.NewSentinelClient(&redis.Options{
|
||||
Addr: aclSentinelAddrs[0],
|
||||
MaxRetries: -1,
|
||||
Username: aclSentinelUsername,
|
||||
Password: aclSentinelPassword,
|
||||
})
|
||||
|
||||
addr, err := sentinel.GetMasterAddrByName(ctx, aclSentinelName).Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
server = redis.NewClient(&redis.Options{
|
||||
Addr: net.JoinHostPort(addr[0], addr[1]),
|
||||
MaxRetries: -1,
|
||||
})
|
||||
|
||||
// Wait until sentinels are picked up by each other.
|
||||
Eventually(func() string {
|
||||
return aclSentinel1.Info(ctx).Val()
|
||||
}, "15s", "100ms").Should(ContainSubstring("sentinels=3"))
|
||||
Eventually(func() string {
|
||||
return aclSentinel2.Info(ctx).Val()
|
||||
}, "15s", "100ms").Should(ContainSubstring("sentinels=3"))
|
||||
Eventually(func() string {
|
||||
return aclSentinel3.Info(ctx).Val()
|
||||
}, "15s", "100ms").Should(ContainSubstring("sentinels=3"))
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
_ = client.Close()
|
||||
_ = server.Close()
|
||||
_ = sentinel.Close()
|
||||
})
|
||||
|
||||
It("should still facilitate operations", func() {
|
||||
err := client.Set(ctx, "wow", "acl-auth", 0).Err()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
val, err := client.Get(ctx, "wow").Result()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(val).To(Equal("acl-auth"))
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue