move clustersconfig out
This commit is contained in:
parent
68c87509f2
commit
9dc80cd34b
@ -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"))
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user