diff --git a/controllers/dbsecret_controller.go b/controllers/dbsecret_controller.go index e9e8fb7..ab7e89b 100644 --- a/controllers/dbsecret_controller.go +++ b/controllers/dbsecret_controller.go @@ -223,11 +223,13 @@ func (r *DbSecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c } func (r *DbSecretReconciler) revokeLease(sDef *digitalisiov1beta1.DbSecret, currentSecret *corev1.Secret) error { + r.Log.Info(fmt.Sprintf("Revoking lease for %s", currentSecret.Name)) + if currentSecret == nil || currentSecret.Name != "" { return nil } if currentSecret.ObjectMeta.Annotations[leaseIdLabel] == "" { - return fmt.Errorf("cannot renew without lease Id") + return fmt.Errorf("cannot revoke credentials without lease Id") } leaseId := fmt.Sprintf("%s/creds/%s/%s", sDef.Spec.Vault.Mount, @@ -311,6 +313,12 @@ func (r *DbSecretReconciler) upsertSecret(sDef *digitalisiov1beta1.DbSecret, cre dataStr := make(map[string]string) dataStr["username"] = creds.Username dataStr["password"] = creds.Password + if creds.ConnectionURL != "" { + dataStr["connection_url"] = creds.ConnectionURL + } + if creds.Hosts != "" { + dataStr["hosts"] = creds.Hosts + } data := r.renderTemplate(sDef, dataStr) if len(data) < 1 { diff --git a/vault/vault.go b/vault/vault.go index 16a1ffb..91c46a8 100644 --- a/vault/vault.go +++ b/vault/vault.go @@ -3,9 +3,11 @@ package vault import ( "context" "crypto/tls" + "encoding/json" "fmt" "net/http" "os" + "strings" "github.com/hashicorp/vault/api" vault "github.com/hashicorp/vault/api" @@ -198,6 +200,8 @@ type VaultDbSecret struct { LeaseDuration int `json:"lease_duration"` Username string `json:"username"` Password string `json:"password"` + Hosts string `json:"hosts"` + ConnectionURL string `json:"hosts"` } func RenewDbCredentials(leaseId string, increment int) (err error) { @@ -266,13 +270,43 @@ func GetDbCredentials(role string, mount string) (VaultDbSecret, error) { if s == nil || s.Data["username"] == "" || s.Data["password"] == "" || s.Data["username"] == nil || s.Data["password"] == nil { - return dbSecret, fmt.Errorf("Vault did not return credentials") + return dbSecret, fmt.Errorf("vault did not return credentials: %v", err) } + /* Get connection URL or hosts list */ + var connectionURL string + var hosts string + var port string + path = fmt.Sprintf("%s/config/%s", mount, mount) + cfg, err2 := client.Logical().Read(path) + if err2 != nil { + return dbSecret, fmt.Errorf("vault did not return the connection details for the database: %v", err2) + } + conn, ok := cfg.Data["connection_details"].(map[string]interface{}) + if !ok { + return dbSecret, fmt.Errorf("vault did not return the connection details for the database") + } + + hosts, _ = conn["hosts"].(string) + connectionURL, _ = conn["connection_url"].(string) + port = conn["port"].(json.Number).String() + + if connectionURL != "" { + connectionURL = strings.Replace(connectionURL, "{{username}}", s.Data["username"].(string), 1) + connectionURL = strings.Replace(connectionURL, "{{password}}", s.Data["password"].(string), 1) + } + + if hosts != "" && port != "" { + rep := fmt.Sprintf(":%s,", port) + hosts = fmt.Sprintf("%s:%s", strings.Replace(hosts, ",", rep, -1), port) + } + dbSecret = VaultDbSecret{ LeaseId: s.LeaseID, LeaseDuration: s.LeaseDuration, Username: s.Data["username"].(string), Password: s.Data["password"].(string), + Hosts: hosts, + ConnectionURL: connectionURL, } return dbSecret, nil