dir2config: switch to includes instead of ad-hoc defaults
This commit is contained in:
@ -3,7 +3,6 @@ package clustersconfig
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@ -15,24 +14,21 @@ import (
|
||||
// Debug enables debug logs from this package.
|
||||
var Debug = false
|
||||
|
||||
func FromDir(dirPath, defaultsPath string) (*Config, error) {
|
||||
if Debug {
|
||||
log.Printf("loading config from dir %s (defaults from %s)", dirPath, defaultsPath)
|
||||
}
|
||||
func FromDir(
|
||||
read func(path string) ([]byte, error),
|
||||
assemble func(path string) ([]byte, error),
|
||||
listBase func(path string) ([]string, error),
|
||||
listMerged func(path string) ([]string, error),
|
||||
) (*Config, error) {
|
||||
|
||||
defaults, err := NewDefaults(defaultsPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load defaults: %v", err)
|
||||
}
|
||||
|
||||
store := &dirStore{dirPath}
|
||||
load := func(dir, name string, out Rev) error {
|
||||
ba, err := store.Get(path.Join(dir, name))
|
||||
load := func(dir, name string, out any) (err error) {
|
||||
ba, err := assemble(filepath.Join(dir, name))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load %s/%s from dir: %v", dir, name, err)
|
||||
return
|
||||
}
|
||||
if err = defaults.Load(dir, ".yaml", out, ba); err != nil {
|
||||
return fmt.Errorf("failed to enrich %s/%s from defaults: %v", dir, name, err)
|
||||
err = yaml.UnmarshalStrict(ba, out)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -43,12 +39,13 @@ func FromDir(dirPath, defaultsPath string) (*Config, error) {
|
||||
}
|
||||
|
||||
// load clusters
|
||||
names, err := store.List("clusters")
|
||||
names, err := listBase("clusters")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list clusters: %v", err)
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
name, _ = strings.CutSuffix(name, ".yaml")
|
||||
cluster := &Cluster{Name: name}
|
||||
if err := load("clusters", name, cluster); err != nil {
|
||||
return nil, err
|
||||
@ -57,103 +54,14 @@ func FromDir(dirPath, defaultsPath string) (*Config, error) {
|
||||
config.Clusters = append(config.Clusters, cluster)
|
||||
}
|
||||
|
||||
// load groups
|
||||
names, err = store.List("groups")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list groups: %v", err)
|
||||
}
|
||||
|
||||
read := func(rev, filePath string) (data []byte, fromDefaults bool, err error) {
|
||||
data, err = store.Get(filePath)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("faild to read %s: %v", filePath, err)
|
||||
return
|
||||
}
|
||||
|
||||
if data != nil {
|
||||
return // ok
|
||||
}
|
||||
|
||||
if len(rev) == 0 {
|
||||
err = fmt.Errorf("entry not found: %s", filePath)
|
||||
return
|
||||
}
|
||||
|
||||
data, err = defaults.ReadAll(rev, filePath+".yaml")
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to read %s:%s: %v", rev, filePath, err)
|
||||
return
|
||||
}
|
||||
|
||||
fromDefaults = true
|
||||
return
|
||||
}
|
||||
|
||||
template := func(rev, dir, name string, templates *[]*Template) (ref string, err error) {
|
||||
ref = name
|
||||
if len(name) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
ba, fromDefaults, err := read(rev, path.Join(dir, name))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if fromDefaults {
|
||||
ref = rev + ":" + name
|
||||
}
|
||||
|
||||
if !hasTemplate(ref, *templates) {
|
||||
if Debug {
|
||||
log.Printf("new template in %s: %s", dir, ref)
|
||||
}
|
||||
|
||||
*templates = append(*templates, &Template{
|
||||
Name: ref,
|
||||
Template: string(ba),
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
group := &Group{Name: name}
|
||||
if err := load("groups", name, group); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
group.BootstrapConfig, err = template(group.Rev(), "configs", group.BootstrapConfig, &config.Configs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load config for group %q: %v", name, err)
|
||||
}
|
||||
|
||||
group.Config, err = template(group.Rev(), "configs", group.Config, &config.Configs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load config for group %q: %v", name, err)
|
||||
}
|
||||
|
||||
if Debug {
|
||||
log.Printf("group %q: config=%q static_pods=%q",
|
||||
group.Name, group.Config, group.StaticPods)
|
||||
}
|
||||
|
||||
group.StaticPods, err = template(group.Rev(), "static-pods", group.StaticPods, &config.StaticPods)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load static pods for group %q: %v", name, err)
|
||||
}
|
||||
|
||||
config.Groups = append(config.Groups, group)
|
||||
}
|
||||
|
||||
// load hosts
|
||||
names, err = store.List("hosts")
|
||||
names, err = listBase("hosts")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list hosts: %v", err)
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
name, _ = strings.CutSuffix(name, ".yaml")
|
||||
o := &Host{Name: name}
|
||||
if err := load("hosts", name, o); err != nil {
|
||||
return nil, err
|
||||
@ -163,28 +71,20 @@ func FromDir(dirPath, defaultsPath string) (*Config, error) {
|
||||
}
|
||||
|
||||
// load config templates
|
||||
loadTemplates := func(rev, dir string, templates *[]*Template) error {
|
||||
names, err := store.List(dir)
|
||||
loadTemplates := func(dir string, templates *[]*Template) error {
|
||||
names, err := listMerged(dir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list %s: %v", dir, err)
|
||||
}
|
||||
|
||||
if len(rev) != 0 {
|
||||
var defaultsNames []string
|
||||
defaultsNames, err = defaults.List(rev, dir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list %s:%s: %v", rev, dir, err)
|
||||
}
|
||||
for _, fullName := range names {
|
||||
name, _ := strings.CutSuffix(fullName, ".yaml")
|
||||
|
||||
names = append(names, defaultsNames...)
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
if hasTemplate(name, *templates) {
|
||||
continue
|
||||
}
|
||||
|
||||
ba, _, err := read(rev, path.Join(dir, name))
|
||||
ba, err := read(path.Join(dir, fullName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -198,6 +98,8 @@ func FromDir(dirPath, defaultsPath string) (*Config, error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
loadTemplates("configs", &config.Configs)
|
||||
|
||||
// cluster addons
|
||||
for _, cluster := range config.Clusters {
|
||||
addonSet := cluster.Addons
|
||||
@ -210,7 +112,7 @@ func FromDir(dirPath, defaultsPath string) (*Config, error) {
|
||||
}
|
||||
|
||||
templates := make([]*Template, 0)
|
||||
if err = loadTemplates(cluster.Rev(), path.Join("addons", addonSet), &templates); err != nil {
|
||||
if err = loadTemplates(path.Join("addons", addonSet), &templates); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -218,8 +120,8 @@ func FromDir(dirPath, defaultsPath string) (*Config, error) {
|
||||
}
|
||||
|
||||
// cluster bootstrap pods
|
||||
for _, cluster := range config.Clusters {
|
||||
bpSet := cluster.BootstrapPods
|
||||
for _, host := range config.Hosts {
|
||||
bpSet := host.BootstrapPods
|
||||
if bpSet == "" {
|
||||
continue
|
||||
}
|
||||
@ -229,7 +131,7 @@ func FromDir(dirPath, defaultsPath string) (*Config, error) {
|
||||
}
|
||||
|
||||
templates := make([]*Template, 0)
|
||||
if err = loadTemplates(cluster.Rev(), path.Join("bootstrap-pods", bpSet), &templates); err != nil {
|
||||
if err = loadTemplates(path.Join("bootstrap-pods", bpSet), &templates); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -237,14 +139,14 @@ func FromDir(dirPath, defaultsPath string) (*Config, error) {
|
||||
}
|
||||
|
||||
// load SSL configuration
|
||||
if ba, err := ioutil.ReadFile(filepath.Join(dirPath, "ssl-config.json")); err == nil {
|
||||
if ba, err := read("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 {
|
||||
if ba, err := read("cert-requests.yaml"); err == nil {
|
||||
reqs := make([]*CertRequest, 0)
|
||||
if err = yaml.Unmarshal(ba, &reqs); err != nil {
|
||||
return nil, err
|
||||
|
Reference in New Issue
Block a user