From 4ff85eaeb30bf29cdcfd47481a2cb4a7fd339d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Cluseau?= Date: Mon, 16 Jan 2023 18:17:11 +0100 Subject: [PATCH] remove bootstrap pods from cluster, and render in hosts' context --- cmd/dkl-dir2config/main.go | 5 +- cmd/dkl-dir2config/render-cluster.go | 106 --------------------------- cmd/dkl-dir2config/render-context.go | 13 +++- cmd/dkl-dir2config/render-host.go | 77 +++++++++++++++++++ 4 files changed, 88 insertions(+), 113 deletions(-) create mode 100644 cmd/dkl-dir2config/render-host.go diff --git a/cmd/dkl-dir2config/main.go b/cmd/dkl-dir2config/main.go index fa7b3d0..624c79e 100644 --- a/cmd/dkl-dir2config/main.go +++ b/cmd/dkl-dir2config/main.go @@ -43,9 +43,8 @@ func main() { // ---------------------------------------------------------------------- for _, cluster := range src.Clusters { dst.Clusters = append(dst.Clusters, &localconfig.Cluster{ - Name: cluster.Name, - Addons: renderAddons(cluster), - BootstrapPods: renderBootstrapPodsDS(cluster), + Name: cluster.Name, + Addons: renderAddons(cluster), }) } diff --git a/cmd/dkl-dir2config/render-cluster.go b/cmd/dkl-dir2config/render-cluster.go index ba5abad..1637108 100644 --- a/cmd/dkl-dir2config/render-cluster.go +++ b/cmd/dkl-dir2config/render-cluster.go @@ -3,12 +3,9 @@ package main import ( "bytes" "fmt" - "io" "log" "path" - yaml "gopkg.in/yaml.v2" - "novit.tech/direktil/local-server/pkg/clustersconfig" ) @@ -117,106 +114,3 @@ type namePod struct { Name string Pod map[string]interface{} } - -func renderBootstrapPods(cluster *clustersconfig.Cluster) (pods []namePod) { - if cluster.BootstrapPods == "" { - return nil - } - - bootstrapPods := src.BootstrapPods[cluster.BootstrapPods] - if bootstrapPods == nil { - log.Fatalf("no bootstrap pods template named %q", cluster.BootstrapPods) - } - - // render bootstrap pods - parts := bytes.Split(renderClusterTemplates(cluster, "bootstrap-pods", bootstrapPods), []byte("\n---\n")) - for _, part := range parts { - buf := bytes.NewBuffer(part) - dec := yaml.NewDecoder(buf) - - for n := 0; ; n++ { - str := buf.String() - - podMap := map[string]interface{}{} - err := dec.Decode(podMap) - - 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}) - } - } - - return -} - -func renderBootstrapPodsDS(cluster *clustersconfig.Cluster) string { - buf := &bytes.Buffer{} - enc := yaml.NewEncoder(buf) - for _, namePod := range renderBootstrapPods(cluster) { - pod := namePod.Pod - - md := pod["metadata"].(map[interface{}]interface{}) - labels := md["labels"] - - if labels == nil { - labels = map[string]interface{}{ - "app": namePod.Name, - } - md["labels"] = labels - } - - ann := md["annotations"] - annotations := map[interface{}]interface{}{} - if ann != nil { - annotations = ann.(map[interface{}]interface{}) - } - annotations["node.kubernetes.io/bootstrap-checkpoint"] = "true" - - md["annotations"] = annotations - - delete(md, "name") - delete(md, "namespace") - - err := enc.Encode(map[string]interface{}{ - "apiVersion": "apps/v1", - "kind": "DaemonSet", - "metadata": map[string]interface{}{ - "namespace": namePod.Namespace, - "name": namePod.Name, - "labels": labels, - }, - "spec": map[string]interface{}{ - "minReadySeconds": 60, - "selector": map[string]interface{}{ - "matchLabels": labels, - }, - "template": map[string]interface{}{ - "metadata": pod["metadata"], - "spec": pod["spec"], - }, - }, - }) - - if err != nil { - panic(err) - } - } - return buf.String() -} diff --git a/cmd/dkl-dir2config/render-context.go b/cmd/dkl-dir2config/render-context.go index 15d6d45..5f3b2b7 100644 --- a/cmd/dkl-dir2config/render-context.go +++ b/cmd/dkl-dir2config/render-context.go @@ -5,9 +5,11 @@ import ( "crypto/sha1" "encoding/hex" "fmt" + "io" "log" "path" "reflect" + "strings" yaml "gopkg.in/yaml.v2" @@ -154,6 +156,12 @@ func (ctx *renderContext) Config() string { } func (ctx *renderContext) renderConfig(configTemplate *clustersconfig.Template) string { + buf := new(strings.Builder) + ctx.renderConfigTo(buf, configTemplate) + return buf.String() +} + +func (ctx *renderContext) renderConfigTo(buf io.Writer, configTemplate *clustersconfig.Template) { ctxName := ctx.Name() ctxMap := ctx.asMap() @@ -189,7 +197,7 @@ func (ctx *renderContext) renderConfig(configTemplate *clustersconfig.Template) } extraFuncs["bootstrap_pods_files"] = func(dir string) (string, error) { - namePods := renderBootstrapPods(ctx.Cluster) + namePods := ctx.renderBootstrapPods() defs := make([]config.FileDef, 0) @@ -217,12 +225,9 @@ func (ctx *renderContext) renderConfig(configTemplate *clustersconfig.Template) return hex.EncodeToString(ba[:]) } - buf := bytes.NewBuffer(make([]byte, 0, 4096)) if err := configTemplate.Execute(ctxName, "config", buf, ctxMap, extraFuncs); err != nil { log.Fatalf("failed to render config %q for host %q: %v", ctx.Group.Config, ctx.Host.Name, err) } - - return buf.String() } func (ctx *renderContext) StaticPods() (ba []byte, err error) { diff --git a/cmd/dkl-dir2config/render-host.go b/cmd/dkl-dir2config/render-host.go new file mode 100644 index 0000000..f985164 --- /dev/null +++ b/cmd/dkl-dir2config/render-host.go @@ -0,0 +1,77 @@ +package main + +import ( + "bytes" + "fmt" + "io" + "log" + + yaml "gopkg.in/yaml.v2" + "novit.tech/direktil/local-server/pkg/clustersconfig" +) + +func (ctx *renderContext) renderBootstrapPods() (pods []namePod) { + if ctx.Cluster.BootstrapPods == "" { + return + } + + bootstrapPods, ok := src.BootstrapPods[ctx.Cluster.BootstrapPods] + if !ok { + log.Fatalf("no bootstrap pods template named %q", ctx.Cluster.BootstrapPods) + } + + // render bootstrap pods + parts := bytes.Split(ctx.renderHostTemplates("bootstrap-pods", bootstrapPods), []byte("\n---\n")) + for _, part := range parts { + buf := bytes.NewBuffer(part) + dec := yaml.NewDecoder(buf) + + for n := 0; ; n++ { + str := buf.String() + + podMap := map[string]interface{}{} + err := dec.Decode(podMap) + + 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}) + } + } + + return +} + +func (ctx *renderContext) renderHostTemplates(setName string, + templates []*clustersconfig.Template) []byte { + + log.Print("rendering host templates in ", setName) + + buf := &bytes.Buffer{} + + for _, t := range templates { + log.Print("- template: ", setName, ": ", t.Name) + fmt.Fprintf(buf, "---\n# %s: %s\n", setName, t.Name) + + ctx.renderConfigTo(buf, t) + fmt.Fprintln(buf) + } + + return buf.Bytes() +}