diff --git a/go/cmd/entrypoint/nebula.go b/go/cmd/entrypoint/nebula.go index c43fb97..6a57eca 100644 --- a/go/cmd/entrypoint/nebula.go +++ b/go/cmd/entrypoint/nebula.go @@ -6,6 +6,7 @@ import ( "isle/daemon" "isle/jsonutil" "isle/nebula" + "net/netip" "os" ) @@ -16,6 +17,7 @@ var subCmdNebulaCreateCert = subCmd{ var ( flags = subCmdCtx.flagSet(false) hostName nebula.HostName + ip netip.Addr ) hostNameF := flags.VarPF( @@ -29,6 +31,12 @@ var subCmdNebulaCreateCert = subCmd{ `Path to PEM file containing public key which will be embedded in the cert.`, ) + flags.Var( + textUnmarshalerFlag{&ip}, + "ip", + "IP address to create a cert for. If this is not given then the IP associated with the host via its `hosts create` call will be used", + ) + if err := flags.Parse(subCmdCtx.args); err != nil { return fmt.Errorf("parsing flags: %w", err) } @@ -55,6 +63,9 @@ var subCmdNebulaCreateCert = subCmd{ daemon.CreateNebulaCertificateRequest{ HostName: hostName, HostEncryptingPublicKey: hostPub, + Opts: daemon.CreateNebulaCertificateOpts{ + IP: ip, + }, }, ) if err != nil { diff --git a/go/daemon/daemon.go b/go/daemon/daemon.go index dbd5cfd..376d75b 100644 --- a/go/daemon/daemon.go +++ b/go/daemon/daemon.go @@ -29,6 +29,18 @@ type CreateHostOpts struct { CanCreateHosts bool } +// CreateNebulaCertificateOpts are optional parameters to the +// CreateNebulaCertificate method. +type CreateNebulaCertificateOpts struct { + + // IP, if given will be used for the host's IP in the created cert. If this + // is given then it is not required that the host have an entry in garage. + // + // TODO once `hosts create` automatically adds the host to garage this can + // be removed. + IP netip.Addr +} + // Daemon presents all functionality required for client frontends to interact // with isle, typically via the unix socket. type Daemon interface { @@ -87,6 +99,7 @@ type Daemon interface { ctx context.Context, hostName nebula.HostName, hostPubKey nebula.EncryptingPublicKey, + opts CreateNebulaCertificateOpts, ) ( nebula.Certificate, error, ) @@ -735,6 +748,7 @@ func (d *daemon) CreateNebulaCertificate( ctx context.Context, hostName nebula.HostName, hostPubKey nebula.EncryptingPublicKey, + opts CreateNebulaCertificateOpts, ) ( nebula.Certificate, error, ) { @@ -743,9 +757,13 @@ func (d *daemon) CreateNebulaCertificate( ) ( nebula.Certificate, error, ) { - host, ok := currBootstrap.Hosts[hostName] - if !ok { - return nebula.Certificate{}, ErrHostNotFound + ip := opts.IP + if ip == (netip.Addr{}) { + host, ok := currBootstrap.Hosts[hostName] + if !ok { + return nebula.Certificate{}, ErrHostNotFound + } + ip = host.IP() } caSigningPrivateKey, err := getNebulaCASigningPrivateKey( @@ -757,7 +775,7 @@ func (d *daemon) CreateNebulaCertificate( caCreds := makeCACreds(currBootstrap, caSigningPrivateKey) - return nebula.NewHostCert(caCreds, hostPubKey, hostName, host.IP()) + return nebula.NewHostCert(caCreds, hostPubKey, hostName, ip) }) } diff --git a/go/daemon/rpc.go b/go/daemon/rpc.go index 5c24afa..d4edc54 100644 --- a/go/daemon/rpc.go +++ b/go/daemon/rpc.go @@ -163,6 +163,7 @@ func (r *RPC) CreateHost( type CreateNebulaCertificateRequest struct { HostName nebula.HostName HostEncryptingPublicKey nebula.EncryptingPublicKey + Opts CreateNebulaCertificateOpts } // CreateNebulaCertificateResult wraps the results from the @@ -179,7 +180,7 @@ func (r *RPC) CreateNebulaCertificate( CreateNebulaCertificateResult, error, ) { cert, err := r.daemon.CreateNebulaCertificate( - ctx, req.HostName, req.HostEncryptingPublicKey, + ctx, req.HostName, req.HostEncryptingPublicKey, req.Opts, ) if err != nil { return CreateNebulaCertificateResult{}, err