Skip to content

Add SubnetPool controller#844

Open
winiciusallan wants to merge 5 commits into
k-orc:mainfrom
winiciusallan:subnet-pool-controller
Open

Add SubnetPool controller#844
winiciusallan wants to merge 5 commits into
k-orc:mainfrom
winiciusallan:subnet-pool-controller

Conversation

@winiciusallan

Copy link
Copy Markdown
Member

This PR introduces the SubnetPool controller, which delegates the manage of subnet addresses allocation to Neutron.

Notes:

  • I decide to not implement the DefaultQuota, because we can't unset it, neither create it as 0.
  • Also I thought reasonable to keep the <Min|Max>PrefixLength required in the API, because we can't unset them when updating. Another possibility is to keep them immutable.

Closes #393

@github-actions github-actions Bot added the semver:major Breaking change label Jul 8, 2026
Comment thread api/v1alpha1/subnetpool_types.go

@dlaw4608 dlaw4608 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @winiciusallan ran through the e2e tests all work locally, overall the controller looks really good, only have the minor question regarding the mutability of the shared field

$ go run ./cmd/scaffold-controller -interactive=false \
    -gophercloud-client=NewNetworkV2 \
    -kind SubnetPool \
    -gophercloud-module=github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/subnetpools \
    -import-dependency Project \
    -import-dependency AddressScope \
    -optional-create-dependency Project \
    -optional-create-dependency AddressScope
@winiciusallan winiciusallan force-pushed the subnet-pool-controller branch from 97fd880 to 64d0da4 Compare July 9, 2026 18:25
@winiciusallan winiciusallan force-pushed the subnet-pool-controller branch from 64d0da4 to 8923c5f Compare July 11, 2026 19:38

@eshulman2 eshulman2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is a blocking issue for this one (from initial review) will make a second pass later

}
}

func handlePrefixesUpdate(updateOpts *subnetpools.UpdateOpts, resource *resourceSpecT, osResource *osResourceT) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note the following:

A list of subnet prefixes to assign to the subnet pool. The API merges adjacent prefixes and treats them as a single prefix. Each subnet prefix must be unique among all subnet prefixes in all subnet pools that are associated with the address scope.

https://docs.openstack.org/api-ref/network/v2/#id295

Neutron merges adjacent prefixes meaning that the response for:

{
  "prefixes": ["192.168.0.0/24", "192.168.1.0/24", "172.16.0.0/21"]
}

Would look like this:

{
  "prefixes": ["192.168.0.0/23", "172.16.0.0/21"]
}

(from the example in the link above)

Because this compares the literal sorted slices, the desired and observed values will never match in that case. The controller will repeatedly call UpdateSubnetPool and request another refresh, even though the address space is already correct.

Can you compare normalized CIDR sets instead?

Please also add a KUTTL test that creates a pool with two adjacent prefixes and verifies that it reaches Available=True and Progressing=False. That should catch a continuous reconciliation loop.

// +kubebuilder:validation:MaxItems:=64
// +listType=set
// +required
Prefixes []CIDR `json:"prefixes,omitempty"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefix is mutable but neutron would only accept a superset of the old list of prefixes meaning that removing a prefix from the list would cause neutron to fail (although CRD update would be allowed). This means users are allowed to request an operation that the controller can't complete.

To actually allow update I think we should add a reconciler that uses the add and remove prefix endpoint. This will allow real mutability for this field.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I think this is the approach to be followed, we're currently missing the API calls for operations on subnet pool prefixes in Gophercloud. I opened gophercloud/gophercloud#3850 to track this work, but while this is not merged, what do you think of having this field immutable?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a fair compromise for now.

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

Labels

semver:major Breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable (IPv6) Subnet Allocation with AddressScope/SubnetPool

3 participants