94 lines
2.2 KiB
Go
94 lines
2.2 KiB
Go
|
package crypticnet
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"io/fs"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
|
||
|
"gopkg.in/yaml.v3"
|
||
|
)
|
||
|
|
||
|
// NebulaHost describes the contents of a `./nebula/hosts/<hostname>.yml` file.
|
||
|
type NebulaHost struct {
|
||
|
Name string `yaml:"name"`
|
||
|
IP string `yaml:"ip"`
|
||
|
PublicAddr string `yaml:"public_addr,omitempty"`
|
||
|
}
|
||
|
|
||
|
// GarageHostInstance describes a single garage instance running on a host.
|
||
|
type GarageHostInstance struct {
|
||
|
APIPort int `yaml:"api_port"`
|
||
|
RPCPort int `yaml:"rpc_port"`
|
||
|
WebPort int `yaml:"web_port"`
|
||
|
}
|
||
|
|
||
|
// GarageHost describes the contents of a `./garage/hosts/<hostname>.yml` file.
|
||
|
type GarageHost struct {
|
||
|
Instances []GarageHostInstance `yaml:"instances"`
|
||
|
}
|
||
|
|
||
|
// Host consolidates all information about a single host from the bootstrap
|
||
|
// file.
|
||
|
type Host struct {
|
||
|
Name string
|
||
|
Nebula NebulaHost
|
||
|
Garage *GarageHost
|
||
|
}
|
||
|
|
||
|
// LostHosts returns a mapping of hostnames to Host objects for each host.
|
||
|
func LoadHosts(bootstrapFS fs.FS) (map[string]Host, error) {
|
||
|
|
||
|
hosts := map[string]Host{}
|
||
|
|
||
|
readAsYaml := func(into interface{}, path string) error {
|
||
|
b, err := fs.ReadFile(bootstrapFS, path)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("reading file from fs: %w", err)
|
||
|
}
|
||
|
|
||
|
return yaml.Unmarshal(b, into)
|
||
|
}
|
||
|
|
||
|
{
|
||
|
nebulaHostFiles, err := fs.Glob(bootstrapFS, "nebula/hosts/*.yml")
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("listing nebula host files: %w", err)
|
||
|
}
|
||
|
|
||
|
for _, nebulaHostPath := range nebulaHostFiles {
|
||
|
|
||
|
hostName := filepath.Base(nebulaHostPath)
|
||
|
hostName = strings.TrimSuffix(hostName, filepath.Ext(hostName))
|
||
|
|
||
|
var nebulaHost NebulaHost
|
||
|
if err := readAsYaml(&nebulaHost, nebulaHostPath); err != nil {
|
||
|
return nil, fmt.Errorf("reading %q as yaml: %w", nebulaHostPath, err)
|
||
|
}
|
||
|
|
||
|
hosts[hostName] = Host{
|
||
|
Name: hostName,
|
||
|
Nebula: nebulaHost,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for hostName, host := range hosts {
|
||
|
|
||
|
garageHostPath := filepath.Join("garage/hosts", hostName+".yml")
|
||
|
|
||
|
var garageHost GarageHost
|
||
|
if err := readAsYaml(&garageHost, garageHostPath); errors.Is(err, fs.ErrNotExist) {
|
||
|
continue
|
||
|
} else if err != nil {
|
||
|
return nil, fmt.Errorf("reading %q as yaml: %w", garageHostPath, err)
|
||
|
}
|
||
|
|
||
|
host.Garage = &garageHost
|
||
|
hosts[hostName] = host
|
||
|
}
|
||
|
|
||
|
return hosts, nil
|
||
|
}
|