package daemon import ( "cmp" "context" "fmt" "isle/bootstrap" "isle/nebula" "slices" "golang.org/x/exp/maps" ) // GetHostsResult wraps the results from the GetHosts RPC method. type GetHostsResult struct { Hosts []bootstrap.Host } // CreateHostResult wraps the results from the CreateHost RPC method. type CreateHostResult struct { JoiningBootstrap JoiningBootstrap } // CreateNebulaCertificateResult wraps the results from the // CreateNebulaCertificate RPC method. type CreateNebulaCertificateResult struct { HostNebulaCertificate nebula.Certificate } // RPC exposes all RPC methods which are available to be called over the RPC // interface. type RPC interface { // CreateNetwork passes through to the Daemon method of the same name. // // name: Human-readable name of the network. // domain: Primary domain name that network services are served under. // ipNet: // An IP subnet, in CIDR form, which will be the overall range of // possible IPs in the network. The first IP in this network range will // become this first host's IP. // hostName: The name of this first host in the network. CreateNetwork( ctx context.Context, name string, domain string, ipNet nebula.IPNet, hostName nebula.HostName, ) error // JoinNetwork passes through to the Daemon method of the same name. JoinNetwork(ctx context.Context, req JoiningBootstrap) error // GetHosts returns all hosts known to the network, sorted by their name. GetHosts(ctx context.Context) (GetHostsResult, error) // GetGarageClientParams passes the call through to the Daemon method of the // same name. GetGarageClientParams(ctx context.Context) (GarageClientParams, error) // GetNebulaCAPublicCredentials returns the CAPublicCredentials for the // network. GetNebulaCAPublicCredentials( ctx context.Context, ) ( nebula.CAPublicCredentials, error, ) // RemoveHost passes the call through to the Daemon method of the same name. RemoveHost(ctx context.Context, hostName nebula.HostName) error // CreateHost passes the call through to the Daemon method of the same name. CreateHost( ctx context.Context, hostName nebula.HostName, opts CreateHostOpts, ) ( CreateHostResult, error, ) // CreateNebulaCertificate passes the call through to the Daemon method of // the same name. CreateNebulaCertificate( ctx context.Context, hostName nebula.HostName, hostEncryptingPublicKey nebula.EncryptingPublicKey, ) ( CreateNebulaCertificateResult, error, ) } type rpcImpl struct { daemon Daemon } // NewRPC initializes and returns an RPC instance. func NewRPC(daemon Daemon) RPC { return &rpcImpl{daemon} } func (r *rpcImpl) CreateNetwork( ctx context.Context, name string, domain string, ipNet nebula.IPNet, hostName nebula.HostName, ) error { return r.daemon.CreateNetwork( ctx, name, domain, ipNet, hostName, ) } func (r *rpcImpl) JoinNetwork( ctx context.Context, req JoiningBootstrap, ) error { return r.daemon.JoinNetwork(ctx, req) } func (r *rpcImpl) GetHosts(ctx context.Context) (GetHostsResult, error) { b, err := r.daemon.GetBootstrap(ctx) if err != nil { return GetHostsResult{}, fmt.Errorf("retrieving bootstrap: %w", err) } hosts := maps.Values(b.Hosts) slices.SortFunc(hosts, func(a, b bootstrap.Host) int { return cmp.Compare(a.Name, b.Name) }) return GetHostsResult{hosts}, nil } func (r *rpcImpl) GetGarageClientParams( ctx context.Context, ) ( GarageClientParams, error, ) { return r.daemon.GetGarageClientParams(ctx) } func (r *rpcImpl) GetNebulaCAPublicCredentials( ctx context.Context, ) ( nebula.CAPublicCredentials, error, ) { b, err := r.daemon.GetBootstrap(ctx) if err != nil { return nebula.CAPublicCredentials{}, fmt.Errorf( "retrieving bootstrap: %w", err, ) } return b.CAPublicCredentials, nil } func (r *rpcImpl) RemoveHost( ctx context.Context, hostName nebula.HostName, ) error { return r.daemon.RemoveHost(ctx, hostName) } func (r *rpcImpl) CreateHost( ctx context.Context, hostName nebula.HostName, opts CreateHostOpts, ) ( CreateHostResult, error, ) { joiningBootstrap, err := r.daemon.CreateHost(ctx, hostName, opts) if err != nil { return CreateHostResult{}, err } return CreateHostResult{JoiningBootstrap: joiningBootstrap}, nil } func (r *rpcImpl) CreateNebulaCertificate( ctx context.Context, hostName nebula.HostName, hostEncryptingPublicKey nebula.EncryptingPublicKey, ) ( CreateNebulaCertificateResult, error, ) { cert, err := r.daemon.CreateNebulaCertificate( ctx, hostName, hostEncryptingPublicKey, ) if err != nil { return CreateNebulaCertificateResult{}, err } return CreateNebulaCertificateResult{HostNebulaCertificate: cert}, nil }