Rotate password in redigo client redis pool library

325 views Asked by At

My application is using redigo client library to establish TCP connection with redis server. I want to change the password of the redis at run-time and want the redigo library to use the new password in subsequent connections. ( in redis pool )

I have defined my redis-pool object in the following way to achieve that.

 return &redis.Pool{
        MaxIdle:     5,
        MaxActive:   1000,
        IdleTimeout: time.Minute,
        Dial: func() (redis.Conn, error) {
            cErr = getRedisPassword()
            if cErr != nil {
                return nil, cErr
            }

                   if gRedisAuthPassword != "" {
                           opts[1] =  redis.DialPassword(gRedisAuthPassword)
                   }
            return redis.Dial("tcp", addr, opts...)
        },
        TestOnBorrow: func(c redis.Conn, t time.Time) error {
            _, err := c.Do("PING")
            cErr = err
            return err
        },
    }, nil

Options while calling the function were :

  cluster := &redisc.Cluster{
        StartupNodes: nodesInfo,
        DialOptions:  []redis.DialOption{redis.DialConnectTimeout(5 * time.Second), redis.DialPassword(gRedisAuthPassword)},
        CreatePool:   createPool,

getRedisPassword Function looks like this : This function does call a script which fetches the latest password of the redis cluster.

func getRedisPassword() error {
        var cErr error
        cErr = nil

        if ssFlag == "YES" {
             cmd := exec.Command("/bin/bash", "-c", "/opt/lte/etc/utility/fetch_redisPassword.sh")
             pass, err := cmd.CombinedOutput()
             gRedisAuthPassword = string(pass)
             cErr = err

             // Wait for the process to finish or kill it after a timeout (whichever happens first):
             done := make(chan error, 1)
             go func() {
                     done <- cmd.Wait()
             }()
                  select {
                          case <-time.After(3 * time.Second):
                                  if err := cmd.Process.Kill(); err != nil {
                                   fmt.Println("error:", err)
                                  }
                          case err := <-done:
                                    if err != nil {
                                    fmt.Println("error:", err)
                                        }
                  }
        } else {
                return cErr
        }

        if cErr != nil || gRedisAuthPassword == "null" || gRedisAuthPassword == "" {
          //print log
                        cErr = ErrDbConnFailed
        }

        return cErr
}

I am facing two issues while calling the function:

  1. Lots of curl connections being established and left hanging.
  2. Heavy load causes the goroutine/threads to exhaust.
  3. Script process does not get terminated.

Can you help me with a better method to achieve the same? Thanks in advance.

0

There are 0 answers