From bf4dbb45e5b10ea6d0c1f5ef08fd18c2cc52b7e6 Mon Sep 17 00:00:00 2001 From: Daniel Fuentes Date: Thu, 2 Aug 2018 12:24:46 -0700 Subject: [PATCH] Make secret backend configurable --- cmd/delete.go | 2 +- cmd/exec.go | 3 +-- cmd/export.go | 3 +-- cmd/history.go | 2 +- cmd/import.go | 2 +- cmd/list.go | 3 +-- cmd/read.go | 3 ++- cmd/root.go | 42 ++++++++++++++++++++++++++++++++++++++++++ cmd/write.go | 2 +- 9 files changed, 51 insertions(+), 11 deletions(-) diff --git a/cmd/delete.go b/cmd/delete.go index bf7c00b0..eb20c80f 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -31,7 +31,7 @@ func delete(cmd *cobra.Command, args []string) error { return errors.Wrap(err, "Failed to validate key") } - secretStore := store.NewSSMStore(numRetries) + secretStore := getSecretStore() secretId := store.SecretId{ Service: service, Key: key, diff --git a/cmd/exec.go b/cmd/exec.go index cb994cf1..67b8450c 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/pkg/errors" - "github.com/segmentio/chamber/store" "github.com/spf13/cobra" ) @@ -39,7 +38,7 @@ func execRun(cmd *cobra.Command, args []string) error { services, command, commandArgs := args[:dashIx], args[dashIx], args[dashIx+1:] env := environ(os.Environ()) - secretStore := store.NewSSMStore(numRetries) + secretStore := getSecretStore() for _, service := range services { if err := validateService(service); err != nil { return errors.Wrap(err, "Failed to validate service") diff --git a/cmd/export.go b/cmd/export.go index a54f1149..657172e8 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -12,7 +12,6 @@ import ( "github.com/magiconair/properties" "github.com/pkg/errors" - "github.com/segmentio/chamber/store" "github.com/spf13/cobra" ) @@ -38,7 +37,7 @@ func init() { func runExport(cmd *cobra.Command, args []string) error { var err error - secretStore := store.NewSSMStore(numRetries) + secretStore := getSecretStore() params := make(map[string]string) for _, service := range args { if err := validateService(service); err != nil { diff --git a/cmd/history.go b/cmd/history.go index 634fd07f..76de02d0 100644 --- a/cmd/history.go +++ b/cmd/history.go @@ -34,7 +34,7 @@ func history(cmd *cobra.Command, args []string) error { return errors.Wrap(err, "Failed to validate key") } - secretStore := store.NewSSMStore(numRetries) + secretStore := getSecretStore() secretId := store.SecretId{ Service: service, Key: key, diff --git a/cmd/import.go b/cmd/import.go index 80471834..9ee65145 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -51,7 +51,7 @@ func importRun(cmd *cobra.Command, args []string) error { return errors.Wrap(err, "Failed to decode input as json") } - secretStore := store.NewSSMStore(numRetries) + secretStore := getSecretStore() for key, value := range toBeImported { secretId := store.SecretId{ diff --git a/cmd/list.go b/cmd/list.go index 83adedc8..5b504f57 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -7,7 +7,6 @@ import ( "text/tabwriter" "github.com/pkg/errors" - "github.com/segmentio/chamber/store" "github.com/spf13/cobra" ) @@ -34,7 +33,7 @@ func list(cmd *cobra.Command, args []string) error { return errors.Wrap(err, "Failed to validate service") } - secretStore := store.NewSSMStore(numRetries) + secretStore := getSecretStore() secrets, err := secretStore.List(service, withValues) if err != nil { return errors.Wrap(err, "Failed to list store contents") diff --git a/cmd/read.go b/cmd/read.go index d403479a..d18d6b1f 100644 --- a/cmd/read.go +++ b/cmd/read.go @@ -41,7 +41,8 @@ func read(cmd *cobra.Command, args []string) error { return errors.Wrap(err, "Failed to validate key") } - secretStore := store.NewSSMStore(numRetries) + secretStore := getSecretStore() + secretId := store.SecretId{ Service: service, Key: key, diff --git a/cmd/root.go b/cmd/root.go index ef689c80..b75e1256 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -6,6 +6,7 @@ import ( "regexp" "strings" + "github.com/segmentio/chamber/store" "github.com/spf13/cobra" ) @@ -26,6 +27,15 @@ const ( DefaultNumRetries = 10 ) +const ( + SSMBackend = "SSM" + S3Backend = "S3" + + BackendEnvVar = "CHAMBER_SECRET_BACKEND" +) + +var Backends = []string{SSMBackend, S3Backend} + // RootCmd represents the base command when called without any subcommands var RootCmd = &cobra.Command{ Use: "chamber", @@ -62,3 +72,35 @@ func validateKey(key string) error { } return nil } + +func getSecretStore() store.Store { + backend, ok := os.LookupEnv(BackendEnvVar) + if !ok { + backend = SSMBackend + } + + backend = strings.ToUpper(backend) + if !stringInSlice(backend, Backends) { + // TODO: warn user + backend = SSMBackend + } + + switch backend { + case SSMBackend: + return store.NewSSMStore(numRetries) + case S3Backend: + return store.NewS3Store(numRetries) + } + + // This line is unreachable, but necessary to satisfy the compiler + panic("unreachable") +} + +func stringInSlice(v string, sl []string) bool { + for _, val := range sl { + if v == val { + return true + } + } + return false +} diff --git a/cmd/write.go b/cmd/write.go index 50a58fe0..de7d4de0 100644 --- a/cmd/write.go +++ b/cmd/write.go @@ -58,7 +58,7 @@ func write(cmd *cobra.Command, args []string) error { } } - secretStore := store.NewSSMStore(numRetries) + secretStore := getSecretStore() secretId := store.SecretId{ Service: service, Key: key,