Skip to content

Commit

Permalink
DEVOPS-30643: adds pgbouncer config to set the role before running SQ…
Browse files Browse the repository at this point in the history
…L commands. (#391)
  • Loading branch information
leandrorichardtoledo authored Jan 14, 2025
1 parent e7923bd commit 84f1a71
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 78 deletions.
1 change: 0 additions & 1 deletion dbproxy/cmd/dbproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ func main() {
PGBReloadScript: pgbReloadScript,
LocalAddr: addr,
})

if err != nil {
log.Fatal(err)
}
Expand Down
8 changes: 4 additions & 4 deletions dbproxy/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@ go 1.22.4
require (
github.com/fsnotify/fsnotify v1.7.0
github.com/go-logr/logr v1.4.2
github.com/go-logr/zapr v1.3.0
github.com/lib/pq v1.10.9
go.uber.org/zap v1.27.0
sigs.k8s.io/controller-runtime v0.18.4
)

require (
github.com/go-logr/zapr v1.3.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/text v0.16.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/apimachinery v0.30.1 // indirect
k8s.io/apimachinery v0.30.2 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
Expand Down
16 changes: 8 additions & 8 deletions dbproxy/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -71,14 +71,14 @@ golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand All @@ -94,8 +94,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY=
k8s.io/api v0.30.1/go.mod h1:ddbN2C0+0DIiPntan/bye3SW3PdwLa11/0yqwvuRrJM=
k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U=
k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
k8s.io/apimachinery v0.30.2 h1:fEMcnBj6qkzzPGSVsAZtQThU62SmQ4ZymlXRC5yFSCg=
k8s.io/apimachinery v0.30.2/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
Expand Down
72 changes: 7 additions & 65 deletions dbproxy/pgbouncer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"text/template"
)

// PGBouncerConfig represents a pgbouncer configuration.
type PGBouncerConfig struct {
tmpl *template.Template
configPath string
Expand All @@ -31,8 +32,10 @@ type PGBouncerConfig struct {
UserName string
Password string
SSLMode string
RoleName string
}

// String returns the DSN for the pgbouncer config.
func (pgb *PGBouncerConfig) String() string {
pass := pgb.Password
// Redact all but last 4 characters of password
Expand All @@ -50,7 +53,7 @@ type Params struct {
OutPath string
}

// GenerateConfig generates a pgbouncer config from a dsn
// NewConfig generates a pgbouncer config from a dsn
// The Port is the local port to bind to
// passwordPath is used with old style DSN as db-controller
// tends not to update the password in it
Expand Down Expand Up @@ -82,69 +85,6 @@ func NewConfig(p Params) (*PGBouncerConfig, error) {
return &cfg, nil
}

// FIXME: remove if not used, webhook is hardcoded to
// uri-formatted dsn
func parseOldDSN(content string, passwordPath string) (PGBouncerConfig, error) {
var cfg PGBouncerConfig
fields := strings.Split(string(content), " ")

f := func(c rune) bool {
return (c == '=')
}

m := make(map[string]*string)

for _, field := range fields {
fieldPair := strings.FieldsFunc(field, f)
fieldPair = strings.SplitN(field, "=", 2)
if len(fieldPair) == 2 {
unquotedString := strings.Trim(fieldPair[1], `'`)
m[fieldPair[0]] = &unquotedString
} else if len(fieldPair) == 1 {
m[fieldPair[0]] = nil
}
}

passwordContent, err := ioutil.ReadFile(passwordPath)
if err != nil {
return cfg, err
}

// FIXME: password in dsn never gets updated, read from password key for rotated password
password := string(passwordContent)
m["password"] = &password

if m["host"] == nil {
return cfg, errors.New("host value not found in db credential")
}

if m["port"] == nil {
return cfg, errors.New("port value not found in db credential")
}

if m["dbname"] == nil {
return cfg, errors.New("dbname value not found in db credential")
}

if m["user"] == nil {
return cfg, errors.New("user value not found in db credential")
}

if m["password"] == nil {
return cfg, errors.New("password value not found in db credential")
}

cfg.RemoteHost = *m["host"]
cfg.UserName = *m["user"]
remotePort, _ := strconv.Atoi(*m["port"])
cfg.RemotePort = int16(remotePort)
cfg.Password = *m["password"]
cfg.LocalDbName = *m["dbname"]
cfg.SSLMode = *m["sslmode"]

return cfg, nil
}

func parseURI(c *PGBouncerConfig, dsn string) error {

u, err := url.Parse(dsn)
Expand All @@ -156,6 +96,8 @@ func parseURI(c *PGBouncerConfig, dsn string) error {
return fmt.Errorf("invalid_scheme: %s", u.Scheme)
}

// Ensure this maps to dbuser.SuffixA dbuser.SuffixB
c.RoleName = strings.TrimSuffix(strings.TrimSuffix(u.User.Username(), "_a"), "_b")
c.RemoteHost = u.Hostname()
c.UserName = u.User.Username()
remotePort, err := strconv.Atoi(u.Port())
Expand Down Expand Up @@ -198,6 +140,7 @@ client_tls_sslmode = prefer
client_tls_key_file=dbproxy-client.key
client_tls_cert_file=dbproxy-client.crt
server_tls_sslmode = {{.SSLMode}}
server_reset_query = SET ROLE {{.RoleName}}
#server_tls_key_file=dbproxy-server.key
#server_tls_cert_file=dbproxy-server.crt
`
Expand All @@ -214,7 +157,6 @@ func (config *PGBouncerConfig) Write() error {
return err
}

//func (p *PGBouncerConfig) WritePGBouncerConfig(path string, config *PGBouncerConfig) error {
configFile, err := os.OpenFile(config.configPath, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions dbproxy/pgbouncer/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ client_tls_sslmode = prefer
client_tls_key_file=dbproxy-client.key
client_tls_cert_file=dbproxy-client.crt
server_tls_sslmode = disable
server_reset_query = SET ROLE myuser
#server_tls_key_file=dbproxy-server.key
#server_tls_cert_file=dbproxy-server.crt
`
Expand Down Expand Up @@ -103,6 +104,7 @@ client_tls_sslmode = prefer
client_tls_key_file=dbproxy-client.key
client_tls_cert_file=dbproxy-client.crt
server_tls_sslmode = disable
server_reset_query = SET ROLE myuser
#server_tls_key_file=dbproxy-server.key
#server_tls_cert_file=dbproxy-server.crt
`
Expand Down

0 comments on commit 84f1a71

Please sign in to comment.