From eef6fa6cdb7ae6a3781a2bf61c3a4634ca1fdcd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Go=CC=88kc=CC=A7e=20Go=CC=88k=20Klingel?= Date: Thu, 28 Nov 2024 10:43:03 +0100 Subject: [PATCH 01/13] extend network commands with new fields --- docs/stackit_beta_network_create.md | 25 +++++-- docs/stackit_beta_network_update.md | 23 ++++-- internal/cmd/beta/network/create/create.go | 71 ++++++++++++++++--- .../cmd/beta/network/create/create_test.go | 64 ++++++++++++++++- .../cmd/beta/network/describe/describe.go | 16 +++++ internal/cmd/beta/network/list/list.go | 9 ++- internal/cmd/beta/network/update/update.go | 58 +++++++++++++-- .../cmd/beta/network/update/update_test.go | 57 ++++++++++++++- 8 files changed, 287 insertions(+), 36 deletions(-) diff --git a/docs/stackit_beta_network_create.md b/docs/stackit_beta_network_create.md index e9ac60921..6940eb759 100644 --- a/docs/stackit_beta_network_create.md +++ b/docs/stackit_beta_network_create.md @@ -16,22 +16,35 @@ stackit beta network create [flags] Create a network with name "network-1" $ stackit beta network create --name network-1 - Create an IPv4 network with name "network-1" with DNS name servers and a prefix length - $ stackit beta network create --name network-1 --ipv4-dns-name-servers "1.1.1.1,8.8.8.8,9.9.9.9" --ipv4-prefix-length 25 + Create a routed network with name "network-1" + $ stackit beta network create --name network-1 --routed - Create an IPv6 network with name "network-1" with DNS name servers and a prefix length - $ stackit beta network create --name network-1 --ipv6-dns-name-servers "2001:4860:4860::8888,2001:4860:4860::8844" --ipv6-prefix-length 56 + Create a network with name "network-1" and no gateway + $ stackit beta network create --name network-1 --no-ipv4-gateway + + Create an IPv4 network with name "network-1" with DNS name servers, a prefix, a gateway and a prefix length + $ stackit beta network create --name network-1 --ipv4-dns-name-servers "1.1.1.1,8.8.8.8,9.9.9.9" --ipv4-prefix-length 25 --ipv4-prefix "10.1.2.0/24" --ipv4-gateway "10.1.2.3" + + Create an IPv6 network with name "network-1" with DNS name servers, a prefix, a gateway and a prefix length + $ stackit beta network create --name network-1 --ipv6-dns-name-servers "2001:4860:4860::8888,2001:4860:4860::8844" --ipv6-prefix-length 56 --ipv6-prefix "2001:4860:4860::8888" --ipv6-gateway "2001:4860:4860::8888" ``` ### Options ``` -h, --help Help for "stackit beta network create" - --ipv4-dns-name-servers strings List of DNS name servers for IPv4 + --ipv4-dns-name-servers strings List of DNS name servers for IPv4. Nameservers cannot be defined for routed networks. + --ipv4-gateway string The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway. + --ipv4-prefix string The IPv4 prefix of the network (CIDR) --ipv4-prefix-length int The prefix length of the IPv4 network - --ipv6-dns-name-servers strings List of DNS name servers for IPv6 + --ipv6-dns-name-servers strings List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks. + --ipv6-gateway string The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway. + --ipv6-prefix string The IPv6 prefix of the network (CIDR) --ipv6-prefix-length int The prefix length of the IPv6 network -n, --name string Network name + --no-ipv4-gateway If set to true, the network doesn't have an IPv4 gateway. + --no-ipv6-gateway If set to true, the network doesn't have an IPv6 gateway. + --routed If set to true, the network is routed and therefore accessible from other networks ``` ### Options inherited from parent commands diff --git a/docs/stackit_beta_network_update.md b/docs/stackit_beta_network_update.md index b14bc9a8d..e320d7918 100644 --- a/docs/stackit_beta_network_update.md +++ b/docs/stackit_beta_network_update.md @@ -16,20 +16,31 @@ stackit beta network update [flags] Update network with ID "xxx" with new name "network-1-new" $ stackit beta network update xxx --name network-1-new - Update IPv4 network with ID "xxx" with new name "network-1-new" and new DNS name servers - $ stackit beta network update xxx --name network-1-new --ipv4-dns-name-servers "2.2.2.2" + Update network with ID "xxx" with routed true + $ stackit beta network update xxx --routed - Update IPv6 network with ID "xxx" with new name "network-1-new" and new DNS name servers - $ stackit beta network update xxx --name network-1-new --ipv6-dns-name-servers "2001:4860:4860::8888" + Update network with ID "xxx" with no gateway + $ stackit beta network update --no-ipv4-gateway + + Update IPv4 network with ID "xxx" with new name "network-1-new", new gateway and new DNS name servers + $ stackit beta network update xxx --name network-1-new --ipv4-dns-name-servers "2.2.2.2" --ipv4-gateway "10.1.2.3" + + Update IPv6 network with ID "xxx" with new name "network-1-new", new gateway and new DNS name servers + $ stackit beta network update xxx --name network-1-new --ipv6-dns-name-servers "2001:4860:4860::8888" --ipv6-gateway "2001:4860:4860::8888" ``` ### Options ``` -h, --help Help for "stackit beta network update" - --ipv4-dns-name-servers strings List of DNS name servers IPv4 - --ipv6-dns-name-servers strings List of DNS name servers for IPv6 + --ipv4-dns-name-servers strings List of DNS name servers IPv4. Nameservers cannot be defined for routed networks. + --ipv4-gateway string The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway. + --ipv6-dns-name-servers strings List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks. + --ipv6-gateway string The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway. -n, --name string Network name + --no-ipv4-gateway If set to true, the network doesn't have an IPv4 gateway. + --no-ipv6-gateway If set to true, the network doesn't have an IPv6 gateway. + --routed If set to true, the network is routed and therefore accessible from other networks ``` ### Options inherited from parent commands diff --git a/internal/cmd/beta/network/create/create.go b/internal/cmd/beta/network/create/create.go index c057098ec..4b8dd6af9 100644 --- a/internal/cmd/beta/network/create/create.go +++ b/internal/cmd/beta/network/create/create.go @@ -25,8 +25,15 @@ const ( nameFlag = "name" ipv4DnsNameServersFlag = "ipv4-dns-name-servers" ipv4PrefixLengthFlag = "ipv4-prefix-length" + ipv4PrefixFlag = "ipv4-prefix" + ipv4GatewayFlag = "ipv4-gateway" ipv6DnsNameServersFlag = "ipv6-dns-name-servers" ipv6PrefixLengthFlag = "ipv6-prefix-length" + ipv6PrefixFlag = "ipv6-prefix" + ipv6GatewayFlag = "ipv6-gateway" + routedFlag = "routed" + noIpv4Gateway = "no-ipv4-gateway" + noIpv6Gateway = "no-ipv6-gateway" ) type inputModel struct { @@ -34,8 +41,15 @@ type inputModel struct { Name *string IPv4DnsNameServers *[]string IPv4PrefixLength *int64 + IPv4Prefix *string + IPv4Gateway *string IPv6DnsNameServers *[]string IPv6PrefixLength *int64 + IPv6Prefix *string + IPv6Gateway *string + Routed *bool + NoIPv4Gateway bool + NoIPv6Gateway bool } func NewCmd(p *print.Printer) *cobra.Command { @@ -50,12 +64,20 @@ func NewCmd(p *print.Printer) *cobra.Command { `$ stackit beta network create --name network-1`, ), examples.NewExample( - `Create an IPv4 network with name "network-1" with DNS name servers and a prefix length`, - `$ stackit beta network create --name network-1 --ipv4-dns-name-servers "1.1.1.1,8.8.8.8,9.9.9.9" --ipv4-prefix-length 25`, + `Create a routed network with name "network-1"`, + `$ stackit beta network create --name network-1 --routed`, ), examples.NewExample( - `Create an IPv6 network with name "network-1" with DNS name servers and a prefix length`, - `$ stackit beta network create --name network-1 --ipv6-dns-name-servers "2001:4860:4860::8888,2001:4860:4860::8844" --ipv6-prefix-length 56`, + `Create a network with name "network-1" and no gateway`, + `$ stackit beta network create --name network-1 --no-ipv4-gateway`, + ), + examples.NewExample( + `Create an IPv4 network with name "network-1" with DNS name servers, a prefix, a gateway and a prefix length`, + `$ stackit beta network create --name network-1 --ipv4-dns-name-servers "1.1.1.1,8.8.8.8,9.9.9.9" --ipv4-prefix-length 25 --ipv4-prefix "10.1.2.0/24" --ipv4-gateway "10.1.2.3"`, + ), + examples.NewExample( + `Create an IPv6 network with name "network-1" with DNS name servers, a prefix, a gateway and a prefix length`, + `$ stackit beta network create --name network-1 --ipv6-dns-name-servers "2001:4860:4860::8888,2001:4860:4860::8844" --ipv6-prefix-length 56 --ipv6-prefix "2001:4860:4860::8888" --ipv6-gateway "2001:4860:4860::8888"`, ), ), RunE: func(cmd *cobra.Command, _ []string) error { @@ -113,11 +135,20 @@ func NewCmd(p *print.Printer) *cobra.Command { func configureFlags(cmd *cobra.Command) { cmd.Flags().StringP(nameFlag, "n", "", "Network name") - cmd.Flags().StringSlice(ipv4DnsNameServersFlag, []string{}, "List of DNS name servers for IPv4") + cmd.Flags().StringSlice(ipv4DnsNameServersFlag, []string{}, "List of DNS name servers for IPv4. Nameservers cannot be defined for routed networks.") cmd.Flags().Int64(ipv4PrefixLengthFlag, 0, "The prefix length of the IPv4 network") - cmd.Flags().StringSlice(ipv6DnsNameServersFlag, []string{}, "List of DNS name servers for IPv6") + cmd.Flags().String(ipv4PrefixFlag, "", "The IPv4 prefix of the network (CIDR)") + cmd.Flags().String(ipv4GatewayFlag, "", "The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway.") + cmd.Flags().StringSlice(ipv6DnsNameServersFlag, []string{}, "List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks.") cmd.Flags().Int64(ipv6PrefixLengthFlag, 0, "The prefix length of the IPv6 network") + cmd.Flags().String(ipv6PrefixFlag, "", "The IPv6 prefix of the network (CIDR)") + cmd.Flags().String(ipv6GatewayFlag, "", "The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway.") + cmd.Flags().Bool(routedFlag, false, "If set to true, the network is routed and therefore accessible from other networks") + cmd.Flags().Bool(noIpv4Gateway, false, "If set to true, the network doesn't have an IPv4 gateway.") + cmd.Flags().Bool(noIpv6Gateway, false, "If set to true, the network doesn't have an IPv6 gateway.") + cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv4DnsNameServersFlag) + cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv6DnsNameServersFlag) err := flags.MarkFlagsRequired(cmd, nameFlag) cobra.CheckErr(err) } @@ -133,8 +164,15 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { Name: flags.FlagToStringPointer(p, cmd, nameFlag), IPv4DnsNameServers: flags.FlagToStringSlicePointer(p, cmd, ipv4DnsNameServersFlag), IPv4PrefixLength: flags.FlagToInt64Pointer(p, cmd, ipv4PrefixLengthFlag), + IPv4Prefix: flags.FlagToStringPointer(p, cmd, ipv4PrefixFlag), + IPv4Gateway: flags.FlagToStringPointer(p, cmd, ipv4GatewayFlag), IPv6DnsNameServers: flags.FlagToStringSlicePointer(p, cmd, ipv6DnsNameServersFlag), IPv6PrefixLength: flags.FlagToInt64Pointer(p, cmd, ipv6PrefixLengthFlag), + IPv6Prefix: flags.FlagToStringPointer(p, cmd, ipv6PrefixFlag), + IPv6Gateway: flags.FlagToStringPointer(p, cmd, ipv6GatewayFlag), + Routed: flags.FlagToBoolPointer(p, cmd, routedFlag), + NoIPv4Gateway: flags.FlagToBoolValue(p, cmd, noIpv4Gateway), + NoIPv6Gateway: flags.FlagToBoolValue(p, cmd, noIpv6Gateway), } if p.IsVerbosityDebug() { @@ -153,22 +191,37 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli req := apiClient.CreateNetwork(ctx, model.ProjectId) addressFamily := &iaas.CreateNetworkAddressFamily{} - if model.IPv6DnsNameServers != nil || model.IPv6PrefixLength != nil { + if model.IPv6DnsNameServers != nil || model.IPv6PrefixLength != nil || model.IPv6Prefix != nil { addressFamily.Ipv6 = &iaas.CreateNetworkIPv6Body{ Nameservers: model.IPv6DnsNameServers, PrefixLength: model.IPv6PrefixLength, + Prefix: model.IPv6Prefix, } } - if model.IPv4DnsNameServers != nil || model.IPv4PrefixLength != nil { + if model.NoIPv6Gateway { + addressFamily.Ipv6.Gateway = iaas.NewNullableString(nil) + } else if model.IPv6Gateway != nil { + addressFamily.Ipv6.Gateway = iaas.NewNullableString(model.IPv6Gateway) + } + + if model.IPv4DnsNameServers != nil || model.IPv4PrefixLength != nil || model.IPv4Prefix != nil { addressFamily.Ipv4 = &iaas.CreateNetworkIPv4Body{ Nameservers: model.IPv4DnsNameServers, PrefixLength: model.IPv4PrefixLength, + Prefix: model.IPv4Prefix, } } + if model.NoIPv4Gateway { + addressFamily.Ipv4.Gateway = iaas.NewNullableString(nil) + } else if model.IPv4Gateway != nil { + addressFamily.Ipv4.Gateway = iaas.NewNullableString(model.IPv4Gateway) + } + payload := iaas.CreateNetworkPayload{ - Name: model.Name, + Name: model.Name, + Routed: model.Routed, } if addressFamily.Ipv4 != nil || addressFamily.Ipv6 != nil { diff --git a/internal/cmd/beta/network/create/create_test.go b/internal/cmd/beta/network/create/create_test.go index d1284558d..f74e9fbda 100644 --- a/internal/cmd/beta/network/create/create_test.go +++ b/internal/cmd/beta/network/create/create_test.go @@ -29,8 +29,13 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st nameFlag: "example-network-name", ipv4DnsNameServersFlag: "1.1.1.0,1.1.2.0", ipv4PrefixLengthFlag: "24", + ipv4PrefixFlag: "10.1.2.0/24", + ipv4GatewayFlag: "10.1.2.3", ipv6DnsNameServersFlag: "2001:4860:4860::8888,2001:4860:4860::8844", ipv6PrefixLengthFlag: "24", + ipv6PrefixFlag: "2001:4860:4860::8888", + ipv6GatewayFlag: "2001:4860:4860::8888", + routedFlag: "true", } for _, mod := range mods { mod(flagValues) @@ -47,8 +52,13 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Name: utils.Ptr("example-network-name"), IPv4DnsNameServers: utils.Ptr([]string{"1.1.1.0", "1.1.2.0"}), IPv4PrefixLength: utils.Ptr(int64(24)), + IPv4Prefix: utils.Ptr("10.1.2.0/24"), + IPv4Gateway: utils.Ptr("10.1.2.3"), IPv6DnsNameServers: utils.Ptr([]string{"2001:4860:4860::8888", "2001:4860:4860::8844"}), IPv6PrefixLength: utils.Ptr(int64(24)), + IPv6Prefix: utils.Ptr("2001:4860:4860::8888"), + IPv6Gateway: utils.Ptr("2001:4860:4860::8888"), + Routed: utils.Ptr(true), } for _, mod := range mods { mod(model) @@ -78,15 +88,20 @@ func fixtureRequiredRequest(mods ...func(request *iaas.ApiCreateNetworkRequest)) func fixturePayload(mods ...func(payload *iaas.CreateNetworkPayload)) iaas.CreateNetworkPayload { payload := iaas.CreateNetworkPayload{ - Name: utils.Ptr("example-network-name"), + Name: utils.Ptr("example-network-name"), + Routed: utils.Ptr(true), AddressFamily: &iaas.CreateNetworkAddressFamily{ Ipv4: &iaas.CreateNetworkIPv4Body{ Nameservers: utils.Ptr([]string{"1.1.1.0", "1.1.2.0"}), PrefixLength: utils.Ptr(int64(24)), + Prefix: utils.Ptr("10.1.2.0/24"), + Gateway: iaas.NewNullableString(utils.Ptr("10.1.2.3")), }, Ipv6: &iaas.CreateNetworkIPv6Body{ Nameservers: utils.Ptr([]string{"2001:4860:4860::8888", "2001:4860:4860::8844"}), PrefixLength: utils.Ptr(int64(24)), + Prefix: utils.Ptr("2001:4860:4860::8888"), + Gateway: iaas.NewNullableString(utils.Ptr("2001:4860:4860::8888")), }, }, } @@ -155,27 +170,69 @@ func TestParseInput(t *testing.T) { isValid: false, }, { - description: "use dns servers and prefix", + description: "use dns servers, prefix, gateway and prefix length", flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[ipv4DnsNameServersFlag] = "1.1.1.1" flagValues[ipv4PrefixLengthFlag] = "25" + flagValues[ipv4PrefixFlag] = "10.1.2.0/24" + flagValues[ipv4GatewayFlag] = "10.1.2.3" }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { model.IPv4DnsNameServers = utils.Ptr([]string{"1.1.1.1"}) model.IPv4PrefixLength = utils.Ptr(int64(25)) + model.IPv4Prefix = utils.Ptr("10.1.2.0/24") + model.IPv4Gateway = utils.Ptr("10.1.2.3") }), }, { - description: "use ipv6 dns servers and prefix", + description: "use ipv4 gateway nil", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[noIpv4Gateway] = "true" + delete(flagValues, ipv4GatewayFlag) + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.NoIPv4Gateway = true + model.IPv4Gateway = nil + }), + }, + { + description: "use ipv6 dns servers, prefix, gateway and prefix length", flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[ipv6DnsNameServersFlag] = "2001:4860:4860::8888" flagValues[ipv6PrefixLengthFlag] = "25" + flagValues[ipv6PrefixFlag] = "2001:4860:4860::8888" + flagValues[ipv6GatewayFlag] = "2001:4860:4860::8888" }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { model.IPv6DnsNameServers = utils.Ptr([]string{"2001:4860:4860::8888"}) model.IPv6PrefixLength = utils.Ptr(int64(25)) + model.IPv6Prefix = utils.Ptr("2001:4860:4860::8888") + model.IPv6Gateway = utils.Ptr("2001:4860:4860::8888") + }), + }, + { + description: "use ipv6 gateway nil", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[noIpv6Gateway] = "true" + delete(flagValues, ipv6GatewayFlag) + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.NoIPv6Gateway = true + model.IPv6Gateway = nil + }), + }, + { + description: "use routed true", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[routedFlag] = "true" + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.Routed = utils.Ptr(true) }), }, } @@ -257,6 +314,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), cmpopts.EquateComparable(testCtx), + cmp.AllowUnexported(iaas.NullableString{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) diff --git a/internal/cmd/beta/network/describe/describe.go b/internal/cmd/beta/network/describe/describe.go index bbd2a3fa4..cb5ba80a6 100644 --- a/internal/cmd/beta/network/describe/describe.go +++ b/internal/cmd/beta/network/describe/describe.go @@ -152,6 +152,16 @@ func outputResult(p *print.Printer, outputFormat string, network *iaas.Network) table.AddSeparator() } + if network.Routed != nil { + table.AddRow("ROUTED", *network.Routed) + table.AddSeparator() + } + + if network.Gateway != nil { + table.AddRow("IPv4 GATEWAY", *network.Gateway.Get()) + table.AddSeparator() + } + if len(ipv4nameservers) > 0 { table.AddRow("IPv4 NAME SERVERS", strings.Join(ipv4nameservers, ", ")) } @@ -160,6 +170,12 @@ func outputResult(p *print.Printer, outputFormat string, network *iaas.Network) table.AddRow("IPv4 PREFIXES", strings.Join(ipv4prefixes, ", ")) } table.AddSeparator() + + if network.Gatewayv6 != nil { + table.AddRow("IPv6 GATEWAY", *network.Gatewayv6.Get()) + table.AddSeparator() + } + if len(ipv6nameservers) > 0 { table.AddRow("IPv6 NAME SERVERS", strings.Join(ipv6nameservers, ", ")) } diff --git a/internal/cmd/beta/network/list/list.go b/internal/cmd/beta/network/list/list.go index af91a4a1c..889f9e307 100644 --- a/internal/cmd/beta/network/list/list.go +++ b/internal/cmd/beta/network/list/list.go @@ -151,7 +151,7 @@ func outputResult(p *print.Printer, outputFormat string, networks []iaas.Network return nil default: table := tables.NewTable() - table.SetHeader("ID", "Name", "Status", "Public IP") + table.SetHeader("ID", "NAME", "STATUS", "PUBLIC IP", "ROUTED") for _, network := range networks { publicIp := "" @@ -159,7 +159,12 @@ func outputResult(p *print.Printer, outputFormat string, networks []iaas.Network publicIp = *network.PublicIp } - table.AddRow(*network.NetworkId, *network.Name, *network.State, publicIp) + routed := false + if network.Routed != nil { + routed = *network.Routed + } + + table.AddRow(*network.NetworkId, *network.Name, *network.State, publicIp, routed) table.AddSeparator() } diff --git a/internal/cmd/beta/network/update/update.go b/internal/cmd/beta/network/update/update.go index 748828778..9ba5b0c27 100644 --- a/internal/cmd/beta/network/update/update.go +++ b/internal/cmd/beta/network/update/update.go @@ -24,16 +24,26 @@ const ( networkIdArg = "NETWORK_ID" nameFlag = "name" + routedFlag = "routed" ipv4DnsNameServersFlag = "ipv4-dns-name-servers" + ipv4GatewayFlag = "ipv4-gateway" ipv6DnsNameServersFlag = "ipv6-dns-name-servers" + ipv6GatewayFlag = "ipv6-gateway" + noIpv4Gateway = "no-ipv4-gateway" + noIpv6Gateway = "no-ipv6-gateway" ) type inputModel struct { *globalflags.GlobalFlagModel NetworkId string Name *string + Routed *bool IPv4DnsNameServers *[]string + IPv4Gateway *string IPv6DnsNameServers *[]string + IPv6Gateway *string + NoIPv4Gateway bool + NoIPv6Gateway bool } func NewCmd(p *print.Printer) *cobra.Command { @@ -48,12 +58,20 @@ func NewCmd(p *print.Printer) *cobra.Command { `$ stackit beta network update xxx --name network-1-new`, ), examples.NewExample( - `Update IPv4 network with ID "xxx" with new name "network-1-new" and new DNS name servers`, - `$ stackit beta network update xxx --name network-1-new --ipv4-dns-name-servers "2.2.2.2"`, + `Update network with ID "xxx" with routed true`, + `$ stackit beta network update xxx --routed`, ), examples.NewExample( - `Update IPv6 network with ID "xxx" with new name "network-1-new" and new DNS name servers`, - `$ stackit beta network update xxx --name network-1-new --ipv6-dns-name-servers "2001:4860:4860::8888"`, + `Update network with ID "xxx" with no gateway`, + `$ stackit beta network update --no-ipv4-gateway`, + ), + examples.NewExample( + `Update IPv4 network with ID "xxx" with new name "network-1-new", new gateway and new DNS name servers`, + `$ stackit beta network update xxx --name network-1-new --ipv4-dns-name-servers "2.2.2.2" --ipv4-gateway "10.1.2.3"`, + ), + examples.NewExample( + `Update IPv6 network with ID "xxx" with new name "network-1-new", new gateway and new DNS name servers`, + `$ stackit beta network update xxx --name network-1-new --ipv6-dns-name-servers "2001:4860:4860::8888" --ipv6-gateway "2001:4860:4860::8888"`, ), ), RunE: func(cmd *cobra.Command, args []string) error { @@ -116,8 +134,16 @@ func NewCmd(p *print.Printer) *cobra.Command { func configureFlags(cmd *cobra.Command) { cmd.Flags().StringP(nameFlag, "n", "", "Network name") - cmd.Flags().StringSlice(ipv4DnsNameServersFlag, nil, "List of DNS name servers IPv4") - cmd.Flags().StringSlice(ipv6DnsNameServersFlag, nil, "List of DNS name servers for IPv6") + cmd.Flags().Bool(routedFlag, false, "If set to true, the network is routed and therefore accessible from other networks") + cmd.Flags().StringSlice(ipv4DnsNameServersFlag, nil, "List of DNS name servers IPv4. Nameservers cannot be defined for routed networks.") + cmd.Flags().String(ipv4GatewayFlag, "", "The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway.") + cmd.Flags().StringSlice(ipv6DnsNameServersFlag, nil, "List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks.") + cmd.Flags().String(ipv6GatewayFlag, "", "The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway.") + cmd.Flags().Bool(noIpv4Gateway, false, "If set to true, the network doesn't have an IPv4 gateway.") + cmd.Flags().Bool(noIpv6Gateway, false, "If set to true, the network doesn't have an IPv6 gateway.") + + cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv4DnsNameServersFlag) + cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv6DnsNameServersFlag) } func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { @@ -132,8 +158,13 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu GlobalFlagModel: globalFlags, Name: flags.FlagToStringPointer(p, cmd, nameFlag), NetworkId: networkId, + Routed: flags.FlagToBoolPointer(p, cmd, routedFlag), IPv4DnsNameServers: flags.FlagToStringSlicePointer(p, cmd, ipv4DnsNameServersFlag), + IPv4Gateway: flags.FlagToStringPointer(p, cmd, ipv4GatewayFlag), IPv6DnsNameServers: flags.FlagToStringSlicePointer(p, cmd, ipv6DnsNameServersFlag), + IPv6Gateway: flags.FlagToStringPointer(p, cmd, ipv6GatewayFlag), + NoIPv4Gateway: flags.FlagToBoolValue(p, cmd, noIpv4Gateway), + NoIPv6Gateway: flags.FlagToBoolValue(p, cmd, noIpv6Gateway), } if p.IsVerbosityDebug() { @@ -158,14 +189,27 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli } } + if model.NoIPv6Gateway { + addressFamily.Ipv6.Gateway = iaas.NewNullableString(nil) + } else if model.IPv6Gateway != nil { + addressFamily.Ipv6.Gateway = iaas.NewNullableString(model.IPv6Gateway) + } + if model.IPv4DnsNameServers != nil { addressFamily.Ipv4 = &iaas.UpdateNetworkIPv4Body{ Nameservers: model.IPv4DnsNameServers, } } + if model.NoIPv4Gateway { + addressFamily.Ipv4.Gateway = iaas.NewNullableString(nil) + } else if model.IPv4Gateway != nil { + addressFamily.Ipv4.Gateway = iaas.NewNullableString(model.IPv4Gateway) + } + payload := iaas.PartialUpdateNetworkPayload{ - Name: model.Name, + Name: model.Name, + Routed: model.Routed, } if addressFamily.Ipv4 != nil || addressFamily.Ipv6 != nil { diff --git a/internal/cmd/beta/network/update/update_test.go b/internal/cmd/beta/network/update/update_test.go index bc2c28e4e..b87b869c9 100644 --- a/internal/cmd/beta/network/update/update_test.go +++ b/internal/cmd/beta/network/update/update_test.go @@ -38,8 +38,11 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st flagValues := map[string]string{ nameFlag: "example-network-name", projectIdFlag: testProjectId, + routedFlag: "true", ipv4DnsNameServersFlag: "1.1.1.0,1.1.2.0", + ipv4GatewayFlag: "10.1.2.3", ipv6DnsNameServersFlag: "2001:4860:4860::8888,2001:4860:4860::8844", + ipv6GatewayFlag: "2001:4860:4860::8888", } for _, mod := range mods { mod(flagValues) @@ -55,8 +58,11 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { }, Name: utils.Ptr("example-network-name"), NetworkId: testNetworkId, + Routed: utils.Ptr(true), IPv4DnsNameServers: utils.Ptr([]string{"1.1.1.0", "1.1.2.0"}), + IPv4Gateway: utils.Ptr("10.1.2.3"), IPv6DnsNameServers: utils.Ptr([]string{"2001:4860:4860::8888", "2001:4860:4860::8844"}), + IPv6Gateway: utils.Ptr("2001:4860:4860::8888"), } for _, mod := range mods { mod(model) @@ -75,13 +81,16 @@ func fixtureRequest(mods ...func(request *iaas.ApiPartialUpdateNetworkRequest)) func fixturePayload(mods ...func(payload *iaas.PartialUpdateNetworkPayload)) iaas.PartialUpdateNetworkPayload { payload := iaas.PartialUpdateNetworkPayload{ - Name: utils.Ptr("example-network-name"), + Name: utils.Ptr("example-network-name"), + Routed: utils.Ptr(true), AddressFamily: &iaas.UpdateNetworkAddressFamily{ Ipv4: &iaas.UpdateNetworkIPv4Body{ Nameservers: utils.Ptr([]string{"1.1.1.0", "1.1.2.0"}), + Gateway: iaas.NewNullableString(utils.Ptr("10.1.2.3")), }, Ipv6: &iaas.UpdateNetworkIPv6Body{ Nameservers: utils.Ptr([]string{"2001:4860:4860::8888", "2001:4860:4860::8844"}), + Gateway: iaas.NewNullableString(utils.Ptr("2001:4860:4860::8888")), }, }, } @@ -161,25 +170,66 @@ func TestParseInput(t *testing.T) { isValid: false, }, { - description: "use dns servers and prefix", + description: "use dns servers and gateway", argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[ipv4DnsNameServersFlag] = "1.1.1.1" + flagValues[ipv4GatewayFlag] = "10.1.2.3" }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { model.IPv4DnsNameServers = utils.Ptr([]string{"1.1.1.1"}) + model.IPv4Gateway = utils.Ptr("10.1.2.3") }), }, { - description: "use ipv6 dns servers and prefix", + description: "use ipv4 gateway nil", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[noIpv4Gateway] = "true" + delete(flagValues, ipv4GatewayFlag) + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.NoIPv4Gateway = true + model.IPv4Gateway = nil + }), + }, + { + description: "use ipv6 dns servers and gateway", argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { flagValues[ipv6DnsNameServersFlag] = "2001:4860:4860::8888" + flagValues[ipv6GatewayFlag] = "2001:4860:4860::8888" }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { model.IPv6DnsNameServers = utils.Ptr([]string{"2001:4860:4860::8888"}) + model.IPv6Gateway = utils.Ptr("2001:4860:4860::8888") + }), + }, + { + description: "use ipv6 gateway nil", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[noIpv6Gateway] = "true" + delete(flagValues, ipv6GatewayFlag) + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.NoIPv6Gateway = true + model.IPv6Gateway = nil + }), + }, + { + description: "use routed true", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[routedFlag] = "true" + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.Routed = utils.Ptr(true) }), }, } @@ -258,6 +308,7 @@ func TestBuildRequest(t *testing.T) { diff := cmp.Diff(request, tt.expectedRequest, cmp.AllowUnexported(tt.expectedRequest), cmpopts.EquateComparable(testCtx), + cmp.AllowUnexported(iaas.NullableString{}), ) if diff != "" { t.Fatalf("Data does not match: %s", diff) From ef7296e1888bb44f3b5dde2b5d19d38e79cc435d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Go=CC=88kc=CC=A7e=20Go=CC=88k=20Klingel?= Date: Thu, 28 Nov 2024 17:22:49 +0100 Subject: [PATCH 02/13] change payload handling for create and update --- internal/cmd/beta/network/create/create.go | 30 +++++++++---------- .../cmd/beta/network/create/create_test.go | 7 +++-- internal/cmd/beta/network/update/update.go | 30 +++++++++---------- .../cmd/beta/network/update/update_test.go | 4 +-- 4 files changed, 36 insertions(+), 35 deletions(-) diff --git a/internal/cmd/beta/network/create/create.go b/internal/cmd/beta/network/create/create.go index 4b8dd6af9..beecbc68b 100644 --- a/internal/cmd/beta/network/create/create.go +++ b/internal/cmd/beta/network/create/create.go @@ -47,7 +47,7 @@ type inputModel struct { IPv6PrefixLength *int64 IPv6Prefix *string IPv6Gateway *string - Routed *bool + Routed bool NoIPv4Gateway bool NoIPv6Gateway bool } @@ -170,7 +170,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { IPv6PrefixLength: flags.FlagToInt64Pointer(p, cmd, ipv6PrefixLengthFlag), IPv6Prefix: flags.FlagToStringPointer(p, cmd, ipv6PrefixFlag), IPv6Gateway: flags.FlagToStringPointer(p, cmd, ipv6GatewayFlag), - Routed: flags.FlagToBoolPointer(p, cmd, routedFlag), + Routed: flags.FlagToBoolValue(p, cmd, routedFlag), NoIPv4Gateway: flags.FlagToBoolValue(p, cmd, noIpv4Gateway), NoIPv6Gateway: flags.FlagToBoolValue(p, cmd, noIpv6Gateway), } @@ -191,37 +191,37 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli req := apiClient.CreateNetwork(ctx, model.ProjectId) addressFamily := &iaas.CreateNetworkAddressFamily{} - if model.IPv6DnsNameServers != nil || model.IPv6PrefixLength != nil || model.IPv6Prefix != nil { + if model.IPv6DnsNameServers != nil || model.IPv6PrefixLength != nil || model.IPv6Prefix != nil || model.NoIPv6Gateway || model.IPv6Gateway != nil { addressFamily.Ipv6 = &iaas.CreateNetworkIPv6Body{ Nameservers: model.IPv6DnsNameServers, PrefixLength: model.IPv6PrefixLength, Prefix: model.IPv6Prefix, } - } - if model.NoIPv6Gateway { - addressFamily.Ipv6.Gateway = iaas.NewNullableString(nil) - } else if model.IPv6Gateway != nil { - addressFamily.Ipv6.Gateway = iaas.NewNullableString(model.IPv6Gateway) + if model.NoIPv6Gateway { + addressFamily.Ipv6.Gateway = iaas.NewNullableString(nil) + } else if model.IPv6Gateway != nil { + addressFamily.Ipv6.Gateway = iaas.NewNullableString(model.IPv6Gateway) + } } - if model.IPv4DnsNameServers != nil || model.IPv4PrefixLength != nil || model.IPv4Prefix != nil { + if model.IPv4DnsNameServers != nil || model.IPv4PrefixLength != nil || model.IPv4Prefix != nil || model.NoIPv4Gateway || model.IPv4Gateway != nil { addressFamily.Ipv4 = &iaas.CreateNetworkIPv4Body{ Nameservers: model.IPv4DnsNameServers, PrefixLength: model.IPv4PrefixLength, Prefix: model.IPv4Prefix, } - } - if model.NoIPv4Gateway { - addressFamily.Ipv4.Gateway = iaas.NewNullableString(nil) - } else if model.IPv4Gateway != nil { - addressFamily.Ipv4.Gateway = iaas.NewNullableString(model.IPv4Gateway) + if model.NoIPv4Gateway { + addressFamily.Ipv4.Gateway = iaas.NewNullableString(nil) + } else if model.IPv4Gateway != nil { + addressFamily.Ipv4.Gateway = iaas.NewNullableString(model.IPv4Gateway) + } } payload := iaas.CreateNetworkPayload{ Name: model.Name, - Routed: model.Routed, + Routed: &model.Routed, } if addressFamily.Ipv4 != nil || addressFamily.Ipv6 != nil { diff --git a/internal/cmd/beta/network/create/create_test.go b/internal/cmd/beta/network/create/create_test.go index f74e9fbda..a490a4fa8 100644 --- a/internal/cmd/beta/network/create/create_test.go +++ b/internal/cmd/beta/network/create/create_test.go @@ -58,7 +58,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { IPv6PrefixLength: utils.Ptr(int64(24)), IPv6Prefix: utils.Ptr("2001:4860:4860::8888"), IPv6Gateway: utils.Ptr("2001:4860:4860::8888"), - Routed: utils.Ptr(true), + Routed: true, } for _, mod := range mods { mod(model) @@ -78,7 +78,8 @@ func fixtureRequest(mods ...func(request *iaas.ApiCreateNetworkRequest)) iaas.Ap func fixtureRequiredRequest(mods ...func(request *iaas.ApiCreateNetworkRequest)) iaas.ApiCreateNetworkRequest { request := testClient.CreateNetwork(testCtx, testProjectId) request = request.CreateNetworkPayload(iaas.CreateNetworkPayload{ - Name: utils.Ptr("example-network-name"), + Name: utils.Ptr("example-network-name"), + Routed: utils.Ptr(false), }) for _, mod := range mods { mod(&request) @@ -232,7 +233,7 @@ func TestParseInput(t *testing.T) { }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { - model.Routed = utils.Ptr(true) + model.Routed = true }), }, } diff --git a/internal/cmd/beta/network/update/update.go b/internal/cmd/beta/network/update/update.go index 9ba5b0c27..13c2c59bd 100644 --- a/internal/cmd/beta/network/update/update.go +++ b/internal/cmd/beta/network/update/update.go @@ -37,7 +37,7 @@ type inputModel struct { *globalflags.GlobalFlagModel NetworkId string Name *string - Routed *bool + Routed bool IPv4DnsNameServers *[]string IPv4Gateway *string IPv6DnsNameServers *[]string @@ -158,7 +158,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu GlobalFlagModel: globalFlags, Name: flags.FlagToStringPointer(p, cmd, nameFlag), NetworkId: networkId, - Routed: flags.FlagToBoolPointer(p, cmd, routedFlag), + Routed: flags.FlagToBoolValue(p, cmd, routedFlag), IPv4DnsNameServers: flags.FlagToStringSlicePointer(p, cmd, ipv4DnsNameServersFlag), IPv4Gateway: flags.FlagToStringPointer(p, cmd, ipv4GatewayFlag), IPv6DnsNameServers: flags.FlagToStringSlicePointer(p, cmd, ipv6DnsNameServersFlag), @@ -183,33 +183,33 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli req := apiClient.PartialUpdateNetwork(ctx, model.ProjectId, model.NetworkId) addressFamily := &iaas.UpdateNetworkAddressFamily{} - if model.IPv6DnsNameServers != nil { + if model.IPv6DnsNameServers != nil || model.NoIPv6Gateway || model.IPv6Gateway != nil { addressFamily.Ipv6 = &iaas.UpdateNetworkIPv6Body{ Nameservers: model.IPv6DnsNameServers, } - } - if model.NoIPv6Gateway { - addressFamily.Ipv6.Gateway = iaas.NewNullableString(nil) - } else if model.IPv6Gateway != nil { - addressFamily.Ipv6.Gateway = iaas.NewNullableString(model.IPv6Gateway) + if model.NoIPv6Gateway { + addressFamily.Ipv6.Gateway = iaas.NewNullableString(nil) + } else if model.IPv6Gateway != nil { + addressFamily.Ipv6.Gateway = iaas.NewNullableString(model.IPv6Gateway) + } } - if model.IPv4DnsNameServers != nil { + if model.IPv4DnsNameServers != nil || model.NoIPv4Gateway || model.IPv4Gateway != nil { addressFamily.Ipv4 = &iaas.UpdateNetworkIPv4Body{ Nameservers: model.IPv4DnsNameServers, } - } - if model.NoIPv4Gateway { - addressFamily.Ipv4.Gateway = iaas.NewNullableString(nil) - } else if model.IPv4Gateway != nil { - addressFamily.Ipv4.Gateway = iaas.NewNullableString(model.IPv4Gateway) + if model.NoIPv4Gateway { + addressFamily.Ipv4.Gateway = iaas.NewNullableString(nil) + } else if model.IPv4Gateway != nil { + addressFamily.Ipv4.Gateway = iaas.NewNullableString(model.IPv4Gateway) + } } payload := iaas.PartialUpdateNetworkPayload{ Name: model.Name, - Routed: model.Routed, + Routed: &model.Routed, } if addressFamily.Ipv4 != nil || addressFamily.Ipv6 != nil { diff --git a/internal/cmd/beta/network/update/update_test.go b/internal/cmd/beta/network/update/update_test.go index b87b869c9..7a778d343 100644 --- a/internal/cmd/beta/network/update/update_test.go +++ b/internal/cmd/beta/network/update/update_test.go @@ -58,7 +58,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { }, Name: utils.Ptr("example-network-name"), NetworkId: testNetworkId, - Routed: utils.Ptr(true), + Routed: true, IPv4DnsNameServers: utils.Ptr([]string{"1.1.1.0", "1.1.2.0"}), IPv4Gateway: utils.Ptr("10.1.2.3"), IPv6DnsNameServers: utils.Ptr([]string{"2001:4860:4860::8888", "2001:4860:4860::8844"}), @@ -229,7 +229,7 @@ func TestParseInput(t *testing.T) { }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { - model.Routed = utils.Ptr(true) + model.Routed = true }), }, } From d8015a3204c605f32e7959eafb9ceea369b18f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Go=CC=88kc=CC=A7e=20Go=CC=88k=20Klingel?= Date: Tue, 3 Dec 2024 08:48:49 +0100 Subject: [PATCH 03/13] edit flag descriptions in create and update command --- docs/stackit_beta_network_create.md | 12 ++++++------ docs/stackit_beta_network_update.md | 12 ++++++------ internal/cmd/beta/network/create/create.go | 12 ++++++------ internal/cmd/beta/network/update/update.go | 12 ++++++------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/stackit_beta_network_create.md b/docs/stackit_beta_network_create.md index 6940eb759..59cdf2476 100644 --- a/docs/stackit_beta_network_create.md +++ b/docs/stackit_beta_network_create.md @@ -33,17 +33,17 @@ stackit beta network create [flags] ``` -h, --help Help for "stackit beta network create" - --ipv4-dns-name-servers strings List of DNS name servers for IPv4. Nameservers cannot be defined for routed networks. - --ipv4-gateway string The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway. + --ipv4-dns-name-servers strings List of DNS name servers for IPv4. Nameservers cannot be defined for routed networks + --ipv4-gateway string The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway --ipv4-prefix string The IPv4 prefix of the network (CIDR) --ipv4-prefix-length int The prefix length of the IPv4 network - --ipv6-dns-name-servers strings List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks. - --ipv6-gateway string The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway. + --ipv6-dns-name-servers strings List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks + --ipv6-gateway string The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway --ipv6-prefix string The IPv6 prefix of the network (CIDR) --ipv6-prefix-length int The prefix length of the IPv6 network -n, --name string Network name - --no-ipv4-gateway If set to true, the network doesn't have an IPv4 gateway. - --no-ipv6-gateway If set to true, the network doesn't have an IPv6 gateway. + --no-ipv4-gateway If set to true, the network doesn't have an IPv4 gateway + --no-ipv6-gateway If set to true, the network doesn't have an IPv6 gateway --routed If set to true, the network is routed and therefore accessible from other networks ``` diff --git a/docs/stackit_beta_network_update.md b/docs/stackit_beta_network_update.md index e320d7918..ff0817501 100644 --- a/docs/stackit_beta_network_update.md +++ b/docs/stackit_beta_network_update.md @@ -33,13 +33,13 @@ stackit beta network update [flags] ``` -h, --help Help for "stackit beta network update" - --ipv4-dns-name-servers strings List of DNS name servers IPv4. Nameservers cannot be defined for routed networks. - --ipv4-gateway string The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway. - --ipv6-dns-name-servers strings List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks. - --ipv6-gateway string The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway. + --ipv4-dns-name-servers strings List of DNS name servers IPv4. Nameservers cannot be defined for routed networks + --ipv4-gateway string The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway + --ipv6-dns-name-servers strings List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks + --ipv6-gateway string The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway -n, --name string Network name - --no-ipv4-gateway If set to true, the network doesn't have an IPv4 gateway. - --no-ipv6-gateway If set to true, the network doesn't have an IPv6 gateway. + --no-ipv4-gateway If set to true, the network doesn't have an IPv4 gateway + --no-ipv6-gateway If set to true, the network doesn't have an IPv6 gateway --routed If set to true, the network is routed and therefore accessible from other networks ``` diff --git a/internal/cmd/beta/network/create/create.go b/internal/cmd/beta/network/create/create.go index beecbc68b..d514ef40e 100644 --- a/internal/cmd/beta/network/create/create.go +++ b/internal/cmd/beta/network/create/create.go @@ -135,17 +135,17 @@ func NewCmd(p *print.Printer) *cobra.Command { func configureFlags(cmd *cobra.Command) { cmd.Flags().StringP(nameFlag, "n", "", "Network name") - cmd.Flags().StringSlice(ipv4DnsNameServersFlag, []string{}, "List of DNS name servers for IPv4. Nameservers cannot be defined for routed networks.") + cmd.Flags().StringSlice(ipv4DnsNameServersFlag, []string{}, "List of DNS name servers for IPv4. Nameservers cannot be defined for routed networks") cmd.Flags().Int64(ipv4PrefixLengthFlag, 0, "The prefix length of the IPv4 network") cmd.Flags().String(ipv4PrefixFlag, "", "The IPv4 prefix of the network (CIDR)") - cmd.Flags().String(ipv4GatewayFlag, "", "The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway.") - cmd.Flags().StringSlice(ipv6DnsNameServersFlag, []string{}, "List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks.") + cmd.Flags().String(ipv4GatewayFlag, "", "The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway") + cmd.Flags().StringSlice(ipv6DnsNameServersFlag, []string{}, "List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks") cmd.Flags().Int64(ipv6PrefixLengthFlag, 0, "The prefix length of the IPv6 network") cmd.Flags().String(ipv6PrefixFlag, "", "The IPv6 prefix of the network (CIDR)") - cmd.Flags().String(ipv6GatewayFlag, "", "The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway.") + cmd.Flags().String(ipv6GatewayFlag, "", "The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway") cmd.Flags().Bool(routedFlag, false, "If set to true, the network is routed and therefore accessible from other networks") - cmd.Flags().Bool(noIpv4Gateway, false, "If set to true, the network doesn't have an IPv4 gateway.") - cmd.Flags().Bool(noIpv6Gateway, false, "If set to true, the network doesn't have an IPv6 gateway.") + cmd.Flags().Bool(noIpv4Gateway, false, "If set to true, the network doesn't have an IPv4 gateway") + cmd.Flags().Bool(noIpv6Gateway, false, "If set to true, the network doesn't have an IPv6 gateway") cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv4DnsNameServersFlag) cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv6DnsNameServersFlag) diff --git a/internal/cmd/beta/network/update/update.go b/internal/cmd/beta/network/update/update.go index 13c2c59bd..56cd448f8 100644 --- a/internal/cmd/beta/network/update/update.go +++ b/internal/cmd/beta/network/update/update.go @@ -135,12 +135,12 @@ func NewCmd(p *print.Printer) *cobra.Command { func configureFlags(cmd *cobra.Command) { cmd.Flags().StringP(nameFlag, "n", "", "Network name") cmd.Flags().Bool(routedFlag, false, "If set to true, the network is routed and therefore accessible from other networks") - cmd.Flags().StringSlice(ipv4DnsNameServersFlag, nil, "List of DNS name servers IPv4. Nameservers cannot be defined for routed networks.") - cmd.Flags().String(ipv4GatewayFlag, "", "The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway.") - cmd.Flags().StringSlice(ipv6DnsNameServersFlag, nil, "List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks.") - cmd.Flags().String(ipv6GatewayFlag, "", "The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway. If 'null' is sent, then the network doesn't have a gateway.") - cmd.Flags().Bool(noIpv4Gateway, false, "If set to true, the network doesn't have an IPv4 gateway.") - cmd.Flags().Bool(noIpv6Gateway, false, "If set to true, the network doesn't have an IPv6 gateway.") + cmd.Flags().StringSlice(ipv4DnsNameServersFlag, nil, "List of DNS name servers IPv4. Nameservers cannot be defined for routed networks") + cmd.Flags().String(ipv4GatewayFlag, "", "The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway") + cmd.Flags().StringSlice(ipv6DnsNameServersFlag, nil, "List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks") + cmd.Flags().String(ipv6GatewayFlag, "", "The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway") + cmd.Flags().Bool(noIpv4Gateway, false, "If set to true, the network doesn't have an IPv4 gateway") + cmd.Flags().Bool(noIpv6Gateway, false, "If set to true, the network doesn't have an IPv6 gateway") cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv4DnsNameServersFlag) cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv6DnsNameServersFlag) From 2ec29aa18460702d4a6ecc9896d467e8a7b5def9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Go=CC=88kc=CC=A7e=20Go=CC=88k=20Klingel?= Date: Tue, 3 Dec 2024 08:52:32 +0100 Subject: [PATCH 04/13] fix flag names --- internal/cmd/beta/network/create/create.go | 12 ++++++------ internal/cmd/beta/network/create/create_test.go | 4 ++-- internal/cmd/beta/network/update/update.go | 12 ++++++------ internal/cmd/beta/network/update/update_test.go | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/internal/cmd/beta/network/create/create.go b/internal/cmd/beta/network/create/create.go index d514ef40e..1797b147c 100644 --- a/internal/cmd/beta/network/create/create.go +++ b/internal/cmd/beta/network/create/create.go @@ -32,8 +32,8 @@ const ( ipv6PrefixFlag = "ipv6-prefix" ipv6GatewayFlag = "ipv6-gateway" routedFlag = "routed" - noIpv4Gateway = "no-ipv4-gateway" - noIpv6Gateway = "no-ipv6-gateway" + noIpv4GatewayFlag = "no-ipv4-gateway" + noIpv6GatewayFlag = "no-ipv6-gateway" ) type inputModel struct { @@ -144,8 +144,8 @@ func configureFlags(cmd *cobra.Command) { cmd.Flags().String(ipv6PrefixFlag, "", "The IPv6 prefix of the network (CIDR)") cmd.Flags().String(ipv6GatewayFlag, "", "The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway") cmd.Flags().Bool(routedFlag, false, "If set to true, the network is routed and therefore accessible from other networks") - cmd.Flags().Bool(noIpv4Gateway, false, "If set to true, the network doesn't have an IPv4 gateway") - cmd.Flags().Bool(noIpv6Gateway, false, "If set to true, the network doesn't have an IPv6 gateway") + cmd.Flags().Bool(noIpv4GatewayFlag, false, "If set to true, the network doesn't have an IPv4 gateway") + cmd.Flags().Bool(noIpv6GatewayFlag, false, "If set to true, the network doesn't have an IPv6 gateway") cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv4DnsNameServersFlag) cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv6DnsNameServersFlag) @@ -171,8 +171,8 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { IPv6Prefix: flags.FlagToStringPointer(p, cmd, ipv6PrefixFlag), IPv6Gateway: flags.FlagToStringPointer(p, cmd, ipv6GatewayFlag), Routed: flags.FlagToBoolValue(p, cmd, routedFlag), - NoIPv4Gateway: flags.FlagToBoolValue(p, cmd, noIpv4Gateway), - NoIPv6Gateway: flags.FlagToBoolValue(p, cmd, noIpv6Gateway), + NoIPv4Gateway: flags.FlagToBoolValue(p, cmd, noIpv4GatewayFlag), + NoIPv6Gateway: flags.FlagToBoolValue(p, cmd, noIpv6GatewayFlag), } if p.IsVerbosityDebug() { diff --git a/internal/cmd/beta/network/create/create_test.go b/internal/cmd/beta/network/create/create_test.go index a490a4fa8..38cdbb5d8 100644 --- a/internal/cmd/beta/network/create/create_test.go +++ b/internal/cmd/beta/network/create/create_test.go @@ -189,7 +189,7 @@ func TestParseInput(t *testing.T) { { description: "use ipv4 gateway nil", flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[noIpv4Gateway] = "true" + flagValues[noIpv4GatewayFlag] = "true" delete(flagValues, ipv4GatewayFlag) }), isValid: true, @@ -217,7 +217,7 @@ func TestParseInput(t *testing.T) { { description: "use ipv6 gateway nil", flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[noIpv6Gateway] = "true" + flagValues[noIpv6GatewayFlag] = "true" delete(flagValues, ipv6GatewayFlag) }), isValid: true, diff --git a/internal/cmd/beta/network/update/update.go b/internal/cmd/beta/network/update/update.go index 56cd448f8..3adeb9662 100644 --- a/internal/cmd/beta/network/update/update.go +++ b/internal/cmd/beta/network/update/update.go @@ -29,8 +29,8 @@ const ( ipv4GatewayFlag = "ipv4-gateway" ipv6DnsNameServersFlag = "ipv6-dns-name-servers" ipv6GatewayFlag = "ipv6-gateway" - noIpv4Gateway = "no-ipv4-gateway" - noIpv6Gateway = "no-ipv6-gateway" + noIpv4GatewayFlag = "no-ipv4-gateway" + noIpv6GatewayFlag = "no-ipv6-gateway" ) type inputModel struct { @@ -139,8 +139,8 @@ func configureFlags(cmd *cobra.Command) { cmd.Flags().String(ipv4GatewayFlag, "", "The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway") cmd.Flags().StringSlice(ipv6DnsNameServersFlag, nil, "List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks") cmd.Flags().String(ipv6GatewayFlag, "", "The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway") - cmd.Flags().Bool(noIpv4Gateway, false, "If set to true, the network doesn't have an IPv4 gateway") - cmd.Flags().Bool(noIpv6Gateway, false, "If set to true, the network doesn't have an IPv6 gateway") + cmd.Flags().Bool(noIpv4GatewayFlag, false, "If set to true, the network doesn't have an IPv4 gateway") + cmd.Flags().Bool(noIpv6GatewayFlag, false, "If set to true, the network doesn't have an IPv6 gateway") cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv4DnsNameServersFlag) cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv6DnsNameServersFlag) @@ -163,8 +163,8 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu IPv4Gateway: flags.FlagToStringPointer(p, cmd, ipv4GatewayFlag), IPv6DnsNameServers: flags.FlagToStringSlicePointer(p, cmd, ipv6DnsNameServersFlag), IPv6Gateway: flags.FlagToStringPointer(p, cmd, ipv6GatewayFlag), - NoIPv4Gateway: flags.FlagToBoolValue(p, cmd, noIpv4Gateway), - NoIPv6Gateway: flags.FlagToBoolValue(p, cmd, noIpv6Gateway), + NoIPv4Gateway: flags.FlagToBoolValue(p, cmd, noIpv4GatewayFlag), + NoIPv6Gateway: flags.FlagToBoolValue(p, cmd, noIpv6GatewayFlag), } if p.IsVerbosityDebug() { diff --git a/internal/cmd/beta/network/update/update_test.go b/internal/cmd/beta/network/update/update_test.go index 7a778d343..962fdb3a9 100644 --- a/internal/cmd/beta/network/update/update_test.go +++ b/internal/cmd/beta/network/update/update_test.go @@ -186,7 +186,7 @@ func TestParseInput(t *testing.T) { description: "use ipv4 gateway nil", argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[noIpv4Gateway] = "true" + flagValues[noIpv4GatewayFlag] = "true" delete(flagValues, ipv4GatewayFlag) }), isValid: true, @@ -212,7 +212,7 @@ func TestParseInput(t *testing.T) { description: "use ipv6 gateway nil", argValues: fixtureArgValues(), flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[noIpv6Gateway] = "true" + flagValues[noIpv6GatewayFlag] = "true" delete(flagValues, ipv6GatewayFlag) }), isValid: true, From 30d7c265e7ee2899d6c71ae3c207bbf35e93cb6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Go=CC=88kc=CC=A7e=20Go=CC=88k=20Klingel?= Date: Tue, 3 Dec 2024 08:57:27 +0100 Subject: [PATCH 05/13] remove routed from the updated --- docs/stackit_beta_network_update.md | 4 ---- internal/cmd/beta/network/update/update.go | 14 +------------- internal/cmd/beta/network/update/update_test.go | 16 +--------------- 3 files changed, 2 insertions(+), 32 deletions(-) diff --git a/docs/stackit_beta_network_update.md b/docs/stackit_beta_network_update.md index ff0817501..99ac5f728 100644 --- a/docs/stackit_beta_network_update.md +++ b/docs/stackit_beta_network_update.md @@ -16,9 +16,6 @@ stackit beta network update [flags] Update network with ID "xxx" with new name "network-1-new" $ stackit beta network update xxx --name network-1-new - Update network with ID "xxx" with routed true - $ stackit beta network update xxx --routed - Update network with ID "xxx" with no gateway $ stackit beta network update --no-ipv4-gateway @@ -40,7 +37,6 @@ stackit beta network update [flags] -n, --name string Network name --no-ipv4-gateway If set to true, the network doesn't have an IPv4 gateway --no-ipv6-gateway If set to true, the network doesn't have an IPv6 gateway - --routed If set to true, the network is routed and therefore accessible from other networks ``` ### Options inherited from parent commands diff --git a/internal/cmd/beta/network/update/update.go b/internal/cmd/beta/network/update/update.go index 3adeb9662..710205cd7 100644 --- a/internal/cmd/beta/network/update/update.go +++ b/internal/cmd/beta/network/update/update.go @@ -24,7 +24,6 @@ const ( networkIdArg = "NETWORK_ID" nameFlag = "name" - routedFlag = "routed" ipv4DnsNameServersFlag = "ipv4-dns-name-servers" ipv4GatewayFlag = "ipv4-gateway" ipv6DnsNameServersFlag = "ipv6-dns-name-servers" @@ -37,7 +36,6 @@ type inputModel struct { *globalflags.GlobalFlagModel NetworkId string Name *string - Routed bool IPv4DnsNameServers *[]string IPv4Gateway *string IPv6DnsNameServers *[]string @@ -57,10 +55,6 @@ func NewCmd(p *print.Printer) *cobra.Command { `Update network with ID "xxx" with new name "network-1-new"`, `$ stackit beta network update xxx --name network-1-new`, ), - examples.NewExample( - `Update network with ID "xxx" with routed true`, - `$ stackit beta network update xxx --routed`, - ), examples.NewExample( `Update network with ID "xxx" with no gateway`, `$ stackit beta network update --no-ipv4-gateway`, @@ -134,16 +128,12 @@ func NewCmd(p *print.Printer) *cobra.Command { func configureFlags(cmd *cobra.Command) { cmd.Flags().StringP(nameFlag, "n", "", "Network name") - cmd.Flags().Bool(routedFlag, false, "If set to true, the network is routed and therefore accessible from other networks") cmd.Flags().StringSlice(ipv4DnsNameServersFlag, nil, "List of DNS name servers IPv4. Nameservers cannot be defined for routed networks") cmd.Flags().String(ipv4GatewayFlag, "", "The IPv4 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway") cmd.Flags().StringSlice(ipv6DnsNameServersFlag, nil, "List of DNS name servers for IPv6. Nameservers cannot be defined for routed networks") cmd.Flags().String(ipv6GatewayFlag, "", "The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway") cmd.Flags().Bool(noIpv4GatewayFlag, false, "If set to true, the network doesn't have an IPv4 gateway") cmd.Flags().Bool(noIpv6GatewayFlag, false, "If set to true, the network doesn't have an IPv6 gateway") - - cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv4DnsNameServersFlag) - cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv6DnsNameServersFlag) } func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { @@ -158,7 +148,6 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu GlobalFlagModel: globalFlags, Name: flags.FlagToStringPointer(p, cmd, nameFlag), NetworkId: networkId, - Routed: flags.FlagToBoolValue(p, cmd, routedFlag), IPv4DnsNameServers: flags.FlagToStringSlicePointer(p, cmd, ipv4DnsNameServersFlag), IPv4Gateway: flags.FlagToStringPointer(p, cmd, ipv4GatewayFlag), IPv6DnsNameServers: flags.FlagToStringSlicePointer(p, cmd, ipv6DnsNameServersFlag), @@ -208,8 +197,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli } payload := iaas.PartialUpdateNetworkPayload{ - Name: model.Name, - Routed: &model.Routed, + Name: model.Name, } if addressFamily.Ipv4 != nil || addressFamily.Ipv6 != nil { diff --git a/internal/cmd/beta/network/update/update_test.go b/internal/cmd/beta/network/update/update_test.go index 962fdb3a9..99b3e8ba6 100644 --- a/internal/cmd/beta/network/update/update_test.go +++ b/internal/cmd/beta/network/update/update_test.go @@ -38,7 +38,6 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st flagValues := map[string]string{ nameFlag: "example-network-name", projectIdFlag: testProjectId, - routedFlag: "true", ipv4DnsNameServersFlag: "1.1.1.0,1.1.2.0", ipv4GatewayFlag: "10.1.2.3", ipv6DnsNameServersFlag: "2001:4860:4860::8888,2001:4860:4860::8844", @@ -58,7 +57,6 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { }, Name: utils.Ptr("example-network-name"), NetworkId: testNetworkId, - Routed: true, IPv4DnsNameServers: utils.Ptr([]string{"1.1.1.0", "1.1.2.0"}), IPv4Gateway: utils.Ptr("10.1.2.3"), IPv6DnsNameServers: utils.Ptr([]string{"2001:4860:4860::8888", "2001:4860:4860::8844"}), @@ -81,8 +79,7 @@ func fixtureRequest(mods ...func(request *iaas.ApiPartialUpdateNetworkRequest)) func fixturePayload(mods ...func(payload *iaas.PartialUpdateNetworkPayload)) iaas.PartialUpdateNetworkPayload { payload := iaas.PartialUpdateNetworkPayload{ - Name: utils.Ptr("example-network-name"), - Routed: utils.Ptr(true), + Name: utils.Ptr("example-network-name"), AddressFamily: &iaas.UpdateNetworkAddressFamily{ Ipv4: &iaas.UpdateNetworkIPv4Body{ Nameservers: utils.Ptr([]string{"1.1.1.0", "1.1.2.0"}), @@ -221,17 +218,6 @@ func TestParseInput(t *testing.T) { model.IPv6Gateway = nil }), }, - { - description: "use routed true", - argValues: fixtureArgValues(), - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[routedFlag] = "true" - }), - isValid: true, - expectedModel: fixtureInputModel(func(model *inputModel) { - model.Routed = true - }), - }, } for _, tt := range tests { From 5ad9813083d8fa3f67f81ccaaa96d57f8d53a6ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Go=CC=88kc=CC=A7e=20Go=CC=88k=20Klingel?= Date: Tue, 3 Dec 2024 10:11:02 +0100 Subject: [PATCH 06/13] change routed handling in describe output --- internal/cmd/beta/network/describe/describe.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/cmd/beta/network/describe/describe.go b/internal/cmd/beta/network/describe/describe.go index cb5ba80a6..854fd65b0 100644 --- a/internal/cmd/beta/network/describe/describe.go +++ b/internal/cmd/beta/network/describe/describe.go @@ -152,11 +152,14 @@ func outputResult(p *print.Printer, outputFormat string, network *iaas.Network) table.AddSeparator() } + routed := false if network.Routed != nil { - table.AddRow("ROUTED", *network.Routed) - table.AddSeparator() + routed = *network.Routed } + table.AddRow("ROUTED", routed) + table.AddSeparator() + if network.Gateway != nil { table.AddRow("IPv4 GATEWAY", *network.Gateway.Get()) table.AddSeparator() From 756aac211eb7eff7e880597ace861c59c00693e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Go=CC=88kc=CC=A7e=20Go=CC=88k=20Klingel?= Date: Tue, 3 Dec 2024 10:12:57 +0100 Subject: [PATCH 07/13] update descriptions --- docs/stackit_beta_network_create.md | 8 ++++---- internal/cmd/beta/network/create/create.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/stackit_beta_network_create.md b/docs/stackit_beta_network_create.md index 59cdf2476..30071b95f 100644 --- a/docs/stackit_beta_network_create.md +++ b/docs/stackit_beta_network_create.md @@ -22,11 +22,11 @@ stackit beta network create [flags] Create a network with name "network-1" and no gateway $ stackit beta network create --name network-1 --no-ipv4-gateway - Create an IPv4 network with name "network-1" with DNS name servers, a prefix, a gateway and a prefix length - $ stackit beta network create --name network-1 --ipv4-dns-name-servers "1.1.1.1,8.8.8.8,9.9.9.9" --ipv4-prefix-length 25 --ipv4-prefix "10.1.2.0/24" --ipv4-gateway "10.1.2.3" + Create an IPv4 network with name "network-1" with DNS name servers, a prefix and a gateway + $ stackit beta network create --name network-1 --ipv4-dns-name-servers "1.1.1.1,8.8.8.8,9.9.9.9" --ipv4-prefix "10.1.2.0/24" --ipv4-gateway "10.1.2.3" - Create an IPv6 network with name "network-1" with DNS name servers, a prefix, a gateway and a prefix length - $ stackit beta network create --name network-1 --ipv6-dns-name-servers "2001:4860:4860::8888,2001:4860:4860::8844" --ipv6-prefix-length 56 --ipv6-prefix "2001:4860:4860::8888" --ipv6-gateway "2001:4860:4860::8888" + Create an IPv6 network with name "network-1" with DNS name servers, a prefix and a gateway + $ stackit beta network create --name network-1 --ipv6-dns-name-servers "2001:4860:4860::8888,2001:4860:4860::8844" --ipv6-prefix "2001:4860:4860::8888" --ipv6-gateway "2001:4860:4860::8888" ``` ### Options diff --git a/internal/cmd/beta/network/create/create.go b/internal/cmd/beta/network/create/create.go index 1797b147c..bf005e065 100644 --- a/internal/cmd/beta/network/create/create.go +++ b/internal/cmd/beta/network/create/create.go @@ -72,12 +72,12 @@ func NewCmd(p *print.Printer) *cobra.Command { `$ stackit beta network create --name network-1 --no-ipv4-gateway`, ), examples.NewExample( - `Create an IPv4 network with name "network-1" with DNS name servers, a prefix, a gateway and a prefix length`, - `$ stackit beta network create --name network-1 --ipv4-dns-name-servers "1.1.1.1,8.8.8.8,9.9.9.9" --ipv4-prefix-length 25 --ipv4-prefix "10.1.2.0/24" --ipv4-gateway "10.1.2.3"`, + `Create an IPv4 network with name "network-1" with DNS name servers, a prefix and a gateway`, + `$ stackit beta network create --name network-1 --ipv4-dns-name-servers "1.1.1.1,8.8.8.8,9.9.9.9" --ipv4-prefix "10.1.2.0/24" --ipv4-gateway "10.1.2.3"`, ), examples.NewExample( - `Create an IPv6 network with name "network-1" with DNS name servers, a prefix, a gateway and a prefix length`, - `$ stackit beta network create --name network-1 --ipv6-dns-name-servers "2001:4860:4860::8888,2001:4860:4860::8844" --ipv6-prefix-length 56 --ipv6-prefix "2001:4860:4860::8888" --ipv6-gateway "2001:4860:4860::8888"`, + `Create an IPv6 network with name "network-1" with DNS name servers, a prefix and a gateway`, + `$ stackit beta network create --name network-1 --ipv6-dns-name-servers "2001:4860:4860::8888,2001:4860:4860::8844" --ipv6-prefix "2001:4860:4860::8888" --ipv6-gateway "2001:4860:4860::8888"`, ), ), RunE: func(cmd *cobra.Command, _ []string) error { From dd659ae8499b1b4a1e23d5e479f3f11f24fe550b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Go=CC=88kc=CC=A7e=20Go=CC=88k=20Klingel?= Date: Tue, 3 Dec 2024 11:16:53 +0100 Subject: [PATCH 08/13] replace routed flag with non-routed to align with api values --- docs/stackit_beta_network_create.md | 6 +++--- internal/cmd/beta/network/create/create.go | 21 +++++++++++-------- .../cmd/beta/network/create/create_test.go | 10 ++++----- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/docs/stackit_beta_network_create.md b/docs/stackit_beta_network_create.md index 30071b95f..bdca2eca6 100644 --- a/docs/stackit_beta_network_create.md +++ b/docs/stackit_beta_network_create.md @@ -16,8 +16,8 @@ stackit beta network create [flags] Create a network with name "network-1" $ stackit beta network create --name network-1 - Create a routed network with name "network-1" - $ stackit beta network create --name network-1 --routed + Create a non-routed network with name "network-1" + $ stackit beta network create --name network-1 --non-routed Create a network with name "network-1" and no gateway $ stackit beta network create --name network-1 --no-ipv4-gateway @@ -44,7 +44,7 @@ stackit beta network create [flags] -n, --name string Network name --no-ipv4-gateway If set to true, the network doesn't have an IPv4 gateway --no-ipv6-gateway If set to true, the network doesn't have an IPv6 gateway - --routed If set to true, the network is routed and therefore accessible from other networks + --non-routed If set to true, the network is not routed and therefore not accessible from other networks ``` ### Options inherited from parent commands diff --git a/internal/cmd/beta/network/create/create.go b/internal/cmd/beta/network/create/create.go index bf005e065..2e406c39e 100644 --- a/internal/cmd/beta/network/create/create.go +++ b/internal/cmd/beta/network/create/create.go @@ -31,7 +31,7 @@ const ( ipv6PrefixLengthFlag = "ipv6-prefix-length" ipv6PrefixFlag = "ipv6-prefix" ipv6GatewayFlag = "ipv6-gateway" - routedFlag = "routed" + nonRoutedFlag = "non-routed" noIpv4GatewayFlag = "no-ipv4-gateway" noIpv6GatewayFlag = "no-ipv6-gateway" ) @@ -47,7 +47,7 @@ type inputModel struct { IPv6PrefixLength *int64 IPv6Prefix *string IPv6Gateway *string - Routed bool + NonRouted bool NoIPv4Gateway bool NoIPv6Gateway bool } @@ -64,8 +64,8 @@ func NewCmd(p *print.Printer) *cobra.Command { `$ stackit beta network create --name network-1`, ), examples.NewExample( - `Create a routed network with name "network-1"`, - `$ stackit beta network create --name network-1 --routed`, + `Create a non-routed network with name "network-1"`, + `$ stackit beta network create --name network-1 --non-routed`, ), examples.NewExample( `Create a network with name "network-1" and no gateway`, @@ -143,12 +143,10 @@ func configureFlags(cmd *cobra.Command) { cmd.Flags().Int64(ipv6PrefixLengthFlag, 0, "The prefix length of the IPv6 network") cmd.Flags().String(ipv6PrefixFlag, "", "The IPv6 prefix of the network (CIDR)") cmd.Flags().String(ipv6GatewayFlag, "", "The IPv6 gateway of a network. If not specified, the first IP of the network will be assigned as the gateway") - cmd.Flags().Bool(routedFlag, false, "If set to true, the network is routed and therefore accessible from other networks") + cmd.Flags().Bool(nonRoutedFlag, false, "If set to true, the network is not routed and therefore not accessible from other networks") cmd.Flags().Bool(noIpv4GatewayFlag, false, "If set to true, the network doesn't have an IPv4 gateway") cmd.Flags().Bool(noIpv6GatewayFlag, false, "If set to true, the network doesn't have an IPv6 gateway") - cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv4DnsNameServersFlag) - cmd.MarkFlagsMutuallyExclusive(routedFlag, ipv6DnsNameServersFlag) err := flags.MarkFlagsRequired(cmd, nameFlag) cobra.CheckErr(err) } @@ -170,7 +168,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { IPv6PrefixLength: flags.FlagToInt64Pointer(p, cmd, ipv6PrefixLengthFlag), IPv6Prefix: flags.FlagToStringPointer(p, cmd, ipv6PrefixFlag), IPv6Gateway: flags.FlagToStringPointer(p, cmd, ipv6GatewayFlag), - Routed: flags.FlagToBoolValue(p, cmd, routedFlag), + NonRouted: flags.FlagToBoolValue(p, cmd, nonRoutedFlag), NoIPv4Gateway: flags.FlagToBoolValue(p, cmd, noIpv4GatewayFlag), NoIPv6Gateway: flags.FlagToBoolValue(p, cmd, noIpv6GatewayFlag), } @@ -219,9 +217,14 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APICli } } + routed := true + if model.NonRouted { + routed = false + } + payload := iaas.CreateNetworkPayload{ Name: model.Name, - Routed: &model.Routed, + Routed: &routed, } if addressFamily.Ipv4 != nil || addressFamily.Ipv6 != nil { diff --git a/internal/cmd/beta/network/create/create_test.go b/internal/cmd/beta/network/create/create_test.go index 38cdbb5d8..9158ec67c 100644 --- a/internal/cmd/beta/network/create/create_test.go +++ b/internal/cmd/beta/network/create/create_test.go @@ -35,7 +35,7 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st ipv6PrefixLengthFlag: "24", ipv6PrefixFlag: "2001:4860:4860::8888", ipv6GatewayFlag: "2001:4860:4860::8888", - routedFlag: "true", + nonRoutedFlag: "false", } for _, mod := range mods { mod(flagValues) @@ -58,7 +58,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { IPv6PrefixLength: utils.Ptr(int64(24)), IPv6Prefix: utils.Ptr("2001:4860:4860::8888"), IPv6Gateway: utils.Ptr("2001:4860:4860::8888"), - Routed: true, + NonRouted: false, } for _, mod := range mods { mod(model) @@ -79,7 +79,7 @@ func fixtureRequiredRequest(mods ...func(request *iaas.ApiCreateNetworkRequest)) request := testClient.CreateNetwork(testCtx, testProjectId) request = request.CreateNetworkPayload(iaas.CreateNetworkPayload{ Name: utils.Ptr("example-network-name"), - Routed: utils.Ptr(false), + Routed: utils.Ptr(true), }) for _, mod := range mods { mod(&request) @@ -229,11 +229,11 @@ func TestParseInput(t *testing.T) { { description: "use routed true", flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[routedFlag] = "true" + flagValues[nonRoutedFlag] = "false" }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { - model.Routed = true + model.NonRouted = false }), }, } From 17f9cf8e7c6a206934d607101f6d99b94ec027df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Go=CC=88kc=CC=A7e=20Go=CC=88k=20Klingel?= Date: Tue, 3 Dec 2024 11:18:24 +0100 Subject: [PATCH 09/13] set default values of routed to true --- internal/cmd/beta/network/describe/describe.go | 2 +- internal/cmd/beta/network/list/list.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/cmd/beta/network/describe/describe.go b/internal/cmd/beta/network/describe/describe.go index 854fd65b0..49a5570d7 100644 --- a/internal/cmd/beta/network/describe/describe.go +++ b/internal/cmd/beta/network/describe/describe.go @@ -152,7 +152,7 @@ func outputResult(p *print.Printer, outputFormat string, network *iaas.Network) table.AddSeparator() } - routed := false + routed := true if network.Routed != nil { routed = *network.Routed } diff --git a/internal/cmd/beta/network/list/list.go b/internal/cmd/beta/network/list/list.go index 889f9e307..61326a9e8 100644 --- a/internal/cmd/beta/network/list/list.go +++ b/internal/cmd/beta/network/list/list.go @@ -159,7 +159,7 @@ func outputResult(p *print.Printer, outputFormat string, networks []iaas.Network publicIp = *network.PublicIp } - routed := false + routed := true if network.Routed != nil { routed = *network.Routed } From 52713b96b23cba28e359540683fd6263fa050f36 Mon Sep 17 00:00:00 2001 From: GokceGK <161626272+GokceGK@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:28:54 +0100 Subject: [PATCH 10/13] Update internal/cmd/beta/network/create/create_test.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: João Palet --- internal/cmd/beta/network/create/create_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/cmd/beta/network/create/create_test.go b/internal/cmd/beta/network/create/create_test.go index 9158ec67c..8d77f65db 100644 --- a/internal/cmd/beta/network/create/create_test.go +++ b/internal/cmd/beta/network/create/create_test.go @@ -227,13 +227,13 @@ func TestParseInput(t *testing.T) { }), }, { - description: "use routed true", + description: "non-routed network", flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[nonRoutedFlag] = "false" + flagValues[nonRoutedFlag] = "true" }), isValid: true, expectedModel: fixtureInputModel(func(model *inputModel) { - model.NonRouted = false + model.NonRouted = true }), }, } From 091dadf3bca9c8cc7d9b93b7c7f3c6cfe25039b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Go=CC=88kc=CC=A7e=20Go=CC=88k=20Klingel?= Date: Tue, 3 Dec 2024 12:18:54 +0100 Subject: [PATCH 11/13] extend unit tests --- .../cmd/beta/network/create/create_test.go | 104 +++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/internal/cmd/beta/network/create/create_test.go b/internal/cmd/beta/network/create/create_test.go index 8d77f65db..2cd2d606e 100644 --- a/internal/cmd/beta/network/create/create_test.go +++ b/internal/cmd/beta/network/create/create_test.go @@ -285,7 +285,7 @@ func TestParseInput(t *testing.T) { } func TestBuildRequest(t *testing.T) { - tests := []struct { + var tests = []struct { description string model *inputModel expectedRequest iaas.ApiCreateNetworkRequest @@ -306,8 +306,108 @@ func TestBuildRequest(t *testing.T) { }, expectedRequest: fixtureRequiredRequest(), }, + { + description: "non-routed network", + model: &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Verbosity: globalflags.VerbosityDefault, + }, + Name: utils.Ptr("example-network-name"), + NonRouted: true, + }, + expectedRequest: testClient.CreateNetwork(testCtx, testProjectId).CreateNetworkPayload(iaas.CreateNetworkPayload{ + Name: utils.Ptr("example-network-name"), + Routed: utils.Ptr(false), + }), + }, + { + description: "use dns servers, prefix, gateway and prefix length", + model: &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Verbosity: globalflags.VerbosityDefault, + }, + IPv4DnsNameServers: utils.Ptr([]string{"1.1.1.1"}), + IPv4PrefixLength: utils.Ptr(int64(25)), + IPv4Prefix: utils.Ptr("10.1.2.0/24"), + IPv4Gateway: utils.Ptr("10.1.2.3"), + }, + expectedRequest: testClient.CreateNetwork(testCtx, testProjectId).CreateNetworkPayload(iaas.CreateNetworkPayload{ + AddressFamily: &iaas.CreateNetworkAddressFamily{ + Ipv4: &iaas.CreateNetworkIPv4Body{ + Nameservers: utils.Ptr([]string{"1.1.1.1"}), + PrefixLength: utils.Ptr(int64(25)), + Prefix: utils.Ptr("10.1.2.0/24"), + Gateway: iaas.NewNullableString(utils.Ptr("10.1.2.3")), + }, + }, + Routed: utils.Ptr(true), + }), + }, + { + description: "use ipv4 gateway nil", + model: &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Verbosity: globalflags.VerbosityDefault, + }, + NoIPv4Gateway: true, + IPv4Gateway: nil, + }, + expectedRequest: testClient.CreateNetwork(testCtx, testProjectId).CreateNetworkPayload(iaas.CreateNetworkPayload{ + AddressFamily: &iaas.CreateNetworkAddressFamily{ + Ipv4: &iaas.CreateNetworkIPv4Body{ + Gateway: iaas.NewNullableString(nil), + }, + }, + Routed: utils.Ptr(true), + }), + }, + { + description: "use ipv6 dns servers, prefix, gateway and prefix length", + model: &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Verbosity: globalflags.VerbosityDefault, + }, + IPv6DnsNameServers: utils.Ptr([]string{"2001:4860:4860::8888"}), + IPv6PrefixLength: utils.Ptr(int64(25)), + IPv6Prefix: utils.Ptr("2001:4860:4860::8888"), + IPv6Gateway: utils.Ptr("2001:4860:4860::8888"), + }, + expectedRequest: testClient.CreateNetwork(testCtx, testProjectId).CreateNetworkPayload(iaas.CreateNetworkPayload{ + AddressFamily: &iaas.CreateNetworkAddressFamily{ + Ipv6: &iaas.CreateNetworkIPv6Body{ + Nameservers: utils.Ptr([]string{"2001:4860:4860::8888"}), + PrefixLength: utils.Ptr(int64(25)), + Prefix: utils.Ptr("2001:4860:4860::8888"), + Gateway: iaas.NewNullableString(utils.Ptr("2001:4860:4860::8888")), + }, + }, + Routed: utils.Ptr(true), + }), + }, + { + description: "use ipv6 gateway nil", + model: &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + ProjectId: testProjectId, + Verbosity: globalflags.VerbosityDefault, + }, + NoIPv6Gateway: true, + IPv6Gateway: nil, + }, + expectedRequest: testClient.CreateNetwork(testCtx, testProjectId).CreateNetworkPayload(iaas.CreateNetworkPayload{ + AddressFamily: &iaas.CreateNetworkAddressFamily{ + Ipv6: &iaas.CreateNetworkIPv6Body{ + Gateway: iaas.NewNullableString(nil), + }, + }, + Routed: utils.Ptr(true), + }), + }, } - for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { request := buildRequest(testCtx, tt.model, testClient) From 9c72ce7de80ff3252a8c19f3a7f5514a604e0596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Go=CC=88kc=CC=A7e=20Go=CC=88k=20Klingel?= Date: Tue, 3 Dec 2024 12:58:54 +0100 Subject: [PATCH 12/13] set routed values to false --- internal/cmd/beta/network/describe/describe.go | 2 +- internal/cmd/beta/network/list/list.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/cmd/beta/network/describe/describe.go b/internal/cmd/beta/network/describe/describe.go index 49a5570d7..854fd65b0 100644 --- a/internal/cmd/beta/network/describe/describe.go +++ b/internal/cmd/beta/network/describe/describe.go @@ -152,7 +152,7 @@ func outputResult(p *print.Printer, outputFormat string, network *iaas.Network) table.AddSeparator() } - routed := true + routed := false if network.Routed != nil { routed = *network.Routed } diff --git a/internal/cmd/beta/network/list/list.go b/internal/cmd/beta/network/list/list.go index 61326a9e8..889f9e307 100644 --- a/internal/cmd/beta/network/list/list.go +++ b/internal/cmd/beta/network/list/list.go @@ -159,7 +159,7 @@ func outputResult(p *print.Printer, outputFormat string, networks []iaas.Network publicIp = *network.PublicIp } - routed := true + routed := false if network.Routed != nil { routed = *network.Routed } From 93d03628744b6354ce13947b9d5e64e1f6a71c41 Mon Sep 17 00:00:00 2001 From: "test.test@freiheit.com" Date: Tue, 3 Dec 2024 18:53:18 +0000 Subject: [PATCH 13/13] fix: Fix output of async network creation --- internal/cmd/beta/network/create/create.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/cmd/beta/network/create/create.go b/internal/cmd/beta/network/create/create.go index 2e406c39e..74abb08a4 100644 --- a/internal/cmd/beta/network/create/create.go +++ b/internal/cmd/beta/network/create/create.go @@ -253,7 +253,11 @@ func outputResult(p *print.Printer, model *inputModel, projectLabel string, netw return nil default: - p.Outputf("Created network for project %q.\nNetwork ID: %s\n", projectLabel, *network.NetworkId) + operationState := "Created" + if model.Async { + operationState = "Triggered creation of" + } + p.Outputf("%s network for project %q.\nNetwork ID: %s\n", operationState, projectLabel, *network.NetworkId) return nil } }