package main import ( "bytes" "flag" "fmt" "log" "os" yaml "gopkg.in/yaml.v2" "novit.nc/direktil/pkg/localconfig" "novit.nc/direktil/local-server/pkg/clustersconfig" ) var ( dir = flag.String("in", ".", "Source directory") outPath = flag.String("out", "config.yaml", "Output file") defaultsPath = flag.String("defaults", "defaults", "Path to the defaults") src *clustersconfig.Config dst *localconfig.Config ) func loadSrc() { var err error src, err = clustersconfig.FromDir(*dir, *defaultsPath) if err != nil { log.Fatal("failed to load config from dir: ", err) } } func main() { flag.Parse() loadSrc() dst = &localconfig.Config{ SSLConfig: src.SSLConfig, } // ---------------------------------------------------------------------- for _, cluster := range src.Clusters { dst.Clusters = append(dst.Clusters, &localconfig.Cluster{ Name: cluster.Name, Addons: renderAddons(cluster), }) } // ---------------------------------------------------------------------- for _, host := range src.Hosts { loadSrc() // FIXME ugly fix of some template caching or something log.Print("rendering host ", host.Name) ctx, err := newRenderContext(host, src) if err != nil { log.Fatal("failed to create render context for host ", host.Name, ": ", err) } macs := make([]string, 0) if host.MAC != "" { macs = append(macs, host.MAC) } ips := make([]string, 0) if len(host.IP) != 0 { ips = append(ips, host.IP) } ips = append(ips, host.IPs...) if ctx.Group.Versions["modules"] == "" { // default modules' version to kernel's version ctx.Group.Versions["modules"] = ctx.Group.Kernel } dst.Hosts = append(dst.Hosts, &localconfig.Host{ Name: host.Name, MACs: macs, IPs: ips, IPXE: ctx.Group.IPXE, // TODO render Kernel: ctx.Group.Kernel, Initrd: ctx.Group.Initrd, Versions: ctx.Group.Versions, Config: ctx.Config(), }) } // ---------------------------------------------------------------------- out, err := os.Create(*outPath) if err != nil { log.Fatal("failed to create output: ", err) } defer out.Close() if err = yaml.NewEncoder(out).Encode(dst); err != nil { log.Fatal("failed to render output: ", err) } } func renderAddons(cluster *clustersconfig.Cluster) string { if len(cluster.Addons) == 0 { return "" } addons := src.Addons[cluster.Addons] if addons == nil { log.Fatalf("cluster %q: no addons with name %q", cluster.Name, cluster.Addons) } clusterAsMap := asMap(cluster) clusterAsMap["kubernetes_svc_ip"] = cluster.KubernetesSvcIP().String() clusterAsMap["dns_svc_ip"] = cluster.DNSSvcIP().String() buf := &bytes.Buffer{} for _, addon := range addons { fmt.Fprintf(buf, "---\n# addon: %s\n", addon.Name) err := addon.Execute(buf, clusterAsMap, nil) if err != nil { log.Fatalf("cluster %q: addons %q: failed to render %q: %v", cluster.Name, cluster.Addons, addon.Name, err) } fmt.Fprintln(buf) } return buf.String() }