Skip to content

Consolidate IPAddress/IPAddressClaim into IPPrefix/IPPrefixClaim #22

@scotwells

Description

@scotwells

Background

We are integrating milo-os/ipam into datum-cloud/network-services-operator as the IPAM backend for a cloud networking platform. During design, we identified that IPAddress/IPAddressClaim and IPPrefix/IPPrefixClaim are mathematically the same concept — a single host address is just a prefix with prefixLength: 128 (IPv6) or prefixLength: 32 (IPv4).

The IPAM service's own database schema reflects this: both resource types write to ipam_prefix_allocations, with only the is_child_pool flag distinguishing them. The core allocation algorithm FindFirstAvailableBlock in internal/allocation/cidr.go is identical for both cases.

Proposal

Remove IPAddress and IPAddressClaim as distinct resource types. Treat a single host address as an IPPrefixClaim with prefixLength: 128. The childPrefixTemplate and capacity tracking on IPPrefix simply become irrelevant at /128 — no enforcement needed.

This gives a natural continuum across a single resource type:

IPPrefixClaim { prefixLength: 48  } → network pool
IPPrefixClaim { prefixLength: 56  } → regional delegation
IPPrefixClaim { prefixLength: 64  } → subnet
IPPrefixClaim { prefixLength: 128 } → single host address

Benefits

  • Reduces the API surface from four resource types to two (IPPrefix, IPPrefixClaim)
  • Consumers only need one claim type regardless of whether they want a single IP or a subnet — controlled by prefixLength
  • Eliminates a conceptual split that doesn't exist at the storage or algorithm layer
  • Simplifies client code that currently needs to branch between IPAddressClaim and IPPrefixClaim depending on allocation size

Impact on Consumers

In datum-cloud/network-services-operator, NetworkInterface resources need to allocate either a single address (/128) or an entire subnet (e.g., /64) depending on the interface type. With consolidation, this becomes a single ipPrefixClaimTemplate field with a prefixLength parameter rather than two separate mutually exclusive template fields (ipAddressClaimTemplate vs ipPrefixClaimTemplate).

The integration also spans datum-cloud/compute, which creates NetworkInterfaceClaim resources that flow down through NSO to IPAM for address allocation.

Things to Verify Before Implementing

  • Confirm FindFirstAvailableBlock handles /128 claims against a /64 parent pool correctly (expected: yes, since it operates on prefix lengths generically)
  • Confirm capacity tracking on IPPrefix handles the case where prefixLength == 128 without breaking utilization metrics
  • Confirm childPrefixTemplate is simply a no-op / not applicable when prefixLength == 128
  • Migration path for any existing users of IPAddressClaim

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions