Move create-nebula-cert into nebula create-cert, move most logic into daemon
This commit is contained in:
parent
cc121f0752
commit
cb8fef38c4
@ -173,6 +173,7 @@ in rec {
|
|||||||
pkgs.yq-go
|
pkgs.yq-go
|
||||||
pkgs.jq
|
pkgs.jq
|
||||||
pkgs.dig
|
pkgs.dig
|
||||||
|
pkgs.nebula
|
||||||
]}
|
]}
|
||||||
export SHELL=${pkgs.bash}/bin/bash
|
export SHELL=${pkgs.bash}/bin/bash
|
||||||
exec ${pkgs.bash}/bin/bash ${./tests}/entrypoint.sh "$@"
|
exec ${pkgs.bash}/bin/bash ${./tests}/entrypoint.sh "$@"
|
||||||
|
@ -3,7 +3,7 @@ package bootstrap
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"isle/nebula"
|
"isle/nebula"
|
||||||
"net"
|
"net/netip"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NebulaHost describes the nebula configuration of a Host which is relevant for
|
// NebulaHost describes the nebula configuration of a Host which is relevant for
|
||||||
@ -77,10 +77,17 @@ type Host struct {
|
|||||||
//
|
//
|
||||||
// This assumes that the Host and its data has already been verified against the
|
// This assumes that the Host and its data has already been verified against the
|
||||||
// CA signing key.
|
// CA signing key.
|
||||||
func (h Host) IP() net.IP {
|
func (h Host) IP() netip.Addr {
|
||||||
cert := h.PublicCredentials.Cert.Unwrap()
|
cert := h.PublicCredentials.Cert.Unwrap()
|
||||||
if len(cert.Details.Ips) == 0 {
|
if len(cert.Details.Ips) == 0 {
|
||||||
panic(fmt.Sprintf("host %q not configured with any ips: %+v", h.Name, h))
|
panic(fmt.Sprintf("host %q not configured with any ips: %+v", h.Name, h))
|
||||||
}
|
}
|
||||||
return cert.Details.Ips[0].IP
|
|
||||||
|
ip := cert.Details.Ips[0].IP
|
||||||
|
addr, ok := netip.AddrFromSlice(ip)
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Sprintf("ip %q (%#v) is not valid, somehow", ip, ip))
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr
|
||||||
}
|
}
|
||||||
|
@ -111,89 +111,12 @@ var subCmdAdminCreateBootstrap = subCmd{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var subCmdAdminCreateNebulaCert = subCmd{
|
|
||||||
name: "create-nebula-cert",
|
|
||||||
descr: "Creates a signed nebula certificate file and writes it to stdout",
|
|
||||||
do: func(subCmdCtx subCmdCtx) error {
|
|
||||||
var (
|
|
||||||
flags = subCmdCtx.flagSet(false)
|
|
||||||
hostName nebula.HostName
|
|
||||||
ip netip.Addr
|
|
||||||
)
|
|
||||||
|
|
||||||
hostNameF := flags.VarPF(
|
|
||||||
textUnmarshalerFlag{&hostName},
|
|
||||||
"hostname", "h",
|
|
||||||
"Name of the host to generate a certificate for",
|
|
||||||
)
|
|
||||||
|
|
||||||
ipF := flags.VarPF(
|
|
||||||
textUnmarshalerFlag{&ip}, "ip", "i", "IP of the new host",
|
|
||||||
)
|
|
||||||
|
|
||||||
adminPath := flags.StringP(
|
|
||||||
"admin-path", "a", "",
|
|
||||||
`Path to admin.json file. If the given path is "-" then stdin is used.`,
|
|
||||||
)
|
|
||||||
|
|
||||||
pubKeyPath := flags.StringP(
|
|
||||||
"public-key-path", "p", "",
|
|
||||||
`Path to PEM file containing public key which will be embedded in the cert.`,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err := flags.Parse(subCmdCtx.args); err != nil {
|
|
||||||
return fmt.Errorf("parsing flags: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !hostNameF.Changed ||
|
|
||||||
!ipF.Changed ||
|
|
||||||
*adminPath == "" ||
|
|
||||||
*pubKeyPath == "" {
|
|
||||||
return errors.New("--hostname, --ip, --admin-path, and --pub-key-path are required")
|
|
||||||
}
|
|
||||||
|
|
||||||
adm, err := readAdmin(*adminPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("reading admin.json with --admin-path of %q: %w", *adminPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
hostPubPEM, err := os.ReadFile(*pubKeyPath)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("reading public key from %q: %w", *pubKeyPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var hostPub nebula.EncryptingPublicKey
|
|
||||||
if err := hostPub.UnmarshalNebulaPEM(hostPubPEM); err != nil {
|
|
||||||
return fmt.Errorf("unmarshaling public key as PEM: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
nebulaHostCert, err := nebula.NewHostCert(
|
|
||||||
adm.Nebula.CACredentials, hostPub, hostName, ip,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("creating cert: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
nebulaHostCertPEM, err := nebulaHostCert.Unwrap().MarshalToPEM()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("marshaling cert to PEM: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := os.Stdout.Write([]byte(nebulaHostCertPEM)); err != nil {
|
|
||||||
return fmt.Errorf("writing to stdout: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var subCmdAdmin = subCmd{
|
var subCmdAdmin = subCmd{
|
||||||
name: "admin",
|
name: "admin",
|
||||||
descr: "Sub-commands which only admins can run",
|
descr: "Sub-commands which only admins can run",
|
||||||
do: func(subCmdCtx subCmdCtx) error {
|
do: func(subCmdCtx subCmdCtx) error {
|
||||||
return subCmdCtx.doSubCmd(
|
return subCmdCtx.doSubCmd(
|
||||||
subCmdAdminCreateBootstrap,
|
subCmdAdminCreateBootstrap,
|
||||||
subCmdAdminCreateNebulaCert,
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,92 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"isle/daemon"
|
||||||
"isle/jsonutil"
|
"isle/jsonutil"
|
||||||
"isle/nebula"
|
"isle/nebula"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var subCmdNebulaCreateCert = subCmd{
|
||||||
|
name: "create-cert",
|
||||||
|
descr: "Creates a signed nebula certificate file for an existing host and writes it to stdout",
|
||||||
|
do: func(subCmdCtx subCmdCtx) error {
|
||||||
|
var (
|
||||||
|
flags = subCmdCtx.flagSet(false)
|
||||||
|
hostName nebula.HostName
|
||||||
|
)
|
||||||
|
|
||||||
|
hostNameF := flags.VarPF(
|
||||||
|
textUnmarshalerFlag{&hostName},
|
||||||
|
"hostname", "h",
|
||||||
|
"Name of the host to generate a certificate for",
|
||||||
|
)
|
||||||
|
|
||||||
|
adminPath := flags.StringP(
|
||||||
|
"admin-path", "a", "",
|
||||||
|
`Path to admin.json file. If the given path is "-" then stdin is used.`,
|
||||||
|
)
|
||||||
|
|
||||||
|
pubKeyPath := flags.StringP(
|
||||||
|
"public-key-path", "p", "",
|
||||||
|
`Path to PEM file containing public key which will be embedded in the cert.`,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err := flags.Parse(subCmdCtx.args); err != nil {
|
||||||
|
return fmt.Errorf("parsing flags: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hostNameF.Changed ||
|
||||||
|
*adminPath == "" ||
|
||||||
|
*pubKeyPath == "" {
|
||||||
|
return errors.New("--hostname, --admin-path, and --pub-key-path are required")
|
||||||
|
}
|
||||||
|
|
||||||
|
adm, err := readAdmin(*adminPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("reading admin.json with --admin-path of %q: %w", *adminPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hostPubPEM, err := os.ReadFile(*pubKeyPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("reading public key from %q: %w", *pubKeyPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hostPub nebula.EncryptingPublicKey
|
||||||
|
if err := hostPub.UnmarshalNebulaPEM(hostPubPEM); err != nil {
|
||||||
|
return fmt.Errorf("unmarshaling public key as PEM: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var res daemon.CreateNebulaCertificateResult
|
||||||
|
err = subCmdCtx.daemonRCPClient.Call(
|
||||||
|
subCmdCtx.ctx,
|
||||||
|
&res,
|
||||||
|
"CreateNebulaCertificate",
|
||||||
|
daemon.CreateNebulaCertificateRequest{
|
||||||
|
CASigningPrivateKey: adm.Nebula.CACredentials.SigningPrivateKey,
|
||||||
|
HostName: hostName,
|
||||||
|
HostEncryptingPublicKey: hostPub,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("calling CreateNebulaCertificate: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nebulaHostCertPEM, err := res.HostNebulaCertifcate.Unwrap().MarshalToPEM()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("marshaling cert to PEM: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stdout.Write([]byte(nebulaHostCertPEM)); err != nil {
|
||||||
|
return fmt.Errorf("writing to stdout: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
var subCmdNebulaShow = subCmd{
|
var subCmdNebulaShow = subCmd{
|
||||||
name: "show",
|
name: "show",
|
||||||
descr: "Writes nebula network information to stdout in JSON format",
|
descr: "Writes nebula network information to stdout in JSON format",
|
||||||
@ -30,20 +110,17 @@ var subCmdNebulaShow = subCmd{
|
|||||||
return fmt.Errorf("calling GetNebulaCAPublicCredentials: %w", err)
|
return fmt.Errorf("calling GetNebulaCAPublicCredentials: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
caCert := caPublicCreds.Cert.Unwrap()
|
caCert := caPublicCreds.Cert
|
||||||
caCertPEM, err := caCert.MarshalToPEM()
|
caCertDetails := caCert.Unwrap().Details
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("marshaling CA cert to PEM: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(caCert.Details.Subnets) != 1 {
|
if len(caCertDetails.Subnets) != 1 {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"malformed ca.crt, contains unexpected subnets %#v",
|
"malformed ca.crt, contains unexpected subnets %#v",
|
||||||
caCert.Details.Subnets,
|
caCertDetails.Subnets,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
subnet := caCert.Details.Subnets[0]
|
subnet := caCertDetails.Subnets[0]
|
||||||
|
|
||||||
type outLighthouse struct {
|
type outLighthouse struct {
|
||||||
PublicAddr string
|
PublicAddr string
|
||||||
@ -51,11 +128,11 @@ var subCmdNebulaShow = subCmd{
|
|||||||
}
|
}
|
||||||
|
|
||||||
out := struct {
|
out := struct {
|
||||||
CACert string
|
CACert nebula.Certificate
|
||||||
SubnetCIDR string
|
SubnetCIDR string
|
||||||
Lighthouses []outLighthouse
|
Lighthouses []outLighthouse
|
||||||
}{
|
}{
|
||||||
CACert: string(caCertPEM),
|
CACert: caCert,
|
||||||
SubnetCIDR: subnet.String(),
|
SubnetCIDR: subnet.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +160,7 @@ var subCmdNebula = subCmd{
|
|||||||
descr: "Sub-commands related to the nebula VPN",
|
descr: "Sub-commands related to the nebula VPN",
|
||||||
do: func(subCmdCtx subCmdCtx) error {
|
do: func(subCmdCtx subCmdCtx) error {
|
||||||
return subCmdCtx.doSubCmd(
|
return subCmdCtx.doSubCmd(
|
||||||
|
subCmdNebulaCreateCert,
|
||||||
subCmdNebulaShow,
|
subCmdNebulaShow,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -22,7 +22,7 @@ func waitForNebula(
|
|||||||
ctx context.Context, logger *mlog.Logger, hostBootstrap bootstrap.Bootstrap,
|
ctx context.Context, logger *mlog.Logger, hostBootstrap bootstrap.Bootstrap,
|
||||||
) error {
|
) error {
|
||||||
var (
|
var (
|
||||||
ip = hostBootstrap.ThisHost().IP()
|
ip = net.IP(hostBootstrap.ThisHost().IP().AsSlice())
|
||||||
lUDPAddr = &net.UDPAddr{IP: ip, Port: 0}
|
lUDPAddr = &net.UDPAddr{IP: ip, Port: 0}
|
||||||
rUDPAddr = &net.UDPAddr{IP: ip, Port: 45535}
|
rUDPAddr = &net.UDPAddr{IP: ip, Port: 45535}
|
||||||
)
|
)
|
||||||
|
@ -55,6 +55,21 @@ type Daemon interface {
|
|||||||
// RemoveHost removes the host of the given name from the network.
|
// RemoveHost removes the host of the given name from the network.
|
||||||
RemoveHost(context.Context, nebula.HostName) error
|
RemoveHost(context.Context, nebula.HostName) error
|
||||||
|
|
||||||
|
// CreateNebulaCertificate creates and signs a new nebula certficate for an
|
||||||
|
// existing host, given the public key for that host. This is currently
|
||||||
|
// mostly useful for creating certs for mobile devices.
|
||||||
|
//
|
||||||
|
// Errors:
|
||||||
|
// - ErrHostNotFound
|
||||||
|
CreateNebulaCertificate(
|
||||||
|
ctx context.Context,
|
||||||
|
caSigningPrivateKey nebula.SigningPrivateKey, // TODO load from secrets storage
|
||||||
|
hostName nebula.HostName,
|
||||||
|
hostPubKey nebula.EncryptingPublicKey,
|
||||||
|
) (
|
||||||
|
nebula.Certificate, error,
|
||||||
|
)
|
||||||
|
|
||||||
// Shutdown blocks until all resources held or created by the daemon,
|
// Shutdown blocks until all resources held or created by the daemon,
|
||||||
// including child processes it has started, have been cleaned up.
|
// including child processes it has started, have been cleaned up.
|
||||||
//
|
//
|
||||||
@ -592,6 +607,40 @@ func (d *daemon) RemoveHost(ctx context.Context, hostName nebula.HostName) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeCACreds(
|
||||||
|
currBootstrap bootstrap.Bootstrap,
|
||||||
|
caSigningPrivateKey nebula.SigningPrivateKey,
|
||||||
|
) nebula.CACredentials {
|
||||||
|
return nebula.CACredentials{
|
||||||
|
Public: currBootstrap.CAPublicCredentials,
|
||||||
|
SigningPrivateKey: caSigningPrivateKey,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *daemon) CreateNebulaCertificate(
|
||||||
|
ctx context.Context,
|
||||||
|
caSigningPrivateKey nebula.SigningPrivateKey,
|
||||||
|
hostName nebula.HostName,
|
||||||
|
hostPubKey nebula.EncryptingPublicKey,
|
||||||
|
) (
|
||||||
|
nebula.Certificate, error,
|
||||||
|
) {
|
||||||
|
return withCurrBootstrap(d, func(
|
||||||
|
currBootstrap bootstrap.Bootstrap,
|
||||||
|
) (
|
||||||
|
nebula.Certificate, error,
|
||||||
|
) {
|
||||||
|
host, ok := currBootstrap.Hosts[hostName]
|
||||||
|
if !ok {
|
||||||
|
return nebula.Certificate{}, ErrHostNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
caCreds := makeCACreds(currBootstrap, caSigningPrivateKey)
|
||||||
|
|
||||||
|
return nebula.NewHostCert(caCreds, hostPubKey, hostName, host.IP())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (d *daemon) Shutdown() error {
|
func (d *daemon) Shutdown() error {
|
||||||
d.l.Lock()
|
d.l.Lock()
|
||||||
defer d.l.Unlock()
|
defer d.l.Unlock()
|
||||||
|
@ -24,4 +24,8 @@ var (
|
|||||||
//
|
//
|
||||||
// The Data field will be a string containing further details.
|
// The Data field will be a string containing further details.
|
||||||
ErrInvalidConfig = jsonrpc2.NewError(5, "Invalid daemon config")
|
ErrInvalidConfig = jsonrpc2.NewError(5, "Invalid daemon config")
|
||||||
|
|
||||||
|
// ErrHostNotFound is returned when performing an operation which expected a
|
||||||
|
// host to exist in the network, but that host wasn't found.
|
||||||
|
ErrHostNotFound = jsonrpc2.NewError(6, "Host not found")
|
||||||
)
|
)
|
||||||
|
@ -119,7 +119,7 @@ func (r *RPC) GetNebulaCAPublicCredentials(
|
|||||||
return b.CAPublicCredentials, nil
|
return b.CAPublicCredentials, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveHostRequest contains the arguments to the RemoveHost method.
|
// RemoveHostRequest contains the arguments to the RemoveHost RPC method.
|
||||||
//
|
//
|
||||||
// All fields are required.
|
// All fields are required.
|
||||||
type RemoveHostRequest struct {
|
type RemoveHostRequest struct {
|
||||||
@ -130,3 +130,38 @@ type RemoveHostRequest struct {
|
|||||||
func (r *RPC) RemoveHost(ctx context.Context, req RemoveHostRequest) (struct{}, error) {
|
func (r *RPC) RemoveHost(ctx context.Context, req RemoveHostRequest) (struct{}, error) {
|
||||||
return struct{}{}, r.daemon.RemoveHost(ctx, req.HostName)
|
return struct{}{}, r.daemon.RemoveHost(ctx, req.HostName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateNebulaCertificateRequest contains the arguments to the
|
||||||
|
// CreateNebulaCertificate RPC method.
|
||||||
|
//
|
||||||
|
// All fields are required.
|
||||||
|
type CreateNebulaCertificateRequest struct {
|
||||||
|
CASigningPrivateKey nebula.SigningPrivateKey // TODO load from secrets storage
|
||||||
|
HostName nebula.HostName
|
||||||
|
HostEncryptingPublicKey nebula.EncryptingPublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateNebulaCertificateResult wraps the results from the
|
||||||
|
// CreateNebulaCertificate RPC method.
|
||||||
|
type CreateNebulaCertificateResult struct {
|
||||||
|
HostNebulaCertifcate nebula.Certificate
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateNebulaCertificate passes the call through to the Daemon method of the
|
||||||
|
// same name.
|
||||||
|
func (r *RPC) CreateNebulaCertificate(
|
||||||
|
ctx context.Context, req CreateNebulaCertificateRequest,
|
||||||
|
) (
|
||||||
|
CreateNebulaCertificateResult, error,
|
||||||
|
) {
|
||||||
|
cert, err := r.daemon.CreateNebulaCertificate(
|
||||||
|
ctx, req.CASigningPrivateKey, req.HostName, req.HostEncryptingPublicKey,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return CreateNebulaCertificateResult{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return CreateNebulaCertificateResult{
|
||||||
|
HostNebulaCertifcate: cert,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
@ -46,7 +46,7 @@ func (pk *EncryptingPublicKey) UnmarshalText(b []byte) error {
|
|||||||
// UnmarshalNebulaPEM unmarshals the EncryptingPublicKey as a nebula host public
|
// UnmarshalNebulaPEM unmarshals the EncryptingPublicKey as a nebula host public
|
||||||
// key PEM.
|
// key PEM.
|
||||||
func (pk *EncryptingPublicKey) UnmarshalNebulaPEM(b []byte) error {
|
func (pk *EncryptingPublicKey) UnmarshalNebulaPEM(b []byte) error {
|
||||||
b, _, err := cert.UnmarshalEd25519PublicKey(b)
|
b, _, err := cert.UnmarshalX25519PublicKey(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unmarshaling: %w", err)
|
return fmt.Errorf("unmarshaling: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,6 @@ source "$UTILS"/with-1-data-1-empty-node-network.sh
|
|||||||
[ "$(jq -r <admin.json '.CreationParams.Name')" = "testing" ]
|
[ "$(jq -r <admin.json '.CreationParams.Name')" = "testing" ]
|
||||||
[ "$(jq -r <admin.json '.CreationParams.Domain')" = "shared.test" ]
|
[ "$(jq -r <admin.json '.CreationParams.Domain')" = "shared.test" ]
|
||||||
|
|
||||||
bootstrap_file="$XDG_STATE_HOME/isle/bootstrap.json"
|
[ "$(jq -rc <"$BOOTSTRAP_FILE" '.AdminCreationParams')" = "$(jq -rc <admin.json '.CreationParams')" ]
|
||||||
|
[ "$(jq -rc <"$BOOTSTRAP_FILE" '.CAPublicCredentials')" = "$(jq -rc <admin.json '.Nebula.CACredentials.Public')" ]
|
||||||
[ "$(jq -rc <"$bootstrap_file" '.AdminCreationParams')" = "$(jq -rc <admin.json '.CreationParams')" ]
|
[ "$(jq -r <"$BOOTSTRAP_FILE" '.SignedHostAssigned.Body.Name')" = "primus" ]
|
||||||
[ "$(jq -rc <"$bootstrap_file" '.CAPublicCredentials')" = "$(jq -rc <admin.json '.Nebula.CACredentials.Public')" ]
|
|
||||||
[ "$(jq -r <"$bootstrap_file" '.SignedHostAssigned.Body.Name')" = "primus" ]
|
|
||||||
|
12
tests/cases/nebula/00-show.sh
Normal file
12
tests/cases/nebula/00-show.sh
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# shellcheck source=../../utils/with-1-data-1-empty-node-network.sh
|
||||||
|
source "$UTILS"/with-1-data-1-empty-node-network.sh
|
||||||
|
|
||||||
|
info="$(isle nebula show)"
|
||||||
|
|
||||||
|
[ "$(echo "$info" | jq -r '.CACert')" \
|
||||||
|
= "$(jq -r <"$BOOTSTRAP_FILE" '.CAPublicCredentials.Cert')" ]
|
||||||
|
|
||||||
|
[ "$(echo "$info" | jq -r '.SubnetCIDR')" = "10.6.9.0/24" ]
|
||||||
|
[ "$(echo "$info" | jq -r '.Lighthouses|length')" = "1" ]
|
||||||
|
[ "$(echo "$info" | jq -r '.Lighthouses[0].PublicAddr')" = "127.0.0.1:60000" ]
|
||||||
|
[ "$(echo "$info" | jq -r '.Lighthouses[0].IP')" = "10.6.9.1" ]
|
19
tests/cases/nebula/01-create-cert.sh
Normal file
19
tests/cases/nebula/01-create-cert.sh
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# shellcheck source=../../utils/with-1-data-1-empty-node-network.sh
|
||||||
|
source "$UTILS"/with-1-data-1-empty-node-network.sh
|
||||||
|
|
||||||
|
nebula-cert keygen -out-key /dev/null -out-pub pubkey
|
||||||
|
cat pubkey
|
||||||
|
|
||||||
|
(
|
||||||
|
isle nebula create-cert \
|
||||||
|
--admin-path admin.json \
|
||||||
|
--hostname non-esiste \
|
||||||
|
--public-key-path pubkey \
|
||||||
|
2>&1 || true \
|
||||||
|
) | grep '\[6\] Host not found'
|
||||||
|
|
||||||
|
isle nebula create-cert \
|
||||||
|
--admin-path admin.json \
|
||||||
|
--hostname primus \
|
||||||
|
--public-key-path pubkey \
|
||||||
|
| grep -- '-----BEGIN NEBULA CERTIFICATE-----'
|
@ -13,5 +13,6 @@ export TMPDIR="$TMPDIR"
|
|||||||
export XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR"
|
export XDG_RUNTIME_DIR="$XDG_RUNTIME_DIR"
|
||||||
export XDG_STATE_HOME="$XDG_STATE_HOME"
|
export XDG_STATE_HOME="$XDG_STATE_HOME"
|
||||||
export ISLE_DAEMON_HTTP_SOCKET_PATH="$ROOT_TMPDIR/$base-daemon.sock"
|
export ISLE_DAEMON_HTTP_SOCKET_PATH="$ROOT_TMPDIR/$base-daemon.sock"
|
||||||
|
BOOTSTRAP_FILE="$XDG_STATE_HOME/isle/bootstrap.json"
|
||||||
cd "$TMPDIR"
|
cd "$TMPDIR"
|
||||||
EOF
|
EOF
|
||||||
|
Loading…
Reference in New Issue
Block a user