Repository navigation
Allow servers without a public IPv6 address - #38
Conversation
Hetzner Cloud servers can have their public IPv6 disabled, in which case
the API returns `"ipv6": null` under `public_net`. The sync crashed with
NoMethodError when chaining `fetch("ip")` on that nil, failing the whole
"Refresh servers" action.
Make `servers.ipv6` nullable, drop its presence validation and use `dig`
when reading it from the Hetzner Cloud payload.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| @@ -20,7 +20,7 @@ def self.sync_to_activerecord | |||
| data_center: server_payload.fetch("location").fetch("name"), | |||
| hetzner_vswitch_id: nil, | |||
| ip: server_payload.fetch("public_net").fetch("ipv4").fetch("ip"), | |||
There was a problem hiding this comment.
The same crash still exists for the IPv4 side: Hetzner Cloud also lets you create servers with public IPv4 disabled (IPv6-only, which is cheaper). The API then returns "ipv4": null, so .fetch("ipv4").fetch("ip") raises NoMethodError on nil and "Refresh servers" fails for every API key. The fix here only covers one of the two symmetric cases. Fully supporting IPv6-only servers would also need ip to be nullable and SSH/bootstrap to fall back to ipv6. If that is out of scope, consider at least raising a clear error that names the server instead of crashing the whole sync.
| @@ -0,0 +1,5 @@ | |||
| class ChangeServersIpv6Nullable < ActiveRecord::Migration[8.0] | |||
| def change | |||
| change_column_null :servers, :ipv6, true | |||
There was a problem hiding this comment.
Nit: once any server has been synced with ipv6 = NULL, rolling back this migration fails with PG::NotNullViolation, because change_column_null reverses to NOT NULL without a default. That is probably fine, but you could pass a default for rollback (change_column_null :servers, :ipv6, true, "") or make it explicitly irreversible.
Hetzner Cloud servers can have their public IPv6 disabled, in which case the API returns
"ipv6": nullunderpublic_net. "Refresh servers" then failed with a 500:Changes
servers.ipv6nullablevalidates_presence_of :ipv6onServerdig("public_net", "ipv6", "ip")inHetznerCloud.sync_to_activerecordworker-2now has"ipv6": null, and the sync request spec asserts it ends up withipv6: nil(the spec fails with the originalNoMethodErrorwithout the fix)ipv6isn't read anywhere else in the app, so nothing downstream depends on it being present.🤖 Generated with Claude Code