2022-10-15 14:28:03 +00:00
|
|
|
package bootstrap
|
2021-04-20 21:31:37 +00:00
|
|
|
|
|
|
|
import (
|
2022-11-05 14:23:29 +00:00
|
|
|
"bytes"
|
2024-06-10 16:56:36 +00:00
|
|
|
"encoding/json"
|
2021-04-20 21:31:37 +00:00
|
|
|
"fmt"
|
2024-06-10 16:56:36 +00:00
|
|
|
"isle/nebula"
|
2022-10-29 19:11:40 +00:00
|
|
|
"net"
|
2022-11-05 14:23:29 +00:00
|
|
|
"strings"
|
2022-10-15 16:41:07 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// NebulaHost describes the nebula configuration of a Host which is relevant for
|
|
|
|
// other hosts to know.
|
2021-04-20 21:31:37 +00:00
|
|
|
type NebulaHost struct {
|
2024-06-10 16:56:36 +00:00
|
|
|
SignedPublicCredentials string
|
|
|
|
PublicAddr string
|
2022-11-05 14:23:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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,
|
|
|
|
) {
|
|
|
|
|
2024-06-10 16:56:36 +00:00
|
|
|
hostPublicCredsB, err := json.Marshal(hostPublicCreds)
|
2022-11-05 14:23:29 +00:00
|
|
|
if err != nil {
|
2024-06-10 16:56:36 +00:00
|
|
|
return "", fmt.Errorf("marshaling host's public credentials: %w", err)
|
2022-11-05 14:23:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2021-04-20 21:31:37 +00:00
|
|
|
}
|
|
|
|
|
2022-10-15 16:41:07 +00:00
|
|
|
// GarageHost describes a single garage instance in the GarageHost.
|
2021-04-20 21:31:37 +00:00
|
|
|
type GarageHostInstance struct {
|
2024-06-10 16:56:36 +00:00
|
|
|
ID string
|
|
|
|
RPCPort int
|
|
|
|
S3APIPort int
|
2021-04-20 21:31:37 +00:00
|
|
|
}
|
|
|
|
|
2022-10-15 16:41:07 +00:00
|
|
|
// GarageHost describes the garage configuration of a Host which is relevant for
|
|
|
|
// other hosts to know.
|
2021-04-20 21:31:37 +00:00
|
|
|
type GarageHost struct {
|
2024-06-10 16:56:36 +00:00
|
|
|
Instances []GarageHostInstance
|
2021-04-20 21:31:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Host consolidates all information about a single host from the bootstrap
|
|
|
|
// file.
|
|
|
|
type Host struct {
|
2024-06-10 16:56:36 +00:00
|
|
|
Name string
|
|
|
|
Nebula NebulaHost
|
|
|
|
Garage GarageHost
|
2021-04-20 21:31:37 +00:00
|
|
|
}
|
|
|
|
|
2022-10-29 19:11:40 +00:00
|
|
|
// IP returns the IP address encoded in the Host's nebula certificate, or panics
|
|
|
|
// if there is an error.
|
2022-11-05 14:23:29 +00:00
|
|
|
//
|
|
|
|
// This assumes that the Host and its data has already been verified against the
|
|
|
|
// CA signing key.
|
2022-10-29 19:11:40 +00:00
|
|
|
func (h Host) IP() net.IP {
|
|
|
|
|
2022-11-05 14:23:29 +00:00
|
|
|
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
|
2024-06-10 16:56:36 +00:00
|
|
|
if err := json.Unmarshal(hostPublicCredsB, &hostPublicCreds); err != nil {
|
|
|
|
panic(fmt.Errorf("unmarshaling host's public credentials: %w", err))
|
2022-11-05 14:23:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ip, err := nebula.IPFromHostCertPEM(hostPublicCreds.CertPEM)
|
2022-10-29 19:11:40 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(fmt.Errorf("could not parse IP out of cert for host %q: %w", h.Name, err))
|
|
|
|
}
|
|
|
|
|
|
|
|
return ip
|
|
|
|
}
|