86 lines
1.7 KiB
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
|
|
}
|