fix per-host scope

This commit is contained in:
Mikaël Cluseau
2019-01-22 11:44:11 +13:00
parent 155a619aee
commit 376b77fd6b
15 changed files with 221 additions and 68 deletions

View File

@ -54,7 +54,6 @@ func main() {
log.Print("rendering host ", host.Name)
ctx, err := newRenderContext(host, src)
log.Printf(" ctx: %p", ctx)
if err != nil {
log.Fatal("failed to create render context for host ", host.Name, ": ", err)

View File

@ -23,7 +23,6 @@ type renderContext struct {
func newRenderContext(host *clustersconfig.Host, cfg *clustersconfig.Config) (ctx *renderContext, err error) {
cluster := cfg.Cluster(host.Cluster)
log.Printf("===> newRenderContext: cluster: %v", cluster.Name)
if cluster == nil {
err = fmt.Errorf("no cluster named %q", host.Cluster)
return
@ -69,7 +68,6 @@ func (ctx *renderContext) Config() string {
templateFuncs := ctx.templateFuncs(ctxMap)
render := func(what string, t *clustersconfig.Template) (s string, err error) {
log.Printf("render %q %p", what, t)
buf := &bytes.Buffer{}
err = t.Execute(buf, ctxMap, templateFuncs)
if err != nil {
@ -120,8 +118,6 @@ func (ctx *renderContext) templateFuncs(ctxMap map[string]interface{}) map[strin
cluster := ctx.Cluster.Name
getKeyCert := func(name, funcName string) (s string, err error) {
log.Print("=====> getKeyCert ", funcName, ": cluster: ", cluster)
req := ctx.clusterConfig.CSR(name)
if req == nil {
err = fmt.Errorf("no certificate request named %q", name)
@ -139,6 +135,10 @@ func (ctx *renderContext) templateFuncs(ctxMap map[string]interface{}) map[strin
return
}
if req.PerHost {
name = name + "/" + ctx.Host.Name
}
s = fmt.Sprintf("{{ %s %q %q %q %q %q %q }}", funcName,
cluster, req.CA, name, req.Profile, req.Label, buf.String())
return
@ -173,7 +173,6 @@ func (ctx *renderContext) templateFuncs(ctxMap map[string]interface{}) map[strin
},
"tls_dir": func(name string) (s string, err error) {
log.Printf(" CTX: %p", ctx)
return getKeyCert(name, "tls_dir")
},

View File

@ -31,6 +31,12 @@ func cleanCAS() error {
activeTags := make([]string, len(cfg.Hosts))
for i, host := range cfg.Hosts {
// FIXME ugly hack, same as in dir2config
cfg, err := readConfig()
if err != nil {
return err
}
ctx, err := newRenderContext(host, cfg)
if err != nil {
return err

View File

@ -49,7 +49,29 @@ func renderCtx(w http.ResponseWriter, r *http.Request, ctx *renderContext, what
return nil
}
var prevSSLConfig = "-"
func newRenderContext(host *localconfig.Host, cfg *localconfig.Config) (ctx *renderContext, err error) {
if prevSSLConfig != cfg.SSLConfig {
var sslCfg *cfsslconfig.Config
if len(cfg.SSLConfig) == 0 {
sslCfg = &cfsslconfig.Config{}
} else {
sslCfg, err = cfsslconfig.LoadConfig([]byte(cfg.SSLConfig))
if err != nil {
return
}
}
err = loadSecretData(sslCfg)
if err != nil {
return
}
prevSSLConfig = cfg.SSLConfig
}
return &renderContext{
SSLConfig: cfg.SSLConfig,
Host: host,
@ -57,13 +79,8 @@ func newRenderContext(host *localconfig.Host, cfg *localconfig.Config) (ctx *ren
}
func (ctx *renderContext) Config() (ba []byte, cfg *config.Config, err error) {
secretData, err := ctx.secretData()
if err != nil {
return
}
tmpl, err := template.New(ctx.Host.Name + "/config").
Funcs(ctx.templateFuncs(secretData)).
Funcs(ctx.templateFuncs()).
Parse(ctx.Host.Config)
if err != nil {
@ -93,23 +110,7 @@ func (ctx *renderContext) Config() (ba []byte, cfg *config.Config, err error) {
return
}
func (ctx *renderContext) secretData() (data *SecretData, err error) {
var sslCfg *cfsslconfig.Config
if len(ctx.SSLConfig) == 0 {
sslCfg = &cfsslconfig.Config{}
} else {
sslCfg, err = cfsslconfig.LoadConfig([]byte(ctx.SSLConfig))
if err != nil {
return
}
}
data, err = loadSecretData(sslCfg)
return
}
func (ctx *renderContext) templateFuncs(secretData *SecretData) map[string]interface{} {
func (ctx *renderContext) templateFuncs() map[string]interface{} {
getKeyCert := func(cluster, caName, name, profile, label, reqJson string) (kc *KeyCert, err error) {
certReq := &csr.CertificateRequest{
KeyRequest: csr.NewBasicKeyRequest(),

View File

@ -10,18 +10,26 @@ import (
"net"
"os"
"path/filepath"
"sync"
"github.com/cloudflare/cfssl/config"
"github.com/cloudflare/cfssl/csr"
"github.com/cloudflare/cfssl/helpers"
"github.com/cloudflare/cfssl/initca"
"github.com/cloudflare/cfssl/log"
"github.com/cloudflare/cfssl/signer"
"github.com/cloudflare/cfssl/signer/local"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
)
var (
secretData *SecretData
)
type SecretData struct {
l sync.Mutex
clusters map[string]*ClusterSecrets
changed bool
config *config.Config
@ -45,27 +53,36 @@ type KeyCert struct {
ReqHash string
}
func loadSecretData(config *config.Config) (*SecretData, error) {
func secretDataPath() string {
return filepath.Join(*dataDir, "secret-data.json")
}
func loadSecretData(config *config.Config) (err error) {
log.Info("Loading secret data")
sd := &SecretData{
clusters: make(map[string]*ClusterSecrets),
changed: false,
config: config,
}
ba, err := ioutil.ReadFile(filepath.Join(*dataDir, "secret-data.json"))
ba, err := ioutil.ReadFile(secretDataPath())
if err != nil {
if os.IsNotExist(err) {
sd.changed = true
return sd, nil
err = nil
secretData = sd
return
}
return nil, err
return
}
if err := json.Unmarshal(ba, &sd.clusters); err != nil {
return nil, err
if err = json.Unmarshal(ba, &sd.clusters); err != nil {
return
}
return sd, nil
secretData = sd
return
}
func (sd *SecretData) Changed() bool {
@ -73,11 +90,15 @@ func (sd *SecretData) Changed() bool {
}
func (sd *SecretData) Save() error {
sd.l.Lock()
defer sd.l.Unlock()
log.Info("Saving secret data")
ba, err := json.Marshal(sd.clusters)
if err != nil {
return err
}
return ioutil.WriteFile(filepath.Join(*dataDir, "secret-data.json"), ba, 0600)
return ioutil.WriteFile(secretDataPath(), ba, 0600)
}
func (sd *SecretData) cluster(name string) (cs *ClusterSecrets) {
@ -86,6 +107,11 @@ func (sd *SecretData) cluster(name string) (cs *ClusterSecrets) {
return
}
sd.l.Lock()
defer sd.l.Unlock()
log.Info("secret-data: new cluster: ", name)
cs = &ClusterSecrets{
CAs: make(map[string]*CA),
Tokens: make(map[string]string),
@ -103,6 +129,11 @@ func (sd *SecretData) Token(cluster, name string) (token string, err error) {
return
}
sd.l.Lock()
defer sd.l.Unlock()
log.Info("secret-data: new token in cluster ", cluster, ": ", name)
b := make([]byte, 16)
_, err = rand.Read(b)
if err != nil {
@ -124,6 +155,11 @@ func (sd *SecretData) CA(cluster, name string) (ca *CA, err error) {
return
}
sd.l.Lock()
defer sd.l.Unlock()
log.Info("secret-data: new CA in cluster ", cluster, ": ", name)
req := &csr.CertificateRequest{
CN: "Direktil Local Server",
KeyRequest: &csr.BasicKeyRequest{
@ -191,8 +227,16 @@ func (sd *SecretData) KeyCert(cluster, caName, name, profile, label string, req
kc, ok := ca.Signed[name]
if ok && rh == kc.ReqHash {
return
} else if ok {
log.Infof("secret-data: cluster %s: CA %s: CSR changed for %s: hash=%q previous=%q",
cluster, caName, name, rh, kc.ReqHash)
} else {
log.Infof("secret-data: cluster %s: CA %s: new CSR for %s", cluster, caName, name)
}
sd.l.Lock()
defer sd.l.Unlock()
sgr, err := ca.Signer(sd.config.Signing)
if err != nil {
return