Skip to content

Commit

Permalink
- fix login flow (use Kube auth and path)
Browse files Browse the repository at this point in the history
  • Loading branch information
JimBugwadia committed Oct 9, 2018
1 parent 3c8649f commit 15a732e
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
.vscode
61 changes: 61 additions & 0 deletions login.go
@@ -0,0 +1,61 @@
package main

import (
"path"

"github.com/golang/glog"
"github.com/hashicorp/vault/api"
)

func kubeLogin() (*api.Client, error) {
glog.Infof("Connecting to Vault at %s", *url)
config := &api.Config{
Address: *url,
}

tls := &api.TLSConfig{Insecure: true}
config.ConfigureTLS(tls)

client, err := api.NewClient(config)
if err != nil {
glog.Errorf("ERROR: failed to connect to Vault at %s: %v", *url, err)
return nil, err
}

body := map[string]interface{}{
"role": *role,
"jwt": *jwt,
}

loginPath := "/v1/auth/" + *kubeAuthPath + "/login"
loginPath = path.Clean(loginPath)
glog.Infof("Vault login using path %s role %s jwt [%d bytes]", loginPath, *role, len(*jwt))

req := client.NewRequest("POST", loginPath)
req.SetJSONBody(body)

resp, err := client.RawRequest(req)
if err != nil {
glog.Errorf("ERROR: failed to login with Vault: %v", err)
return nil, err
}

if respErr := resp.Error(); respErr != nil {
glog.Errorf("ERROR: api error: %v", respErr)
return nil, err
}

var result api.Secret
if err := resp.DecodeJSON(&result); err != nil {
glog.Errorf("ERROR: failed to decode JSON response: %v", err)
return nil, err
}

glog.Infof("Login results %+v", result)

auth := result.Auth
glog.Infof("Got auth %+v", auth)

client.SetToken(auth.ClientToken)
return client, nil
}
23 changes: 9 additions & 14 deletions main.go
Expand Up @@ -5,11 +5,12 @@ import (
"strconv"

"github.com/golang/glog"
"github.com/hashicorp/vault/api"
)

var url = flag.String("url", "http://127.0.0.1:8200", "the Vault server URL")
var token = flag.String("jwt", "", "the token to use for Vault authentication")
var kubeAuthPath = flag.String("kubePath", "kubernetes", "the Vault path for Kubernetes auth (e.g. kubernetes/prod)")
var role = flag.String("role", "", "the role to use for Vault authentication")
var jwt = flag.String("jwt", "", "the token to use for Vault authentication")
var secrets = flag.String("secrets", "", "a comma separated list of paths, keys, and variable names e.g (/secret/s1#k1#name, /secret/s1#k2#name, /secret/s2#k5#name")
var tokenPath = flag.String("tokenPath", "/var/run/secrets/kubernetes.io/serviceaccount/token", "location of token - used if a token is not provided.")
var out = flag.String("out", "/var/vault/secrets", "location to store the secrets fetched from Vault")
Expand All @@ -27,32 +28,26 @@ func main() {
}
}

if *url == "" || *secrets == "" {
if *url == "" || *secrets == "" || *role == "" {
glog.Infof("Usage: ")
flag.Usage()
return
}

if *token == "" {
if *jwt == "" {
lookupJwt()
if *token == "" {
glog.Errorf("ERROR: failed to retrieve Vault access token")
if *jwt == "" {
glog.Errorf("ERROR: failed to retrieve JWT")
return
}
}

glog.Infof("Connecting to Vault at %s", *url)
client, err := api.NewClient(&api.Config{
Address: *url,
})

client, err := kubeLogin()
if err != nil {
glog.Errorf("ERROR: failed to connect to Vault at %s: %v", *url, err)
glog.Errorf("ERROR: Failed to login using Kubernetes auth: %v", err)
return
}

client.SetToken(*token)

s, err := fetchSecrets(*secrets, client)
if err != nil {
glog.Errorf("ERROR: failed to fetch secrets: %v", err)
Expand Down
29 changes: 22 additions & 7 deletions secrets.go
Expand Up @@ -35,7 +35,10 @@ func fetchSecrets(paths string, client *api.Client) ([]*secret, error) {
}

for _, s := range secrets {
fetchSecret(s, client)
glog.V(6).Infof("Fetching secret path=%s key=%s", s.path, s.key)
if err := fetchSecret(s, client); err != nil {
return nil, err
}
}

return secrets, nil
Expand Down Expand Up @@ -64,10 +67,16 @@ func parsePaths(paths string) ([]*secret, error) {
return results, nil
}

func fetchSecret(s *secret, client *api.Client) (*secret, error) {
func fetchSecret(s *secret, client *api.Client) error {
resp, err := client.Logical().Read(s.path)
if err != nil {
return nil, err
glog.V(6).Infof("Failed to fetch secret %s from %s", s.String(), client.Address())
return err
}

if resp == nil {
glog.V(3).Infof("No entry found at path %s", s.path)
return fmt.Errorf("Secret (%s) not found", s.path)
}

// Vault v1 KV returns secrets in "data"
Expand All @@ -77,11 +86,17 @@ func fetchSecret(s *secret, client *api.Client) (*secret, error) {
data = resp.Data["data"].(map[string]interface{})
}

val := data[s.key]
s.value = val.(string)
glog.V(6).Infof("Found %d entries at path %s", len(data), s.path)

val, ok := data[s.key]
if !ok {
glog.V(3).Infof("No entry found at path %s and key %s", s.path, s.key)
return fmt.Errorf("Secret (%s#%s) not found", s.path, s.key)
}

glog.Infof("Secret: %s", s.String())
return s, nil
s.value = val.(string)
glog.Infof("Got secret: %s", s.String())
return nil
}

func writeSecrets(secrets []*secret, location string) error {
Expand Down
2 changes: 1 addition & 1 deletion token.go
Expand Up @@ -23,6 +23,6 @@ func lookupJwt() {
return
}

*token = s
*jwt = s
return
}

0 comments on commit 15a732e

Please sign in to comment.