2024-07-07 10:44:49 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
2024-07-09 09:43:17 +00:00
|
|
|
"isle/admin"
|
2024-07-07 10:44:49 +00:00
|
|
|
"isle/bootstrap"
|
2024-07-09 09:43:17 +00:00
|
|
|
"isle/daemon"
|
|
|
|
"os"
|
2024-07-07 10:44:49 +00:00
|
|
|
)
|
|
|
|
|
2024-07-09 09:43:17 +00:00
|
|
|
var subCmdNetworkCreate = subCmd{
|
|
|
|
name: "create",
|
|
|
|
descr: "Create's a new network, with this host being the first host in that network. The resulting admin.json is output to stdout.",
|
|
|
|
do: func(subCmdCtx subCmdCtx) error {
|
|
|
|
var (
|
|
|
|
ctx = subCmdCtx.ctx
|
|
|
|
flags = subCmdCtx.flagSet(false)
|
|
|
|
req daemon.CreateNetworkRequest
|
|
|
|
)
|
|
|
|
|
|
|
|
flags.StringVarP(
|
|
|
|
&req.Name, "name", "n", "",
|
|
|
|
"Human-readable name to identify the network as.",
|
|
|
|
)
|
|
|
|
|
|
|
|
flags.StringVarP(
|
|
|
|
&req.Domain, "domain", "d", "",
|
|
|
|
"Domain name that should be used as the root domain in the network.",
|
|
|
|
)
|
|
|
|
|
|
|
|
flags.StringVarP(
|
|
|
|
&req.IPNet, "ip-net", "i", "",
|
|
|
|
`IP+prefix (e.g. "10.10.0.1/16") which denotes the IP of this`+
|
|
|
|
` host, which will be the first host in the network, and the`+
|
|
|
|
` range of IPs which other hosts in the network can be`+
|
|
|
|
` assigned`,
|
|
|
|
)
|
|
|
|
|
|
|
|
flags.StringVarP(
|
|
|
|
&req.HostName, "hostname", "h", "",
|
|
|
|
"Name of this host, which will be the first host in the network",
|
|
|
|
)
|
|
|
|
|
|
|
|
if err := flags.Parse(subCmdCtx.args); err != nil {
|
|
|
|
return fmt.Errorf("parsing flags: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if req.Name == "" ||
|
|
|
|
req.Domain == "" ||
|
|
|
|
req.IPNet == "" ||
|
|
|
|
req.HostName == "" {
|
|
|
|
return errors.New("--name, --domain, --ip-net, and --hostname are required")
|
|
|
|
}
|
|
|
|
|
|
|
|
var adm admin.Admin
|
|
|
|
err := subCmdCtx.daemonRCPClient.Call(ctx, &adm, "CreateNetwork", req)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("creating network: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := adm.WriteTo(os.Stdout); err != nil {
|
|
|
|
return fmt.Errorf("writing admin.json to stdout")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-07-07 10:44:49 +00:00
|
|
|
var subCmdNetworkJoin = subCmd{
|
|
|
|
name: "join",
|
|
|
|
descr: "Joins this host to an existing network",
|
|
|
|
do: func(subCmdCtx subCmdCtx) error {
|
|
|
|
var (
|
|
|
|
ctx = subCmdCtx.ctx
|
|
|
|
flags = subCmdCtx.flagSet(false)
|
|
|
|
)
|
|
|
|
|
|
|
|
bootstrapPath := flags.StringP(
|
|
|
|
"bootstrap-path", "b", "", "Path to a bootstrap.json file.",
|
|
|
|
)
|
|
|
|
|
|
|
|
if err := flags.Parse(subCmdCtx.args); err != nil {
|
|
|
|
return fmt.Errorf("parsing flags: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if *bootstrapPath == "" {
|
|
|
|
return errors.New("--bootstrap-path is required")
|
|
|
|
}
|
|
|
|
|
|
|
|
newBootstrap, err := bootstrap.FromFile(*bootstrapPath)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf(
|
|
|
|
"loading bootstrap from %q: %w", *bootstrapPath, err,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
return subCmdCtx.daemonRCPClient.Call(
|
|
|
|
ctx, nil, "JoinNetwork", newBootstrap,
|
|
|
|
)
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var subCmdNetwork = subCmd{
|
|
|
|
name: "network",
|
|
|
|
descr: "Sub-commands related to network membership",
|
|
|
|
do: func(subCmdCtx subCmdCtx) error {
|
|
|
|
return subCmdCtx.doSubCmd(
|
2024-07-09 09:43:17 +00:00
|
|
|
subCmdNetworkCreate,
|
2024-07-07 10:44:49 +00:00
|
|
|
subCmdNetworkJoin,
|
|
|
|
)
|
|
|
|
},
|
|
|
|
}
|