Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ layout:
projectName: orc
repo: github.com/k-orc/openstack-resource-controller
resources:
- api:
crdVersion: v1
namespaced: true
domain: k-orc.cloud
group: openstack
kind: AddressScope
path: github.com/k-orc/openstack-resource-controller/api/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ kubectl delete -f $ORC_RELEASE

| **controller** | **1.x** | **2.x** | **main** |
|:---------------------------:|:-------:|:-------:|:--------:|
| addressscope | | ✔ | ✔ |
| domain | | ✔ | ✔ |
| endpoint | | ◐ | ◐ |
| flavor | | ✔ | ✔ |
Expand Down
88 changes: 88 additions & 0 deletions api/v1alpha1/addressscope_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
Copyright The ORC Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

// AddressScopeResourceSpec contains the desired state of the resource.
type AddressScopeResourceSpec struct {
// name will be the name of the created resource. If not specified, the
// name of the ORC object will be used.
// +optional
Name *OpenStackName `json:"name,omitempty"`

// projectRef is a reference to the ORC Project which this resource is associated with.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="projectRef is immutable"
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`

// ipVersion is the IP protocol version.
// +required
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ipVersion is immutable"
IPVersion IPVersion `json:"ipVersion"`

// shared indicates whether this resource is shared across all
// projects or not. By default, only admin users can change set
// this value. We can't unshared a shared address scope; Neutron
// enforces this.
// +optional
// +kubebuilder:validation:XValidation:rule="!(oldSelf && !self)",message="shared address scope can't be unshared"
Copy link
Collaborator

Choose a reason for hiding this comment

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

We haven't been really good at consistently writing API validation tests for our controller. Ideally we should have one for this field because the CEL validation is getting complex.

(I've just asked claude to write the missing tests, we'll see what it's going to come up with 😅)

Shared *bool `json:"shared,omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Although the Shared field is mutable in the API, I've decided to keep it as immutable because we can't update true -> false

Is that right? It's both a pointer here and in gophercloud, so we should be able to pass it a value of false when updating the field. Do you recall what the problem was exactly?

Copy link
Contributor Author

@winiciusallan winiciusallan Mar 9, 2026

Choose a reason for hiding this comment

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

Yes. The error is with those lines. Looks like something to change in OpenStack (if it really makes sense to change).

Taking a quick look at the feature spec[1] and at the first commit review[2] for this feature, I didn't find any rationale to have this as it is.

[1] https://specs.openstack.org/openstack/neutron-specs/specs/mitaka/address-scopes.html
[2] https://review.opendev.org/c/openstack/neutron/+/189741?tab=comments

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you are okay with this, I can bring this discussion to the next neutron meeting and double-check with the maintainers.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh ok, thanks for the pointer. It looks intentional. In that case, we should add a comment explaining our choice.
Or alternatively, we make it mutable, but add a CEL validation that prevents unsharing a shared address scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok. I made the field mutable, but added a validation to prevent unsharing the address scope. I think it is better to comply with the OpenStack behavior and give the operator the ability to share it if they want to.

About the addressscope-update, I added a new step file to create an AddressScope so we can change the share field later, but not revert it on 02-reverted-resource.yaml.

Actually, I think it'll be cleaner if we could capture the CEL validation and ensure that it's throwing properly. About this, I thought of capturing the output of the command in 02-reverted-resource.yaml and checking for the same message as in the CEL expression. Wdyt?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Or we just test CEL validation via test/apivalidations. Whatever is simpler.

I like using test/apivalidations because that provides more flexibility, and we already have that in place.

}

// AddressScopeFilter defines an existing resource by its properties
// +kubebuilder:validation:MinProperties:=1
type AddressScopeFilter struct {
// name of the existing resource
// +optional
Name *OpenStackName `json:"name,omitempty"`

// projectRef is a reference to the ORC Project which this resource is associated with.
// +optional
ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"`

// ipVersion is the IP protocol version.
// +optional
IPVersion IPVersion `json:"ipVersion,omitempty"`

// shared indicates whether this resource is shared across all
// projects or not. By default, only admin users can change set
// this value.
// +optional
Shared *bool `json:"shared,omitempty"`
}

// AddressScopeResourceStatus represents the observed state of the resource.
type AddressScopeResourceStatus struct {
// name is a Human-readable name for the resource. Might not be unique.
// +kubebuilder:validation:MaxLength=1024
// +optional
Name string `json:"name,omitempty"`

// projectID is the ID of the Project to which the resource is associated.
// +kubebuilder:validation:MaxLength=1024
// +optional
ProjectID string `json:"projectID,omitempty"`

// ipVersion is the IP protocol version.
// +optional
IPVersion int32 `json:"ipVersion,omitempty"`

// shared indicates whether this resource is shared across all
// projects or not. By default, only admin users can change set
// this value.
// +optional
Shared *bool `json:"shared,omitempty"`
}
179 changes: 179 additions & 0 deletions api/v1alpha1/zz_generated.addressscope-resource.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading