package main import ( "encoding/json" "fmt" "log" "path" cfsslconfig "github.com/cloudflare/cfssl/config" "github.com/cloudflare/cfssl/csr" yaml "gopkg.in/yaml.v2" "novit.tech/direktil/pkg/config" ) func templateFuncs(sslCfg *cfsslconfig.Config) map[string]any { getKeyCert := func(cluster, caName, name, profile, label, reqJson string) (kc KeyCert, err error) { certReq := &csr.CertificateRequest{ KeyRequest: csr.NewKeyRequest(), } err = json.Unmarshal([]byte(reqJson), certReq) if err != nil { log.Print("CSR unmarshal failed on: ", reqJson) return } return getUsableKeyCert(cluster, caName, name, profile, label, certReq, sslCfg) } return map[string]any{ "password": func(cluster, name string) (password string, err error) { password, _, err = clusterPasswords.Get(cluster + "/" + name) if err != nil { return } if len(password) == 0 { err = fmt.Errorf("password %q not defined for cluster %q", name, cluster) } return }, "token": getOrCreateClusterToken, "ca_key": func(cluster, name string) (s string, err error) { ca, err := getUsableClusterCA(cluster, name) if err != nil { return } s = string(ca.Key) return }, "ca_crt": func(cluster, name string) (s string, err error) { ca, err := getUsableClusterCA(cluster, name) if err != nil { return } s = string(ca.Cert) return }, "ca_dir": func(cluster, name string) (s string, err error) { ca, err := getUsableClusterCA(cluster, name) if err != nil { return } dir := "/etc/tls-ca/" + name return asYaml([]config.FileDef{ { Path: path.Join(dir, "ca.crt"), Mode: 0644, Content: string(ca.Cert), }, { Path: path.Join(dir, "ca.key"), Mode: 0600, Content: string(ca.Key), }, }) }, "tls_key": func(cluster, caName, name, profile, label, reqJson string) (s string, err error) { kc, err := getKeyCert(cluster, caName, name, profile, label, reqJson) if err != nil { return } s = string(kc.Key) return }, "tls_crt": func(cluster, caName, name, profile, label, reqJson string) (s string, err error) { kc, err := getKeyCert(cluster, caName, name, profile, label, reqJson) if err != nil { return } s = string(kc.Cert) return }, "tls_dir": func(dir, cluster, caName, name, profile, label, reqJson string) (s string, err error) { ca, err := getUsableClusterCA(cluster, caName) if err != nil { return } kc, err := getKeyCert(cluster, caName, name, profile, label, reqJson) if err != nil { return } return asYaml([]config.FileDef{ { Path: path.Join(dir, "ca.crt"), Mode: 0644, Content: string(ca.Cert), }, { Path: path.Join(dir, "tls.crt"), Mode: 0644, Content: string(kc.Cert), }, { Path: path.Join(dir, "tls.key"), Mode: 0600, Content: string(kc.Key), }, }) }, "ssh_host_keys": func(dir, cluster, host string) (s string, err error) { pairs, err := getSSHKeyPairs(host) if err != nil { return } files := make([]config.FileDef, 0, len(pairs)*2) for _, pair := range pairs { basePath := path.Join(dir, "ssh_host_"+pair.Type+"_key") files = append(files, []config.FileDef{ { Path: basePath, Mode: 0600, Content: pair.Private, }, { Path: basePath + ".pub", Mode: 0644, Content: pair.Public, }, }...) } return asYaml(files) }, } } func asYaml(v interface{}) (string, error) { ba, err := yaml.Marshal(v) if err != nil { return "", err } return string(ba), nil }