-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathvault.go
More file actions
99 lines (90 loc) · 2.49 KB
/
vault.go
File metadata and controls
99 lines (90 loc) · 2.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main
import (
"fmt"
"log"
"time"
"github.com/hashicorp/vault/api"
)
type vaultClient struct {
client *api.Client
secret *api.Secret
}
func newVaultClient(address string) (*vaultClient, error) {
config := api.Config{Address: address}
client, err := api.NewClient(&config)
if err != nil {
return nil, err
}
return &vaultClient{client: client}, nil
}
func (v *vaultClient) readVaultSecret(path string) error {
secret, err := v.client.Logical().Read(path)
if err != nil {
return err
}
v.secret = secret
return nil
}
func (v *vaultClient) getCredentials(vaultAddr, vaultToken, vaultRoleID, vaultSecretID string) (string, string, error) {
if vaultRoleID != "" && vaultSecretID != "" {
options := map[string]interface{}{
"role_id": vaultRoleID,
"secret_id": vaultSecretID,
}
path := "auth/approle/login"
pingExternalService(vaultAddr, &vaultAppRolePinger{v.client, path, options})
secret, err := v.client.Logical().Write(path, options)
if err != nil {
return "", "", err
}
v.client.SetToken(secret.Auth.ClientToken)
if secret.Auth == nil {
return "", "", fmt.Errorf("could not read auth info from secret")
}
err = v.readVaultSecret("database/creds/vault-mysql-role")
if err != nil {
return "", "", err
}
username := v.secret.Data["username"].(string)
password := v.secret.Data["password"].(string)
return username, password, nil
}
if vaultToken != "" {
v.client.SetToken(vaultToken)
path := "secrets/dbwebapp"
pingExternalService(vaultAddr, &vaultPinger{v.client, path})
err := v.readVaultSecret(path)
if err != nil {
return "", "", err
}
username := v.secret.Data["username"].(string)
password := v.secret.Data["password"].(string)
return username, password, nil
}
return "", "", fmt.Errorf("could not read vault secret")
}
func (v *vaultClient) renewLease() error {
log.Printf("Renewing lease %v.", v.secret.LeaseID)
_, err := v.client.Sys().Renew(v.secret.LeaseID, v.secret.LeaseDuration)
if err != nil {
return err
}
return nil
}
func (v *vaultClient) regularlyRenewLease() error {
if !v.secret.Renewable {
log.Println("Cowardly refusing to renew unrenewable secret.")
return nil
}
v.renewLease()
// renew lease 100 seconds before expiry
interval := time.Duration(v.secret.LeaseDuration)*time.Second - 100*time.Second
renewTicker := time.NewTicker(interval)
log.Printf("Scheduling regular renewal for lease %s every %v", v.secret.LeaseID, interval)
for {
select {
case <-renewTicker.C:
v.renewLease()
}
}
}