Я решил эту проблему, создав собственный драйвер, который импортирует github.com/go-sql-driver/mysql и регистрируется в пакете sql, так что, когда требуется новое соединение, драйвер пользователя может получить пароль из хранилище и передать его драйверу MySQL, чтобы открыть соединение См. Пример кода ниже.
package vault-mysql-driver
import (
"database/sql"
"github.com/go-sql-driver/mysql"
)
type VaultMysqlDriver struct {
*mysql.MySQLDriver
}
func updateDsn(dsn string) (string, err) {
// logic to fetch password from vault and update dsn with the password
}
func (d VaultMysqlDriver) Open(dsn string) (driver.Conn, error) {
updateddsn, err := updateDsn(dsn)
// Pass down the dsn with password to mysql driver's open function
return d.MySQLDriver.Open(updateddsn)
}
// When initialised will register the driver in sql package
func init() {
sql.Register(vault-driver, &CyberarkMysqlDriver{&mysql.MySQLDriver{}})
}
Этот пакет теперь импортируется в демон, как показано ниже,
import (
"database/sql"
_ "vault-mysql-driver"// init is invoked and it will get registered in sql package
"net"
)
var db *sql.DB
const port = "port number"
func main() {
// vault-driver is used instead of mysql so that the sql package knows to use the custom driver for new connections.
db, err = sql.Open("vault-driver","<Connection string that contains the password fetched from vault>")
db.SetMaxOpenConns(100)
listener, err := net.Listen("tcp", ":"+port)
for {
conn, err := listener.Accept()
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
// Uses db variable to connect to db.
}
Таким образом, всякий раз, когда хранилище поворачивает пароль, не будет никакого сбоя соединения, так как драйвер хранилища всегда будет извлекать пароль из хранилища для каждого нового соединения.