Implement 'vpn firewall list', and move 'nebula create-cert' to 'vpn create-cert'
This commit is contained in:
parent
a984ffc724
commit
b38d780bdf
@ -38,10 +38,10 @@ var rootCmd = subCmd{
|
|||||||
subCmdDaemon,
|
subCmdDaemon,
|
||||||
subCmdGarage,
|
subCmdGarage,
|
||||||
subCmdHost,
|
subCmdHost,
|
||||||
subCmdNebula,
|
|
||||||
subCmdNetwork,
|
subCmdNetwork,
|
||||||
subCmdStorage,
|
subCmdStorage,
|
||||||
subCmdVersion,
|
subCmdVersion,
|
||||||
|
subCmdVPN,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ var subCmdStorageAllocationRemove = subCmd{
|
|||||||
|
|
||||||
var subCmdStorage = subCmd{
|
var subCmdStorage = subCmd{
|
||||||
name: "storage",
|
name: "storage",
|
||||||
descr: "Sub-commands having to do with configuration of storage on this host",
|
descr: "Sub-commands related to configuration of storage on this host",
|
||||||
do: func(ctx subCmdCtx) error {
|
do: func(ctx subCmdCtx) error {
|
||||||
return ctx.doSubCmd(
|
return ctx.doSubCmd(
|
||||||
subCmdStorageAllocationAdd,
|
subCmdStorageAllocationAdd,
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var subCmdNebulaCreateCert = subCmd{
|
var subCmdVPNCreateCert = subCmd{
|
||||||
name: "create-cert",
|
name: "create-cert",
|
||||||
descr: "Creates a signed nebula certificate file for an existing host and writes it to stdout",
|
descr: "Creates a signed nebula certificate file for an existing host and writes it to stdout",
|
||||||
do: func(ctx subCmdCtx) error {
|
do: func(ctx subCmdCtx) error {
|
||||||
@ -63,12 +63,13 @@ var subCmdNebulaCreateCert = subCmd{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var subCmdNebula = subCmd{
|
var subCmdVPN = subCmd{
|
||||||
name: "nebula",
|
name: "vpn",
|
||||||
descr: "Sub-commands related to the nebula VPN",
|
descr: "Sub-commands related to this host's VPN, which connects it to other hosts in the network",
|
||||||
do: func(ctx subCmdCtx) error {
|
do: func(ctx subCmdCtx) error {
|
||||||
return ctx.doSubCmd(
|
return ctx.doSubCmd(
|
||||||
subCmdNebulaCreateCert,
|
subCmdVPNCreateCert,
|
||||||
|
subCmdVPNFirewall,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
64
go/cmd/entrypoint/vpn_firewall.go
Normal file
64
go/cmd/entrypoint/vpn_firewall.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"isle/daemon/daecommon"
|
||||||
|
)
|
||||||
|
|
||||||
|
type firewallRuleView struct {
|
||||||
|
Index int `yaml:"index"`
|
||||||
|
daecommon.ConfigFirewallRule `yaml:",inline"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFirewallRuleViews(
|
||||||
|
rules []daecommon.ConfigFirewallRule,
|
||||||
|
) []firewallRuleView {
|
||||||
|
views := make([]firewallRuleView, len(rules))
|
||||||
|
for i := range rules {
|
||||||
|
views[i] = firewallRuleView{
|
||||||
|
Index: i,
|
||||||
|
ConfigFirewallRule: rules[i],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return views
|
||||||
|
}
|
||||||
|
|
||||||
|
type firewallView struct {
|
||||||
|
Outbound []firewallRuleView `yaml:"outbound"`
|
||||||
|
Inbound []firewallRuleView `yaml:"inbound"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFirewallView(firewallConfig daecommon.ConfigFirewall) firewallView {
|
||||||
|
return firewallView{
|
||||||
|
Outbound: newFirewallRuleViews(firewallConfig.Outbound),
|
||||||
|
Inbound: newFirewallRuleViews(firewallConfig.Inbound),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var subCmdVPNFirewallList = subCmd{
|
||||||
|
name: "list",
|
||||||
|
descr: "List all currently configured firewall rules",
|
||||||
|
do: doWithOutput(func(ctx subCmdCtx) (any, error) {
|
||||||
|
ctx, err := ctx.withParsedFlags()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parsing flags: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
config, err := ctx.getDaemonRPC().GetConfig(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("getting network config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return newFirewallView(config.VPN.Firewall), nil
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
var subCmdVPNFirewall = subCmd{
|
||||||
|
name: "firewall",
|
||||||
|
descr: "Sub-commands related to this host's VPN firewall",
|
||||||
|
do: func(ctx subCmdCtx) error {
|
||||||
|
return ctx.doSubCmd(
|
||||||
|
subCmdVPNFirewallList,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
108
go/cmd/entrypoint/vpn_firewall_test.go
Normal file
108
go/cmd/entrypoint/vpn_firewall_test.go
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"isle/daemon/daecommon"
|
||||||
|
"isle/toolkit"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestVPNFirewallList(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
outbound, inbound []string
|
||||||
|
want map[string][]any
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
want: map[string][]any{
|
||||||
|
"outbound": {},
|
||||||
|
"inbound": {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single",
|
||||||
|
outbound: []string{
|
||||||
|
`{"port":"any","proto":"icmp","host":"any"}`,
|
||||||
|
},
|
||||||
|
want: map[string][]any{
|
||||||
|
"outbound": {
|
||||||
|
map[string]any{
|
||||||
|
"index": 0,
|
||||||
|
"port": "any",
|
||||||
|
"proto": "icmp",
|
||||||
|
"host": "any",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"inbound": {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple",
|
||||||
|
outbound: []string{
|
||||||
|
`{"port":"any","proto":"icmp","host":"any"}`,
|
||||||
|
},
|
||||||
|
inbound: []string{
|
||||||
|
`{"port":"any","proto":"icmp","host":"any"}`,
|
||||||
|
`{"port":"22","proto":"tcp","host":"foo"}`,
|
||||||
|
},
|
||||||
|
want: map[string][]any{
|
||||||
|
"outbound": {
|
||||||
|
map[string]any{
|
||||||
|
"index": 0,
|
||||||
|
"port": "any",
|
||||||
|
"proto": "icmp",
|
||||||
|
"host": "any",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"inbound": {
|
||||||
|
map[string]any{
|
||||||
|
"index": 0,
|
||||||
|
"port": "any",
|
||||||
|
"proto": "icmp",
|
||||||
|
"host": "any",
|
||||||
|
},
|
||||||
|
map[string]any{
|
||||||
|
"index": 1,
|
||||||
|
"port": "22",
|
||||||
|
"proto": "tcp",
|
||||||
|
"host": "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
var (
|
||||||
|
h = newRunHarness(t)
|
||||||
|
config daecommon.NetworkConfig
|
||||||
|
|
||||||
|
outboundRawJSON = "[" + strings.Join(test.outbound, ",") + "]"
|
||||||
|
inboundRawJSON = "[" + strings.Join(test.inbound, ",") + "]"
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(t, json.Unmarshal(
|
||||||
|
[]byte(outboundRawJSON), &config.VPN.Firewall.Outbound,
|
||||||
|
))
|
||||||
|
|
||||||
|
require.NoError(t, json.Unmarshal(
|
||||||
|
[]byte(inboundRawJSON), &config.VPN.Firewall.Inbound,
|
||||||
|
))
|
||||||
|
|
||||||
|
h.daemonRPC.
|
||||||
|
On("GetConfig", toolkit.MockArg[context.Context]()).
|
||||||
|
Return(config, nil).
|
||||||
|
Once()
|
||||||
|
|
||||||
|
h.runAssertStdout(t, test.want, "vpn", "firewall", "list")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user