Skip to content

Manila: Share network#691

Open
dlaw4608 wants to merge 2 commits intok-orc:mainfrom
dlaw4608:share_network
Open

Manila: Share network#691
dlaw4608 wants to merge 2 commits intok-orc:mainfrom
dlaw4608:share_network

Conversation

@dlaw4608
Copy link
Contributor

Add support for Openstack Manila Service Share Network resource
Closes: #687

@github-actions
Copy link

Failed to assess the semver bump. See logs for details.

@github-actions github-actions bot added the semver:major Breaking change label Feb 24, 2026
@dlaw4608 dlaw4608 force-pushed the share_network branch 2 times, most recently from 79282c8 to 08867bf Compare February 24, 2026 19:10
@dlaw4608 dlaw4608 marked this pull request as ready for review February 25, 2026 10:21
Copy link
Contributor

@winiciusallan winiciusallan left a comment

Choose a reason for hiding this comment

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

Hey @dlaw4608, I left a few comments, but I need some more time to take a look at the other test scenarios. For now, let me know what you think about what it is commented.

Comment on lines 35 to 42
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="networkRef is immutable"
NetworkRef *KubernetesNameRef `json:"networkRef,omitempty"`

// subnetRef is a reference to the ORC Subnet which this resource is associated with.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="subnetRef is immutable"
SubnetRef *KubernetesNameRef `json:"subnetRef,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like both NetworkRef and SubnetRef are required according to the docs.

Specify both a neutron network and a neutron subnet that belongs to that neutron network.

Also, you've specified these two fields in the create-minimal, so I'm assuming that the claim above is true. Isn't it better to define these two fields as required and remove the omitempty tag?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting because when i look at the API docs it says that the fields are optional, now in what scenario are you not including a neutron_id or neutron_subnet when creating a share_network resource I'm not quite sure 🤷, but I guess I was more just reflecting what the fields were shown as in the API and gophercloud. I am curious though to the documentation you refer to above, so please share a link if you can 👍 , happy to make the change if needed.

For the moment though I just stripped the dependencies from the create-minimal assertion in step 0, and left the dependencies as optional.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I wasn't too clear. I meant that network and subnet should both be passed together and I thought they were required, but this is wrong.

Ella has already pointed out a comment to use a validation to ensure that these two fields will be passed together in the request, so you can consider this as resolved :)

const ShareNetworkStatusInUse = "in-use"
const ShareNetworkStatusDeleting = "deleting"

const (
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe we're not using any of these statuses throughout the code, and it looks like we don't have a status field in the ShareNetwork struct on Gophercloud's side. Is this useful?

Maybe do we need to create an issue to address this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes you are correct they are not necessary here I removed them, thanks 👍

Comment on lines +37 to +38
- celExpr: "sharenetwork.status.resource.name == 'sharenetwork-create-full-override'"
- celExpr: "sharenetwork.status.resource.description == 'ShareNetwork from \"create full\" test'"
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need this check since KUTTL already matches fields from declaration vs status.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the Feedback @winiciusallan , i could of sworn i had already left these comments last week but clearly never actually clicked the big green button ack.

Copy link
Contributor

Choose a reason for hiding this comment

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

It happens 😄

@dlaw4608 dlaw4608 force-pushed the share_network branch 2 times, most recently from b5292e8 to dacb270 Compare March 4, 2026 18:29
Copy link
Contributor

@eshulman2 eshulman2 left a comment

Choose a reason for hiding this comment

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

Generally looks good, dded a few comments and question, please LMK what you think.

enable_workaround_docker_io: 'false'
branch: ${{ matrix.openstack_version }}
enabled_services: "openstack-cli-server,neutron-trunk"
enabled_services: "openstack-cli-server,neutron-trunk,manila,m-api,m-sch,m-shr,m-dat"
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment is not specific to this patch but I believe we should consider a coherent approach to the services we enable in the gates and possibly making specific gates with specific services enabled for certain controllers like being done in gophercloud for loadbalancers for example. @mandre WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed. At some point we'll have to split our jobs as they grow bigger (gophercloud is a good example).

// networkRef is a reference to the ORC Network which this resource is associated with.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="networkRef is immutable"
NetworkRef *KubernetesNameRef `json:"networkRef"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Should there be a rule here that make sure that if a network is set the subnet is also set? from the api referance:

