139 lines
2.2 KiB
Go
139 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
|
|
yaml "gopkg.in/yaml.v2"
|
|
)
|
|
|
|
var (
|
|
secrets SecretBackend
|
|
)
|
|
|
|
type SecretBackend interface {
|
|
Get(ref string) (string, error)
|
|
Set(ref, value string) error
|
|
}
|
|
|
|
type SecretsFile struct {
|
|
Path string
|
|
}
|
|
|
|
func (sf *SecretsFile) readData() (map[string]string, error) {
|
|
ba, err := ioutil.ReadFile(sf.Path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
data := map[string]string{}
|
|
yaml.Unmarshal(ba, &data)
|
|
|
|
return data, nil
|
|
}
|
|
|
|
func (sf *SecretsFile) Get(ref string) (string, error) {
|
|
data, err := sf.readData()
|
|
|
|
if os.IsNotExist(err) {
|
|
return "", nil
|
|
|
|
} else if err != nil {
|
|
log.Printf("secret file: failed to read: %v", err)
|
|
return "", err
|
|
}
|
|
|
|
return data[ref], nil
|
|
}
|
|
|
|
func (sf *SecretsFile) Set(ref, value string) (err error) {
|
|
data, err := sf.readData()
|
|
|
|
if os.IsNotExist(err) {
|
|
data = map[string]string{}
|
|
|
|
} else if err != nil {
|
|
log.Printf("secret file: failed to read: %v", err)
|
|
return
|
|
}
|
|
|
|
data[ref] = value
|
|
|
|
ba, err := yaml.Marshal(data)
|
|
if err != nil {
|
|
log.Printf("secret file: failed to encode: %v", err)
|
|
return
|
|
}
|
|
|
|
os.Rename(sf.Path, sf.Path+".old")
|
|
|
|
err = ioutil.WriteFile(sf.Path, ba, 0600)
|
|
if err != nil {
|
|
log.Printf("secret file: failed to write: %v", err)
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func getSecret(ref string, ctx *renderContext) (string, error) {
|
|
fullRef := fmt.Sprintf("%s/%s", ctx.Cluster.Name, ref)
|
|
|
|
v, err := secrets.Get(fullRef)
|
|
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if v != "" {
|
|
return v, nil
|
|
}
|
|
|
|
// no value, generate
|
|
split := strings.SplitN(ref, ":", 2)
|
|
kind, path := split[0], split[1]
|
|
|
|
switch kind {
|
|
case "tls-key":
|
|
_, ba := PrivateKeyPEM()
|
|
v = string(ba)
|
|
|
|
case "tls-self-signed-cert":
|
|
caKey, err := loadPrivateKey(path, ctx)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
ba := SelfSignedCertificatePEM(5, caKey)
|
|
v = string(ba)
|
|
|
|
case "tls-host-cert":
|
|
hostKey, err := loadPrivateKey(path, ctx)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
ba, err := HostCertificatePEM(3, hostKey, ctx)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
v = string(ba)
|
|
|
|
default:
|
|
return "", fmt.Errorf("unknown secret kind: %q", kind)
|
|
}
|
|
|
|
if v == "" {
|
|
panic("value not generated?!")
|
|
}
|
|
|
|
if err := secrets.Set(fullRef, v); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return v, nil
|
|
}
|