diff --git a/CHANGELOG.md b/CHANGELOG.md index d50f0e3..c9ab796 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,4 +6,7 @@ # v0.1.1 - Added DataDog metrics -- Added 'interactive' flag to allow users to specify which token they want to load. \ No newline at end of file +- Added 'interactive' flag to allow users to specify which token they want to load. + +# v0.1.2 +- Add `create-from` flag in CLI to allow creation of secrets from file contents. \ No newline at end of file diff --git a/README.md b/README.md index 5c2bf04..6894d98 100644 --- a/README.md +++ b/README.md @@ -131,10 +131,16 @@ $ go run cmd/main.go ping exit status 1 ``` -Other commands include `create`, `update`, `delete` and `list` which do pretty much what you'd expect with AWS Secret Manager secrets logically scoped to the user's k8s namespace. Check the relevant `-help` for more information. +Other commands include `create`, `create-from`, `update`, `delete` and `list` which do pretty much what you'd expect with AWS Secret Manager secrets logically scoped to the user's k8s namespace. Check the relevant `-help` for more information. + + +### Creating a secret from a file + +Sometimes it may be necessary to create a secret which contains newlines, to support this, you can use the `create-from` command, specifying the filepath in the `-value` argument. **Notes** * The `-token-path` is optional for all commands. Without it `kiss` will attempt to find the first file in the default `~/.kube/cache/oidc-login` directory * On a Mac you can't use the `~/` path when specifying the token path - instead use `$HOME/` * When you create a secret it will be base64 encoded, so you should specify it's value in plaintext * A secret name cannot contain underscores as this will result in the "Error occurred while creating secret" error +* The `-interactive` flag can be used to help choose which token to load if there are multiple in your ~/.kube/cache/oidc-login` directory. diff --git a/client/cmd/main.go b/client/cmd/main.go index 7159b35..a6e336a 100644 --- a/client/cmd/main.go +++ b/client/cmd/main.go @@ -15,7 +15,6 @@ import ( "time" "github.com/hashicorp/logutils" - "github.com/ovotech/kiss/client" pb "github.com/ovotech/kiss/proto" @@ -47,6 +46,15 @@ var ( "Create an AWS IAM policy for reading this secret.", ) + createSecretFromCmd = flag.NewFlagSet("create-from", flag.ExitOnError) + createSecretFromName = createSecretFromCmd.String("name", "", "The name of the secret.") + createSecretFromValue = createSecretFromCmd.String("value", "", "The path to the file containing the secret.") + createSecretFromPolicy = createSecretFromCmd.Bool( + "policy", + false, + "Create an AWS IAM policy for reading this secret.", + ) + listSecretsCmd = flag.NewFlagSet("list", flag.ExitOnError) bindSecretCmd = flag.NewFlagSet("bind", flag.ExitOnError) @@ -70,13 +78,14 @@ var ( ) subcommands = map[string]*flag.FlagSet{ - helpCmd.Name(): helpCmd, - pingCmd.Name(): pingCmd, - createSecretCmd.Name(): createSecretCmd, - listSecretsCmd.Name(): listSecretsCmd, - bindSecretCmd.Name(): bindSecretCmd, - updateSecretCmd.Name(): updateSecretCmd, - deleteSecretCmd.Name(): deleteSecretCmd, + helpCmd.Name(): helpCmd, + pingCmd.Name(): pingCmd, + createSecretCmd.Name(): createSecretCmd, + createSecretFromCmd.Name(): createSecretFromCmd, + listSecretsCmd.Name(): listSecretsCmd, + bindSecretCmd.Name(): bindSecretCmd, + updateSecretCmd.Name(): updateSecretCmd, + deleteSecretCmd.Name(): deleteSecretCmd, } ) @@ -152,6 +161,27 @@ func main() { if *createSecretPolicy { client.CreateSecretIAMPolicy(kissClient, timeout, namespace, *createSecretName) } + case "create-from": + if *createSecretFromName == "" { + log.Fatalf("[ERROR] -name is required, see help for more details.") + } + if *createSecretFromValue == "" { + + log.Fatalf("[ERROR] -value is required, please specify full file path. See help for more details.") + } + // read value from file + + dat, err := os.ReadFile(*createSecretFromValue) + if err != nil { + log.Fatalf("Error occurred reading file %v", err) + } + + *createSecretFromValue = string(dat) + client.CreateSecret(kissClient, timeout, namespace, *createSecretFromName, *createSecretFromValue) + + if *createSecretFromPolicy { + client.CreateSecretIAMPolicy(kissClient, timeout, namespace, *createSecretFromName) + } case "list": client.ListSecrets(kissClient, timeout, namespace) case "bind":