The UUID of a neutron network when setting up or updating a share network subnet with neutron. Specify both a neutron network and a neutron subnet that belongs to that neutron network.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree! , I created a new validation rule

// +kubebuilder:validation:XValidation:rule="has(self.networkRef) == has(self.subnetRef)",message="networkRef and subnetRef must be specified together"

also added a test file in the apivalidations directory here, I used securitygroup_test.go and network_test.go as my main sources of reference (both in the apivalidations dir),

The CEL rule is a boolean equality and tests 4 combinations, both networkRef and subnetRef present = valid, both networkRef and subnetRef absent = valid aswell, but if either network Ref or subnetRef is missing or vice versa it is flagged as invalid.
The idea is to follow the API Ref statement creating a both or neither configuration rule.

The UUID of a neutron network when setting up or updating a share network subnet with neutron. Specify both a neutron network and a neutron subnet that belongs to that neutron network.

please lmk what you think 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

LGTM


// networkRef is a reference to the ORC Network which this resource is associated with.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="networkRef is immutable"
Copy link
Contributor

Choose a reason for hiding this comment

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

As far as I can tell from the API docs it is possible to change this https://docs.openstack.org/api-ref/shared-file-system/#update-share-network any specific reason for making it immutable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, you are correct the validation test is not required here, with the two dependencies being mutable according to the API, Thanks 👍

Copy link
Collaborator

Choose a reason for hiding this comment

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

That's true. But it's also true that it's not a problem leaving a field immutable in the first implementation as writing a controller that supports all the fields, with dependency and mutability can sometimes be quite a lot of work.
I prefer to have a partially implemented controller that is robust than a half baked fully implemented controller.


// subnetRef is a reference to the ORC Subnet which this resource is associated with.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="subnetRef is immutable"
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks again, this validation rule was generated by the scaffolding tool both have been removed.

Copy link
Contributor

@eshulman2 eshulman2 left a comment

Choose a reason for hiding this comment

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

regarding the gate failures

ref: sharenetwork
assertAll:
- celExpr: "sharenetwork.status.id != ''"
- celExpr: "sharenetwork.status.resource.neutronNetID == '"
Copy link
Contributor

@eshulman2 eshulman2 Mar 9, 2026

Choose a reason for hiding this comment

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

