Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend network commands with new fields #517

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions docs/stackit_beta_network_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 17 additions & 6 deletions docs/stackit_beta_network_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
71 changes: 62 additions & 9 deletions internal/cmd/beta/network/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,31 @@ 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 {
*globalflags.GlobalFlagModel
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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be adjusted here, for no network we have the --no-ipv4-network flag

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.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

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.")
Comment on lines +146 to +147
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Soma flag descriptions are ending in . and other not. I think usually we end them without punctuation across other commands

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)
}
Expand All @@ -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() {
Expand All @@ -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 {
Expand Down
64 changes: 61 additions & 3 deletions internal/cmd/beta/network/create/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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")),
},
},
}
Expand Down Expand Up @@ -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)
}),
},
}
Expand Down Expand Up @@ -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)
Expand Down
16 changes: 16 additions & 0 deletions internal/cmd/beta/network/describe/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, ", "))
}
Expand All @@ -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, ", "))
}
Expand Down
9 changes: 7 additions & 2 deletions internal/cmd/beta/network/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,20 @@ 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 := ""
if network.PublicIp != nil {
publicIp = *network.PublicIp
}

table.AddRow(*network.NetworkId, *network.Name, *network.State, publicIp)
routed := false
if network.Routed != nil {
routed = *network.Routed
}
Comment on lines +162 to +165
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


table.AddRow(*network.NetworkId, *network.Name, *network.State, publicIp, routed)
table.AddSeparator()
}

Expand Down
Loading