move clustersconfig out
This commit is contained in:
		| @ -1,10 +0,0 @@ | |||||||
| package clustersconfig |  | ||||||
|  |  | ||||||
| type CertRequest struct { |  | ||||||
| 	Template `yaml:",inline"` |  | ||||||
|  |  | ||||||
| 	CA      string |  | ||||||
| 	Profile string |  | ||||||
| 	Label   string |  | ||||||
| 	PerHost bool `yaml:"per_host"` |  | ||||||
| } |  | ||||||
| @ -1,222 +0,0 @@ | |||||||
| package clustersconfig |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"net" |  | ||||||
| 	"strings" |  | ||||||
| 	"text/template" |  | ||||||
|  |  | ||||||
| 	yaml "gopkg.in/yaml.v2" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type Config struct { |  | ||||||
| 	Hosts        []*Host |  | ||||||
| 	Groups       []*Group |  | ||||||
| 	Clusters     []*Cluster |  | ||||||
| 	Configs      []*Template |  | ||||||
| 	StaticPods   []*Template `yaml:"static_pods"` |  | ||||||
| 	Addons       map[string][]*Template |  | ||||||
| 	SSLConfig    string         `yaml:"ssl_config"` |  | ||||||
| 	CertRequests []*CertRequest `yaml:"cert_requests"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func FromBytes(data []byte) (*Config, error) { |  | ||||||
| 	config := &Config{Addons: make(map[string][]*Template)} |  | ||||||
| 	if err := yaml.Unmarshal(data, config); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	return config, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func FromFile(path string) (*Config, error) { |  | ||||||
| 	ba, err := ioutil.ReadFile(path) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return FromBytes(ba) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Config) Host(name string) *Host { |  | ||||||
| 	for _, host := range c.Hosts { |  | ||||||
| 		if host.Name == name { |  | ||||||
| 			return host |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Config) HostByIP(ip string) *Host { |  | ||||||
| 	for _, host := range c.Hosts { |  | ||||||
| 		if host.IP == ip { |  | ||||||
| 			return host |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		for _, otherIP := range host.IPs { |  | ||||||
| 			if otherIP == ip { |  | ||||||
| 				return host |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Config) HostByMAC(mac string) *Host { |  | ||||||
| 	// a bit of normalization |  | ||||||
| 	mac = strings.Replace(strings.ToLower(mac), "-", ":", -1) |  | ||||||
|  |  | ||||||
| 	for _, host := range c.Hosts { |  | ||||||
| 		if strings.ToLower(host.MAC) == mac { |  | ||||||
| 			return host |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Config) Group(name string) *Group { |  | ||||||
| 	for _, group := range c.Groups { |  | ||||||
| 		if group.Name == name { |  | ||||||
| 			return group |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Config) Cluster(name string) *Cluster { |  | ||||||
| 	for _, cluster := range c.Clusters { |  | ||||||
| 		if cluster.Name == name { |  | ||||||
| 			return cluster |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Config) ConfigTemplate(name string) *Template { |  | ||||||
| 	for _, cfg := range c.Configs { |  | ||||||
| 		if cfg.Name == name { |  | ||||||
| 			return cfg |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Config) StaticPodsTemplate(name string) *Template { |  | ||||||
| 	for _, s := range c.StaticPods { |  | ||||||
| 		if s.Name == name { |  | ||||||
| 			return s |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Config) CSR(name string) *CertRequest { |  | ||||||
| 	for _, s := range c.CertRequests { |  | ||||||
| 		if s.Name == name { |  | ||||||
| 			return s |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Config) SaveTo(path string) error { |  | ||||||
| 	ba, err := yaml.Marshal(c) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return ioutil.WriteFile(path, ba, 0600) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type Template struct { |  | ||||||
| 	Name     string |  | ||||||
| 	Template string |  | ||||||
|  |  | ||||||
| 	parsedTemplate *template.Template |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (t *Template) Execute(wr io.Writer, data interface{}, extraFuncs map[string]interface{}) error { |  | ||||||
| 	if t.parsedTemplate == nil { |  | ||||||
| 		var templateFuncs = map[string]interface{}{ |  | ||||||
| 			"indent": func(indent, s string) (indented string) { |  | ||||||
| 				indented = indent + strings.Replace(s, "\n", "\n"+indent, -1) |  | ||||||
| 				return |  | ||||||
| 			}, |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		for name, f := range extraFuncs { |  | ||||||
| 			templateFuncs[name] = f |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		tmpl, err := template.New(t.Name). |  | ||||||
| 			Funcs(templateFuncs). |  | ||||||
| 			Parse(t.Template) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		t.parsedTemplate = tmpl |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return t.parsedTemplate.Execute(wr, data) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Host represents a host served by this server. |  | ||||||
| type Host struct { |  | ||||||
| 	Name    string |  | ||||||
| 	MAC     string |  | ||||||
| 	IP      string |  | ||||||
| 	IPs     []string |  | ||||||
| 	Cluster string |  | ||||||
| 	Group   string |  | ||||||
| 	Vars    Vars |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Group represents a group of hosts and provides their configuration. |  | ||||||
| type Group struct { |  | ||||||
| 	Name       string |  | ||||||
| 	Master     bool |  | ||||||
| 	IPXE       string |  | ||||||
| 	Kernel     string |  | ||||||
| 	Initrd     string |  | ||||||
| 	Config     string |  | ||||||
| 	StaticPods string `yaml:"static_pods"` |  | ||||||
| 	Versions   map[string]string |  | ||||||
| 	Vars       Vars |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Vars store user-defined key-values |  | ||||||
| type Vars map[string]interface{} |  | ||||||
|  |  | ||||||
| // Cluster represents a cluster of hosts, allowing for cluster-wide variables. |  | ||||||
| type Cluster struct { |  | ||||||
| 	Name    string |  | ||||||
| 	Domain  string |  | ||||||
| 	Addons  string |  | ||||||
| 	Subnets struct { |  | ||||||
| 		Services string |  | ||||||
| 		Pods     string |  | ||||||
| 	} |  | ||||||
| 	Vars Vars |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Cluster) KubernetesSvcIP() net.IP { |  | ||||||
| 	return c.NthSvcIP(1) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Cluster) DNSSvcIP() net.IP { |  | ||||||
| 	return c.NthSvcIP(2) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Cluster) NthSvcIP(n byte) net.IP { |  | ||||||
| 	_, cidr, err := net.ParseCIDR(c.Subnets.Services) |  | ||||||
| 	if err != nil { |  | ||||||
| 		panic(fmt.Errorf("Invalid services CIDR: %v", err)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ip := cidr.IP |  | ||||||
| 	ip[len(ip)-1] += n |  | ||||||
|  |  | ||||||
| 	return ip |  | ||||||
| } |  | ||||||
| @ -1,192 +0,0 @@ | |||||||
| package clustersconfig |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"os" |  | ||||||
| 	"path" |  | ||||||
| 	"path/filepath" |  | ||||||
| 	"strings" |  | ||||||
|  |  | ||||||
| 	yaml "gopkg.in/yaml.v2" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| func FromDir(dirPath string) (*Config, error) { |  | ||||||
| 	config := &Config{Addons: make(map[string][]*Template)} |  | ||||||
|  |  | ||||||
| 	store := dirStore{dirPath} |  | ||||||
| 	load := func(dir, name string, out interface{}) error { |  | ||||||
| 		ba, err := store.Get(path.Join(dir, name)) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		return yaml.Unmarshal(ba, out) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// load clusters |  | ||||||
| 	names, err := store.List("clusters") |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for _, name := range names { |  | ||||||
| 		cluster := &Cluster{Name: name} |  | ||||||
| 		if err := load("clusters", name, cluster); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		config.Clusters = append(config.Clusters, cluster) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// load groups |  | ||||||
| 	names, err = store.List("groups") |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for _, name := range names { |  | ||||||
| 		o := &Group{Name: name} |  | ||||||
| 		if err := load("groups", name, o); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		config.Groups = append(config.Groups, o) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// load hosts |  | ||||||
| 	names, err = store.List("hosts") |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	for _, name := range names { |  | ||||||
| 		o := &Host{Name: name} |  | ||||||
| 		if err := load("hosts", name, o); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		config.Hosts = append(config.Hosts, o) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// load config templates |  | ||||||
| 	loadTemplates := func(dir string, templates *[]*Template) error { |  | ||||||
| 		names, err = store.List(dir) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		for _, name := range names { |  | ||||||
| 			ba, err := store.Get(path.Join(dir, name)) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return err |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			o := &Template{Name: name, Template: string(ba)} |  | ||||||
|  |  | ||||||
| 			*templates = append(*templates, o) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if err := loadTemplates("configs", &config.Configs); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
| 	if err := loadTemplates("static-pods", &config.StaticPods); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	{ |  | ||||||
| 		addonSets, err := store.listDir("addons") |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		for _, addonSet := range addonSets { |  | ||||||
| 			templates := make([]*Template, 0) |  | ||||||
| 			if err = loadTemplates(path.Join("addons", addonSet), &templates); err != nil { |  | ||||||
| 				return nil, err |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			config.Addons[addonSet] = templates |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// load SSL configuration |  | ||||||
| 	if ba, err := ioutil.ReadFile(filepath.Join(dirPath, "ssl-config.json")); err == nil { |  | ||||||
| 		config.SSLConfig = string(ba) |  | ||||||
|  |  | ||||||
| 	} else if !os.IsNotExist(err) { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if ba, err := ioutil.ReadFile(filepath.Join(dirPath, "cert-requests.yaml")); err == nil { |  | ||||||
| 		reqs := make([]*CertRequest, 0) |  | ||||||
| 		if err = yaml.Unmarshal(ba, &reqs); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		config.CertRequests = reqs |  | ||||||
|  |  | ||||||
| 	} else if !os.IsNotExist(err) { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return config, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| type dirStore struct { |  | ||||||
| 	path string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // listDir |  | ||||||
| func (b *dirStore) listDir(prefix string) (subDirs []string, err error) { |  | ||||||
| 	entries, err := ioutil.ReadDir(filepath.Join(b.path, prefix)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	subDirs = make([]string, 0, len(entries)) |  | ||||||
|  |  | ||||||
| 	for _, entry := range entries { |  | ||||||
| 		if !entry.IsDir() { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		name := entry.Name() |  | ||||||
|  |  | ||||||
| 		if len(name) == 0 || name[0] == '.' { |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		subDirs = append(subDirs, name) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Names is part of the kvStore interface |  | ||||||
| func (b *dirStore) List(prefix string) ([]string, error) { |  | ||||||
| 	files, err := filepath.Glob(filepath.Join(b.path, filepath.Join(path.Split(prefix)), "*.yaml")) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	names := make([]string, 0, len(files)) |  | ||||||
| 	for _, f := range files { |  | ||||||
| 		f2 := strings.TrimSuffix(f, ".yaml") |  | ||||||
| 		f2 = filepath.Base(f2) |  | ||||||
|  |  | ||||||
| 		if f2[0] == '.' { // ignore hidden files |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		names = append(names, f2) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return names, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Load is part of the DataBackend interface |  | ||||||
| func (b *dirStore) Get(key string) ([]byte, error) { |  | ||||||
| 	return ioutil.ReadFile(filepath.Join(b.path, filepath.Join(path.Split(key))+".yaml")) |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user