feat: more template funcs

This commit is contained in:
Mikaël Cluseau 2018-06-20 14:01:10 +11:00
parent 748cb0945a
commit f348c9e94c

View File

@ -66,6 +66,7 @@ func (ctx *renderContext) Config() (ba []byte, cfg *config.Config, err error) {
ctxMap := ctx.asMap() ctxMap := ctx.asMap()
// FIXME duplicate
sslCfg, err := cfsslconfig.LoadConfig([]byte(ctx.clusterConfig.SSLConfig)) sslCfg, err := cfsslconfig.LoadConfig([]byte(ctx.clusterConfig.SSLConfig))
if err != nil { if err != nil {
return return
@ -76,6 +77,76 @@ func (ctx *renderContext) Config() (ba []byte, cfg *config.Config, err error) {
return return
} }
extraFuncs := ctx.templateFuncs(secretData, ctxMap)
extraFuncs["static_pods"] = func(name string) (string, error) {
t := ctx.clusterConfig.StaticPodsTemplate(name)
if t == nil {
return "", fmt.Errorf("no static pods template named %q", name)
}
buf := &bytes.Buffer{}
err := t.Execute(buf, ctxMap, ctx.templateFuncs(secretData, ctxMap))
if err != nil {
log.Printf("host %s: failed to render static pods: %v", ctx.Host.Name, err)
return "", err
}
return buf.String(), nil
}
buf := bytes.NewBuffer(make([]byte, 0, 4096))
if err = ctx.ConfigTemplate.Execute(buf, ctxMap, extraFuncs); err != nil {
return
}
if secretData.Changed() {
err = secretData.Save()
if err != nil {
return
}
}
ba = buf.Bytes()
cfg = &config.Config{}
if err = yaml.Unmarshal(buf.Bytes(), cfg); err != nil {
return
}
return
}
func (ctx *renderContext) StaticPods() (ba []byte, err error) {
// FIXME duplicate
sslCfg, err := cfsslconfig.LoadConfig([]byte(ctx.clusterConfig.SSLConfig))
if err != nil {
return
}
secretData, err := loadSecretData(sslCfg)
if err != nil {
return
}
if ctx.StaticPodsTemplate == nil {
err = notFoundError{fmt.Sprintf("static-pods %q", ctx.Group.StaticPods)}
return
}
ctxMap := ctx.asMap()
buf := bytes.NewBuffer(make([]byte, 0, 4096))
if err = ctx.StaticPodsTemplate.Execute(buf, ctxMap, ctx.templateFuncs(secretData, ctxMap)); err != nil {
return
}
ba = buf.Bytes()
return
}
func (ctx *renderContext) templateFuncs(secretData *SecretData, ctxMap map[string]interface{}) map[string]interface{} {
cluster := ctx.Cluster.Name cluster := ctx.Cluster.Name
getKeyCert := func(name string) (kc *KeyCert, err error) { getKeyCert := func(name string) (kc *KeyCert, err error) {
@ -122,23 +193,7 @@ func (ctx *renderContext) Config() (ba []byte, cfg *config.Config, err error) {
return string(ba), nil return string(ba), nil
} }
extraFuncs := map[string]interface{}{ return map[string]interface{}{
"static_pods": func(name string) (string, error) {
t := ctx.clusterConfig.StaticPodsTemplate(name)
if t == nil {
return "", fmt.Errorf("no static pods template named %q", name)
}
buf := &bytes.Buffer{}
err := t.Execute(buf, ctxMap, nil)
if err != nil {
log.Printf("host %s: failed to render static pods: %v", ctx.Host.Name, err)
return "", err
}
return buf.String(), nil
},
"token": func(name string) (s string, err error) { "token": func(name string) (s string, err error) {
return secretData.Token(cluster, name) return secretData.Token(cluster, name)
}, },
@ -242,44 +297,32 @@ func (ctx *renderContext) Config() (ba []byte, cfg *config.Config, err error) {
}, },
}) })
}, },
"hosts_of_group": func() (hosts []interface{}) {
hosts = make([]interface{}, 0)
for _, host := range ctx.clusterConfig.Hosts {
if host.Group != ctx.Host.Group {
continue
} }
buf := bytes.NewBuffer(make([]byte, 0, 4096)) hosts = append(hosts, asMap(host))
if err = ctx.ConfigTemplate.Execute(buf, ctxMap, extraFuncs); err != nil {
return
} }
if secretData.Changed() { return hosts
err = secretData.Save() },
if err != nil {
return "hosts_of_group_count": func() (count int) {
} for _, host := range ctx.clusterConfig.Hosts {
if host.Group != ctx.Host.Group {
continue
} }
ba = buf.Bytes() count++
cfg = &config.Config{}
if err = yaml.Unmarshal(buf.Bytes(), cfg); err != nil {
return
} }
return
}
func (ctx *renderContext) StaticPods() (ba []byte, err error) {
if ctx.StaticPodsTemplate == nil {
err = notFoundError{fmt.Sprintf("static-pods %q", ctx.Group.StaticPods)}
return return
},
} }
buf := bytes.NewBuffer(make([]byte, 0, 4096))
if err = ctx.StaticPodsTemplate.Execute(buf, ctx.asMap(), nil); err != nil {
return
}
ba = buf.Bytes()
return
} }
func (ctx *renderContext) distFilePath(path ...string) string { func (ctx *renderContext) distFilePath(path ...string) string {
@ -306,16 +349,7 @@ func (ctx *renderContext) Tag() (string, error) {
} }
func (ctx *renderContext) asMap() map[string]interface{} { func (ctx *renderContext) asMap() map[string]interface{} {
ba, err := yaml.Marshal(ctx) result := asMap(ctx)
if err != nil {
panic(err) // shouldn't happen
}
result := make(map[string]interface{})
if err := yaml.Unmarshal(ba, result); err != nil {
panic(err)
}
// also expand cluster: // also expand cluster:
cluster := result["cluster"].(map[interface{}]interface{}) cluster := result["cluster"].(map[interface{}]interface{})
@ -324,3 +358,18 @@ func (ctx *renderContext) asMap() map[string]interface{} {
return result return result
} }
func asMap(v interface{}) map[string]interface{} {
ba, err := yaml.Marshal(v)
if err != nil {
panic(err) // shouldn't happen
}
result := make(map[string]interface{})
if err := yaml.Unmarshal(ba, result); err != nil {
panic(err) // shouldn't happen
}
return result
}