Skip to content
Snippets Groups Projects
main.go 2.71 KiB
package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
)

var (
	flagDry  = flag.Bool("n", false, "dry run, output everything to standard output")
	flagType = flag.String("t", "all", "generate config for: 'all', 'dns', 'dhcp', 'netboot'")
)

func main() {
	flag.Parse()
	conf := &Config{}
	for _, arg := range flag.Args() {
		buf, err := os.ReadFile(arg)
		if err != nil {
			log.Fatal(err)
		}
		c, err := confParser.ParseBytes(arg, buf)
		if err != nil {
			log.Fatal(err)
		}
		for i := range c.Blocks {
			c.Blocks[i].Source = arg
		}
		conf.Blocks = append(conf.Blocks, c.Blocks...)
	}
	if flag.NArg() == 0 {
		buf, err := io.ReadAll(os.Stdin)
		if err != nil {
			log.Fatal(err)
		}
		c, err := confParser.ParseBytes("-", buf)
		if err != nil {
			log.Fatal(err)
		}
		if len(c.Blocks) > 0 {
			c.Blocks[0].Source = "-"
		}
		conf.Blocks = append(conf.Blocks, c.Blocks...)
	}

	if err := conf.Validate(); err != nil {
		log.Fatal(err)
	}

	dns, err := makeDNS(conf)
	if err != nil {
		log.Fatal(err)
	}
	if IsFlagType("dns") {
		if err := dumpToFiles(dns, ";"); err != nil {
			log.Print(err)
		}
	}

	dh, err := makeDHCP(conf)
	if err != nil {
		log.Fatal(err)
	}
	if IsFlagType("dhcp") {
		if err := dumpToFiles(dh, "#"); err != nil {
			log.Print(err)
		}
	}

	nb, err := makeNetBoot(conf)
	if err != nil {
		log.Fatal(err)
	}
	if IsFlagType("netboot") {
		if err := dumpToFiles(nb, "#"); err != nil {
			log.Print(err)
		}
	}
}

func IsFlagType(t string) bool {
	if *flagType == "all" {
		return true
	}
	return *flagType == t
}

// Dump each of the elements of the map to the file named with the key.
func dumpToFiles(data map[string]*bytes.Buffer, commentchar string) error {
	for k, b := range data {
		log.Printf("Writing to %q", k)
		if *flagDry {
			fmt.Printf("********* %s *********\n", k)
			fmt.Print(b.String())
			fmt.Println("******************")
			continue
		}
		if err := os.WriteFile(k, b.Bytes(), 0640); err != nil {
			return err
		}
	}
	return nil
}

// https://gitlab.science.ru.nl/cncz/go/-/blob/b5d5a95a0840cfd55cbd88b89e4571f7eb5fc770/cmd/graaf/dashboard.go
const by = `%s Generated, source is "https://gitlab.cncz.nl/sys/dhcp/-/blob/%s/%s"`

func generatedBy(file, commentchar string) string {
	path := lsFile(file)
	if path == "" {
		return fmt.Sprintf("%s Generated, source is NOT IN GIT: %q", commentchar, file)
	}
	ref := revParse("HEAD")
	return fmt.Sprintf(by, commentchar, ref, path)
}

func newlineIfNotFirst(s io.Writer) {
	b, ok := s.(*bytes.Buffer)
	if !ok {
		return
	}
	if b.Len() > 0 {
		fmt.Fprintln(s)
	}
}

func contact(s io.Writer, c, commentchar string) { fmt.Fprintf(s, "%s Contact %s\n", commentchar, c) }
func source(s io.Writer, c, commentchar string)  { fmt.Fprintf(s, "%s\n", generatedBy(c, commentchar)) }