From 43130bc5f2335be4c223091d611e45a52941e1bb Mon Sep 17 00:00:00 2001 From: Mitya_Eremeev Date: Tue, 15 Oct 2024 18:07:25 +0300 Subject: [PATCH] Added feature to get password from Vault To use the feature we need to set the following options in config section 'client': use_vault = true vault_address = http:// vault_role_id = vault_secret_id = vault_secret_path = /dev/user/passwords_yml> vault_secret_mount_path = credential_name_in_vault_secret = https://github.com/prometheus/mysqld_exporter/issues/883 Signed-off-by: Mitya_Eremeev --- .gitignore | 2 ++ config/config.go | 76 ++++++++++++++++++++++++++++++++++++++++++++---- go.mod | 8 +++++ go.sum | 19 ++++++++++++ 4 files changed, 99 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 5c3bd96be..6fbad666a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ .idea *.iml /vendor + +.my.cnf diff --git a/config/config.go b/config/config.go index a69805113..9e3d0a695 100644 --- a/config/config.go +++ b/config/config.go @@ -23,10 +23,14 @@ import ( "strconv" "strings" "sync" + "context" "github.com/go-sql-driver/mysql" "github.com/prometheus/client_golang/prometheus" + "github.com/hashicorp/vault-client-go" + "github.com/hashicorp/vault-client-go/schema" + "gopkg.in/ini.v1" ) @@ -93,13 +97,9 @@ func (ch *MySqlConfigHandler) ReloadConfig(filename string, mysqldAddress string } }() - cfg, err := ini.LoadSources( - opts, - []byte("[client]\npassword = ${MYSQLD_EXPORTER_PASSWORD}\n"), - filename, - ) + cfg, err := PutPasswordInConfig(filename, logger ) if err != nil { - return fmt.Errorf("failed to load config from %s: %w", filename, err) + return fmt.Errorf("failed to put password in config file: %w", err) } if host, port, err = net.SplitHostPort(mysqldAddress); err != nil { @@ -234,3 +234,67 @@ func (m MySqlConfig) CustomizeTLS() error { mysql.RegisterTLSConfig("custom", &tlsCfg) return nil } + +func PutPasswordInConfig(filename string, logger *slog.Logger) (cfg *ini.File, err error) { + cfg, err = ini.LoadSources(opts, filename,) + if err != nil { + return nil, fmt.Errorf("failed to load config file %s: %w", filename, err) + } + + clientSection := cfg.Section("client") + if clientSection == nil { + logger.Error("msg", "no section 'client' in config", "err", err) + return nil, fmt.Errorf("error: %w", err) + } + useVault, err := clientSection.Key("use_vault").Bool() + if err != nil { + logger.Error("msg", "failed to get 'use_vault'", "err", err) + return nil, fmt.Errorf("error: %w", err) + } + + password := "${MYSQLD_EXPORTER_PASSWORD}" + if useVault { + client, err := vault.New(vault.WithAddress(clientSection.Key("vault_address").String()),) + if err != nil { + logger.Error("msg", "failed to create vault client", "err", err) + return nil, fmt.Errorf("error: %w", err) + } + ctx := context.Background() + resp, err := client.Auth.AppRoleLogin( + ctx, + schema.AppRoleLoginRequest{ + RoleId: clientSection.Key("vault_role_id").String(), + SecretId: clientSection.Key("vault_secret_id").String(), + }, + ) + if err != nil { + logger.Error("msg", "failed to login to vault", "err", err) + return nil, fmt.Errorf("error: %w", err) + } + if err := client.SetToken(resp.Auth.ClientToken); err != nil { + logger.Error("msg", "failed to set vault token", "err", err) + return nil, fmt.Errorf("error: %w", err) + } + data, err := client.Secrets.KvV2Read( + ctx, + clientSection.Key("vault_secret_path").String(), + vault.WithMountPath(clientSection.Key("vault_secret_mount_path").String()), + ) + if err != nil { + logger.Error("msg", "failed to get data", "err", err) + return nil, fmt.Errorf("error: %w", err) + } + + password = data.Data.Data[clientSection.Key("credential_name_in_vault_secret").String()].(string) + } + + cfg, err = ini.LoadSources( + opts, + []byte("[client]\npassword = " + password + "\n"), + filename, + ) + if err != nil { + return nil, fmt.Errorf("failed to load %s: %w", filename, err) + } + return cfg, nil +} diff --git a/go.mod b/go.mod index 17ba2ac16..0d49085f3 100644 --- a/go.mod +++ b/go.mod @@ -24,14 +24,21 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-retryablehttp v0.7.1 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/vault-client-go v0.4.3 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/mdlayher/socket v0.4.1 // indirect github.com/mdlayher/vsock v1.2.1 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/prometheus/procfs v0.15.1 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect github.com/smarty/assertions v1.15.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect golang.org/x/crypto v0.27.0 // indirect @@ -40,6 +47,7 @@ require ( golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect + golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 663a1a4f1..45df64a8f 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,18 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ= +github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/vault-client-go v0.4.3 h1:zG7STGVgn/VK6rnZc0k8PGbfv2x/sJExRKHSUg3ljWc= +github.com/hashicorp/vault-client-go v0.4.3/go.mod h1:4tDw7Uhq5XOxS1fO+oMtotHL7j4sB9cp0T7U6m4FzDY= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= @@ -43,6 +55,8 @@ github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ= github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= @@ -61,11 +75,14 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -83,6 +100,8 @@ golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=