seems like there is something wrong with the test here:

    harness.go:395: failed to prepare expression evaluation: failed to load expression(s): failed to build CEL program from expression "sharenetwork.status.resource.neutronNetID == '": type-check error: ERROR: <input>:1:46: Syntax error: token recognition error at: '''
         | sharenetwork.status.resource.neutronNetID == '
         | .............................................^
        ERROR: <input>:1:47: Syntax error: mismatched input '<EOF>' expecting {'[', '{', '(', '.', '-', '!', 'true', 'false', 'null', NUM_FLOAT, NUM_INT, NUM_UINT, STRING, BYTES, IDENTIFIER}
         | sharenetwork.status.resource.neutronNetID == '
         | ..............................................^

I suspect it is a small typo yo have only a single ' instead of what I assumed you mean which is ' ' but I might be wrong

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good Spot, thanks for the help @eshulman2 👍

@github-actions github-actions bot removed the semver:major Breaking change label Mar 9, 2026
@github-actions
Copy link

github-actions bot commented Mar 9, 2026

Failed to assess the semver bump. See logs for details.

go run ./cmd/scaffold-controller -interactive=false \
    -kind=ShareNetwork \
    -gophercloud-client=NewSharedFilesystemV2 \
    -gophercloud-module=github.com/gophercloud/gophercloud/v2/openstack/sharedfilesystems/v2/sharenetworks \
    -gophercloud-type=ShareNetwork \
    -openstack-json-object=share_network \
    -optional-create-dependency=Network \
    -optional-create-dependency=Subnet
Signed-off-by: Daniel Lawton <dlawton@redhat.com>
@github-actions github-actions bot added the semver:major Breaking change label Mar 9, 2026
Implements ShareNetwork controller to manage Manila share networks.
- E2E tests included
- API configured
- Manila enabled in CI

Signed-off-by: Daniel Lawton <dlawton@redhat.com>

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copy link
Collaborator

@mandre mandre left a comment

Choose a reason for hiding this comment

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

Just an initial pass for now, I believe we should make the dependencies immutable unless we have more test coverage proving it works as expected, and that the resources that are no longer dependencies no longer have a finalizer.

enable_workaround_docker_io: 'false'
branch: ${{ matrix.openstack_version }}
enabled_services: "openstack-cli-server,neutron-trunk"
enabled_services: "openstack-cli-server,neutron-trunk,manila,m-api,m-sch,m-shr,m-dat"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed. At some point we'll have to split our jobs as they grow bigger (gophercloud is a good example).


// networkRef is a reference to the ORC Network which this resource is associated with.
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="networkRef is immutable"
Copy link
Collaborator

Choose a reason for hiding this comment

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

That's true. But it's also true that it's not a problem leaving a field immutable in the first implementation as writing a controller that supports all the fields, with dependency and mutability can sometimes be quite a lot of work.
I prefer to have a partially implemented controller that is robust than a half baked fully implemented controller.

resource:
name: sharenetwork-create-full-override
description: ShareNetwork from "create full" test
# TODO(scaffolding): Add all fields the resource supports
Copy link
Collaborator

Choose a reason for hiding this comment

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

What about SegmentationID, CIRD, NetworkType, ProjectID, etc. ? We should test their value, or lack thereof.

status:
resource:
name: sharenetwork-create-minimal
# TODO(scaffolding): Add all fields the resource supports
Copy link
Collaborator

Choose a reason for hiding this comment

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

There too, we should make sure the resulting resource is exactly as we expect it to be, including for absence of fields in its status.

managementPolicy: managed
# TODO(scaffolding): Only add the mandatory fields. It's possible the resource
# doesn't have mandatory fields, in that case, leave it empty.
resource: {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just tried with openstack client and indeed all fields are optional:

❯ openstack share network create
+---------------------------------+-------------------------------------------+
| Field                           | Value                                     |
+---------------------------------+-------------------------------------------+
| created_at                      | 2026-03-10T16:22:38.561269                |
| description                     | None                                      |
| id                              | f267364b-d1b4-46d3-85b1-8baeeda3831a      |
| name                            | None                                      |
| project_id                      | c73b7097d07c46f78eb4b4dcfbac5ca8          |
| security_service_update_support | True                                      |
| share_network_subnets           |                                           |
|                                 | id = 227458f7-22f6-4574-9edb-9ee57d37e6cc |
|                                 | availability_zone = None                  |
|                                 | created_at = 2026-03-10T16:22:38.580313   |
|                                 | updated_at = None                         |
|                                 | segmentation_id = None                    |
|                                 | neutron_net_id = None                     |
|                                 | neutron_subnet_id = None                  |
|                                 | ip_version = None                         |
|                                 | cidr = None                               |
|                                 | network_type = None                       |
|                                 | mtu = None                                |
|                                 | gateway = None                            |
| status                          | active                                    |
| updated_at                      | None                                      |
+---------------------------------+-------------------------------------------+

package v1alpha1

// ShareNetworkResourceSpec contains the desired state of the resource.
type ShareNetworkResourceSpec struct {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you forget to run the generator with -optional-create-dependency=Project or was it intentional to leave it out in the first iteration?

resource:
name: sharenetwork-update-updated
description: sharenetwork-update-updated
# TODO(scaffolding): match all fields that were modified
Copy link
Collaborator

Choose a reason for hiding this comment

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

We need to validate that updating networkRef and subnetRef had any effect.

handleNameUpdate(&updateOpts, obj, osResource)
handleDescriptionUpdate(&updateOpts, resource, osResource)

// TODO(scaffolding): add handler for all fields supporting mutability
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should add a dependence on network and subnet here, and ensure we set the updateOpts correctly.

We may also need to remove the finalizer on the old dependencies, that might be a tricky one to handle. I would suggest you make the dependencies immutable 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.

Manila: Share Network Controller

4 participants