93 lines
2.4 KiB
Go
93 lines
2.4 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"bytes"
|
|
"isle/nebula"
|
|
"fmt"
|
|
"net"
|
|
"strings"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
// NebulaHost describes the nebula configuration of a Host which is relevant for
|
|
// other hosts to know.
|
|
type NebulaHost struct {
|
|
SignedPublicCredentials string `yaml:"signed_public_credentials"`
|
|
PublicAddr string `yaml:"public_addr,omitempty"`
|
|
}
|
|
|
|
// NewNebulaHostSignedPublicCredentials constructs the SignedPublicCredentials
|
|
// field of the NebulaHost struct, using the CACredentials to sign the
|
|
// HostPublicCredentials.
|
|
func NewNebulaHostSignedPublicCredentials(
|
|
caCreds nebula.CACredentials,
|
|
hostPublicCreds nebula.HostPublicCredentials,
|
|
) (
|
|
string, error,
|
|
) {
|
|
|
|
hostPublicCredsB, err := yaml.Marshal(hostPublicCreds)
|
|
if err != nil {
|
|
return "", fmt.Errorf("yaml marshaling host's public credentials: %w", err)
|
|
}
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
err = nebula.SignAndWrap(buf, caCreds.SigningPrivateKeyPEM, hostPublicCredsB)
|
|
if err != nil {
|
|
return "", fmt.Errorf("signing host's public credentials: %w", err)
|
|
}
|
|
|
|
return buf.String(), nil
|
|
}
|
|
|
|
// GarageHost describes a single garage instance in the GarageHost.
|
|
type GarageHostInstance struct {
|
|
ID string `yaml:"id"`
|
|
RPCPort int `yaml:"rpc_port"`
|
|
S3APIPort int `yaml:"s3_api_port"`
|
|
}
|
|
|
|
// GarageHost describes the garage configuration of a Host which is relevant for
|
|
// other hosts to know.
|
|
type GarageHost struct {
|
|
Instances []GarageHostInstance `yaml:"instances"`
|
|
}
|
|
|
|
// Host consolidates all information about a single host from the bootstrap
|
|
// file.
|
|
type Host struct {
|
|
Name string `yaml:"name"`
|
|
Nebula NebulaHost `yaml:"nebula"`
|
|
Garage GarageHost `yaml:"garage,omitempty"`
|
|
}
|
|
|
|
// IP returns the IP address encoded in the Host's nebula certificate, or panics
|
|
// if there is an error.
|
|
//
|
|
// This assumes that the Host and its data has already been verified against the
|
|
// CA signing key.
|
|
func (h Host) IP() net.IP {
|
|
|
|
hostPublicCredsB, _, err := nebula.Unwrap(
|
|
strings.NewReader(h.Nebula.SignedPublicCredentials),
|
|
)
|
|
|
|
if err != nil {
|
|
panic(fmt.Errorf("unwrapping host's signed public credentials: %w", err))
|
|
}
|
|
|
|
var hostPublicCreds nebula.HostPublicCredentials
|
|
if err := yaml.Unmarshal(hostPublicCredsB, &hostPublicCreds); err != nil {
|
|
panic(fmt.Errorf("yaml unmarshaling host's public credentials: %w", err))
|
|
}
|
|
|
|
ip, err := nebula.IPFromHostCertPEM(hostPublicCreds.CertPEM)
|
|
if err != nil {
|
|
panic(fmt.Errorf("could not parse IP out of cert for host %q: %w", h.Name, err))
|
|
}
|
|
|
|
return ip
|
|
}
|