package main import ( "bytes" "fmt" "log" "path" "novit.tech/direktil/local-server/pkg/clustersconfig" ) func clusterFuncs(clusterSpec *clustersconfig.Cluster) map[string]any { cluster := clusterSpec.Name return map[string]any{ "password": func(name, hash string) (s string) { return fmt.Sprintf("{{ password %q %q %q | quote }}", cluster, name, hash) }, "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_cluster": func(cluster string) (hosts []any) { for _, host := range src.Hosts { if host.Cluster == cluster { hosts = append(hosts, asMap(host)) } } if len(hosts) == 0 { log.Printf("WARNING: no hosts in cluster %q", cluster) } return }, "hosts_by_group": func(group string) (hosts []any) { for _, host := range src.Hosts { if host.Cluster == cluster && host.Group == group { hosts = append(hosts, asMap(host)) } } if len(hosts) == 0 { log.Printf("WARNING: no hosts in group %q", group) } return }, "host_ip_from": func(hostName, net string) string { host := src.Host(hostName) if host == nil { log.Printf("WARNING: no host named %q", hostName) return "" } ipFrom := host.IPFrom if ipFrom == nil { ipFrom = map[string]string{} } ip, ok := ipFrom[net] if !ok { ip = host.IP } return ip }, } } func renderClusterTemplates(cluster *clustersconfig.Cluster, setName string, templates []*clustersconfig.Template) []byte { clusterAsMap := asMap(cluster) clusterAsMap["kubernetes_svc_ip"] = cluster.KubernetesSvcIP().String() clusterAsMap["dns_svc_ip"] = cluster.DNSSvcIP().String() funcs := clusterFuncs(cluster) log.Print("rendering cluster templates in ", setName) buf := &bytes.Buffer{} contextName := "cluster:" + cluster.Name for _, t := range templates { log.Print("- template: ", setName, ": ", t.Name) fmt.Fprintf(buf, "---\n# %s: %s\n", setName, t.Name) err := t.Execute(contextName, path.Join(setName, t.Name), buf, clusterAsMap, funcs) if err != nil { log.Fatalf("cluster %q: %s: failed to render %q: %v", cluster.Name, setName, t.Name, err) } fmt.Fprintln(buf) } return buf.Bytes() } func renderAddons(cluster *clustersconfig.Cluster) string { if len(cluster.Addons) == 0 { return "" } buf := new(bytes.Buffer) for _, addonSet := range cluster.Addons { addons := src.Addons[addonSet] if addons == nil { log.Fatalf("cluster %q: no addons with name %q", cluster.Name, addonSet) } buf.Write(renderClusterTemplates(cluster, "addons", addons)) } return buf.String() } type namePod struct { Namespace string Name string Pod map[string]interface{} }