diff --git a/internal/cmd/network/create.go b/internal/cmd/network/create.go index 475d7280..e94c8906 100644 --- a/internal/cmd/network/create.go +++ b/internal/cmd/network/create.go @@ -26,6 +26,8 @@ func newCreateCommand(cli *state.State) *cobra.Command { cmd.Flags().IPNet("ip-range", net.IPNet{}, "Network IP range (required)") cmd.MarkFlagRequired("ip-range") + cmd.Flags().Bool("expose-routes-to-vswitch", false, "Expose routes from this network to the vSwitch connection. It only takes effect if a vSwitch connection is active.") + cmd.Flags().StringToString("label", nil, "User-defined labels ('key=value') (can be specified multiple times)") return cmd @@ -35,11 +37,13 @@ func runCreate(cli *state.State, cmd *cobra.Command, args []string) error { name, _ := cmd.Flags().GetString("name") ipRange, _ := cmd.Flags().GetIPNet("ip-range") labels, _ := cmd.Flags().GetStringToString("label") + exposeRoutesToVSwitch, _ := cmd.Flags().GetBool("expose-routes-to-vswitch") opts := hcloud.NetworkCreateOpts{ - Name: name, - IPRange: &ipRange, - Labels: labels, + Name: name, + IPRange: &ipRange, + Labels: labels, + ExposeRoutesToVSwitch: exposeRoutesToVSwitch, } network, _, err := cli.Client().Network.Create(cli.Context, opts) diff --git a/internal/cmd/network/describe.go b/internal/cmd/network/describe.go index 0f33c15d..7fcf804f 100644 --- a/internal/cmd/network/describe.go +++ b/internal/cmd/network/describe.go @@ -30,6 +30,7 @@ var DescribeCmd = base.DescribeCmd{ fmt.Printf("Name:\t\t%s\n", network.Name) fmt.Printf("Created:\t%s (%s)\n", util.Datetime(network.Created), humanize.Time(network.Created)) fmt.Printf("IP Range:\t%s\n", network.IPRange.String()) + fmt.Printf("Expose Routes to vSwitch: %s\n", util.YesNo(network.ExposeRoutesToVSwitch)) fmt.Printf("Subnets:\n") if len(network.Subnets) == 0 { diff --git a/internal/cmd/network/expose-routes-to-vswitch.go b/internal/cmd/network/expose-routes-to-vswitch.go new file mode 100644 index 00000000..beae9992 --- /dev/null +++ b/internal/cmd/network/expose-routes-to-vswitch.go @@ -0,0 +1,59 @@ +package network + +import ( + "context" + "fmt" + + "github.com/hetznercloud/cli/internal/cmd/base" + "github.com/hetznercloud/cli/internal/cmd/cmpl" + "github.com/hetznercloud/cli/internal/hcapi2" + "github.com/hetznercloud/cli/internal/state" + "github.com/hetznercloud/hcloud-go/hcloud" + "github.com/spf13/cobra" +) + +var ExposeRoutesToVSwitchCommand = base.Cmd{ + BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { + cmd := &cobra.Command{ + Use: "expose-routes-to-vswitch [flags] network", + Short: "Expose routes to connected vSwitch", + Long: "Enabling this will expose routes to the connected vSwitch. Set the --disable flag to remove the exposed routes.", + Args: cobra.ExactArgs(1), + ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Network().Names)), + TraverseChildren: true, + DisableFlagsInUseLine: true, + } + + cmd.Flags().Bool("disable", false, "Remove any exposed routes from the connected vSwitch") + + return cmd + }, + Run: func(ctx context.Context, client hcapi2.Client, waiter state.ActionWaiter, cmd *cobra.Command, args []string) error { + idOrName := args[0] + network, _, err := client.Network().Get(ctx, idOrName) + if err != nil { + return err + } + if network == nil { + return fmt.Errorf("network not found: %s", idOrName) + } + + disable, _ := cmd.Flags().GetBool("disable") + opts := hcloud.NetworkUpdateOpts{ + ExposeRoutesToVSwitch: hcloud.Ptr(!disable), + } + + _, _, err = client.Network().Update(ctx, network, opts) + if err != nil { + return err + } + + if disable { + fmt.Printf("Exposing routes to connected vSwitch of network %s disabled\n", network.Name) + } else { + fmt.Printf("Exposing routes to connected vSwitch of network %s enabled\n", network.Name) + } + + return nil + }, +} diff --git a/internal/cmd/network/list.go b/internal/cmd/network/list.go index 7435a82d..a9d6d529 100644 --- a/internal/cmd/network/list.go +++ b/internal/cmd/network/list.go @@ -76,12 +76,13 @@ var ListCmd = base.ListCmd{ network := resource.(*hcloud.Network) networkSchema := schema.Network{ - ID: network.ID, - Name: network.Name, - IPRange: network.IPRange.String(), - Protection: schema.NetworkProtection{Delete: network.Protection.Delete}, - Created: network.Created, - Labels: network.Labels, + ID: network.ID, + Name: network.Name, + IPRange: network.IPRange.String(), + Protection: schema.NetworkProtection{Delete: network.Protection.Delete}, + Created: network.Created, + Labels: network.Labels, + ExposeRoutesToVSwitch: network.ExposeRoutesToVSwitch, } for _, subnet := range network.Subnets { networkSchema.Subnets = append(networkSchema.Subnets, schema.NetworkSubnet{ diff --git a/internal/cmd/network/network.go b/internal/cmd/network/network.go index c0a65310..c8a8db0d 100644 --- a/internal/cmd/network/network.go +++ b/internal/cmd/network/network.go @@ -29,6 +29,7 @@ func NewCommand(cli *state.State, client hcapi2.Client) *cobra.Command { labelCmds.RemoveCobraCommand(cli.Context, client, cli), EnableProtectionCommand.CobraCommand(cli.Context, client, cli, cli), DisableProtectionCommand.CobraCommand(cli.Context, client, cli, cli), + ExposeRoutesToVSwitchCommand.CobraCommand(cli.Context, client, cli, cli), ) return cmd } diff --git a/internal/cmd/network/update.go b/internal/cmd/network/update.go index 04c50c7b..0bfa3207 100644 --- a/internal/cmd/network/update.go +++ b/internal/cmd/network/update.go @@ -12,7 +12,7 @@ import ( var updateCmd = base.UpdateCmd{ ResourceNameSingular: "Network", - ShortDescription: "Update a Network", + ShortDescription: "Update a Network.\n\nTo enable or disable exposing routes to the vSwitch connection you can use the subcommand \"hcloud network expose-routes-to-vswitch\".", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Network().Names }, Fetch: func(ctx context.Context, client hcapi2.Client, cmd *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) { return client.Network().Get(ctx, idOrName)