Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package hcloud-cli for openSUSE:Factory 
checked in at 2026-09-28 10:39:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/hcloud-cli (Old)
 and      /work/SRC/openSUSE:Factory/.hcloud-cli.new.383539 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "hcloud-cli"

Mon Sep 28 10:39:12 2026 rev:24 rq:1380299 version:1.69.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/hcloud-cli/hcloud-cli.changes    2026-09-17 
15:20:09.221827983 +0200
+++ /work/SRC/openSUSE:Factory/.hcloud-cli.new.383539/hcloud-cli.changes        
2026-09-28 10:40:27.200871568 +0200
@@ -1,0 +2,18 @@
+Fri Sep 25 04:50:48 UTC 2026 - Johannes Kastl 
<[email protected]>
+
+- Update to version 1.69.0:
+  * Features
+    - network: implement list-members command (#1491) (d4e3726)
+  * Bug Fixes
+    - primary-ip: add fallback for unknown assignee types (#1493)
+      (0856baa)
+  * Dependencies
+    - deps: update dependency jdx/mise to v2026.9.11 (#1486)
+    - deps: update dependency github:goreleaser/goreleaser to
+      v2.18.2 (#1488)
+    - deps: update module github.com/dustin/go-humanize to v1.1.0
+      (#1490)
+    - deps: update module github.com/hetznercloud/hcloud-go/v2 to
+      v2.49.0 (#1489)
+
+-------------------------------------------------------------------

Old:
----
  hcloud-cli-1.68.0.obscpio

New:
----
  hcloud-cli-1.69.0.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ hcloud-cli.spec ++++++
--- /var/tmp/diff_new_pack.gOA2S8/_old  2026-09-28 10:40:28.181912705 +0200
+++ /var/tmp/diff_new_pack.gOA2S8/_new  2026-09-28 10:40:28.183912789 +0200
@@ -19,7 +19,7 @@
 %define executable_name hcloud
 
 Name:           hcloud-cli
-Version:        1.68.0
+Version:        1.69.0
 Release:        0
 Summary:        A command-line interface for Hetzner Cloud
 License:        MIT

++++++ _service ++++++
--- /var/tmp/diff_new_pack.gOA2S8/_old  2026-09-28 10:40:28.214914089 +0200
+++ /var/tmp/diff_new_pack.gOA2S8/_new  2026-09-28 10:40:28.216914173 +0200
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/hetznercloud/cli.git</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">refs/tags/v1.68.0</param>
+    <param name="revision">refs/tags/v1.69.0</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.gOA2S8/_old  2026-09-28 10:40:28.235914970 +0200
+++ /var/tmp/diff_new_pack.gOA2S8/_new  2026-09-28 10:40:28.238915096 +0200
@@ -3,6 +3,6 @@
                 <param name="url">https://github.com/hetznercloud/cli</param>
               <param 
name="changesrevision">a9f3077b036d9145ef75e17b51483fa4481c0a9f</param></service><service
 name="tar_scm">
                 <param 
name="url">https://github.com/hetznercloud/cli.git</param>
-              <param 
name="changesrevision">177c1b5eeb9e2410b19531ed85a8ecd9d96920f8</param></service></servicedata>
+              <param 
name="changesrevision">88350084112192df1317e3cc101419ddcb85c689</param></service></servicedata>
 (No newline at EOF)
 

++++++ hcloud-cli-1.68.0.obscpio -> hcloud-cli-1.69.0.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hcloud-cli-1.68.0/CHANGELOG.md 
new/hcloud-cli-1.69.0/CHANGELOG.md
--- old/hcloud-cli-1.68.0/CHANGELOG.md  2026-09-14 17:14:03.000000000 +0200
+++ new/hcloud-cli-1.69.0/CHANGELOG.md  2026-09-24 16:48:58.000000000 +0200
@@ -1,5 +1,17 @@
 # Changelog
 
+## [v1.69.0](https://github.com/hetznercloud/cli/releases/tag/v1.69.0)
+
+[Compare to previous 
version](https://github.com/hetznercloud/cli/compare/v1.68.0...v1.69.0)
+
+### Features
+
+- **network**: implement list-members command (#1491) 
([d4e3726](https://github.com/hetznercloud/cli/commit/d4e3726cbebba9f5a61389573fc518f03bc3a7ad))
+
+### Bug Fixes
+
+- **primary-ip**: add fallback for unknown assignee types (#1493) 
([0856baa](https://github.com/hetznercloud/cli/commit/0856baa767793f9e9d86a870fcd6432b4aedb954))
+
 ## [v1.68.0](https://github.com/hetznercloud/cli/releases/tag/v1.68.0)
 
 [Compare to previous 
version](https://github.com/hetznercloud/cli/compare/v1.67.0...v1.68.0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hcloud-cli-1.68.0/docs/reference/manual/hcloud_network.md 
new/hcloud-cli-1.69.0/docs/reference/manual/hcloud_network.md
--- old/hcloud-cli-1.68.0/docs/reference/manual/hcloud_network.md       
2026-09-14 17:14:03.000000000 +0200
+++ new/hcloud-cli-1.69.0/docs/reference/manual/hcloud_network.md       
2026-09-24 16:48:58.000000000 +0200
@@ -37,6 +37,7 @@
 * [hcloud network enable-protection](hcloud_network_enable-protection.md)      
 - Enable resource protection for a Network
 * [hcloud network 
expose-routes-to-vswitch](hcloud_network_expose-routes-to-vswitch.md)         - 
Expose routes to connected vSwitch
 * [hcloud network list](hcloud_network_list.md)         - List Networks
+* [hcloud network list-members](hcloud_network_list-members.md)         - List 
Network Members
 * [hcloud network remove-label](hcloud_network_remove-label.md)         - 
Remove a label from a Network
 * [hcloud network remove-route](hcloud_network_remove-route.md)         - 
Remove a route from a Network
 * [hcloud network remove-subnet](hcloud_network_remove-subnet.md)       - 
Remove a subnet from a Network
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hcloud-cli-1.68.0/docs/reference/manual/hcloud_network_list-members.md 
new/hcloud-cli-1.69.0/docs/reference/manual/hcloud_network_list-members.md
--- old/hcloud-cli-1.68.0/docs/reference/manual/hcloud_network_list-members.md  
1970-01-01 01:00:00.000000000 +0100
+++ new/hcloud-cli-1.69.0/docs/reference/manual/hcloud_network_list-members.md  
2026-09-24 16:48:58.000000000 +0200
@@ -0,0 +1,55 @@
+## hcloud network list-members
+
+List Network Members
+
+### Synopsis
+
+Displays a list of Network Members.
+
+Output can be controlled with the -o flag. Use -o noheader to suppress the
+table header. Displayed columns and their order can be set with
+-o columns=alias_ips,id (see available columns below).
+
+Columns:
+ - alias_ips
+ - id
+ - ip
+ - status
+ - subnet
+ - type
+
+```
+hcloud network list-members [options] <network>
+```
+
+### Options
+
+```
+  -h, --help                 help for list-members
+  -o, --output stringArray   output options: noheader|columns=...|json|yaml
+  -l, --selector string      Selector to filter by labels
+  -s, --sort strings         Determine the sorting of the result
+      --status strings       Only Members with one of these statuses are 
displayed
+      --subnet strings       Only Members attached to one of these subnets are 
displayed
+      --type strings         Only Members with one of these types are displayed
+```
+
+### Options inherited from parent commands
+
+```
+      --config string              Config file path (default 
"~/.config/hcloud/cli.toml")
+      --context string             Currently active context
+      --debug                      Enable debug output
+      --debug-file string          File to write debug output to
+      --endpoint string            Hetzner Cloud API endpoint (default 
"https://api.hetzner.cloud/v1";)
+      --hetzner-endpoint string    Hetzner API endpoint (default 
"https://api.hetzner.com/v1";)
+      --http-timeout duration      Timeout for HTTP requests (default 0 = no 
timeout)
+      --no-experimental-warnings   If true, experimental warnings are not shown
+      --poll-interval duration     Interval at which to poll information, for 
example action progress (default 500ms)
+      --quiet                      If true, only print error messages
+```
+
+### SEE ALSO
+
+* [hcloud network](hcloud_network.md)   - Manage Networks
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hcloud-cli-1.68.0/go.mod new/hcloud-cli-1.69.0/go.mod
--- old/hcloud-cli-1.68.0/go.mod        2026-09-14 17:14:03.000000000 +0200
+++ new/hcloud-cli-1.69.0/go.mod        2026-09-24 16:48:58.000000000 +0200
@@ -7,12 +7,12 @@
 require (
        github.com/BurntSushi/toml v1.6.0
        github.com/cheggaaa/pb/v3 v3.2.1
-       github.com/dustin/go-humanize v1.0.1
+       github.com/dustin/go-humanize v1.1.0
        github.com/fatih/color v1.19.0
        github.com/fatih/structs v1.1.0
        github.com/goccy/go-yaml v1.19.2
        github.com/guptarohit/asciigraph v0.10.0
-       github.com/hetznercloud/hcloud-go/v2 v2.48.0
+       github.com/hetznercloud/hcloud-go/v2 v2.49.0
        github.com/jedib0t/go-pretty/v6 v6.8.3
        github.com/spf13/cast v1.10.0
        github.com/spf13/cobra v1.10.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hcloud-cli-1.68.0/go.sum new/hcloud-cli-1.69.0/go.sum
--- old/hcloud-cli-1.68.0/go.sum        2026-09-14 17:14:03.000000000 +0200
+++ new/hcloud-cli-1.69.0/go.sum        2026-09-24 16:48:58.000000000 +0200
@@ -19,8 +19,8 @@
 github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod 
h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/davecgh/go-spew v1.1.0/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dustin/go-humanize v1.0.1 
h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
-github.com/dustin/go-humanize v1.0.1/go.mod 
h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
+github.com/dustin/go-humanize v1.1.0 
h1:dbKTrvD0klcbBV/h4AWJdMuZogJACoMlvWIWZ5b2xWg=
+github.com/dustin/go-humanize v1.1.0/go.mod 
h1:hc1CvRkJMsgxqjmjMQF3QNRAZBwY8AXBAzKYoSX9sFI=
 github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
 github.com/fatih/color v1.19.0/go.mod 
h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
 github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
@@ -37,8 +37,8 @@
 github.com/google/go-cmp v0.7.0/go.mod 
h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/guptarohit/asciigraph v0.10.0 
h1:LmbFXSHZOhaQxjJYexdRk7TzoC5sJ7vDTEjP1YUbKgY=
 github.com/guptarohit/asciigraph v0.10.0/go.mod 
h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag=
-github.com/hetznercloud/hcloud-go/v2 v2.48.0 
h1:P3biOxqEufOxp2xBEZTZGIl56xK4sFbwLkCW/52AbiE=
-github.com/hetznercloud/hcloud-go/v2 v2.48.0/go.mod 
h1:J9QH6j8pRH0K3+HlqgOlQ8abXagWTD/GpTkfra2et+g=
+github.com/hetznercloud/hcloud-go/v2 v2.49.0 
h1:QXONxfgXIF99PFJknkVw+LrQQB4PB5IbEjEDh4Hfmig=
+github.com/hetznercloud/hcloud-go/v2 v2.49.0/go.mod 
h1:J9QH6j8pRH0K3+HlqgOlQ8abXagWTD/GpTkfra2et+g=
 github.com/iancoleman/orderedmap v0.3.0 
h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc=
 github.com/iancoleman/orderedmap v0.3.0/go.mod 
h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE=
 github.com/inconshreveable/mousetrap v1.1.0 
h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hcloud-cli-1.68.0/internal/cmd/network/list_members.go 
new/hcloud-cli-1.69.0/internal/cmd/network/list_members.go
--- old/hcloud-cli-1.68.0/internal/cmd/network/list_members.go  1970-01-01 
01:00:00.000000000 +0100
+++ new/hcloud-cli-1.69.0/internal/cmd/network/list_members.go  2026-09-24 
16:48:58.000000000 +0200
@@ -0,0 +1,140 @@
+package network
+
+import (
+       "fmt"
+       "net"
+       "slices"
+       "strings"
+
+       "github.com/spf13/cobra"
+       "github.com/spf13/pflag"
+
+       "github.com/hetznercloud/cli/internal/cmd/base"
+       "github.com/hetznercloud/cli/internal/cmd/cmpl"
+       "github.com/hetznercloud/cli/internal/cmd/output"
+       "github.com/hetznercloud/cli/internal/cmd/util"
+       "github.com/hetznercloud/cli/internal/hcapi2"
+       "github.com/hetznercloud/cli/internal/state"
+       "github.com/hetznercloud/cli/internal/state/config"
+       "github.com/hetznercloud/hcloud-go/v2/hcloud"
+       "github.com/hetznercloud/hcloud-go/v2/hcloud/schema"
+)
+
+var networkMemberTypeStrings = []string{
+       string(hcloud.NetworkMemberTypeLoadBalancer),
+       string(hcloud.NetworkMemberTypeServer),
+}
+
+var networkMemberStatusStrings = []string{
+       string(hcloud.NetworkMemberStatusAttaching),
+       string(hcloud.NetworkMemberStatusDetaching),
+       string(hcloud.NetworkMemberStatusError),
+       string(hcloud.NetworkMemberStatusOK),
+       string(hcloud.NetworkMemberStatusUpdating),
+}
+
+var ListMembersCmd = &base.ListCmd[*hcloud.NetworkMember, 
schema.NetworkMember]{
+       ResourceNamePlural: "Network Members",
+       JSONKeyGetByName:   "members",
+
+       DefaultColumns: []string{"type", "id", "status", "ip", "alias_ips", 
"subnet"},
+       SortOption:     config.OptionSortNetworkMember,
+
+       ValidArgsFunction: func(client hcapi2.Client) cobra.CompletionFunc {
+               return cmpl.SuggestCandidatesF(client.Network().Names)
+       },
+
+       PositionalArgumentOverride: []string{"network"},
+
+       AdditionalFlags: func(cmd *cobra.Command) {
+               cmd.Flags().StringSlice("type", nil, "Only Members with one of 
these types are displayed")
+               _ = cmd.RegisterFlagCompletionFunc("type", 
cmpl.SuggestCandidates(networkMemberTypeStrings...))
+
+               cmd.Flags().StringSlice("status", nil, "Only Members with one 
of these statuses are displayed")
+               _ = cmd.RegisterFlagCompletionFunc("status", 
cmpl.SuggestCandidates(networkMemberStatusStrings...))
+
+               cmd.Flags().StringSlice("subnet", nil, "Only Members attached 
to one of these subnets are displayed")
+       },
+
+       FetchWithArgs: func(s state.State, flags *pflag.FlagSet, listOpts 
hcloud.ListOpts, sorts []string, args []string) ([]*hcloud.NetworkMember, 
error) {
+               networkIDOrName := args[0]
+
+               types, _ := flags.GetStringSlice("type")
+               subnets, _ := flags.GetStringSlice("subnet")
+               statuses, _ := flags.GetStringSlice("status")
+
+               opts := hcloud.NetworkMemberListOpts{ListOpts: listOpts}
+               if len(sorts) > 0 {
+                       opts.Sort = sorts
+               }
+
+               if len(types) > 0 {
+                       for _, typ := range types {
+                               if !slices.Contains(networkMemberTypeStrings, 
typ) {
+                                       return nil, fmt.Errorf("invalid type: 
%s", typ)
+                               }
+                               opts.Type = append(opts.Type, 
hcloud.NetworkMemberType(typ))
+                       }
+               }
+
+               if len(subnets) > 0 {
+                       for _, subnet := range subnets {
+                               _, ipNet, err := net.ParseCIDR(subnet)
+                               if err != nil {
+                                       return nil, fmt.Errorf("invalid subnet: 
%s", subnet)
+                               }
+                               opts.Subnet = append(opts.Subnet, ipNet)
+                       }
+               }
+
+               if len(statuses) > 0 {
+                       for _, status := range statuses {
+                               if !slices.Contains(networkMemberStatusStrings, 
status) {
+                                       return nil, fmt.Errorf("invalid status: 
%s", status)
+                               }
+                               opts.Status = append(opts.Status, 
hcloud.NetworkMemberStatus(status))
+                       }
+               }
+
+               network, _, err := s.Client().Network().Get(s, networkIDOrName)
+               if err != nil {
+                       return nil, err
+               }
+               if network == nil {
+                       return nil, fmt.Errorf("Network not found: %s", 
networkIDOrName)
+               }
+
+               return s.Client().Network().AllMembersWithOpts(s, network, opts)
+       },
+
+       OutputTable: func(t *output.Table[*hcloud.NetworkMember], _ 
hcapi2.Client) {
+               t.
+                       AddAllowedFields(&hcloud.NetworkMember{}).
+                       AddFieldFn("ip", func(member *hcloud.NetworkMember) 
string {
+                               if member.IP == nil {
+                                       return util.NA("")
+                               }
+                               return member.IP.String()
+                       }).
+                       AddFieldFn("alias_ips", func(member 
*hcloud.NetworkMember) string {
+                               var aliasIPs []string
+                               for _, aliasIP := range member.AliasIPs {
+                                       aliasIPs = append(aliasIPs, 
aliasIP.String())
+                               }
+                               return util.NA(strings.Join(aliasIPs, "\n"))
+                       }).
+                       AddFieldFn("subnet", func(member *hcloud.NetworkMember) 
string {
+                               if member.Subnet == nil {
+                                       return util.NA("")
+                               }
+                               return member.Subnet.String()
+                       })
+       },
+
+       Schema: hcloud.SchemaFromNetworkMember,
+
+       Configure: func(_ state.State, cmd *cobra.Command) *cobra.Command {
+               cmd.Use = "list-members [options] <network>"
+               return cmd
+       },
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hcloud-cli-1.68.0/internal/cmd/network/list_members_test.go 
new/hcloud-cli-1.69.0/internal/cmd/network/list_members_test.go
--- old/hcloud-cli-1.68.0/internal/cmd/network/list_members_test.go     
1970-01-01 01:00:00.000000000 +0100
+++ new/hcloud-cli-1.69.0/internal/cmd/network/list_members_test.go     
2026-09-24 16:48:58.000000000 +0200
@@ -0,0 +1,78 @@
+package network_test
+
+import (
+       "net"
+       "testing"
+
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
+       "go.uber.org/mock/gomock"
+
+       "github.com/hetznercloud/cli/internal/cmd/network"
+       "github.com/hetznercloud/cli/internal/testutil"
+       "github.com/hetznercloud/hcloud-go/v2/hcloud"
+)
+
+func TestListMembers(t *testing.T) {
+       fx := testutil.NewFixture(t)
+       defer fx.Finish()
+
+       cmd := network.ListMembersCmd.CobraCommand(fx.State())
+
+       networkRes := &hcloud.Network{
+               ID:      123,
+               Name:    "test-network",
+               IPRange: &net.IPNet{IP: net.ParseIP("10.0.0.0"), Mask: 
net.CIDRMask(16, 32)},
+       }
+
+       members := []*hcloud.NetworkMember{
+               {
+                       Type:     hcloud.NetworkMemberTypeServer,
+                       ID:       42,
+                       IP:       net.IPv4(10, 0, 0, 2),
+                       Status:   hcloud.NetworkMemberStatusOK,
+                       AliasIPs: []net.IP{net.IPv4(10, 0, 0, 3), net.IPv4(10, 
0, 0, 4)},
+                       Subnet: &net.IPNet{
+                               IP:   net.IPv4(10, 0, 0, 0),
+                               Mask: net.CIDRMask(24, 32),
+                       },
+               },
+               {
+                       Type:   hcloud.NetworkMemberTypeLoadBalancer,
+                       ID:     7,
+                       IP:     net.IPv4(10, 0, 0, 5),
+                       Status: hcloud.NetworkMemberStatusAttaching,
+                       Subnet: &net.IPNet{
+                               IP:   net.IPv4(10, 0, 0, 0),
+                               Mask: net.CIDRMask(24, 32),
+                       },
+               },
+       }
+
+       fx.ExpectEnsureToken()
+       fx.Client.NetworkClient.EXPECT().
+               Get(gomock.Any(), "test-network").
+               Return(networkRes, nil, nil)
+       fx.Client.NetworkClient.EXPECT().
+               AllMembersWithOpts(
+                       gomock.Any(),
+                       networkRes,
+                       hcloud.NetworkMemberListOpts{
+                               ListOpts: hcloud.ListOpts{PerPage: 50},
+                               Sort:     []string{"id:asc"},
+                       },
+               ).
+               Return(members, nil)
+
+       out, errOut, err := fx.Run(cmd, []string{"test-network"})
+
+       expOut := `TYPE            ID   STATUS      IP         ALIAS IPS   
SUBNET
+server          42   ok          10.0.0.2   10.0.0.3    10.0.0.0/24
+                                            10.0.0.4
+load_balancer   7    attaching   10.0.0.5   -           10.0.0.0/24
+`
+
+       require.NoError(t, err)
+       assert.Empty(t, errOut)
+       assert.Equal(t, expOut, out)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hcloud-cli-1.68.0/internal/cmd/network/network.go 
new/hcloud-cli-1.69.0/internal/cmd/network/network.go
--- old/hcloud-cli-1.68.0/internal/cmd/network/network.go       2026-09-14 
17:14:03.000000000 +0200
+++ new/hcloud-cli-1.69.0/internal/cmd/network/network.go       2026-09-24 
16:48:58.000000000 +0200
@@ -43,5 +43,9 @@
                AddSubnetCmd.CobraCommand(s),
                RemoveSubnetCmd.CobraCommand(s),
        )
+
+       util.AddGroup(cmd, "member", "Members",
+               ListMembersCmd.CobraCommand(s),
+       )
        return cmd
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hcloud-cli-1.68.0/internal/cmd/primaryip/list.go 
new/hcloud-cli-1.69.0/internal/cmd/primaryip/list.go
--- old/hcloud-cli-1.68.0/internal/cmd/primaryip/list.go        2026-09-14 
17:14:03.000000000 +0200
+++ new/hcloud-cli-1.69.0/internal/cmd/primaryip/list.go        2026-09-24 
16:48:58.000000000 +0200
@@ -6,6 +6,8 @@
        "time"
 
        "github.com/spf13/pflag"
+       "golang.org/x/text/cases"
+       "golang.org/x/text/language"
 
        "github.com/hetznercloud/cli/internal/cmd/base"
        "github.com/hetznercloud/cli/internal/cmd/output"
@@ -59,6 +61,11 @@
                                        switch primaryIP.AssigneeType {
                                        case "server":
                                                assignee = fmt.Sprintf("Server 
%s", client.Server().ServerName(primaryIP.AssigneeID))
+                                       case "unassigned", "":
+                                               break
+                                       default:
+                                               // fallback: foo_bar 123 -> Foo 
Bar 123
+                                               assignee = fmt.Sprintf("%s %d", 
cases.Title(language.English).String(strings.ReplaceAll(primaryIP.AssigneeType, 
"_", " ")), primaryIP.AssigneeID)
                                        }
                                }
                                return util.NA(assignee)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/hcloud-cli-1.68.0/internal/hcapi2/mock/zz_hcapi_mock.go 
new/hcloud-cli-1.69.0/internal/hcapi2/mock/zz_hcapi_mock.go
--- old/hcloud-cli-1.68.0/internal/hcapi2/mock/zz_hcapi_mock.go 2026-09-14 
17:14:03.000000000 +0200
+++ new/hcloud-cli-1.69.0/internal/hcapi2/mock/zz_hcapi_mock.go 2026-09-24 
16:48:58.000000000 +0200
@@ -2529,6 +2529,36 @@
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "All", 
reflect.TypeOf((*MockNetworkClient)(nil).All), ctx)
 }
 
+// AllMembers mocks base method.
+func (m *MockNetworkClient) AllMembers(ctx context.Context, network 
*hcloud.Network) ([]*hcloud.NetworkMember, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "AllMembers", ctx, network)
+       ret0, _ := ret[0].([]*hcloud.NetworkMember)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// AllMembers indicates an expected call of AllMembers.
+func (mr *MockNetworkClientMockRecorder) AllMembers(ctx, network any) 
*gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllMembers", 
reflect.TypeOf((*MockNetworkClient)(nil).AllMembers), ctx, network)
+}
+
+// AllMembersWithOpts mocks base method.
+func (m *MockNetworkClient) AllMembersWithOpts(ctx context.Context, network 
*hcloud.Network, opts hcloud.NetworkMemberListOpts) ([]*hcloud.NetworkMember, 
error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "AllMembersWithOpts", ctx, network, opts)
+       ret0, _ := ret[0].([]*hcloud.NetworkMember)
+       ret1, _ := ret[1].(error)
+       return ret0, ret1
+}
+
+// AllMembersWithOpts indicates an expected call of AllMembersWithOpts.
+func (mr *MockNetworkClientMockRecorder) AllMembersWithOpts(ctx, network, opts 
any) *gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, 
"AllMembersWithOpts", 
reflect.TypeOf((*MockNetworkClient)(nil).AllMembersWithOpts), ctx, network, 
opts)
+}
+
 // AllWithOpts mocks base method.
 func (m *MockNetworkClient) AllWithOpts(ctx context.Context, opts 
hcloud.NetworkListOpts) ([]*hcloud.Network, error) {
        m.ctrl.T.Helper()
@@ -2717,6 +2747,22 @@
        return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", 
reflect.TypeOf((*MockNetworkClient)(nil).List), ctx, opts)
 }
 
+// ListMembers mocks base method.
+func (m *MockNetworkClient) ListMembers(ctx context.Context, network 
*hcloud.Network, opts hcloud.NetworkMemberListOpts) ([]*hcloud.NetworkMember, 
*hcloud.Response, error) {
+       m.ctrl.T.Helper()
+       ret := m.ctrl.Call(m, "ListMembers", ctx, network, opts)
+       ret0, _ := ret[0].([]*hcloud.NetworkMember)
+       ret1, _ := ret[1].(*hcloud.Response)
+       ret2, _ := ret[2].(error)
+       return ret0, ret1, ret2
+}
+
+// ListMembers indicates an expected call of ListMembers.
+func (mr *MockNetworkClientMockRecorder) ListMembers(ctx, network, opts any) 
*gomock.Call {
+       mr.mock.ctrl.T.Helper()
+       return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListMembers", 
reflect.TypeOf((*MockNetworkClient)(nil).ListMembers), ctx, network, opts)
+}
+
 // Name mocks base method.
 func (m *MockNetworkClient) Name(arg0 int64) string {
        m.ctrl.T.Helper()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hcloud-cli-1.68.0/internal/state/config/options.go 
new/hcloud-cli-1.69.0/internal/state/config/options.go
--- old/hcloud-cli-1.68.0/internal/state/config/options.go      2026-09-14 
17:14:03.000000000 +0200
+++ new/hcloud-cli-1.69.0/internal/state/config/options.go      2026-09-24 
16:48:58.000000000 +0200
@@ -259,6 +259,15 @@
                nil,
        )
 
+       OptionSortNetworkMember = newOpt(
+               "sort.network.member",
+               "Default sorting for Network Member resource",
+               []string{"id:asc"},
+               
(DefaultPreferenceFlags&^OptionFlagPFlag)|OptionFlagSlice|OptionFlagHidden,
+               nil,
+               nil,
+       )
+
        OptionSortPlacementGroup = newOpt(
                "sort.placement-group",
                "Default sorting for Placement Group resource",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hcloud-cli-1.68.0/internal/version/version.go 
new/hcloud-cli-1.69.0/internal/version/version.go
--- old/hcloud-cli-1.68.0/internal/version/version.go   2026-09-14 
17:14:03.000000000 +0200
+++ new/hcloud-cli-1.69.0/internal/version/version.go   2026-09-24 
16:48:58.000000000 +0200
@@ -4,7 +4,7 @@
 
 var (
        // version is a semver version (https://semver.org).
-       version = "1.68.0" // x-releaser-pleaser-version
+       version = "1.69.0" // x-releaser-pleaser-version
 
        // versionPrerelease is a semver version pre-release identifier 
(https://semver.org).
        //
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hcloud-cli-1.68.0/mise.toml 
new/hcloud-cli-1.69.0/mise.toml
--- old/hcloud-cli-1.68.0/mise.toml     2026-09-14 17:14:03.000000000 +0200
+++ new/hcloud-cli-1.69.0/mise.toml     2026-09-24 16:48:58.000000000 +0200
@@ -2,6 +2,6 @@
 go = "1.26.8"
 "go:go.uber.org/mock/mockgen" = "v0.6.0"
 "github:golangci/golangci-lint" = "2.13.2"
-"github:goreleaser/goreleaser" = "v2.18.1"
+"github:goreleaser/goreleaser" = "v2.18.2"
 "github:anchore/quill" = "v0.7.1"
 "github:jstemmer/go-junit-report" = "v2.1.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hcloud-cli-1.68.0/test/e2e/e2e_test.go 
new/hcloud-cli-1.69.0/test/e2e/e2e_test.go
--- old/hcloud-cli-1.68.0/test/e2e/e2e_test.go  2026-09-14 17:14:03.000000000 
+0200
+++ new/hcloud-cli-1.69.0/test/e2e/e2e_test.go  2026-09-24 16:48:58.000000000 
+0200
@@ -50,6 +50,7 @@
        var buf bytes.Buffer
        cmd.SetArgs(args)
        cmd.SetOut(&buf)
+       cmd.SetErr(t.Output())
        err := cmd.Execute()
        return buf.String(), err
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hcloud-cli-1.68.0/test/e2e/network_test.go 
new/hcloud-cli-1.69.0/test/e2e/network_test.go
--- old/hcloud-cli-1.68.0/test/e2e/network_test.go      2026-09-14 
17:14:03.000000000 +0200
+++ new/hcloud-cli-1.69.0/test/e2e/network_test.go      2026-09-24 
16:48:58.000000000 +0200
@@ -65,6 +65,20 @@
                )
        })
 
+       t.Run("list-members", func(t *testing.T) {
+               t.Run("non-existing-network", func(t *testing.T) {
+                       out, err := runCommand(t, "network", "list-members", 
"non-existing-network")
+                       require.EqualError(t, err, "Network not found: 
non-existing-network")
+                       assert.Empty(t, out)
+               })
+
+               t.Run("no-members", func(t *testing.T) {
+                       out, err := runCommand(t, "network", "list-members", 
strconv.FormatInt(networkID, 10))
+                       require.NoError(t, err)
+                       assert.Equal(t, "TYPE   ID   STATUS   IP   ALIAS IPS   
SUBNET\n", out)
+               })
+       })
+
        t.Run("change-ip-range", func(t *testing.T) {
                t.Run("non-existing-network", func(t *testing.T) {
                        out, err := runCommand(t, "network", "change-ip-range", 
"--ip-range", "10.0.2.0/16", "non-existing-network")

++++++ hcloud-cli.obsinfo ++++++
--- /var/tmp/diff_new_pack.gOA2S8/_old  2026-09-28 10:40:28.595930066 +0200
+++ /var/tmp/diff_new_pack.gOA2S8/_new  2026-09-28 10:40:28.599930234 +0200
@@ -1,5 +1,5 @@
 name: hcloud-cli
-version: 1.68.0
-mtime: 1789398843
-commit: 177c1b5eeb9e2410b19531ed85a8ecd9d96920f8
+version: 1.69.0
+mtime: 1790261338
+commit: 88350084112192df1317e3cc101419ddcb85c689
 

++++++ vendor.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/.envrc 
new/vendor/github.com/dustin/go-humanize/.envrc
--- old/vendor/github.com/dustin/go-humanize/.envrc     1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/github.com/dustin/go-humanize/.envrc     2026-09-24 
16:48:58.000000000 +0200
@@ -0,0 +1,4 @@
+# shellcheck shell=bash
+set -eu
+
+use flake
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/.gitignore 
new/vendor/github.com/dustin/go-humanize/.gitignore
--- old/vendor/github.com/dustin/go-humanize/.gitignore 1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/github.com/dustin/go-humanize/.gitignore 2026-09-24 
16:48:58.000000000 +0200
@@ -0,0 +1 @@
+.direnv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/.travis.yml 
new/vendor/github.com/dustin/go-humanize/.travis.yml
--- old/vendor/github.com/dustin/go-humanize/.travis.yml        2026-09-14 
17:14:03.000000000 +0200
+++ new/vendor/github.com/dustin/go-humanize/.travis.yml        1970-01-01 
01:00:00.000000000 +0100
@@ -1,21 +0,0 @@
-sudo: false
-language: go
-go_import_path: github.com/dustin/go-humanize
-go:
-  - 1.13.x
-  - 1.14.x
-  - 1.15.x
-  - 1.16.x
-  - stable
-  - master
-matrix:
-  allow_failures:
-    - go: master
-  fast_finish: true
-install:
-  - # Do nothing. This is needed to prevent default install action "go get -t 
-v ./..." from happening here (we want it to happen inside script step).
-script:
-  - diff -u <(echo -n) <(gofmt -d -s .)
-  - go vet .
-  - go install -v -race ./...
-  - go test -v -race ./...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/README.markdown 
new/vendor/github.com/dustin/go-humanize/README.markdown
--- old/vendor/github.com/dustin/go-humanize/README.markdown    2026-09-14 
17:14:03.000000000 +0200
+++ new/vendor/github.com/dustin/go-humanize/README.markdown    2026-09-24 
16:48:58.000000000 +0200
@@ -1,4 +1,4 @@
-# Humane Units [![Build 
Status](https://travis-ci.org/dustin/go-humanize.svg?branch=master)](https://travis-ci.org/dustin/go-humanize)
 
[![GoDoc](https://godoc.org/github.com/dustin/go-humanize?status.svg)](https://godoc.org/github.com/dustin/go-humanize)
+# Humane Units [![Build 
Status](https://travis-ci.org/dustin/go-humanize.svg?branch=master)](https://travis-ci.org/dustin/go-humanize)
 
[![GoDoc](https://godoc.org/github.com/dustin/go-humanize?status.svg)](https://godoc.org/github.com/dustin/go-humanize)
 
[![Coverage](https://img.shields.io/badge/coverage-report-brightgreen)](https://dustin.github.io/go-humanize/)
 
 Just a few functions for helping humanize times and sizes.
 
@@ -8,6 +8,9 @@
 See [godoc](https://pkg.go.dev/github.com/dustin/go-humanize) for
 complete documentation.
 
+See the [test coverage report](https://dustin.github.io/go-humanize/) for
+coverage details.
+
 ## Sizes
 
 This lets you take numbers like `82854982` and convert them to useful
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/SECURITY.md 
new/vendor/github.com/dustin/go-humanize/SECURITY.md
--- old/vendor/github.com/dustin/go-humanize/SECURITY.md        1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/github.com/dustin/go-humanize/SECURITY.md        2026-09-24 
16:48:58.000000000 +0200
@@ -0,0 +1,5 @@
+# Security Policy
+
+To report a security issue, please disclose it at [security 
advisory](https://github.com/dustin/go-humanize/security/advisories/new).
+
+We will respond within 7 working days of your submission. If the issue is 
confirmed as a vulnerability, we will open a Security Advisory and acknowledge 
your contributions as part of it. This project follows a 90 day disclosure 
timeline.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/bytes.go 
new/vendor/github.com/dustin/go-humanize/bytes.go
--- old/vendor/github.com/dustin/go-humanize/bytes.go   2026-09-14 
17:14:03.000000000 +0200
+++ new/vendor/github.com/dustin/go-humanize/bytes.go   2026-09-24 
16:48:58.000000000 +0200
@@ -3,6 +3,7 @@
 import (
        "fmt"
        "math"
+       "math/bits"
        "strconv"
        "strings"
        "unicode"
@@ -65,39 +66,90 @@
        return math.Log(n) / math.Log(b)
 }
 
-func humanateBytes(s uint64, base float64, sizes []string) string {
+func countDigits(n int64) int {
+       digits := 0
+       for n != 0 {
+               n /= 10
+               digits += 1
+       }
+       return digits
+}
+
+func humanateBytes(s uint64, base float64, minDigits int, sizes []string) 
string {
        if s < 10 {
                return fmt.Sprintf("%d B", s)
        }
        e := math.Floor(logn(float64(s), base))
        suffix := sizes[int(e)]
-       val := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10
-       f := "%.0f %s"
-       if val < 10 {
-               f = "%.1f %s"
+       val := float64(s) / math.Pow(base, e)
+
+       // Determine how many decimal places to keep based on the unrounded
+       // value's integer-digit count, then round exactly once to that
+       // precision. Rounding first to a fixed precision and then again when
+       // formatting (double rounding) can flip the result at a boundary due
+       // to floating point error (see #103).
+       intDigits := countDigits(int64(val))
+       digits := max(minDigits-intDigits, 0)
+       rounding := math.Pow10(digits)
+       val = math.Floor(val*rounding+0.5) / rounding
+
+       // Rounding may have carried into an additional integer digit (e.g.
+       // 9.996 -> 10.0), which means fewer decimal places should be shown
+       // than originally computed.
+       if newIntDigits := countDigits(int64(val)); newIntDigits > intDigits {
+               digits = max(digits-(newIntDigits-intDigits), 0)
        }
 
+       ff := "%%.%df %%s"
+       f := fmt.Sprintf(ff, digits)
        return fmt.Sprintf(f, val, suffix)
 }
 
-// Bytes produces a human readable representation of an SI size.
+// Bytes produces a human-readable representation of an SI size.
 //
 // See also: ParseBytes.
 //
 // Bytes(82854982) -> 83 MB
 func Bytes(s uint64) string {
        sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"}
-       return humanateBytes(s, 1000, sizes)
+       return humanateBytes(s, 1000, 2, sizes)
 }
 
-// IBytes produces a human readable representation of an IEC size.
+// BytesN produces a human-readable representation of an SI size.
+// n specifies the total number of digits to output, including the decimal 
part.
+// If n is less than or equal to the number of digits in the integer part, the 
decimal part will be omitted.
+//
+// See also: ParseBytes.
+//
+// BytesN(82854982, 3) -> 82.9 MB
+// BytesN(82854982, 4) -> 82.85 MB
+func BytesN(s uint64, n int) string {
+       sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"}
+       return humanateBytes(s, 1000, n, sizes)
+}
+
+// IBytes produces a human-readable representation of an IEC size.
 //
 // See also: ParseBytes.
 //
 // IBytes(82854982) -> 79 MiB
 func IBytes(s uint64) string {
        sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}
-       return humanateBytes(s, 1024, sizes)
+       return humanateBytes(s, 1024, 2, sizes)
+}
+
+// IBytesN produces a human-readable representation of an IEC size.
+// n specifies the total number of digits to output, including the decimal 
part.
+// If n is less than or equal to the number of digits in the integer part, the 
decimal part will be omitted.
+//
+// See also: ParseBytes.
+//
+// IBytesN(82854982, 4)  -> 79.02 MiB
+// IBytesN(123456789, 3) -> 118 MiB
+// IBytesN(123456789, 6) -> 117.738 MiB
+func IBytesN(s uint64, n int) string {
+       sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}
+       return humanateBytes(s, 1024, n, sizes)
 }
 
 // ParseBytes parses a string representation of bytes into the number
@@ -132,6 +184,18 @@
 
        extra := strings.ToLower(strings.TrimSpace(s[lastDigit:]))
        if m, ok := bytesSizeTable[extra]; ok {
+               // Parse whole-number inputs exactly. A float64 cannot represent
+               // integers above 2^53, and the multiplication below would also 
reject
+               // otherwise-valid values near math.MaxUint64, so route 
integers through
+               // uint64 arithmetic with an overflow check.
+               if !strings.ContainsRune(num, '.') {
+                       if v, perr := strconv.ParseUint(num, 10, 64); perr == 
nil {
+                               if hi, lo := bits.Mul64(v, m); hi == 0 {
+                                       return lo, nil
+                               }
+                               return 0, fmt.Errorf("too large: %v", s)
+                       }
+               }
                f *= float64(m)
                if f >= math.MaxUint64 {
                        return 0, fmt.Errorf("too large: %v", s)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/comma.go 
new/vendor/github.com/dustin/go-humanize/comma.go
--- old/vendor/github.com/dustin/go-humanize/comma.go   2026-09-14 
17:14:03.000000000 +0200
+++ new/vendor/github.com/dustin/go-humanize/comma.go   2026-09-24 
16:48:58.000000000 +0200
@@ -13,34 +13,48 @@
 //
 // e.g. Comma(834142) -> 834,142
 func Comma(v int64) string {
-       sign := ""
+       // Shortcut for [0, 7]
+       if v&^0b111 == 0 {
+               return string([]byte{byte(v) + 48})
+       }
 
        // Min int64 can't be negated to a usable value, so it has to be 
special cased.
        if v == math.MinInt64 {
                return "-9,223,372,036,854,775,808"
        }
+       // Counting the number of digits.
+       var count byte = 0
+       for n := v; n != 0; n = n / 10 {
+               count++
+       }
 
+       count += (count - 1) / 3
        if v < 0 {
-               sign = "-"
                v = 0 - v
+               count++
        }
+       output := make([]byte, count)
+       j := len(output) - 1
 
-       parts := []string{"", "", "", "", "", "", ""}
-       j := len(parts) - 1
-
-       for v > 999 {
-               parts[j] = strconv.FormatInt(v%1000, 10)
-               switch len(parts[j]) {
-               case 2:
-                       parts[j] = "0" + parts[j]
-               case 1:
-                       parts[j] = "00" + parts[j]
-               }
-               v = v / 1000
+       var counter byte = 0
+       for v > 9 {
+               output[j] = byte(v%10) + 48
+               v = v / 10
                j--
+               if counter == 2 {
+                       counter = 0
+                       output[j] = ','
+                       j--
+               } else {
+                       counter++
+               }
        }
-       parts[j] = strconv.Itoa(int(v))
-       return sign + strings.Join(parts[j:], ",")
+
+       output[j] = byte(v) + 48
+       if j == 1 {
+               output[0] = '-'
+       }
+       return string(output)
 }
 
 // Commaf produces a string form of the given number in base 10 with
@@ -48,6 +62,16 @@
 //
 // e.g. Commaf(834142.32) -> 834,142.32
 func Commaf(v float64) string {
+       if math.IsNaN(v) {
+               return "NaN"
+       }
+       if math.IsInf(v, 1) {
+               return "+Inf"
+       }
+       if math.IsInf(v, -1) {
+               return "-Inf"
+       }
+
        buf := &bytes.Buffer{}
        if v < 0 {
                buf.Write([]byte{'-'})
@@ -76,17 +100,30 @@
        return buf.String()
 }
 
-// CommafWithDigits works like the Commaf but limits the resulting
-// string to the given number of decimal places.
+// CommafWithDigits works like the Commaf but always formats the
+// resulting string to exactly the given number of decimal places,
+// truncating extra digits or padding with zeros as needed.
 //
 // e.g. CommafWithDigits(834142.32, 1) -> 834,142.3
+// e.g. CommafWithDigits(1000, 2) -> 1,000.00
 func CommafWithDigits(f float64, decimals int) string {
-       return stripTrailingDigits(Commaf(f), decimals)
+       s := stripTrailingDigits(Commaf(f), decimals)
+       if decimals <= 0 {
+               return s
+       }
+
+       if dot := strings.IndexByte(s, '.'); dot < 0 {
+               s += "." + strings.Repeat("0", decimals)
+       } else if have := len(s) - dot - 1; have < decimals {
+               s += strings.Repeat("0", decimals-have)
+       }
+       return s
 }
 
 // BigComma produces a string form of the given big.Int in base 10
 // with commas after every three orders of magnitude.
-func BigComma(b *big.Int) string {
+func BigComma(bin *big.Int) string {
+       b := new(big.Int).Set(bin)
        sign := ""
        if b.Sign() < 0 {
                sign = "-"
@@ -114,3 +151,19 @@
        parts[j] = strconv.Itoa(int(b.Int64()))
        return sign + strings.Join(parts[j:], ",")
 }
+
+// ParseComma parses a string produced by Comma.
+// It strips commas and returns the int64 value, or an error if the
+// string cannot be parsed.
+func ParseComma(s string) (int64, error) {
+       s = strings.ReplaceAll(s, ",", "")
+       return strconv.ParseInt(s, 10, 64)
+}
+
+// ParseCommaf parses a string produced by Commaf.
+// It strips commas and returns the float64 value, or an error if the
+// string cannot be parsed.
+func ParseCommaf(s string) (float64, error) {
+       s = strings.ReplaceAll(s, ",", "")
+       return strconv.ParseFloat(s, 64)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/commaf.go 
new/vendor/github.com/dustin/go-humanize/commaf.go
--- old/vendor/github.com/dustin/go-humanize/commaf.go  2026-09-14 
17:14:03.000000000 +0200
+++ new/vendor/github.com/dustin/go-humanize/commaf.go  2026-09-24 
16:48:58.000000000 +0200
@@ -12,6 +12,13 @@
 // BigCommaf produces a string form of the given big.Float in base 10
 // with commas after every three orders of magnitude.
 func BigCommaf(v *big.Float) string {
+       if v.IsInf() {
+               if v.Sign() < 0 {
+                       return "-Inf"
+               }
+               return "+Inf"
+       }
+
        buf := &bytes.Buffer{}
        if v.Sign() < 0 {
                buf.Write([]byte{'-'})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/flake.lock 
new/vendor/github.com/dustin/go-humanize/flake.lock
--- old/vendor/github.com/dustin/go-humanize/flake.lock 1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/github.com/dustin/go-humanize/flake.lock 2026-09-24 
16:48:58.000000000 +0200
@@ -0,0 +1,58 @@
+{
+  "nodes": {
+    "flake-utils": {
+      "inputs": {
+        "systems": "systems"
+      },
+      "locked": {
+        "lastModified": 1731533236,
+        "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1789370336,
+        "narHash": "sha256-obwZbWHP7htCIoq2Z0g/uTMcEgN6yqcMNIcOMe6P2qI=",
+        "rev": "c7def046b9a883d46974757852106483d741586f",
+        "type": "tarball",
+        "url": 
"https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1073483.c7def046b9a8/nixexprs.tar.zst";
+      },
+      "original": {
+        "id": "nixpkgs",
+        "type": "indirect"
+      }
+    },
+    "root": {
+      "inputs": {
+        "flake-utils": "flake-utils",
+        "nixpkgs": "nixpkgs"
+      }
+    },
+    "systems": {
+      "locked": {
+        "lastModified": 1681028828,
+        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+        "owner": "nix-systems",
+        "repo": "default",
+        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+        "type": "github"
+      },
+      "original": {
+        "owner": "nix-systems",
+        "repo": "default",
+        "type": "github"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/flake.nix 
new/vendor/github.com/dustin/go-humanize/flake.nix
--- old/vendor/github.com/dustin/go-humanize/flake.nix  1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/github.com/dustin/go-humanize/flake.nix  2026-09-24 
16:48:58.000000000 +0200
@@ -0,0 +1,15 @@
+{
+  description = "go-humanize";
+  nixConfig.bash-prompt = "\[go-humanize\]$ ";
+
+  inputs.flake-utils.url = "github:numtide/flake-utils";
+
+  outputs = { self, nixpkgs, flake-utils }:
+    flake-utils.lib.eachDefaultSystem
+      (system:
+        let pkgs = nixpkgs.legacyPackages.${system}; in
+        {
+          devShells.default = import ./shell.nix { inherit pkgs; };
+        }
+      );
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/ftoa.go 
new/vendor/github.com/dustin/go-humanize/ftoa.go
--- old/vendor/github.com/dustin/go-humanize/ftoa.go    2026-09-14 
17:14:03.000000000 +0200
+++ new/vendor/github.com/dustin/go-humanize/ftoa.go    2026-09-24 
16:48:58.000000000 +0200
@@ -29,7 +29,7 @@
                        return s[:i]
                }
                i++
-               if i+digits >= len(s) {
+               if digits >= len(s)-i {
                        return s
                }
                return s[:i+digits]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/number.go 
new/vendor/github.com/dustin/go-humanize/number.go
--- old/vendor/github.com/dustin/go-humanize/number.go  2026-09-14 
17:14:03.000000000 +0200
+++ new/vendor/github.com/dustin/go-humanize/number.go  2026-09-24 
16:48:58.000000000 +0200
@@ -42,11 +42,12 @@
 )
 
 // FormatFloat produces a formatted number as string based on the following 
user-specified criteria:
+//
 // * thousands separator
 // * decimal separator
 // * decimal precision
 //
-// Usage: s := RenderFloat(format, n)
+// Usage: s := FormatFloat(format, n)
 // The format parameter tells how to render the number n.
 //
 // See examples: http://play.golang.org/p/LXc1Ddm1lJ
@@ -111,7 +112,7 @@
                        //        +0000
                        if formatIndx[0] == 0 {
                                if format[formatIndx[0]] != '+' {
-                                       panic("RenderFloat(): invalid positive 
sign directive")
+                                       panic("FormatFloat(): invalid positive 
sign directive")
                                }
                                positiveStr = "+"
                                formatIndx = formatIndx[1:]
@@ -125,7 +126,7 @@
                        // 000,000.00
                        if len(formatIndx) == 2 {
                                if (formatIndx[1] - formatIndx[0]) != 4 {
-                                       panic("RenderFloat(): thousands 
separator directive must be followed by 3 digit-specifiers")
+                                       panic("FormatFloat(): thousands 
separator directive must be followed by 3 digit-specifiers")
                                }
                                thousandStr = string(format[formatIndx[0]])
                                formatIndx = formatIndx[1:]
@@ -160,7 +161,7 @@
        intf, fracf := math.Modf(n + renderFloatPrecisionRounders[precision])
 
        // generate integer part string
-       intStr := strconv.FormatInt(int64(intf), 10)
+       intStr := strconv.FormatFloat(intf, 'f', 0, 64)
 
        // add thousand separator if required
        if len(thousandStr) > 0 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/shell.nix 
new/vendor/github.com/dustin/go-humanize/shell.nix
--- old/vendor/github.com/dustin/go-humanize/shell.nix  1970-01-01 
01:00:00.000000000 +0100
+++ new/vendor/github.com/dustin/go-humanize/shell.nix  2026-09-24 
16:48:58.000000000 +0200
@@ -0,0 +1,11 @@
+{ pkgs ? import <nixpkgs> { } }:
+with pkgs;
+mkShell {
+  buildInputs = [
+    go
+    gotools
+  ];
+
+  shellHook = ''
+  '';
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/si.go 
new/vendor/github.com/dustin/go-humanize/si.go
--- old/vendor/github.com/dustin/go-humanize/si.go      2026-09-14 
17:14:03.000000000 +0200
+++ new/vendor/github.com/dustin/go-humanize/si.go      2026-09-24 
16:48:58.000000000 +0200
@@ -33,12 +33,39 @@
 
 var revSIPrefixTable = revfmap(siPrefixTable)
 
+// minSIExponent and maxSIExponent are the smallest and largest exponents
+// siPrefixTable can name. They are derived from the table rather than written
+// down so that adding a prefix (as ronto/quecto/ronna/quetta were added) keeps
+// them correct.
+var minSIExponent, maxSIExponent = func() (float64, float64) {
+       min, max := math.Inf(1), math.Inf(-1)
+       for k := range siPrefixTable {
+               if k < min {
+                       min = k
+               }
+               if k > max {
+                       max = k
+               }
+       }
+       return min, max
+}()
+
+// siParseAliases lets ParseSI accept extra spellings of prefixes that look
+// identical to the canonical ones in siPrefixTable. Output still uses the
+// canonical character; this is input-side only.
+var siParseAliases = map[string]float64{
+       "μ": 1e-6, // GREEK SMALL LETTER MU, often typed instead of µ (U+00B5)
+}
+
 // revfmap reverses the map and precomputes the power multiplier
 func revfmap(in map[float64]string) map[string]float64 {
        rv := map[string]float64{}
        for k, v := range in {
                rv[v] = math.Pow(10, k)
        }
+       for a, v := range siParseAliases {
+               rv[a] = v
+       }
        return rv
 }
 
@@ -49,6 +76,9 @@
        for _, v := range siPrefixTable {
                ri += v
        }
+       for a := range siParseAliases {
+               ri += a
+       }
        ri += `]?)(.*)`
 
        riParseRegex = regexp.MustCompile(ri)
@@ -69,11 +99,23 @@
        exponent := math.Floor(logn(mag, 10))
        exponent = math.Floor(exponent/3) * 3
 
+       // Outside the table there is no prefix that can name the magnitude, so
+       // clamp to the nearest one there is and let the returned value carry 
the
+       // remaining orders of magnitude. Without this the lookup below misses,
+       // the prefix comes back as the empty string, and the value is left 
scaled
+       // for a prefix that was never returned - so the caller silently gets a
+       // number off by as much as 10^300 with no error.
+       if exponent < minSIExponent {
+               exponent = minSIExponent
+       } else if exponent > maxSIExponent {
+               exponent = maxSIExponent
+       }
+
        value := mag / math.Pow(10, exponent)
 
        // Handle special case where value is exactly 1000.0
        // Should return 1 M instead of 1000 k
-       if value == 1000.0 {
+       if value == 1000.0 && exponent+3 <= maxSIExponent {
                exponent += 3
                value = mag / math.Pow(10, exponent)
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/dustin/go-humanize/times.go 
new/vendor/github.com/dustin/go-humanize/times.go
--- old/vendor/github.com/dustin/go-humanize/times.go   2026-09-14 
17:14:03.000000000 +0200
+++ new/vendor/github.com/dustin/go-humanize/times.go   2026-09-24 
16:48:58.000000000 +0200
@@ -4,6 +4,7 @@
        "fmt"
        "math"
        "sort"
+       "strings"
        "time"
 )
 
@@ -113,5 +114,12 @@
                        escaped = ch == '%'
                }
        }
-       return fmt.Sprintf(mag.Format, args...)
+       s := fmt.Sprintf(mag.Format, args...)
+       if lbl == "" {
+               // When the label is empty, trim the whitespace its "%s"
+               // placeholder would otherwise leave behind (e.g. a trailing
+               // space in "3 weeks %s").
+               s = strings.TrimRight(s, " ")
+       }
+       return s
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/internal/version/version.go
 
new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/internal/version/version.go
--- 
old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/internal/version/version.go
  2026-09-14 17:14:03.000000000 +0200
+++ 
new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/internal/version/version.go
  2026-09-24 16:48:58.000000000 +0200
@@ -1,4 +1,4 @@
 package version
 
 // Version is the library's version following Semantic Versioning.
-const Version = "2.48.0" // x-releaser-pleaser-version
+const Version = "2.49.0" // x-releaser-pleaser-version
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/network.go 
new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/network.go
--- old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/network.go   
2026-09-14 17:14:03.000000000 +0200
+++ new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/network.go   
2026-09-24 16:48:58.000000000 +0200
@@ -84,6 +84,47 @@
        Delete bool
 }
 
+// NetworkMember represents a resource attached to a [Network].
+type NetworkMember struct {
+       Type     NetworkMemberType
+       ID       int64
+       IP       net.IP
+       Status   NetworkMemberStatus
+       AliasIPs []net.IP
+       Subnet   *net.IPNet
+}
+
+// NetworkMemberType specifies the type of a resource attached to a [Network].
+type NetworkMemberType string
+
+// List of available [NetworkMember] types.
+const (
+       // NetworkMemberTypeServer is a [Server] attached to a [Network].
+       NetworkMemberTypeServer NetworkMemberType = "server"
+       // NetworkMemberTypeLoadBalancer is a [LoadBalancer] attached to a 
[Network].
+       NetworkMemberTypeLoadBalancer NetworkMemberType = "load_balancer"
+)
+
+// NetworkMemberStatus specifies the status of a resource attached to a 
[Network].
+type NetworkMemberStatus string
+
+// List of available [NetworkMember] statuses.
+const (
+       // NetworkMemberStatusOK indicates the resource is attached and its 
network
+       // configuration is up to date.
+       NetworkMemberStatusOK NetworkMemberStatus = "ok"
+       // NetworkMemberStatusAttaching indicates the resource is being 
attached to the [Network].
+       NetworkMemberStatusAttaching NetworkMemberStatus = "attaching"
+       // NetworkMemberStatusDetaching indicates the resource is being 
detached from the [Network].
+       NetworkMemberStatusDetaching NetworkMemberStatus = "detaching"
+       // NetworkMemberStatusUpdating indicates the resource network 
configuration is being updated.
+       NetworkMemberStatusUpdating NetworkMemberStatus = "updating"
+       // NetworkMemberStatusError indicates the last operation on this member 
failed. Its
+       // network configuration might be out of date, and the resource might 
not be
+       // reachable within the network.
+       NetworkMemberStatusError NetworkMemberStatus = "error"
+)
+
 // NetworkClient is a client for the network API.
 type NetworkClient struct {
        client *Client
@@ -436,3 +477,66 @@
 
        return ActionFromSchema(respBody.Action), resp, nil
 }
+
+// NetworkMemberListOpts specifies options for listing members of a [Network].
+type NetworkMemberListOpts struct {
+       ListOpts
+       Type   []NetworkMemberType
+       Subnet []*net.IPNet
+       Status []NetworkMemberStatus
+       Sort   []string
+}
+
+func (l NetworkMemberListOpts) Values() url.Values {
+       vals := l.ListOpts.Values()
+       for _, t := range l.Type {
+               vals.Add("type", string(t))
+       }
+       for _, s := range l.Subnet {
+               vals.Add("subnet", s.String())
+       }
+       for _, s := range l.Status {
+               vals.Add("status", string(s))
+       }
+       for _, s := range l.Sort {
+               vals.Add("sort", s)
+       }
+       return vals
+}
+
+// ListMembers returns a list of [NetworkMember] attached to a specific 
[Network] for the given options.
+//
+// See 
https://docs.hetzner.cloud/reference/cloud#tag/networks/list_network_members
+func (c *NetworkClient) ListMembers(ctx context.Context, network *Network, 
opts NetworkMemberListOpts) ([]*NetworkMember, *Response, error) {
+       const opPath = "/networks/%d/members?%s"
+       ctx = ctxutil.SetOpPath(ctx, opPath)
+
+       reqPath := fmt.Sprintf(opPath, network.ID, opts.Values().Encode())
+
+       respBody, resp, err := 
getRequest[schema.NetworkMemberListResponse](ctx, c.client, reqPath)
+       if err != nil {
+               return nil, resp, err
+       }
+
+       return allFromSchemaFunc(respBody.Members, NetworkMemberFromSchema), 
resp, nil
+}
+
+// AllMembersWithOpts returns all [NetworkMember] attached to a specific 
[Network] for the given options.
+//
+// See 
https://docs.hetzner.cloud/reference/cloud#tag/networks/list_network_members
+func (c *NetworkClient) AllMembersWithOpts(ctx context.Context, network 
*Network, opts NetworkMemberListOpts) ([]*NetworkMember, error) {
+       if opts.ListOpts.PerPage == 0 {
+               opts.ListOpts.PerPage = 50
+       }
+       return iterPages(func(page int) ([]*NetworkMember, *Response, error) {
+               opts.Page = page
+               return c.ListMembers(ctx, network, opts)
+       })
+}
+
+// AllMembers returns all [NetworkMember] attached to a specific [Network].
+//
+// See 
https://docs.hetzner.cloud/reference/cloud#tag/networks/list_network_members
+func (c *NetworkClient) AllMembers(ctx context.Context, network *Network) 
([]*NetworkMember, error) {
+       return c.AllMembersWithOpts(ctx, network, NetworkMemberListOpts{})
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/network.go 
new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/network.go
--- old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/network.go    
2026-09-14 17:14:03.000000000 +0200
+++ new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema/network.go    
2026-09-24 16:48:58.000000000 +0200
@@ -153,3 +153,19 @@
 type NetworkActionChangeProtectionResponse struct {
        Action Action `json:"action"`
 }
+
+// NetworkMember defines the schema of a resource attached to a network.
+type NetworkMember struct {
+       Type     string   `json:"type"`
+       ID       int64    `json:"id"`
+       IP       string   `json:"ip"`
+       Status   string   `json:"status"`
+       AliasIPs []string `json:"alias_ips"`
+       Subnet   string   `json:"subnet"`
+}
+
+// NetworkMemberListResponse defines the schema of the response when
+// listing members of a network.
+type NetworkMemberListResponse struct {
+       Members []NetworkMember `json:"members"`
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema_gen.go 
new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema_gen.go
--- old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema_gen.go        
2026-09-14 17:14:03.000000000 +0200
+++ new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/schema_gen.go        
2026-09-24 16:48:58.000000000 +0200
@@ -218,6 +218,10 @@
 
        SchemaFromNetworkRoute(NetworkRoute) schema.NetworkRoute
 
+       NetworkMemberFromSchema(schema.NetworkMember) *NetworkMember
+
+       SchemaFromNetworkMember(*NetworkMember) schema.NetworkMember
+
        LoadBalancerFromSchema(schema.LoadBalancer) *LoadBalancer
 
        // goverter:map OutgoingTraffic | mapZeroUint64ToNil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_network_client_iface.go
 
new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_network_client_iface.go
--- 
old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_network_client_iface.go
   2026-09-14 17:14:03.000000000 +0200
+++ 
new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_network_client_iface.go
   2026-09-24 16:48:58.000000000 +0200
@@ -42,4 +42,16 @@
        DeleteRoute(ctx context.Context, network *Network, opts 
NetworkDeleteRouteOpts) (*Action, *Response, error)
        // ChangeProtection changes the resource protection level of a network.
        ChangeProtection(ctx context.Context, network *Network, opts 
NetworkChangeProtectionOpts) (*Action, *Response, error)
+       // ListMembers returns a list of [NetworkMember] attached to a specific 
[Network] for the given options.
+       //
+       // See 
https://docs.hetzner.cloud/reference/cloud#tag/networks/list_network_members
+       ListMembers(ctx context.Context, network *Network, opts 
NetworkMemberListOpts) ([]*NetworkMember, *Response, error)
+       // AllMembersWithOpts returns all [NetworkMember] attached to a 
specific [Network] for the given options.
+       //
+       // See 
https://docs.hetzner.cloud/reference/cloud#tag/networks/list_network_members
+       AllMembersWithOpts(ctx context.Context, network *Network, opts 
NetworkMemberListOpts) ([]*NetworkMember, error)
+       // AllMembers returns all [NetworkMember] attached to a specific 
[Network].
+       //
+       // See 
https://docs.hetzner.cloud/reference/cloud#tag/networks/list_network_members
+       AllMembers(ctx context.Context, network *Network) ([]*NetworkMember, 
error)
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_schema.go 
new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_schema.go
--- old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_schema.go 
2026-09-14 17:14:03.000000000 +0200
+++ new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_schema.go 
2026-09-24 16:48:58.000000000 +0200
@@ -115,6 +115,11 @@
        return c.NetworkFromSchema(in)
 }
 
+// NetworkMemberFromSchema converts schema.NetworkMember to *NetworkMember.
+func NetworkMemberFromSchema(in schema.NetworkMember) *NetworkMember {
+       return c.NetworkMemberFromSchema(in)
+}
+
 // NetworkRouteFromSchema converts schema.NetworkRoute to NetworkRoute.
 func NetworkRouteFromSchema(in schema.NetworkRoute) NetworkRoute {
        return c.NetworkRouteFromSchema(in)
@@ -290,6 +295,11 @@
        return c.SchemaFromNetwork(in)
 }
 
+// SchemaFromNetworkMember converts *NetworkMember to schema.NetworkMember.
+func SchemaFromNetworkMember(in *NetworkMember) schema.NetworkMember {
+       return c.SchemaFromNetworkMember(in)
+}
+
 // SchemaFromNetworkRoute converts NetworkRoute to schema.NetworkRoute.
 func SchemaFromNetworkRoute(in NetworkRoute) schema.NetworkRoute {
        return c.SchemaFromNetworkRoute(in)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_schema_converter.go 
new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_schema_converter.go
--- 
old/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_schema_converter.go   
    2026-09-14 17:14:03.000000000 +0200
+++ 
new/vendor/github.com/hetznercloud/hcloud-go/v2/hcloud/zz_schema_converter.go   
    2026-09-24 16:48:58.000000000 +0200
@@ -341,6 +341,22 @@
        hcloudNetwork.ExposeRoutesToVSwitch = source.ExposeRoutesToVSwitch
        return &hcloudNetwork
 }
+func (c *converterImpl) NetworkMemberFromSchema(source schema.NetworkMember) 
*NetworkMember {
+       var hcloudNetworkMember NetworkMember
+       hcloudNetworkMember.Type = NetworkMemberType(source.Type)
+       hcloudNetworkMember.ID = source.ID
+       hcloudNetworkMember.IP = ipFromString(source.IP)
+       hcloudNetworkMember.Status = NetworkMemberStatus(source.Status)
+       if source.AliasIPs != nil {
+               hcloudNetworkMember.AliasIPs = make([]net.IP, 
len(source.AliasIPs))
+               for i := 0; i < len(source.AliasIPs); i++ {
+                       hcloudNetworkMember.AliasIPs[i] = 
ipFromString(source.AliasIPs[i])
+               }
+       }
+       netIPNet := ipNetFromString(source.Subnet)
+       hcloudNetworkMember.Subnet = &netIPNet
+       return &hcloudNetworkMember
+}
 func (c *converterImpl) NetworkRouteFromSchema(source schema.NetworkRoute) 
NetworkRoute {
        var hcloudNetworkRoute NetworkRoute
        netIPNet := ipNetFromString(source.Destination)
@@ -837,6 +853,23 @@
        }
        return schemaNetwork
 }
+func (c *converterImpl) SchemaFromNetworkMember(source *NetworkMember) 
schema.NetworkMember {
+       var schemaNetworkMember schema.NetworkMember
+       if source != nil {
+               schemaNetworkMember.Type = string((*source).Type)
+               schemaNetworkMember.ID = (*source).ID
+               schemaNetworkMember.IP = stringFromIP((*source).IP)
+               schemaNetworkMember.Status = string((*source).Status)
+               if (*source).AliasIPs != nil {
+                       schemaNetworkMember.AliasIPs = make([]string, 
len((*source).AliasIPs))
+                       for i := 0; i < len((*source).AliasIPs); i++ {
+                               schemaNetworkMember.AliasIPs[i] = 
stringFromIP((*source).AliasIPs[i])
+                       }
+               }
+               schemaNetworkMember.Subnet = 
c.pNetIPNetToString((*source).Subnet)
+       }
+       return schemaNetworkMember
+}
 func (c *converterImpl) SchemaFromNetworkRoute(source NetworkRoute) 
schema.NetworkRoute {
        var schemaNetworkRoute schema.NetworkRoute
        schemaNetworkRoute.Destination = c.pNetIPNetToString(source.Destination)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/modules.txt new/vendor/modules.txt
--- old/vendor/modules.txt      2026-09-14 17:14:03.000000000 +0200
+++ new/vendor/modules.txt      2026-09-24 16:48:58.000000000 +0200
@@ -25,8 +25,8 @@
 # github.com/cpuguy83/go-md2man/v2 v2.0.7
 ## explicit; go 1.12
 github.com/cpuguy83/go-md2man/v2/md2man
-# github.com/dustin/go-humanize v1.0.1
-## explicit; go 1.16
+# github.com/dustin/go-humanize v1.1.0
+## explicit; go 1.21
 github.com/dustin/go-humanize
 # github.com/fatih/color v1.19.0
 ## explicit; go 1.25.0
@@ -56,7 +56,7 @@
 # github.com/guptarohit/asciigraph v0.10.0
 ## explicit; go 1.11
 github.com/guptarohit/asciigraph
-# github.com/hetznercloud/hcloud-go/v2 v2.48.0
+# github.com/hetznercloud/hcloud-go/v2 v2.49.0
 ## explicit; go 1.25.0
 github.com/hetznercloud/hcloud-go/v2/hcloud
 github.com/hetznercloud/hcloud-go/v2/hcloud/exp/actionutil

Reply via email to