135 lines
3.1 KiB
Go
135 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"isle/daemon/network"
|
|
"isle/jsonutil"
|
|
)
|
|
|
|
var subCmdNetworkCreate = subCmd{
|
|
name: "create",
|
|
descr: "Create's a new network, with this host being the first host in that network.",
|
|
noNetwork: true,
|
|
do: func(ctx subCmdCtx) error {
|
|
var (
|
|
ipNet ipNetFlag
|
|
hostName hostNameFlag
|
|
)
|
|
|
|
name := ctx.flags.StringP(
|
|
"name", "N", "",
|
|
"Human-readable name to identify the network as.",
|
|
)
|
|
|
|
domain := ctx.flags.StringP(
|
|
"domain", "d", "",
|
|
"Domain name that should be used as the root domain in the network.",
|
|
)
|
|
|
|
ipNetF := ctx.flags.VarPF(
|
|
&ipNet, "ip-net", "i",
|
|
`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.`,
|
|
)
|
|
|
|
hostNameF := ctx.flags.VarPF(
|
|
&hostName,
|
|
"hostname", "n",
|
|
"Name of this host, which will be the first host in the network",
|
|
)
|
|
|
|
ctx, err := ctx.withParsedFlags()
|
|
if err != nil {
|
|
return fmt.Errorf("parsing flags: %w", err)
|
|
}
|
|
|
|
if *name == "" ||
|
|
*domain == "" ||
|
|
!ipNetF.Changed ||
|
|
!hostNameF.Changed {
|
|
return errors.New("--name, --domain, --ip-net, and --hostname are required")
|
|
}
|
|
|
|
err = newDaemonRPCClient().CreateNetwork(
|
|
ctx, *name, *domain, ipNet.V, hostName.V,
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("creating network: %w", err)
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var subCmdNetworkJoin = subCmd{
|
|
name: "join",
|
|
descr: "Joins this host to an existing network",
|
|
noNetwork: true,
|
|
do: func(ctx subCmdCtx) error {
|
|
bootstrapPath := ctx.flags.StringP(
|
|
"bootstrap-path", "b", "", "Path to a bootstrap.json file.",
|
|
)
|
|
|
|
ctx, err := ctx.withParsedFlags()
|
|
if err != nil {
|
|
return fmt.Errorf("parsing flags: %w", err)
|
|
}
|
|
|
|
if *bootstrapPath == "" {
|
|
return errors.New("--bootstrap-path is required")
|
|
}
|
|
|
|
var newBootstrap network.JoiningBootstrap
|
|
if err := jsonutil.LoadFile(&newBootstrap, *bootstrapPath); err != nil {
|
|
return fmt.Errorf(
|
|
"loading bootstrap from %q: %w", *bootstrapPath, err,
|
|
)
|
|
}
|
|
|
|
return newDaemonRPCClient().JoinNetwork(ctx, newBootstrap)
|
|
},
|
|
}
|
|
|
|
var subCmdNetworkList = subCmd{
|
|
name: "list",
|
|
descr: "Lists all networks which have been joined",
|
|
noNetwork: true,
|
|
do: doWithOutput(func(ctx subCmdCtx) (any, error) {
|
|
ctx, err := ctx.withParsedFlags()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("parsing flags: %w", err)
|
|
}
|
|
|
|
return newDaemonRPCClient().GetNetworks(ctx)
|
|
}),
|
|
}
|
|
|
|
var subCmdNetworkGetConfig = subCmd{
|
|
name: "get-config",
|
|
descr: "Displays the currently active configuration for a joined network",
|
|
do: doWithOutput(func(ctx subCmdCtx) (any, error) {
|
|
ctx, err := ctx.withParsedFlags()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("parsing flags: %w", err)
|
|
}
|
|
|
|
return newDaemonRPCClient().GetConfig(ctx)
|
|
}),
|
|
}
|
|
|
|
var subCmdNetwork = subCmd{
|
|
name: "network",
|
|
descr: "Sub-commands related to network membership",
|
|
plural: "s",
|
|
do: func(ctx subCmdCtx) error {
|
|
return ctx.doSubCmd(
|
|
subCmdNetworkCreate,
|
|
subCmdNetworkJoin,
|
|
subCmdNetworkList,
|
|
subCmdNetworkGetConfig,
|
|
)
|
|
},
|
|
}
|