14
14
package config
15
15
16
16
import (
17
+ "context"
17
18
"crypto/tls"
18
19
"crypto/x509"
19
20
"fmt"
@@ -27,6 +28,9 @@ import (
27
28
"github.com/go-sql-driver/mysql"
28
29
"github.com/prometheus/client_golang/prometheus"
29
30
31
+ "github.com/hashicorp/vault-client-go"
32
+ "github.com/hashicorp/vault-client-go/schema"
33
+
30
34
"gopkg.in/ini.v1"
31
35
)
32
36
@@ -93,13 +97,9 @@ func (ch *MySqlConfigHandler) ReloadConfig(filename string, mysqldAddress string
93
97
}
94
98
}()
95
99
96
- cfg , err := ini .LoadSources (
97
- opts ,
98
- []byte ("[client]\n password = ${MYSQLD_EXPORTER_PASSWORD}\n " ),
99
- filename ,
100
- )
100
+ cfg , err := PutPasswordInConfig (filename , logger )
101
101
if err != nil {
102
- return fmt .Errorf ("failed to load config from %s : %w" , filename , err )
102
+ return fmt .Errorf ("failed to put password in config file : %w" , err )
103
103
}
104
104
105
105
if host , port , err = net .SplitHostPort (mysqldAddress ); err != nil {
@@ -234,3 +234,63 @@ func (m MySqlConfig) CustomizeTLS() error {
234
234
mysql .RegisterTLSConfig ("custom" , & tlsCfg )
235
235
return nil
236
236
}
237
+
238
+ func PutPasswordInConfig (filename string , logger * slog.Logger ) (cfg * ini.File , err error ) {
239
+ cfg , err = ini .LoadSources (opts , filename )
240
+ if err != nil {
241
+ return nil , fmt .Errorf ("failed to load config file %s: %w" , filename , err )
242
+ }
243
+
244
+ clientSection := cfg .Section ("client" )
245
+ if clientSection == nil {
246
+ logger .Error ("msg" , "no section 'client' in config" , "err" , err )
247
+ return nil , fmt .Errorf ("error: %w" , err )
248
+ }
249
+
250
+ password := "${MYSQLD_EXPORTER_PASSWORD}"
251
+
252
+ if clientSection .Key ("use_vault" ).MustBool () {
253
+ client , err := vault .New (vault .WithAddress (clientSection .Key ("vault_address" ).String ()))
254
+ if err != nil {
255
+ logger .Error ("msg" , "failed to create vault client" , "err" , err )
256
+ return nil , fmt .Errorf ("error: %w" , err )
257
+ }
258
+ ctx := context .Background ()
259
+ resp , err := client .Auth .AppRoleLogin (
260
+ ctx ,
261
+ schema.AppRoleLoginRequest {
262
+ RoleId : clientSection .Key ("vault_role_id" ).String (),
263
+ SecretId : clientSection .Key ("vault_secret_id" ).String (),
264
+ },
265
+ )
266
+ if err != nil {
267
+ logger .Error ("msg" , "failed to login to vault" , "err" , err )
268
+ return nil , fmt .Errorf ("error: %w" , err )
269
+ }
270
+ if err := client .SetToken (resp .Auth .ClientToken ); err != nil {
271
+ logger .Error ("msg" , "failed to set vault token" , "err" , err )
272
+ return nil , fmt .Errorf ("error: %w" , err )
273
+ }
274
+ data , err := client .Secrets .KvV2Read (
275
+ ctx ,
276
+ clientSection .Key ("vault_secret_path" ).String (),
277
+ vault .WithMountPath (clientSection .Key ("vault_secret_mount_path" ).String ()),
278
+ )
279
+ if err != nil {
280
+ logger .Error ("msg" , "failed to get data" , "err" , err )
281
+ return nil , fmt .Errorf ("error: %w" , err )
282
+ }
283
+
284
+ password = data .Data .Data [clientSection .Key ("credential_name_in_vault_secret" ).String ()].(string )
285
+ }
286
+
287
+ cfg , err = ini .LoadSources (
288
+ opts ,
289
+ []byte ("[client]\n password = " + password + "\n " ),
290
+ filename ,
291
+ )
292
+ if err != nil {
293
+ return nil , fmt .Errorf ("failed to load %s: %w" , filename , err )
294
+ }
295
+ return cfg , nil
296
+ }
0 commit comments