@@ -16,6 +16,7 @@ import (
1616type  RedisMasterResolver  struct  {
1717	masterName                string 
1818	sentinelAddr              * net.TCPAddr 
19+ 	sentinelPassword          string 
1920	retryOnMasterResolveFail  int 
2021
2122	masterAddrLock            * sync.RWMutex 
@@ -24,10 +25,11 @@ type RedisMasterResolver struct {
2425	masterAddr  string 
2526}
2627
27- func  NewRedisMasterResolver (masterName  string , sentinelAddr  * net.TCPAddr , retryOnMasterResolveFail  int ) * RedisMasterResolver  {
28+ func  NewRedisMasterResolver (masterName  string , sentinelAddr  * net.TCPAddr , sentinelPassword   string ,  retryOnMasterResolveFail  int ) * RedisMasterResolver  {
2829	return  & RedisMasterResolver {
2930		masterName :               masterName ,
3031		sentinelAddr :             sentinelAddr ,
32+ 		sentinelPassword :         sentinelPassword ,
3133		retryOnMasterResolveFail : retryOnMasterResolveFail ,
3234		masterAddrLock :           & sync.RWMutex {},
3335		initialMasterResolveLock : make (chan  struct {}),
@@ -49,7 +51,7 @@ func (r *RedisMasterResolver) setMasterAddress(masterAddr *net.TCPAddr) {
4951}
5052
5153func  (r  * RedisMasterResolver ) updateMasterAddress () error  {
52- 	masterAddr , err  :=  redisMasterFromSentinelAddr (r .sentinelAddr , r .masterName )
54+ 	masterAddr , err  :=  redisMasterFromSentinelAddr (r .sentinelAddr , r .sentinelPassword ,  r . masterName )
5355	if  err  !=  nil  {
5456		log .Println (err )
5557		return  err 
@@ -59,7 +61,7 @@ func (r *RedisMasterResolver) updateMasterAddress() error {
5961}
6062
6163func  (r  * RedisMasterResolver ) UpdateMasterAddressLoop (ctx  context.Context ) error  {
62- 	if  err  :=  r .initialMasterAdressResolve (); err  !=  nil  {
64+ 	if  err  :=  r .initialMasterAddressResolve (); err  !=  nil  {
6365		return  err 
6466	}
6567
@@ -84,46 +86,70 @@ func (r *RedisMasterResolver) UpdateMasterAddressLoop(ctx context.Context) error
8486	return  err 
8587}
8688
87- func  (r  * RedisMasterResolver ) initialMasterAdressResolve () error  {
89+ func  (r  * RedisMasterResolver ) initialMasterAddressResolve () error  {
8890	defer  close (r .initialMasterResolveLock )
8991	return  r .updateMasterAddress ()
9092}
9193
92- func  redisMasterFromSentinelAddr (sentinelAddress  * net.TCPAddr , masterName  string ) (* net.TCPAddr , error ) {
94+ func  redisMasterFromSentinelAddr (sentinelAddress  * net.TCPAddr , sentinelPassword   string ,  masterName  string ) (* net.TCPAddr , error ) {
9395	conn , err  :=  utils .TCPConnectWithTimeout (sentinelAddress .String ())
94- 	conn .SetDeadline (time .Now ().Add (time .Second ))
9596	if  err  !=  nil  {
9697		return  nil , fmt .Errorf ("error connecting to sentinel: %w" , err )
9798	}
9899	defer  conn .Close ()
99100
100- 	getMasterCommand  :=  fmt .Sprintf ("sentinel get-master-addr-by-name %s\n " , masterName )
101+ 	conn .SetDeadline (time .Now ().Add (time .Second ))
102+ 
103+ 	// Authenticate with sentinel if password is provided 
104+ 	if  sentinelPassword  !=  ""  {
105+ 		authCommand  :=  fmt .Sprintf ("AUTH %s\r \n " , sentinelPassword )
106+ 		if  _ , err  :=  conn .Write ([]byte (authCommand )); err  !=  nil  {
107+ 			return  nil , fmt .Errorf ("error sending AUTH to sentinel: %w" , err )
108+ 		}
109+ 
110+ 		// Read response from AUTH 
111+ 		b  :=  make ([]byte , 256 )
112+ 		n , err  :=  conn .Read (b )
113+ 		if  err  !=  nil  {
114+ 			return  nil , fmt .Errorf ("error reading AUTH response: %w" , err )
115+ 		}
116+ 		response  :=  string (b [:n ])
117+ 		if  ! strings .HasPrefix (response , "+OK" ) {
118+ 			return  nil , fmt .Errorf ("sentinel AUTH failed: %s" , response )
119+ 		}
120+ 	}
121+ 
122+ 	// Request master address 
123+ 	getMasterCommand  :=  fmt .Sprintf ("SENTINEL get-master-addr-by-name %s\r \n " , masterName )
101124	if  _ , err  :=  conn .Write ([]byte (getMasterCommand )); err  !=  nil  {
102125		return  nil , fmt .Errorf ("error writing to sentinel: %w" , err )
103126	}
104127
128+ 	// Read response 
105129	b  :=  make ([]byte , 256 )
106- 	if  _ , err  :=  conn .Read (b ); err  !=  nil  {
130+ 	n , err  :=  conn .Read (b )
131+ 	if  err  !=  nil  {
107132		return  nil , fmt .Errorf ("error getting info from sentinel: %w" , err )
108133	}
109134
110- 	parts   :=   strings . Split ( string ( b ),  " \r \n " ) 
111- 
135+ 	// Extract master address parts 
136+ 	 parts   :=   strings . Split ( string ( b [: n ]),  " \r \n " ) 
112137	if  len (parts ) <  5  {
113138		return  nil , errors .New ("couldn't get master address from sentinel" )
114139	}
115140
116- 	// getting the string address for the  master node  
117- 	stringaddr  :=  fmt .Sprintf ("%s:%s" , parts [2 ], parts [4 ])
118- 	addr , err  :=  net .ResolveTCPAddr ("tcp" , stringaddr )
141+ 	// Assemble  master address  
142+ 	formattedMasterAddress  :=  fmt .Sprintf ("%s:%s" , parts [2 ], parts [4 ])
143+ 	addr , err  :=  net .ResolveTCPAddr ("tcp" , formattedMasterAddress )
119144	if  err  !=  nil  {
120145		return  nil , fmt .Errorf ("error resolving redis master: %w" , err )
121146	}
122147
123- 	// check that  there's actually someone  listening on that  address 
148+ 	// Check if  there is a Redis instance  listening on the master  address 
124149	if  err  :=  checkTCPConnect (addr ); err  !=  nil  {
125150		return  nil , fmt .Errorf ("error checking redis master: %w" , err )
126151	}
152+ 
127153	return  addr , nil 
128154}
129155
0 commit comments