compose/ecs/secrets/main.go

86 lines
1.7 KiB
Go

package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
)
// return codes:
// 1: failed to read secret from env
// 2: failed to parse hierarchical secret
// 3: failed to write secret content into file
func main() {
for _, name := range os.Args[1:] {
i := strings.Index(name, ":")
var keys []string
if i > 0 {
keys = strings.Split(name[i+1:], ",")
name = name[:i]
}
value, ok := os.LookupEnv(name)
if !ok {
fmt.Fprintf(os.Stderr, "%q variable not set", name)
os.Exit(1)
}
secrets := filepath.Join("/run/secrets", name)
if len(keys) == 0 {
// raw secret
fmt.Printf("inject secret %q info %s\n", name, secrets)
err := ioutil.WriteFile(secrets, []byte(value), 0444)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(3)
}
os.Exit(0)
}
var unmarshalled interface{}
err := json.Unmarshal([]byte(value), &unmarshalled)
if err == nil {
if dict, ok := unmarshalled.(map[string]interface{}); ok {
os.MkdirAll(secrets, 0555)
for k, v := range dict {
if !contains(keys, k) && !contains(keys, "*") {
continue
}
path := filepath.Join(secrets, k)
fmt.Printf("inject secret %q info %s\n", k, path)
var raw []byte
if s, ok := v.(string); ok {
raw = []byte(s)
} else {
raw, err = json.Marshal(v)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(2)
}
}
err = ioutil.WriteFile(path, raw, 0444)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
os.Exit(3)
}
}
os.Exit(0)
}
}
}
}
func contains(keys []string, s string) bool {
for _, k := range keys {
if k == s {
return true
}
}
return false
}