isle/go-workspace/src/hosts.go
Brian Picciano b35a3d6574 First public commit
There has been over 1 year of commit history leading up to this point,
but almost all of that has had some kind network configuration or
secrets built into the code. As of today all of that has been removed,
and the codebase can finally be published!

I am keeping a private copy of the previous commit history, though it's
unclear if it will ever be able to be published.
2022-07-04 15:18:55 -06:00

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
}