aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go190
1 files changed, 190 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..4e11d21
--- /dev/null
+++ b/main.go
@@ -0,0 +1,190 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "log"
+ "os"
+ "regexp"
+ "strings"
+
+ "riedstra.dev/go/dpw-ssm/store"
+
+ "github.com/aws/aws-sdk-go/aws"
+ "github.com/aws/aws-sdk-go/aws/session"
+ "github.com/aws/aws-sdk-go/service/ssm"
+)
+
+const SSM_MAX_SIZE = 4096
+
+// ((16^4)*4096)/1024/1024
+// If we ever need more than 256 MB in parameter store, we've done something
+// very wrong.
+const SSM_KEY_FORMAT = "%s-%04X" //
+
+var (
+ KMS_KEY_ID *string = nil
+ VersionString = "development"
+ svc *ssm.SSM
+ Logger = log.New(os.Stderr, "", 0)
+ trimRegex = regexp.MustCompile("-[0-9A-E][0-9A-E][0-9A-E][0-9A-E]$")
+ keyPrefix = os.Getenv("DPW_SSM_PREFIX")
+)
+
+func listParams(params []string) {
+ info, err := store.GetInfo(svc)
+ if err != nil {
+ Logger.Fatal(err)
+ }
+
+ for key, _ := range info.ByKey {
+ // Skip over things that aren't prefixed...
+ if keyPrefix != "" && !strings.HasPrefix(key, keyPrefix) {
+ continue
+ }
+ fmt.Println(strings.TrimPrefix(key, keyPrefix))
+ }
+
+ os.Exit(0)
+}
+
+func insertParam(params []string) {
+ if len(params) != 1 {
+ Logger.Printf("Params provided: '%s'", params)
+ Logger.Fatal("Expected exactly one parameter, the path")
+ }
+ path := keyPrefix + params[0]
+
+ err := store.InsertParam(svc, os.Stdin, path)
+ if err != nil {
+ Logger.Fatalf("While inserting: '%s': %s", path, err)
+ }
+
+ os.Exit(0)
+}
+
+func showParam(params []string) {
+ if len(params) != 1 {
+ Logger.Printf("Params provided: '%s'", params)
+ Logger.Fatal("Expected exactly one parameter, the path")
+ }
+ path := keyPrefix + params[0]
+
+ err := store.GetParam(svc, os.Stdout, path)
+ if err != nil {
+ Logger.Fatalf("Encountered: %s\n", err)
+ }
+
+ os.Exit(0)
+}
+
+func removeParam(params []string) {
+ if len(params) != 1 {
+ Logger.Printf("Params provided: '%s'", params)
+ Logger.Fatal("Expected exactly one parameter, the path")
+ }
+ path := keyPrefix + params[0]
+
+ err := store.RemoveParam(svc, path)
+ if err != nil {
+ Logger.Fatalf("Encountered: %s\n", err)
+ }
+
+ os.Exit(0)
+}
+
+func help() {
+ fmt.Printf(`
+dpw-ssm: An AWS SSM backend for the dynamic password manager.
+https://git.riedstra.dev/mitch/dpw/about/
+
+This can be used directly, but for interactive use 'dpw' is encouraged.
+
+Available commands:
+
+list
+insert <key-name>
+show <key-name>
+rm <key-name>
+
+Debugging environment variables:
+
+DPW_SSM_DEBUG=YES # Enable extended logging
+
+Environment variables:
+
+DPW_SSM_PREFIX=<prefix for all keys>
+DPW_SSM_KMS_KEY_ID=<KMS KEY ID> # Optional
+DPW_SSM_TAGS='{"json":"encoded","set":"of","key":"value","pairs":"..."}'
+
+version: %s
+`, VersionString)
+ os.Exit(0)
+}
+
+func setRegion() {
+ if os.Getenv("AWS_REGION") == "" {
+ // Default to us-east-2
+ os.Setenv("AWS_REGION", "us-east-2")
+
+ // But if a default is set, respect that, since the AWS SDK for Go
+ // doesn't, normally.
+ if os.Getenv("AWS_DEFAULT_REGION") != "" {
+ os.Setenv("AWS_REGION", os.Getenv("AWS_DEFAULT_REGION"))
+ }
+ }
+}
+
+func main() {
+ if os.Getenv("DPW_SSM_DEBUG") != "" {
+ Logger = log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile)
+ }
+
+ if os.Getenv("DPW_SSM_KMS_KEY_ID") != "" {
+ store.KMS_KEY_ID = aws.String(os.Getenv("DPW_SSM_KMS_KEY_ID"))
+ }
+
+ ssm_tags_json := os.Getenv("DPW_SSM_TAGS")
+ if ssm_tags_json != "" {
+ tags := map[string]string{}
+ err := json.Unmarshal([]byte(ssm_tags_json), &tags)
+ if err != nil {
+ Logger.Println("Warning, failed to decode DPW_SSM_TAGS: %s\n", err)
+ } else {
+ for k, v := range tags {
+ store.Tags = append(store.Tags, &ssm.Tag{
+ Key: aws.String(k),
+ Value: aws.String(v),
+ })
+ }
+ }
+ }
+
+ setRegion()
+
+ ses := session.Must(session.NewSession())
+ svc = ssm.New(ses)
+
+ for n, arg := range os.Args[1:] {
+ switch arg {
+ case "list":
+ listParams(os.Args[n+2:])
+ break
+ case "insert":
+ insertParam(os.Args[n+2:])
+ break
+ case "show":
+ showParam(os.Args[n+2:])
+ break
+ case "rm":
+ removeParam(os.Args[n+2:])
+ break
+ case "init":
+ fmt.Fprintln(os.Stderr, "No init process is necessary")
+ break
+ default:
+ fmt.Fprintf(os.Stderr, "Unknown argument: '%s'\n", arg)
+ help()
+ }
+ }
+}