Implement 'vpn public-address' subcommands

This commit is contained in:
Brian Picciano 2024-12-16 12:19:48 +01:00
parent 1340f13f95
commit 03b19df115
4 changed files with 102 additions and 7 deletions

View File

@ -70,6 +70,7 @@ var subCmdVPN = subCmd{
return ctx.doSubCmd(
subCmdVPNCreateCert,
subCmdVPNFirewall,
subCmdVPNPublicAddress,
)
},
}

View File

@ -0,0 +1,93 @@
package main
import (
"errors"
"fmt"
"net"
)
var subCmdVPNPublicAddressGet = subCmd{
name: "get",
descr: "Display the currently configured public address",
do: doWithOutput(func(ctx subCmdCtx) (any, error) {
ctx, err := ctx.withParsedFlags(nil)
if err != nil {
return nil, fmt.Errorf("parsing flags: %w", err)
}
config, err := ctx.daemonRPC.GetConfig(ctx)
if err != nil {
return nil, fmt.Errorf("getting network config: %w", err)
}
if config.VPN.PublicAddr == "" {
return nil, errors.New("No public address configured")
}
return config.VPN.PublicAddr, nil
}),
}
var subCmdVPNPublicAddressSet = subCmd{
name: "set",
descr: "Set the public address of the host, or overwrite the already configured one",
do: func(ctx subCmdCtx) error {
publicAddr := ctx.flags.String(
"public-addr",
"",
"Public address (host:port) that this host is publicly available on",
)
ctx, err := ctx.withParsedFlags(nil)
if err != nil {
return fmt.Errorf("parsing flags: %w", err)
}
if *publicAddr == "" {
return errors.New("--public-addr is required")
} else if _, _, err := net.SplitHostPort(*publicAddr); err != nil {
return fmt.Errorf("invalid --public-addr: %w", err)
}
config, err := ctx.daemonRPC.GetConfig(ctx)
if err != nil {
return fmt.Errorf("getting network config: %w", err)
}
config.VPN.PublicAddr = *publicAddr
return ctx.daemonRPC.SetConfig(ctx, config)
},
}
var subCmdVPNPublicAddressUnset = subCmd{
name: "unset",
descr: "Unset the public address",
do: func(ctx subCmdCtx) error {
ctx, err := ctx.withParsedFlags(nil)
if err != nil {
return fmt.Errorf("parsing flags: %w", err)
}
config, err := ctx.daemonRPC.GetConfig(ctx)
if err != nil {
return fmt.Errorf("getting network config: %w", err)
}
config.VPN.PublicAddr = ""
return ctx.daemonRPC.SetConfig(ctx, config)
},
}
var subCmdVPNPublicAddress = subCmd{
name: "public-address",
descr: "Configure the public address of this host, allowing other hosts to use it in order to find and communicate directly with each other",
do: func(ctx subCmdCtx) error {
return ctx.doSubCmd(
subCmdVPNPublicAddressGet,
subCmdVPNPublicAddressSet,
subCmdVPNPublicAddressUnset,
)
},
}

View File

@ -0,0 +1,8 @@
---
type: task
---
# Add a Compare-and-Swap mechanism to SetConfig
This way we can avoid having issues if two different callers are doing a
GetConfig-then-SetConfig.

View File

@ -1,7 +0,0 @@
---
type: task
---
# Add `vpn public-addr set`, and `get` Sub-Commands.
`get` should return an error if no public address is set.