Skip to content

Commit

Permalink
Dualstack Support
Browse files Browse the repository at this point in the history
  • Loading branch information
majst01 committed Jul 25, 2024
1 parent dfe9cef commit 46c3887
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 44 deletions.
5 changes: 5 additions & 0 deletions cmd/completion/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package completion

import (
"github.com/metal-stack/metal-go/api/client/ip"
"github.com/metal-stack/metal-go/api/models"
"github.com/spf13/cobra"
)

Expand All @@ -16,3 +17,7 @@ func (c *Completion) IpListCompletion(cmd *cobra.Command, args []string, toCompl
}
return names, cobra.ShellCompDirectiveNoFileComp
}

func (c *Completion) IPAddressFamilyCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{models.V1IPAllocateRequestAddressfamilyIPV4, models.V1IPAllocateRequestAddressfamilyIPV6}, cobra.ShellCompDirectiveNoFileComp
}
4 changes: 2 additions & 2 deletions cmd/completion/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ func (c *Completion) NetworkDestinationPrefixesCompletion(cmd *cobra.Command, ar
}
return prefixes, cobra.ShellCompDirectiveNoFileComp
}
func (c *Completion) AddressFamilyCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{models.V1NetworkImmutableAddressfamilyIPV4, models.V1NetworkImmutableAddressfamilyIPV6}, cobra.ShellCompDirectiveNoFileComp
func (c *Completion) NetworkAddressFamilyCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{models.V1NetworkAllocateRequestAddressfamilyIPV4, models.V1NetworkAllocateRequestAddressfamilyIPV6}, cobra.ShellCompDirectiveNoFileComp
}
34 changes: 22 additions & 12 deletions cmd/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ func newIPCmd(c *config) *cobra.Command {
cmd.Flags().StringP("network", "", "", "network from where the IP should be allocated.")
cmd.Flags().StringP("project", "", "", "project for which the IP should be allocated.")
cmd.Flags().StringSliceP("tags", "", nil, "tags to attach to the IP.")
cmd.Flags().StringP("addressfamily", "", "", "addressfamily of the ip to acquire, defaults to IPv4 [optional]")
genericcli.Must(cmd.RegisterFlagCompletionFunc("network", c.comp.NetworkListCompletion))
genericcli.Must(cmd.RegisterFlagCompletionFunc("project", c.comp.ProjectListCompletion))
genericcli.Must(cmd.RegisterFlagCompletionFunc("type", cobra.FixedCompletions([]string{models.V1IPAllocateRequestTypeEphemeral, models.V1IPAllocateRequestTypeStatic}, cobra.ShellCompDirectiveNoFileComp)))
genericcli.Must(cmd.RegisterFlagCompletionFunc("addressfamily", c.comp.IPAddressFamilyCompletion))
},
ListCmdMutateFn: func(cmd *cobra.Command) {
cmd.Flags().StringP("ipaddress", "", "", "ipaddress to filter [optional]")
Expand Down Expand Up @@ -172,12 +174,13 @@ func ipResponseToCreate(r *models.V1IPResponse) *ipAllocateRequest {
return &ipAllocateRequest{
SpecificIP: ip,
V1IPAllocateRequest: &models.V1IPAllocateRequest{
Description: r.Description,
Name: r.Name,
Networkid: r.Networkid,
Projectid: r.Projectid,
Tags: r.Tags,
Type: r.Type,
Description: r.Description,
Name: r.Name,
Networkid: r.Networkid,
Projectid: r.Projectid,
Tags: r.Tags,
Type: r.Type,
Addressfamily: pointer.Pointer(models.V1IPAllocateRequestAddressfamilyIPV4),
},
}
}
Expand All @@ -193,15 +196,22 @@ func ipResponseToUpdate(r *models.V1IPResponse) *models.V1IPUpdateRequest {
}

func (c *ipCmd) createRequestFromCLI() (*ipAllocateRequest, error) {

var af *string
if viper.IsSet("addressfamily") {
af = pointer.Pointer(viper.GetString("addressfamily"))
}

return &ipAllocateRequest{
SpecificIP: viper.GetString("ipaddress"),
V1IPAllocateRequest: &models.V1IPAllocateRequest{
Description: viper.GetString("description"),
Name: viper.GetString("name"),
Networkid: pointer.Pointer(viper.GetString("network")),
Projectid: pointer.Pointer(viper.GetString("project")),
Type: pointer.Pointer(viper.GetString("type")),
Tags: viper.GetStringSlice("tags"),
Description: viper.GetString("description"),
Name: viper.GetString("name"),
Networkid: pointer.Pointer(viper.GetString("network")),
Projectid: pointer.Pointer(viper.GetString("project")),
Type: pointer.Pointer(viper.GetString("type")),
Tags: viper.GetStringSlice("tags"),
Addressfamily: af,
},
}, nil
}
Expand Down
1 change: 1 addition & 0 deletions cmd/ip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ IP ALLOCATION UUID DESCRIPTION NAME NETWORK PROJECT TYPE
"--project", *want.Projectid,
"--type", *want.Type,
"--tags", strings.Join(want.Tags, ","),
"--addressfamily", models.V1IPAllocateRequestAddressfamilyIPV4,
}
assertExhaustiveArgs(t, args, commonExcludedFileArgs()...)
return args
Expand Down
18 changes: 11 additions & 7 deletions cmd/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func newNetworkCmd(c *config) *cobra.Command {
cmd.Flags().String("addressfamily", "", "addressfamily to filter, either ipv4 or ipv6 [optional]")
genericcli.Must(cmd.RegisterFlagCompletionFunc("project", c.comp.ProjectListCompletion))
genericcli.Must(cmd.RegisterFlagCompletionFunc("partition", c.comp.PartitionListCompletion))
genericcli.Must(cmd.RegisterFlagCompletionFunc("addressfamily", c.comp.AddressFamilyCompletion))
genericcli.Must(cmd.RegisterFlagCompletionFunc("addressfamily", c.comp.NetworkAddressFamilyCompletion))
},
UpdateCmdMutateFn: func(cmd *cobra.Command) {
cmd.Flags().String("name", "", "the name of the network [optional]")
Expand Down Expand Up @@ -107,10 +107,13 @@ func newNetworkCmd(c *config) *cobra.Command {

var (
af *string
length *int64
length = make(map[string]int64)
)
if viper.IsSet("length") {
length = pointer.Pointer(viper.GetInt64("length"))
if viper.IsSet("ipv4length") {
length[models.V1IPAllocateRequestAddressfamilyIPV4] = viper.GetInt64("ipv4length")
}
if viper.IsSet("ipv6length") {
length[models.V1IPAllocateRequestAddressfamilyIPV6] = viper.GetInt64("ipv6length")
}
if viper.IsSet("addressfamily") {
af = pointer.Pointer(viper.GetString("addressfamily"))
Expand All @@ -125,7 +128,7 @@ func newNetworkCmd(c *config) *cobra.Command {
Labels: labels,
Destinationprefixes: destinationPrefixes,
Nat: nat,
AddressFamily: af,
Addressfamily: af,
Length: length,
}, c.describePrinter)
}
Expand Down Expand Up @@ -156,9 +159,11 @@ func newNetworkCmd(c *config) *cobra.Command {
allocateCmd.Flags().BoolP("dmz", "", false, "use this private network as dmz. [optional]")
allocateCmd.Flags().BoolP("shared", "", false, "shared allows usage of this private network from other networks")
allocateCmd.Flags().StringP("addressfamily", "", "ipv4", "addressfamily of the network to acquire [optional]")
allocateCmd.Flags().Int64P("length", "", 22, "bitlength of network to create. [optional]")
allocateCmd.Flags().Int64P("ipv4length", "", 22, "ipv4 bitlength of network to create. [optional]")
allocateCmd.Flags().Int64P("ipv6length", "", 64, "ip6 bitlength of network to create. [optional]")
genericcli.Must(allocateCmd.RegisterFlagCompletionFunc("project", c.comp.ProjectListCompletion))
genericcli.Must(allocateCmd.RegisterFlagCompletionFunc("partition", c.comp.PartitionListCompletion))
genericcli.Must(allocateCmd.RegisterFlagCompletionFunc("addressfamily", c.comp.NetworkAddressFamilyCompletion))

genericcli.Must(allocateCmd.MarkFlagRequired("name"))
genericcli.Must(allocateCmd.MarkFlagRequired("project"))
Expand Down Expand Up @@ -194,7 +199,6 @@ func (c networkCmd) List() ([]*models.V1NetworkResponse, error) {
Prefixes: viper.GetStringSlice("prefixes"),
Destinationprefixes: viper.GetStringSlice("destination-prefixes"),
Parentnetworkid: viper.GetString("parent"),
Addressfamily: viper.GetString("addressfamily"),
}), nil)
if err != nil {
return nil, err
Expand Down
32 changes: 16 additions & 16 deletions cmd/tableprinters/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,29 +64,29 @@ func addNetwork(prefix string, n *models.V1NetworkResponse, wide bool) []string
}
privateSuper := fmt.Sprintf("%t", flag)
nat := fmt.Sprintf("%t", *n.Nat)

usage := fmt.Sprintf("IPs: %v/%v", *n.Usage.UsedIps, *n.Usage.AvailableIps)

ipUse := float64(*n.Usage.UsedIps) / float64(*n.Usage.AvailableIps)
shortIPUsage := nbr
if ipUse >= 0.9 {
shortIPUsage += color.RedString(dot)
} else if ipUse >= 0.7 {
shortIPUsage += color.YellowString(dot)
// FIXME add ipv6 usage
ipv4usage := fmt.Sprintf("IPs: %v/%v", *n.Usage.UsedIps, *n.Usage.AvailableIps)

ipv4Use := float64(*n.Usage.UsedIps) / float64(*n.Usage.AvailableIps)
shortIPv4IPUsage := nbr
if ipv4Use >= 0.9 {
shortIPv4IPUsage += color.RedString(dot)
} else if ipv4Use >= 0.7 {
shortIPv4IPUsage += color.YellowString(dot)
} else {
shortIPUsage += color.GreenString(dot)
shortIPv4IPUsage += color.GreenString(dot)
}

shortPrefixUsage := ""
shortIPv4PrefixUsage := ""
if *n.Usage.AvailablePrefixes > 0 {
prefixUse := float64(*n.Usage.UsedPrefixes) / float64(*n.Usage.AvailablePrefixes)
if prefixUse >= 0.9 {
shortPrefixUsage = color.RedString(dot)
shortIPv4PrefixUsage = color.RedString(dot)
}
usage = fmt.Sprintf("%s\nPrefixes:%d/%d", usage, *n.Usage.UsedPrefixes, *n.Usage.AvailablePrefixes)
ipv4usage = fmt.Sprintf("%s\nPrefixes:%d/%d", ipv4usage, *n.Usage.UsedPrefixes, *n.Usage.AvailablePrefixes)
}

max := getMaxLineCount(n.Description, n.Name, n.Projectid, n.Partitionid, nat, prefixes, usage, privateSuper)
max := getMaxLineCount(n.Description, n.Name, n.Projectid, n.Partitionid, nat, prefixes, ipv4usage, privateSuper)
for i := 0; i < max-1; i++ {
id += "\n│"
}
Expand All @@ -102,9 +102,9 @@ func addNetwork(prefix string, n *models.V1NetworkResponse, wide bool) []string
annotations := strings.Join(as, "\n")

if wide {
return []string{id, n.Description, n.Name, n.Projectid, n.Partitionid, nat, shared, prefixes, usage, privateSuper, annotations}
return []string{id, n.Description, n.Name, n.Projectid, n.Partitionid, nat, shared, prefixes, ipv4usage, privateSuper, annotations}
} else {
return []string{id, n.Name, n.Projectid, n.Partitionid, nat, shared, prefixes, shortPrefixUsage, shortIPUsage}
return []string{id, n.Name, n.Projectid, n.Partitionid, nat, shared, prefixes, shortIPv4PrefixUsage, shortIPv4IPUsage}
}
}

Expand Down
3 changes: 2 additions & 1 deletion docs/metalctl_network_allocate.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ metalctl network allocate [flags]
-d, --description string description of the network to create. [optional]
--dmz use this private network as dmz. [optional]
-h, --help help for allocate
--ipv4length int ipv4 bitlength of network to create. [optional] (default 22)
--ipv6length int ip6 bitlength of network to create. [optional] (default 64)
--labels strings labels for this network. [optional]
--length int bitlength of network to create. [optional] (default 22)
-n, --name string name of the network to create. [required]
--partition string partition where this network should exist. [required]
--project string partition where this network should exist. [required]
Expand Down
1 change: 1 addition & 0 deletions docs/metalctl_network_ip_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ metalctl network ip create [flags]
### Options

```
--addressfamily string addressfamily of the ip to acquire, defaults to IPv4 [optional]
--bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
-d, --description string description of the IP to allocate. [optional]
-f, --file string filename of the create or update request in yaml format, or - for stdin.
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ require (
github.com/go-openapi/strfmt v0.23.0
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.6.0
github.com/metal-stack/metal-go v0.32.2-0.20240711103636-2b8da1b20985
github.com/metal-stack/metal-lib v0.17.1
github.com/metal-stack/metal-go v0.32.3-0.20240725054241-040df42094d5
github.com/metal-stack/metal-lib v0.17.2
github.com/metal-stack/updater v1.2.2
github.com/metal-stack/v v1.0.3
github.com/olekukonko/tablewriter v0.0.6-0.20230925090304-df64c4bbad77
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,10 @@ github.com/mdlayher/sdnotify v1.0.0 h1:Ma9XeLVN/l0qpyx1tNeMSeTjCPH6NtuD6/N9XdTlQ
github.com/mdlayher/sdnotify v1.0.0/go.mod h1:HQUmpM4XgYkhDLtd+Uad8ZFK1T9D5+pNxnXQjCeJlGE=
github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ=
github.com/metal-stack/metal-go v0.32.2-0.20240711103636-2b8da1b20985 h1:pUAez+Jc8XqJkaxBb6OPZeDECrvx8M6N89jgW7FjtYY=
github.com/metal-stack/metal-go v0.32.2-0.20240711103636-2b8da1b20985/go.mod h1:3MJTYCS4YJz8D8oteTKhjpaAKNMMjMKYDrIy9awHGtQ=
github.com/metal-stack/metal-lib v0.17.1 h1:JLa4wJ62dgxtY9UOLF+QDk10/i/W5vhzrv8RsundDUY=
github.com/metal-stack/metal-lib v0.17.1/go.mod h1:nyNGI4DZFOcWbSoq2Y6V3SHpFxuXBIqYBZHTb6cy//s=
github.com/metal-stack/metal-go v0.32.3-0.20240725054241-040df42094d5 h1:cCX6wyczMdTtMrupE7vRUFmE1pZQ2XVYjzRmPoT+/3Y=
github.com/metal-stack/metal-go v0.32.3-0.20240725054241-040df42094d5/go.mod h1:3MJTYCS4YJz8D8oteTKhjpaAKNMMjMKYDrIy9awHGtQ=
github.com/metal-stack/metal-lib v0.17.2 h1:T1rxCPgagHW/M0wWSrOj4hWsPZMSt1pYw90Z3vBm88Q=
github.com/metal-stack/metal-lib v0.17.2/go.mod h1:nyNGI4DZFOcWbSoq2Y6V3SHpFxuXBIqYBZHTb6cy//s=
github.com/metal-stack/security v0.8.0 h1:tVaSDB9m5clwYrnLyaXfPy7mQlJTnmeoHscG+RUy/xo=
github.com/metal-stack/security v0.8.0/go.mod h1:7GAcQb+pOgflW30ohJygxpqc3i0dQ2ahGJK1CU5tqa0=
github.com/metal-stack/updater v1.2.2 h1:gnUrnQgfT20QFMDtFBY89opKoBAkdeI/8T2iwMHNdxs=
Expand Down

0 comments on commit 46c3887

Please sign in to comment.