bootstrap pods support

This commit is contained in:
Mikaël Cluseau 2019-10-09 17:45:19 +11:00
parent dde0ad6975
commit 4679da1c1e
3 changed files with 91 additions and 49 deletions

View File

@ -10,6 +10,49 @@ import (
"novit.nc/direktil/local-server/pkg/clustersconfig" "novit.nc/direktil/local-server/pkg/clustersconfig"
) )
func clusterFuncs(clusterSpec *clustersconfig.Cluster) map[string]interface{} {
cluster := clusterSpec.Name
return map[string]interface{}{
"password": func(name string) (s string) {
return fmt.Sprintf("{{ password %q %q }}", cluster, name)
},
"token": func(name string) (s string) {
return fmt.Sprintf("{{ token %q %q }}", cluster, name)
},
"ca_key": func(name string) (s string, err error) {
// TODO check CA exists
// ?ctx.clusterConfig.CA(name)
return fmt.Sprintf("{{ ca_key %q %q }}", cluster, name), nil
},
"ca_crt": func(name string) (s string, err error) {
// TODO check CA exists
return fmt.Sprintf("{{ ca_crt %q %q }}", cluster, name), nil
},
"ca_dir": func(name string) (s string, err error) {
return fmt.Sprintf("{{ ca_dir %q %q }}", cluster, name), nil
},
"hosts_by_group": func(group string) (hosts []*clustersconfig.Host) {
for _, host := range src.Hosts {
if host.Group == group {
hosts = append(hosts, host)
}
}
if len(hosts) == 0 {
log.Fatalf("no hosts in group %q", group)
}
return
},
}
}
func renderClusterTemplates(cluster *clustersconfig.Cluster, setName string, func renderClusterTemplates(cluster *clustersconfig.Cluster, setName string,
templates []*clustersconfig.Template) []byte { templates []*clustersconfig.Template) []byte {
clusterAsMap := asMap(cluster) clusterAsMap := asMap(cluster)
@ -20,7 +63,7 @@ func renderClusterTemplates(cluster *clustersconfig.Cluster, setName string,
for _, t := range templates { for _, t := range templates {
fmt.Fprintf(buf, "---\n# %s: %s\n", setName, t.Name) fmt.Fprintf(buf, "---\n# %s: %s\n", setName, t.Name)
err := t.Execute(buf, clusterAsMap, nil) err := t.Execute(buf, clusterAsMap, clusterFuncs(cluster))
if err != nil { if err != nil {
log.Fatalf("cluster %q: %s: failed to render %q: %v", log.Fatalf("cluster %q: %s: failed to render %q: %v",
@ -63,33 +106,38 @@ func renderBootstrapPods(cluster *clustersconfig.Cluster) (pods []namePod) {
} }
// render bootstrap pods // render bootstrap pods
buf := bytes.NewBuffer(renderClusterTemplates(cluster, "bootstrap pods", bootstrapPods)) parts := bytes.Split(renderClusterTemplates(cluster, "bootstrap pods", bootstrapPods), []byte("\n---\n"))
dec := yaml.NewDecoder(buf) for _, part := range parts {
buf := bytes.NewBuffer(part)
dec := yaml.NewDecoder(buf)
for n := 0; ; n++ { for n := 0; ; n++ {
podMap := map[string]interface{}{} str := buf.String()
err := dec.Decode(podMap)
if err == io.EOF { podMap := map[string]interface{}{}
break err := dec.Decode(podMap)
} else if err != nil {
log.Fatalf("bootstrap pod %d: failed to parse: %v\n%s", n, err, buf.String()) if err == io.EOF {
break
} else if err != nil {
log.Fatalf("bootstrap pod %d: failed to parse: %v\n%s", n, err, str)
}
if len(podMap) == 0 {
continue
}
if podMap["metadata"] == nil {
log.Fatalf("bootstrap pod %d: no metadata\n%s", n, buf.String())
}
md := podMap["metadata"].(map[interface{}]interface{})
namespace := md["namespace"].(string)
name := md["name"].(string)
pods = append(pods, namePod{namespace, name, podMap})
} }
if len(podMap) == 0 {
continue
}
if podMap["metadata"] == nil {
log.Fatalf("bootstrap pod %d: no metadata\n%s", n, buf.String())
}
md := podMap["metadata"].(map[interface{}]interface{})
namespace := md["namespace"].(string)
name := md["name"].(string)
pods = append(pods, namePod{namespace, name, podMap})
} }
return return
@ -104,6 +152,13 @@ func renderBootstrapPodsDS(cluster *clustersconfig.Cluster) string {
md := pod["metadata"].(map[interface{}]interface{}) md := pod["metadata"].(map[interface{}]interface{})
labels := md["labels"] labels := md["labels"]
if labels == nil {
labels = map[string]interface{}{
"app": namePod.Name,
}
md["labels"] = labels
}
ann := md["annotations"] ann := md["annotations"]
annotations := map[interface{}]interface{}{} annotations := map[interface{}]interface{}{}
if ann != nil { if ann != nil {

View File

@ -198,30 +198,8 @@ func (ctx *renderContext) templateFuncs(ctxMap map[string]interface{}) map[strin
return return
} }
return map[string]interface{}{ funcs := clusterFuncs(ctx.Cluster)
"password": func(name string) (s string) { for k, v := range map[string]interface{}{
return fmt.Sprintf("{{ password %q %q }}", cluster, name)
},
"token": func(name string) (s string) {
return fmt.Sprintf("{{ token %q %q }}", cluster, name)
},
"ca_key": func(name string) (s string, err error) {
// TODO check CA exists
// ?ctx.clusterConfig.CA(name)
return fmt.Sprintf("{{ ca_key %q %q }}", cluster, name), nil
},
"ca_crt": func(name string) (s string, err error) {
// TODO check CA exists
return fmt.Sprintf("{{ ca_crt %q %q }}", cluster, name), nil
},
"ca_dir": func(name string) (s string, err error) {
return fmt.Sprintf("{{ ca_dir %q %q }}", cluster, name), nil
},
"tls_key": func(name string) (string, error) { "tls_key": func(name string) (string, error) {
return getKeyCert(name, "tls_key") return getKeyCert(name, "tls_key")
}, },
@ -256,7 +234,10 @@ func (ctx *renderContext) templateFuncs(ctxMap map[string]interface{}) map[strin
} }
return return
}, },
} {
funcs[k] = v
} }
return funcs
} }
func (ctx *renderContext) asMap() map[string]interface{} { func (ctx *renderContext) asMap() map[string]interface{} {

View File

@ -34,6 +34,12 @@ func registerWS(rest *restful.Container) {
Returns(http.StatusOK, "OK", nil). Returns(http.StatusOK, "OK", nil).
Returns(http.StatusNotFound, "The cluster does not exists or does not have addons defined", nil)) Returns(http.StatusNotFound, "The cluster does not exists or does not have addons defined", nil))
ws.Route(ws.GET("/clusters/{cluster-name}/bootstrap-pods").To(wsClusterBootstrapPods).
Produces(mime.YAML).
Doc("Get cluster bootstrap pods YAML definitions").
Returns(http.StatusOK, "OK", nil).
Returns(http.StatusNotFound, "The cluster does not exists or does not have bootstrap pods defined", nil))
ws.Route(ws.GET("/clusters/{cluster-name}/passwords").To(wsClusterPasswords). ws.Route(ws.GET("/clusters/{cluster-name}/passwords").To(wsClusterPasswords).
Doc("List cluster's passwords")) Doc("List cluster's passwords"))
ws.Route(ws.GET("/clusters/{cluster-name}/passwords/{password-name}").To(wsClusterPassword). ws.Route(ws.GET("/clusters/{cluster-name}/passwords/{password-name}").To(wsClusterPassword).