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,67 @@ 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
+ useVault , err := clientSection .Key ("use_vault" ).Bool ()
250
+ if err != nil {
251
+ logger .Error ("msg" , "failed to get 'use_vault'" , "err" , err )
252
+ return nil , fmt .Errorf ("error: %w" , err )
253
+ }
254
+
255
+ password := "${MYSQLD_EXPORTER_PASSWORD}"
256
+ if useVault {
257
+ client , err := vault .New (vault .WithAddress (clientSection .Key ("vault_address" ).String ()))
258
+ if err != nil {
259
+ logger .Error ("msg" , "failed to create vault client" , "err" , err )
260
+ return nil , fmt .Errorf ("error: %w" , err )
261
+ }
262
+ ctx := context .Background ()
263
+ resp , err := client .Auth .AppRoleLogin (
264
+ ctx ,
265
+ schema.AppRoleLoginRequest {
266
+ RoleId : clientSection .Key ("vault_role_id" ).String (),
267
+ SecretId : clientSection .Key ("vault_secret_id" ).String (),
268
+ },
269
+ )
270
+ if err != nil {
271
+ logger .Error ("msg" , "failed to login to vault" , "err" , err )
272
+ return nil , fmt .Errorf ("error: %w" , err )
273
+ }
274
+ if err := client .SetToken (resp .Auth .ClientToken ); err != nil {
275
+ logger .Error ("msg" , "failed to set vault token" , "err" , err )
276
+ return nil , fmt .Errorf ("error: %w" , err )
277
+ }
278
+ data , err := client .Secrets .KvV2Read (
279
+ ctx ,
280
+ clientSection .Key ("vault_secret_path" ).String (),
281
+ vault .WithMountPath (clientSection .Key ("vault_secret_mount_path" ).String ()),
282
+ )
283
+ if err != nil {
284
+ logger .Error ("msg" , "failed to get data" , "err" , err )
285
+ return nil , fmt .Errorf ("error: %w" , err )
286
+ }
287
+
288
+ password = data .Data .Data [clientSection .Key ("credential_name_in_vault_secret" ).String ()].(string )
289
+ }
290
+
291
+ cfg , err = ini .LoadSources (
292
+ opts ,
293
+ []byte ("[client]\n password = " + password + "\n " ),
294
+ filename ,
295
+ )
296
+ if err != nil {
297
+ return nil , fmt .Errorf ("failed to load %s: %w" , filename , err )
298
+ }
299
+ return cfg , nil
300
+ }
0 commit comments