Skip to content

feat: support selecting a subnet via ip_range on --hetzner-networks - #131

Open
ufukdev wants to merge 1 commit into
JonasProgrammer:masterfrom
ufukdev:feat/network-ip-range
Open

ufukdev wants to merge 1 commit into
JonasProgrammer:masterfrom
ufukdev:feat/network-ip-range

Conversation

@ufukdev

@ufukdev ufukdev commented Oct 2, 2026

Copy link
Copy Markdown

Summary

Since 2025-09-11 the Hetzner Cloud API supports an ip_range attribute on the attach_to_network action, which selects the subnet a server's private IP is taken from (changelog).

This PR exposes it through the existing --hetzner-networks flag:

--hetzner-networks my-network:10.0.1.0/24

Changes

  • Values are split at the last :. If the suffix is not a CIDR in network form, the whole value is used as ID/name as before, so existing names containing : keep working.
  • The IP range is checked against the network's subnets before the server is created.
  • POST /servers does not accept ip_range, so networks with an IP range are attached after creation: the server is created with start_after_create=false, pending next_actions are awaited, the networks are attached and the server is powered on. This way cloud-init sees all networks on first boot.
  • If all public IPs are disabled and every network has an IP range, the API rejects creating a server without any interface. The server is then created with a temporary public IPv6, which is unassigned and deleted before the first power-on. Firewalls are skipped in this case, since they only filter public traffic.
  • Networks without an IP range are attached during creation, exactly as before.
  • README and flag usage are updated.

Backward compatibility

Without the :<ip-range> suffix nothing changes: no additional API calls are made and start_after_create is not sent.

Testing

  • Unit tests for parsing, subnet validation and the temporary IPv6 decision
  • Create() flow against a mock API enforcing the documented Hetzner rules: request sequence identical to master for all existing flag combinations (plain networks, private network, disabled public network, IDs, firewalls)
  • Injected failures at attach, unassign, delete and power-on
  • golangci-lint: 0 issues
  • Tested against a real Hetzner Cloud project

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant