diff --git a/config.go b/config.go index 1fdae55..0753a3b 100644 --- a/config.go +++ b/config.go @@ -62,7 +62,7 @@ func init() { flag.BoolVar(&options.tlsVerify, "tls-skip-verify", false, "whether to check and verify the vault service certificate") flag.StringVar(&options.vaultCaFile, "ca-cert", "", "the path to the file container the CA used to verify the vault service") flag.DurationVar(&options.statsInterval, "stats", time.Duration(1)*time.Hour, "the interval to produce statistics on the accessed resources") - flag.DurationVar(&options.execTimeout, "exec-timeout", time.Duration(60) * time.Second, "the timeout applied to commands on the exec option") + flag.DurationVar(&options.execTimeout, "exec-timeout", time.Duration(60)*time.Second, "the timeout applied to commands on the exec option") flag.Var(options.resources, "cn", "a resource to retrieve and monitor from vault") } diff --git a/generate.go b/generate.go index b32de34..6a989cf 100644 --- a/generate.go +++ b/generate.go @@ -17,9 +17,8 @@ limitations under the License. package main import ( - "io" "crypto/rand" - + "io" ) var StdChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+,.?/:;{}[]`~") diff --git a/vault_resources.go b/vault_resources.go index 5ee96df..ce88bde 100644 --- a/vault_resources.go +++ b/vault_resources.go @@ -18,11 +18,17 @@ package main import ( "fmt" + "os" + "regexp" "strconv" "strings" "time" ) +var ( + envRegex = regexp.MustCompile("%[[:alnum:]]+%") +) + // VaultResources is a collection of type resource type VaultResources struct { // an array of resource to retrieve @@ -46,6 +52,15 @@ func (r *VaultResources) Set(value string) error { return fmt.Errorf("invalid resource, neither type or path can be empty") } + // step: look for any token in the resource + tokens := envRegex.FindAllStringSubmatch(items[1], -1) + if len(tokens) > 0 { + for _, x := range tokens { + // step: replace the token with the environment variable + items[1] = strings.Replace(items[1], x[0], os.Getenv(strings.Replace(x[0], "%", "", -1)), -1) + } + } + // step: extract the elements rn.resource = items[0] rn.path = items[1] diff --git a/vault_resources_test.go b/vault_resources_test.go index 8eca0f8..6cd2f42 100644 --- a/vault_resources_test.go +++ b/vault_resources_test.go @@ -17,6 +17,7 @@ limitations under the License. package main import ( + "os" "testing" "github.com/stretchr/testify/assert" @@ -33,6 +34,8 @@ func TestSetResources(t *testing.T) { assert.Nil(t, items.Set("pki:example-dot-com:common_name=blah.example.com")) assert.Nil(t, items.Set("pki:example-dot-com:common_name=blah.example.com,file=/etc/certs/ssl/blah.example.com")) assert.Nil(t, items.Set("pki:example-dot-com:common_name=blah.example.com,renew=true")) + assert.Nil(t, items.Set("secret:secrets/%ENV%/me:file=filename.test,fmt=yaml")) + assert.NotNil(t, items.Set("secret:")) assert.NotNil(t, items.Set("secret:test:file=filename.test,fmt=")) assert.NotNil(t, items.Set("secret::file=filename.test,fmt=yaml")) @@ -40,6 +43,54 @@ func TestSetResources(t *testing.T) { assert.NotNil(t, items.Set("file=filename.test,fmt=yaml")) } +func TestSetEnvironmentResource(t *testing.T) { + tests := []struct { + ResourceText string + ExpectedPath string + Vars map[string]string + }{ + { + ResourceText: "secret:secrets/%ENV/me:file=filename.test,fmt=yaml", + ExpectedPath: "secrets/%ENV/me", + }, + { + ResourceText: "secret:secrets/%ENV%/me:file=filename.test,fmt=yaml", + ExpectedPath: "secrets/dev/me", + Vars: map[string]string{ + "ENV": "dev", + }, + }, + { + ResourceText: "secret:secrets/%ENV%/me/%ENV%:file=filename.test,fmt=yaml", + ExpectedPath: "secrets/dev/me/dev", + Vars: map[string]string{ + "ENV": "dev", + }, + }, + { + ResourceText: "secret:secrets/%ENV%/me/%THING%:file=filename.test,fmt=yaml", + ExpectedPath: "secrets/dev/me/yes", + Vars: map[string]string{ + "ENV": "dev", + "THING": "yes", + }, + }, + } + + for i, c := range tests { + var resource VaultResources + if len(c.Vars) > 0 { + for k, v := range c.Vars { + os.Setenv(k, v) + } + } + if !assert.NoError(t, resource.Set(c.ResourceText), "case %d, should not have failed", i) { + continue + } + assert.Equal(t, c.ExpectedPath, resource.items[0].path, "case %d, the paths do not match", i) + } +} + /* func TestResources(t *testing.T) { var items VaultResources