diff --git a/Dockerfile b/Dockerfile index be670f0c..8cbfa75f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.20 +FROM alpine:3.21 LABEL maintainer="metal-stack authors " COPY bin/metalctl-linux-amd64 /metalctl ENTRYPOINT ["/metalctl"] diff --git a/Dockerfile.test b/Dockerfile.test index 4aa48d46..87eb6a44 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -1,4 +1,4 @@ -FROM golang:1.23 +FROM golang:1.24 WORKDIR /work COPY go.* . RUN go mod download diff --git a/cmd/completion/ip.go b/cmd/completion/ip.go index 993878bf..981129c8 100644 --- a/cmd/completion/ip.go +++ b/cmd/completion/ip.go @@ -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" ) @@ -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 +} diff --git a/cmd/completion/network.go b/cmd/completion/network.go index 04422eaf..8565ebe9 100644 --- a/cmd/completion/network.go +++ b/cmd/completion/network.go @@ -2,6 +2,8 @@ package completion import ( "github.com/metal-stack/metal-go/api/client/network" + "github.com/metal-stack/metal-go/api/models" + "github.com/spf13/cobra" ) @@ -28,3 +30,6 @@ func (c *Completion) NetworkDestinationPrefixesCompletion(cmd *cobra.Command, ar } return prefixes, cobra.ShellCompDirectiveNoFileComp } +func (c *Completion) NetworkAddressFamilyCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{models.V1NetworkAllocateRequestAddressfamilyIPV4, models.V1NetworkAllocateRequestAddressfamilyIPV6}, cobra.ShellCompDirectiveNoFileComp +} diff --git a/cmd/ip.go b/cmd/ip.go index c09f33a0..8abd4395 100644 --- a/cmd/ip.go +++ b/cmd/ip.go @@ -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]") @@ -62,11 +64,13 @@ func newIPCmd(c *config) *cobra.Command { cmd.Flags().StringP("network", "", "", "network to filter [optional]") cmd.Flags().StringP("name", "", "", "name to filter [optional]") cmd.Flags().StringSliceP("tags", "", nil, "tags to filter [optional]") + cmd.Flags().StringP("addressfamily", "", "", "addressfamily of the ip to filter, defaults to all addressfamilies [optional]") genericcli.Must(cmd.RegisterFlagCompletionFunc("ipaddress", c.comp.IpListCompletion)) 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("machineid", c.comp.MachineListCompletion)) + genericcli.Must(cmd.RegisterFlagCompletionFunc("addressfamily", c.comp.IPAddressFamilyCompletion)) }, DeleteCmdMutateFn: func(cmd *cobra.Command) { cmd.Aliases = append(cmd.Aliases, "free") @@ -105,6 +109,7 @@ func (c *ipCmd) List() ([]*models.V1IPResponse, error) { Machineid: viper.GetString("machineid"), Networkprefix: viper.GetString("prefix"), Tags: viper.GetStringSlice("tags"), + Addressfamily: viper.GetString("addressfamily"), }), nil) if err != nil { return nil, err @@ -169,6 +174,7 @@ func ipResponseToCreate(r *models.V1IPResponse) *ipAllocateRequest { if r.Ipaddress != nil { ip = *r.Ipaddress } + return &ipAllocateRequest{ SpecificIP: ip, V1IPAllocateRequest: &models.V1IPAllocateRequest{ @@ -196,12 +202,13 @@ func (c *ipCmd) createRequestFromCLI() (*ipAllocateRequest, error) { 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: viper.GetString("addressfamily"), }, }, nil } diff --git a/cmd/ip_test.go b/cmd/ip_test.go index bd19ff72..5af70218 100644 --- a/cmd/ip_test.go +++ b/cmd/ip_test.go @@ -229,7 +229,7 @@ IP ALLOCATION UUID DESCRIPTION NAME NETWORK PROJECT TYPE "--type", *want.Type, "--tags", strings.Join(want.Tags, ","), } - assertExhaustiveArgs(t, args, commonExcludedFileArgs()...) + assertExhaustiveArgs(t, args, append(commonExcludedFileArgs(), "addressfamily")...) return args }, mocks: &client.MetalMockFns{ diff --git a/cmd/network.go b/cmd/network.go index 11d0531a..90051a26 100644 --- a/cmd/network.go +++ b/cmd/network.go @@ -46,6 +46,8 @@ func newNetworkCmd(c *config) *cobra.Command { cmd.Flags().StringP("name", "n", "", "name of the network to create. [optional]") cmd.Flags().StringP("partition", "p", "", "partition where this network should exist.") cmd.Flags().StringP("project", "", "", "project of the network to create. [optional]") + cmd.Flags().Int64("default-ipv4-child-prefix-length", 0, "default child prefix length for ipv4 prefixes for private super networks.") + cmd.Flags().Int64("default-ipv6-child-prefix-length", 0, "default child prefix length for ipv6 prefixes for private super networks.") cmd.Flags().StringSlice("prefixes", []string{}, "prefixes in this network.") cmd.Flags().StringSlice("labels", []string{}, "add initial labels, must be in the form of key=value, use it like: --labels \"key1=value1,key2=value2\".") cmd.Flags().StringSlice("destination-prefixes", []string{}, "destination prefixes in this network.") @@ -70,8 +72,10 @@ func newNetworkCmd(c *config) *cobra.Command { cmd.Flags().Int64P("vrf", "", 0, "vrf to filter [optional]") cmd.Flags().StringSlice("prefixes", []string{}, "prefixes to filter, use it like: --prefixes prefix1,prefix2.") cmd.Flags().StringSlice("destination-prefixes", []string{}, "destination prefixes to filter, use it like: --destination-prefixes prefix1,prefix2.") + 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.NetworkAddressFamilyCompletion)) }, UpdateCmdMutateFn: func(cmd *cobra.Command) { cmd.Flags().String("name", "", "the name of the network [optional]") @@ -105,6 +109,16 @@ func newNetworkCmd(c *config) *cobra.Command { return err } + var ( + length = make(map[string]int64) + ) + if viper.IsSet("ipv4-prefix-length") { + length[models.V1IPAllocateRequestAddressfamilyIPV4] = viper.GetInt64("ipv4-prefix-length") + } + if viper.IsSet("ipv6-prefix-length") { + length[models.V1IPAllocateRequestAddressfamilyIPV6] = viper.GetInt64("ipv6-prefix-length") + } + return w.childCLI.CreateAndPrint(&models.V1NetworkAllocateRequest{ Description: viper.GetString("description"), Name: viper.GetString("name"), @@ -114,6 +128,8 @@ func newNetworkCmd(c *config) *cobra.Command { Labels: labels, Destinationprefixes: destinationPrefixes, Nat: nat, + Addressfamily: viper.GetString("addressfamily"), + Length: length, }, c.describePrinter) } @@ -142,8 +158,12 @@ func newNetworkCmd(c *config) *cobra.Command { allocateCmd.Flags().StringSlice("labels", []string{}, "labels for this network. [optional]") 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", "", "", "addressfamily of the network to acquire, if not specified the network inherits the address families from the parent [optional]") + allocateCmd.Flags().Int64P("ipv4-prefix-length", "", 0, "ipv4 prefix bit length of the network to create, defaults to default child prefix length of the parent network. [optional]") + allocateCmd.Flags().Int64P("ipv6-prefix-length", "", 0, "ipv6 prefix bit length of the network to create, defaults to default child prefix length of the parent network. [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")) @@ -179,6 +199,7 @@ 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 @@ -235,6 +256,7 @@ func networkResponseToCreate(r *models.V1NetworkResponse) *models.V1NetworkCreat Nat: r.Nat, Parentnetworkid: r.Parentnetworkid, Partitionid: r.Partitionid, + Defaultchildprefixlength: r.Defaultchildprefixlength, Prefixes: r.Prefixes, Privatesuper: r.Privatesuper, Projectid: r.Projectid, @@ -256,6 +278,7 @@ func networkResponseToUpdate(r *models.V1NetworkResponse) *models.V1NetworkUpdat Prefixes: r.Prefixes, Shared: r.Shared, AdditionalAnnouncableCIDRs: r.AdditionalAnnouncableCIDRs, + Defaultchildprefixlength: r.Defaultchildprefixlength, } } @@ -265,6 +288,18 @@ func (c *networkCmd) createRequestFromCLI() (*models.V1NetworkCreateRequest, err return nil, err } + var defaultChildPrefixLengths map[string]int64 + if viper.GetBool("privatesuper") { + defaultChildPrefixLengths = map[string]int64{} + + if length := viper.GetInt64("default-ipv4-child-prefix-length"); length > 0 { + defaultChildPrefixLengths[models.V1IPAllocateRequestAddressfamilyIPV4] = length + } + if length := viper.GetInt64("default-ipv6-child-prefix-length"); length > 0 { + defaultChildPrefixLengths[models.V1IPAllocateRequestAddressfamilyIPV6] = length + } + } + return &models.V1NetworkCreateRequest{ ID: pointer.Pointer(viper.GetString("id")), Description: viper.GetString("description"), @@ -280,6 +315,7 @@ func (c *networkCmd) createRequestFromCLI() (*models.V1NetworkCreateRequest, err Vrfshared: viper.GetBool("vrfshared"), Labels: lbs, AdditionalAnnouncableCIDRs: viper.GetStringSlice("additional-announcable-cidrs"), + Defaultchildprefixlength: defaultChildPrefixLengths, }, nil } @@ -375,6 +411,7 @@ func (c *networkCmd) updateRequestFromCLI(args []string) (*models.V1NetworkUpdat Prefixes: nil, Shared: shared, AdditionalAnnouncableCIDRs: additionalCidrs, + Defaultchildprefixlength: resp.Defaultchildprefixlength, } addPrefixes = sets.New(viper.GetStringSlice("add-prefixes")...) removePrefixes = sets.New(viper.GetStringSlice("remove-prefixes")...) diff --git a/cmd/network_test.go b/cmd/network_test.go index e163b704..d73cb786 100644 --- a/cmd/network_test.go +++ b/cmd/network_test.go @@ -33,15 +33,21 @@ var ( Projectid: "", Shared: false, Underlay: pointer.Pointer(true), - Usage: &models.V1NetworkUsage{ - AvailableIps: pointer.Pointer(int64(100)), - AvailablePrefixes: pointer.Pointer(int64(200)), - UsedIps: pointer.Pointer(int64(300)), - UsedPrefixes: pointer.Pointer(int64(400)), + Consumption: &models.V1NetworkConsumption{ + IPV4: &models.V1NetworkUsage{ + AvailableIps: pointer.Pointer(int64(100)), + AvailablePrefixes: pointer.Pointer(int64(200)), + UsedIps: pointer.Pointer(int64(300)), + UsedPrefixes: pointer.Pointer(int64(400)), + }, }, Vrf: 50, Vrfshared: true, AdditionalAnnouncableCIDRs: []string{"10.240.0.0/12"}, + Defaultchildprefixlength: map[string]int64{ + "IPv4": 22, + "IPv6": 96, + }, } network1child = &models.V1NetworkResponse{ Description: "child 1", @@ -57,11 +63,13 @@ var ( Projectid: "project-1", Shared: false, Underlay: pointer.Pointer(false), - Usage: &models.V1NetworkUsage{ - AvailableIps: pointer.Pointer(int64(100)), - AvailablePrefixes: pointer.Pointer(int64(200)), - UsedIps: pointer.Pointer(int64(300)), - UsedPrefixes: pointer.Pointer(int64(400)), + Consumption: &models.V1NetworkConsumption{ + IPV4: &models.V1NetworkUsage{ + AvailableIps: pointer.Pointer(int64(100)), + AvailablePrefixes: pointer.Pointer(int64(200)), + UsedIps: pointer.Pointer(int64(300)), + UsedPrefixes: pointer.Pointer(int64(400)), + }, }, Vrf: 50, Vrfshared: true, @@ -81,11 +89,13 @@ var ( Projectid: "project-1", Shared: false, Underlay: pointer.Pointer(false), - Usage: &models.V1NetworkUsage{ - AvailableIps: pointer.Pointer(int64(400)), - AvailablePrefixes: pointer.Pointer(int64(300)), - UsedIps: pointer.Pointer(int64(200)), - UsedPrefixes: pointer.Pointer(int64(100)), + Consumption: &models.V1NetworkConsumption{ + IPV4: &models.V1NetworkUsage{ + AvailableIps: pointer.Pointer(int64(400)), + AvailablePrefixes: pointer.Pointer(int64(300)), + UsedIps: pointer.Pointer(int64(200)), + UsedPrefixes: pointer.Pointer(int64(100)), + }, }, Vrf: 60, Vrfshared: true, @@ -120,19 +130,16 @@ func Test_NetworkCmd_MultiResult(t *testing.T) { network2, }, wantTable: pointer.Pointer(` -ID NAME PROJECT PARTITION NAT SHARED PREFIXES IPS -nw1 network-1 partition-1 true false prefix ● ● -└─╴child1 network-1 project-1 partition-1 true false prefix ● ● -nw2 network-2 project-1 partition-1 false false prefix ● +ID NAME PROJECT PARTITION NAT SHARED PREFIXES IP USAGE +nw1 network-1 partition-1 true false ◕ prefix ◕ +└─╴child1 network-1 project-1 partition-1 true false ◕ prefix ◕ +nw2 network-2 project-1 partition-1 false false ● prefix ● `), wantWideTable: pointer.Pointer(` -ID DESCRIPTION NAME PROJECT PARTITION NAT SHARED PREFIXES USAGE PRIVATESUPER ANNOTATIONS -nw1 network 1 network-1 partition-1 true false prefix IPs: 300/100 true a=b - Prefixes:400/200 -└─╴child1 child 1 network-1 project-1 partition-1 true false prefix IPs: 300/100 false e=f - Prefixes:400/200 -nw2 network 2 network-2 project-1 partition-1 false false prefix IPs: 200/400 false c=d - Prefixes:100/300 +ID DESCRIPTION NAME PROJECT PARTITION NAT SHARED PREFIXES PRIVATESUPER ANNOTATIONS +nw1 network 1 network-1 partition-1 true false prefix true a=b +└─╴child1 child 1 network-1 project-1 partition-1 true false prefix false e=f +nw2 network 2 network-2 project-1 partition-1 false false prefix false c=d `), template: pointer.Pointer("{{ .id }} {{ .name }}"), wantTemplate: pointer.Pointer(` @@ -141,11 +148,11 @@ nw1 network-1 nw2 network-2 `), wantMarkdown: pointer.Pointer(` -| ID | NAME | PROJECT | PARTITION | NAT | SHARED | PREFIXES | | IPS | -|-----------|-----------|-----------|-------------|-------|--------|----------|---|-----| -| nw1 | network-1 | | partition-1 | true | false | prefix | ● | ● | -| └─╴child1 | network-1 | project-1 | partition-1 | true | false | prefix | ● | ● | -| nw2 | network-2 | project-1 | partition-1 | false | false | prefix | | ● | +| ID | NAME | PROJECT | PARTITION | NAT | SHARED | | PREFIXES | IP USAGE | +|-----------|-----------|-----------|-------------|-------|--------|---|----------|----------| +| nw1 | network-1 | | partition-1 | true | false | ◕ | prefix | ◕ | +| └─╴child1 | network-1 | project-1 | partition-1 | true | false | ◕ | prefix | ◕ | +| nw2 | network-2 | project-1 | partition-1 | false | false | ● | prefix | ● | `), }, { @@ -251,22 +258,21 @@ func Test_NetworkCmd_SingleResult(t *testing.T) { }, want: network1, wantTable: pointer.Pointer(` -ID NAME PROJECT PARTITION NAT SHARED PREFIXES IPS -nw1 network-1 partition-1 true false prefix ●  ● +ID NAME PROJECT PARTITION NAT SHARED PREFIXES IP USAGE +nw1 network-1 partition-1 true false ◕ prefix ◕ `), wantWideTable: pointer.Pointer(` -ID DESCRIPTION NAME PROJECT PARTITION NAT SHARED PREFIXES USAGE PRIVATESUPER ANNOTATIONS -nw1 network 1 network-1 partition-1 true false prefix IPs: 300/100 true a=b - Prefixes:400/200 +ID DESCRIPTION NAME PROJECT PARTITION NAT SHARED PREFIXES PRIVATESUPER ANNOTATIONS +nw1 network 1 network-1 partition-1 true false prefix true a=b `), template: pointer.Pointer("{{ .id }} {{ .name }}"), wantTemplate: pointer.Pointer(` nw1 network-1 `), wantMarkdown: pointer.Pointer(` -| ID | NAME | PROJECT | PARTITION | NAT | SHARED | PREFIXES | | IPS | -|-----|-----------|---------|-------------|------|--------|----------|---|-----| -| nw1 | network-1 | | partition-1 | true | false | prefix | ● | ● | +| ID | NAME | PROJECT | PARTITION | NAT | SHARED | | PREFIXES | IP USAGE | +|-----|-----------|---------|-------------|------|--------|---|----------|----------| +| nw1 | network-1 | | partition-1 | true | false | ◕ | prefix | ◕ | `), }, { @@ -301,6 +307,8 @@ nw1 network-1 "--vrf", strconv.FormatInt(want.Vrf, 10), "--vrfshared", strconv.FormatBool(want.Vrfshared), "--additional-announcable-cidrs", "10.240.0.0/12", + "--default-ipv4-child-prefix-length", "22", + "--default-ipv6-child-prefix-length", "96", } assertExhaustiveArgs(t, args, commonExcludedFileArgs()...) return args @@ -350,6 +358,7 @@ nw1 network-1 Labels: network1.Labels, Shared: network1.Shared, AdditionalAnnouncableCIDRs: network1.AdditionalAnnouncableCIDRs, + Defaultchildprefixlength: network1.Defaultchildprefixlength, }).WithForce(pointer.Pointer(false))), nil).Return(&network.UpdateNetworkOK{ Payload: network1, }, nil) diff --git a/cmd/partition.go b/cmd/partition.go index a251adb5..8d08c307 100644 --- a/cmd/partition.go +++ b/cmd/partition.go @@ -132,13 +132,12 @@ func partitionResponseToCreate(r *models.V1PartitionResponse) *models.V1Partitio Imageurl: r.Bootconfig.Imageurl, Kernelurl: r.Bootconfig.Kernelurl, }, - Description: r.Description, - ID: r.ID, - Mgmtserviceaddress: r.Mgmtserviceaddress, - Name: r.Name, - Privatenetworkprefixlength: r.Privatenetworkprefixlength, - DNSServers: r.DNSServers, - NtpServers: r.NtpServers, + Description: r.Description, + ID: r.ID, + Mgmtserviceaddress: r.Mgmtserviceaddress, + Name: r.Name, + DNSServers: r.DNSServers, + NtpServers: r.NtpServers, } } diff --git a/cmd/partition_test.go b/cmd/partition_test.go index 8d2d4c55..2bcdd0f7 100644 --- a/cmd/partition_test.go +++ b/cmd/partition_test.go @@ -22,11 +22,10 @@ var ( Imageurl: "imageurl", Kernelurl: "kernelurl", }, - Description: "partition 1", - ID: pointer.Pointer("1"), - Mgmtserviceaddress: "mgmt", - Name: "partition-1", - Privatenetworkprefixlength: 24, + Description: "partition 1", + ID: pointer.Pointer("1"), + Mgmtserviceaddress: "mgmt", + Name: "partition-1", Labels: map[string]string{ "a": "b", }, @@ -37,11 +36,10 @@ var ( Imageurl: "imageurl", Kernelurl: "kernelurl", }, - Description: "partition 2", - ID: pointer.Pointer("2"), - Mgmtserviceaddress: "mgmt", - Name: "partition-2", - Privatenetworkprefixlength: 24, + Description: "partition 2", + ID: pointer.Pointer("2"), + Mgmtserviceaddress: "mgmt", + Name: "partition-2", } ) @@ -254,7 +252,6 @@ ID NAME DESCRIPTION LABELS mocks: &client.MetalMockFns{ Partition: func(mock *mock.Mock) { p := partition1 - p.Privatenetworkprefixlength = 0 mock.On("CreatePartition", testcommon.MatchIgnoreContext(t, partition.NewCreatePartitionParams().WithBody(partitionResponseToCreate(p))), nil).Return(&partition.CreatePartitionCreated{ Payload: partition1, }, nil) diff --git a/cmd/tableprinters/common.go b/cmd/tableprinters/common.go index be6a30b9..3371c54f 100644 --- a/cmd/tableprinters/common.go +++ b/cmd/tableprinters/common.go @@ -9,10 +9,12 @@ import ( ) const ( - dot = "●" - nbr = " " - poweron = "⏻" - powersleep = "⏾" + dot = "●" + halfpie = "◒" + threequarterpie = "◕" + nbr = " " + poweron = "⏻" + powersleep = "⏾" ) func depth(path string) uint { diff --git a/cmd/tableprinters/network.go b/cmd/tableprinters/network.go index f21f6b96..e140f3fc 100644 --- a/cmd/tableprinters/network.go +++ b/cmd/tableprinters/network.go @@ -21,9 +21,9 @@ func (t *TablePrinter) NetworkTable(data []*models.V1NetworkResponse, wide bool) rows [][]string ) - header := []string{"ID", "Name", "Project", "Partition", "Nat", "Shared", "Prefixes", "", "IPs"} + header := []string{"ID", "Name", "Project", "Partition", "Nat", "Shared", "", "Prefixes", "IP Usage"} if wide { - header = []string{"ID", "Description", "Name", "Project", "Partition", "Nat", "Shared", "Prefixes", "Usage", "PrivateSuper", "Annotations"} + header = []string{"ID", "Description", "Name", "Project", "Partition", "Nat", "Shared", "Prefixes", "PrivateSuper", "Annotations"} } nn := &networks{} @@ -65,28 +65,50 @@ 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) - } else { - shortIPUsage += color.GreenString(dot) - } + shortPrefixUsage := nbr + ipv4Use := 0.0 + ipv4PrefixUse := 0.0 + ipv6Use := 0.0 + ipv6PrefixUse := 0.0 + + if n.Consumption != nil { + consumption := *n.Consumption + if consumption.IPV4 != nil { + ipv4Consumption := *consumption.IPV4 + ipv4Use = float64(*ipv4Consumption.UsedIps) / float64(*ipv4Consumption.AvailableIps) + + if *ipv4Consumption.AvailablePrefixes > 0 { + ipv4PrefixUse = float64(*ipv4Consumption.UsedPrefixes) / float64(*ipv4Consumption.AvailablePrefixes) + } + } + if consumption.IPV6 != nil { + ipv6Consumption := *consumption.IPV6 + ipv6Use = float64(*ipv6Consumption.UsedIps) / float64(*ipv6Consumption.AvailableIps) + + if *ipv6Consumption.AvailablePrefixes > 0 { + ipv6PrefixUse = float64(*ipv6Consumption.UsedPrefixes) / float64(*ipv6Consumption.AvailablePrefixes) + } + } + + if ipv4Use >= 0.9 || ipv6Use >= 0.9 { + shortIPUsage = color.RedString(threequarterpie) + } else if ipv4Use >= 0.7 || ipv6Use >= 0.7 { + shortIPUsage += color.YellowString(halfpie) + } else { + shortIPUsage += color.GreenString(dot) + } - shortPrefixUsage := "" - if *n.Usage.AvailablePrefixes > 0 { - prefixUse := float64(*n.Usage.UsedPrefixes) / float64(*n.Usage.AvailablePrefixes) - if prefixUse >= 0.9 { - shortPrefixUsage = color.RedString(dot) + if ipv4PrefixUse >= 0.9 || ipv6PrefixUse >= 0.9 { + shortPrefixUsage = color.RedString(threequarterpie) + } else if ipv4PrefixUse >= 0.7 || ipv6PrefixUse >= 0.7 { + shortPrefixUsage = color.YellowString(halfpie) + } else { + shortPrefixUsage = color.GreenString(dot) } - usage = fmt.Sprintf("%s\nPrefixes:%d/%d", usage, *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, shortIPUsage, privateSuper) for i := 0; i < max-1; i++ { id += "\n│" } @@ -102,9 +124,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, 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, shortPrefixUsage, prefixes, shortIPUsage} } } diff --git a/docs/metalctl_network_allocate.md b/docs/metalctl_network_allocate.md index 7fc60398..c5d7e7f0 100644 --- a/docs/metalctl_network_allocate.md +++ b/docs/metalctl_network_allocate.md @@ -9,14 +9,17 @@ metalctl network allocate [flags] ### Options ``` - -d, --description string description of the network to create. [optional] - --dmz use this private network as dmz. [optional] - -h, --help help for allocate - --labels strings labels for this network. [optional] - -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] - --shared shared allows usage of this private network from other networks + --addressfamily string addressfamily of the network to acquire, if not specified the network inherits the address families from the parent [optional] + -d, --description string description of the network to create. [optional] + --dmz use this private network as dmz. [optional] + -h, --help help for allocate + --ipv4-prefix-length int ipv4 prefix bit length of the network to create, defaults to default child prefix length of the parent network. [optional] + --ipv6-prefix-length int ipv6 prefix bit length of the network to create, defaults to default child prefix length of the parent network. [optional] + --labels strings labels for this network. [optional] + -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] + --shared shared allows usage of this private network from other networks ``` ### Options inherited from parent commands diff --git a/docs/metalctl_network_create.md b/docs/metalctl_network_create.md index 11010d24..eed6fb92 100644 --- a/docs/metalctl_network_create.md +++ b/docs/metalctl_network_create.md @@ -11,6 +11,8 @@ metalctl network create [flags] ``` --additional-announcable-cidrs strings list of cidrs which are added to the route maps per tenant private network, these are typically pod- and service cidrs, can only be set in a supernetwork --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. + --default-ipv4-child-prefix-length int default child prefix length for ipv4 prefixes for private super networks. + --default-ipv6-child-prefix-length int default child prefix length for ipv6 prefixes for private super networks. -d, --description string description of the network to create. [optional] --destination-prefixes strings destination prefixes in this network. -f, --file string filename of the create or update request in yaml format, or - for stdin. diff --git a/docs/metalctl_network_ip_create.md b/docs/metalctl_network_ip_create.md index 9d515203..2b37eccd 100644 --- a/docs/metalctl_network_ip_create.md +++ b/docs/metalctl_network_ip_create.md @@ -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. diff --git a/docs/metalctl_network_ip_list.md b/docs/metalctl_network_ip_list.md index 3acfee4c..52ea88ff 100644 --- a/docs/metalctl_network_ip_list.md +++ b/docs/metalctl_network_ip_list.md @@ -9,16 +9,17 @@ metalctl network ip list [flags] ### Options ``` - -h, --help help for list - --ipaddress string ipaddress to filter [optional] - --machineid string machineid to filter [optional] - --name string name to filter [optional] - --network string network to filter [optional] - --prefix string prefix to filter [optional] - --project string project to filter [optional] - --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|description|id|ipaddress|name|network|type - --tags strings tags to filter [optional] - --type string type to filter [optional] + --addressfamily string addressfamily of the ip to filter, defaults to all addressfamilies [optional] + -h, --help help for list + --ipaddress string ipaddress to filter [optional] + --machineid string machineid to filter [optional] + --name string name to filter [optional] + --network string network to filter [optional] + --prefix string prefix to filter [optional] + --project string project to filter [optional] + --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|description|id|ipaddress|name|network|type + --tags strings tags to filter [optional] + --type string type to filter [optional] ``` ### Options inherited from parent commands diff --git a/docs/metalctl_network_list.md b/docs/metalctl_network_list.md index 9197c12d..595d624d 100644 --- a/docs/metalctl_network_list.md +++ b/docs/metalctl_network_list.md @@ -9,6 +9,7 @@ metalctl network list [flags] ### Options ``` + --addressfamily string addressfamily to filter, either ipv4 or ipv6 [optional] --destination-prefixes strings destination prefixes to filter, use it like: --destination-prefixes prefix1,prefix2. -h, --help help for list --id string ID to filter [optional] diff --git a/go.mod b/go.mod index f707f57d..5ea700da 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/metal-stack/metalctl -go 1.23 +go 1.24 require ( github.com/Masterminds/semver/v3 v3.3.0 @@ -10,16 +10,16 @@ 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.39.5 - github.com/metal-stack/metal-lib v0.19.0 + github.com/metal-stack/metal-go v0.40.3 + github.com/metal-stack/metal-lib v0.20.1 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 - github.com/spf13/afero v1.11.0 - github.com/spf13/cobra v1.8.1 - github.com/spf13/pflag v1.0.5 + github.com/spf13/afero v1.12.0 + github.com/spf13/cobra v1.9.1 + github.com/spf13/pflag v1.0.6 github.com/spf13/viper v1.19.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/undefinedlabs/go-mpatch v1.0.7 gopkg.in/yaml.v3 v3.0.1 k8s.io/apimachinery v0.31.2 @@ -51,8 +51,8 @@ require ( github.com/cheggaaa/pb/v3 v3.1.5 // indirect github.com/coder/websocket v1.8.12 // indirect github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // indirect - github.com/coreos/go-oidc/v3 v3.11.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/coreos/go-oidc/v3 v3.12.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dblohm7/wingoes v0.0.0-20240801171404-fc12d7c70140 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect @@ -76,7 +76,7 @@ require ( github.com/go-openapi/swag v0.23.0 // indirect github.com/go-openapi/validate v0.24.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/goccy/go-json v0.10.3 // indirect + github.com/goccy/go-json v0.10.4 // indirect github.com/goccy/go-yaml v1.12.0 // indirect github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect @@ -104,10 +104,10 @@ require ( github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/httprc v1.0.6 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/jwx/v2 v2.1.2 // indirect + github.com/lestrrat-go/jwx/v2 v2.1.3 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect @@ -115,7 +115,7 @@ require ( github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/sdnotify v1.0.0 // indirect github.com/mdlayher/socket v0.5.1 // indirect - github.com/metal-stack/security v0.9.0 // indirect + github.com/metal-stack/security v0.9.3 // indirect github.com/miekg/dns v1.1.58 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -132,7 +132,7 @@ require ( github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cast v1.7.1 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e // indirect @@ -149,27 +149,28 @@ require ( github.com/vishvananda/netns v0.0.4 // indirect github.com/x448/float16 v0.8.4 // indirect go.mongodb.org/mongo-driver v1.17.1 // indirect - go.opentelemetry.io/otel v1.30.0 // indirect - go.opentelemetry.io/otel/metric v1.30.0 // indirect - go.opentelemetry.io/otel/trace v1.30.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/otel/metric v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.34.0 // indirect go.uber.org/multierr v1.11.0 // indirect go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/crypto v0.28.0 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect - golang.org/x/mod v0.21.0 // indirect - golang.org/x/net v0.30.0 // indirect - golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/term v0.25.0 // indirect - golang.org/x/text v0.19.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.25.0 // indirect + golang.org/x/crypto v0.33.0 // indirect + golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect + golang.org/x/mod v0.23.0 // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/oauth2 v0.26.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect + golang.org/x/time v0.10.0 // indirect + golang.org/x/tools v0.30.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard/windows v0.5.3 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gvisor.dev/gvisor v0.0.0-20240722211153-64c016c92987 // indirect diff --git a/go.sum b/go.sum index bc1be19d..de33cf6b 100644 --- a/go.sum +++ b/go.sum @@ -58,10 +58,10 @@ github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NA github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6AYUslN6c6iuZWTKsKxUFDlpnmilO6R2n0= github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= -github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= -github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= -github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo= +github.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= +github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0= github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= @@ -137,8 +137,8 @@ github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3Bum github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= -github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= +github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg= @@ -217,8 +217,8 @@ github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCG github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx/v2 v2.1.2 h1:6poete4MPsO8+LAEVhpdrNI4Xp2xdiafgl2RD89moBc= -github.com/lestrrat-go/jwx/v2 v2.1.2/go.mod h1:pO+Gz9whn7MPdbsqSJzG8TlEpMZCwQDXnFJ+zsUVh8Y= +github.com/lestrrat-go/jwx/v2 v2.1.3 h1:Ud4lb2QuxRClYAmRleF50KrbKIoM1TddXgBrneT5/Jo= +github.com/lestrrat-go/jwx/v2 v2.1.3/go.mod h1:q6uFgbgZfEmQrfJfrCo90QcQOcXFMfbI/fO0NqRtvZo= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -226,8 +226,8 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -244,12 +244,12 @@ 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.39.5 h1:XLw6By7daBzzelyjBFkkFCcWlD+w/8h3PQtfa8QW56A= -github.com/metal-stack/metal-go v0.39.5/go.mod h1:ltItf/Md/z588c7Dr3X6iemCeOFh3rJ8nDL5Dpb9zFQ= -github.com/metal-stack/metal-lib v0.19.0 h1:4yBnp/jPGgX9KeCje3A4MFL2oDjgjOjgsIK391LltRI= -github.com/metal-stack/metal-lib v0.19.0/go.mod h1:fCMaWwVGA/xAoGvBk72/nfzqBkHly0iOzrWpc55Fau4= -github.com/metal-stack/security v0.9.0 h1:FYBXJfNJwUw2E0HBa+jay37XF7b6EikEuf4Mw8u04EY= -github.com/metal-stack/security v0.9.0/go.mod h1:6pQhJ4Kdu4BKnjB4zyzfK9skiHymqfrqt63Y+UmZBKA= +github.com/metal-stack/metal-go v0.40.3 h1:ekgdTY23zHs/XGOg8bUJQFYPTX1GnaqgaT/lgVxS3JI= +github.com/metal-stack/metal-go v0.40.3/go.mod h1:ltItf/Md/z588c7Dr3X6iemCeOFh3rJ8nDL5Dpb9zFQ= +github.com/metal-stack/metal-lib v0.20.1 h1:gxNg512dS5yzDebELtPZjmoWond0Gw0HHEkSVIAOWRE= +github.com/metal-stack/metal-lib v0.20.1/go.mod h1:zYzXYpNA4nQ+ANx19s/+1Yb/Q6xhS1nQK2yK2/ryXZM= +github.com/metal-stack/security v0.9.3 h1:ZF5rGeZ4fIFe0DFFQWkXsUDCzODyjdrpvKmeaLOz9lo= +github.com/metal-stack/security v0.9.3/go.mod h1:ENm5kPjqh4uYvn79sAIxd6GZBwtF2GSsGdkLELrB/D4= github.com/metal-stack/updater v1.2.2 h1:gnUrnQgfT20QFMDtFBY89opKoBAkdeI/8T2iwMHNdxs= github.com/metal-stack/updater v1.2.2/go.mod h1:JMFgqDgzbRaoZGYArqbI/L3zoAlipaGJKOvdGFu/kNY= github.com/metal-stack/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs= @@ -276,8 +276,8 @@ github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= -github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= +github.com/pkg/sftp v1.13.7 h1:uv+I3nNJvlKZIQGSr8JVQLNHFU9YhhNpvC14Y6KgmSM= +github.com/pkg/sftp v1.13.7/go.mod h1:KMKI0t3T6hfA+lTR/ssZdunHo+uwq7ghoN09/FSu3DY= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -287,8 +287,8 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0= @@ -301,14 +301,14 @@ github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= +github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -321,8 +321,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e h1:PtWT87weP5LWHEY//SWsYkSO3RWRZo4OSWagh3YD2vQ= @@ -364,37 +365,39 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= go.mongodb.org/mongo-driver v1.17.1 h1:Wic5cJIwJgSpBhe3lx3+/RybR5PiYRMpVFgO7cOHyIM= go.mongodb.org/mongo-driver v1.17.1/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= -go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= +go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go4.org/mem v0.0.0-20240501181205-ae6ca9944745 h1:Tl++JLUCe4sxGu8cTpDzRLd3tN7US4hOxG5YpKCzkek= go4.org/mem v0.0.0-20240501181205-ae6ca9944745/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= +golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= golang.org/x/exp/typeparams v0.0.0-20240119083558-1b970713d09a h1:8qmSSA8Gz/1kTrCe0nqR0R3Gb/NDhykzWw2q2mWZydM= golang.org/x/exp/typeparams v0.0.0-20240119083558-1b970713d09a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ= golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= +golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= +golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -403,16 +406,16 @@ golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= -golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= +golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= @@ -420,8 +423,8 @@ golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeu golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE= golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=