Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
with:
enable_workaround_docker_io: 'false'
branch: ${{ matrix.openstack_version }}
enabled_services: "openstack-cli-server,neutron-trunk,neutron-port-trusted-vif"
enabled_services: "openstack-cli-server,neutron-trunk,neutron-port-trusted-vif,neutron-uplink-status-propagation"
conf_overrides: |
enable_plugin neutron https://github.com/openstack/neutron ${{ matrix.openstack_version }}
enable_plugin manila https://github.com/openstack/manila ${{ matrix.openstack_version }}
Expand Down
9 changes: 9 additions & 0 deletions api/v1alpha1/port_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,15 @@ type PortResourceSpec struct {
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="valueSpecs is immutable"
ValueSpecs []PortValueSpec `json:"valueSpecs,omitempty"`

// propagateUplinkStatus represents the uplink status propagation of
// the port.
// The field is now immutable due to a limitation on
// Dalmatian (2024.2) release, we should address this later.
// https://github.com/k-orc/openstack-resource-controller/pull/641#discussion_r2694783787
// +optional
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="propagateUplinkStatus is immutable"
PropagateUplinkStatus *bool `json:"propagateUplinkStatus,omitempty"`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We've discussed this privately already, after you brought the issue to my attention: gophercloud implements the PropagateUplinkStatus in the response Port structure as a bool while it should really be a *bool with omitempty, and because of this we can't reliably know the status for PropagateUplinkStatus. I suggest that until the issue if fixed in gophercloud, we make that field immutable.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It's been a while and I don't remember all of the discussion. From reading the PR comments again, I believe we're past the gophercloud limitation (thanks to custom unmarshalling) but we still need to make the field immutable because dalmatien doesn't support updating the field. If that's effectively the case, we should add that as a comment so we know when we can change that behavior.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, you're absolutely right. I'll add this comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

}

type PortResourceStatus struct {
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

7 changes: 7 additions & 0 deletions cmd/models-schema/zz_generated.openapi.go

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

11 changes: 11 additions & 0 deletions config/crd/bases/openstack.k-orc.cloud_ports.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,17 @@ spec:
x-kubernetes-validations:
- message: projectRef is immutable
rule: self == oldSelf
propagateUplinkStatus:
description: |-
propagateUplinkStatus represents the uplink status propagation of
the port.
The field is now immutable due to a limitation on
Dalmatian (2024.2) release, we should address this later.
https://github.com/k-orc/openstack-resource-controller/pull/641#discussion_r2694783787
type: boolean
x-kubernetes-validations:
- message: propagateUplinkStatus is immutable
rule: self == oldSelf
securityGroupRefs:
description: |-
securityGroupRefs are references to the security groups associated
Expand Down
15 changes: 8 additions & 7 deletions internal/controllers/port/actuator.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,14 @@ func (actuator portActuator) CreateResource(ctx context.Context, obj *orcv1alpha
}

createOpts := ports.CreateOpts{
NetworkID: *network.Status.ID,
Name: getResourceName(obj),
Description: string(ptr.Deref(resource.Description, "")),
ProjectID: projectID,
AdminStateUp: resource.AdminStateUp,
MACAddress: resource.MACAddress,
ValueSpecs: valueSpecs,
NetworkID: *network.Status.ID,
Name: getResourceName(obj),
Description: string(ptr.Deref(resource.Description, "")),
ProjectID: projectID,
AdminStateUp: resource.AdminStateUp,
MACAddress: resource.MACAddress,
ValueSpecs: valueSpecs,
PropagateUplinkStatus: resource.PropagateUplinkStatus,
}

if len(resource.AllowedAddressPairs) > 0 {
Expand Down
1 change: 0 additions & 1 deletion internal/controllers/port/actuator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,6 @@ func TestHandleTrustedVIFUpdate(t *testing.T) {
}

updateOpts := handlePortTrustedVIFUpdate(&ports.UpdateOpts{}, resource, osResource)

got, _ := needsUpdate(updateOpts)
if got != tt.expectChange {
t.Errorf("expected needsUpdate=%v, got %v", tt.expectChange, got)
Expand Down
5 changes: 4 additions & 1 deletion internal/controllers/port/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ func (portStatusWriter) ApplyResourceStatus(log logr.Logger, osResource *osResou
WithNetworkID(osResource.NetworkID).
WithTags(osResource.Tags...).
WithSecurityGroups(osResource.SecurityGroups...).
WithPropagateUplinkStatus(osResource.PropagateUplinkStatus).
WithVNICType(osResource.VNICType).
WithPortSecurityEnabled(osResource.PortSecurityEnabled).
WithRevisionNumber(int64(osResource.RevisionNumber)).
Expand Down Expand Up @@ -108,5 +107,9 @@ func (portStatusWriter) ApplyResourceStatus(log logr.Logger, osResource *osResou
resourceStatus.WithTrustedVIF(*osResource.PortTrustedVIF)
}

if osResource.PropagateUplinkStatusPtr != nil {
resourceStatus.WithPropagateUplinkStatus(*osResource.PropagateUplinkStatusPtr)
}

statusApply.WithResource(resourceStatus)
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,4 @@ spec:
macAddress: fa:16:3e:23:fd:d7
hostID:
id: devstack
propagateUplinkStatus: false
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ status:
name: port-create-minimal
adminStateUp: true
portSecurityEnabled: true
propagateUplinkStatus: false
propagateUplinkStatus: true
Comment thread
winiciusallan marked this conversation as resolved.
revisionNumber: 1
status: DOWN
vnicType: normal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ status:
description: Port from "create sriov" test
adminStateUp: true
portSecurityEnabled: false
propagateUplinkStatus: false
propagateUplinkStatus: true
status: DOWN
vnicType: direct
tags:
Expand Down
2 changes: 1 addition & 1 deletion internal/controllers/port/tests/port-update/00-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ status:
name: port-update
adminStateUp: true
portSecurityEnabled: false
propagateUplinkStatus: false
propagateUplinkStatus: true
revisionNumber: 1
status: DOWN
vnicType: normal
Expand Down
2 changes: 1 addition & 1 deletion internal/controllers/port/tests/port-update/01-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ status:
description: port-update-updated
adminStateUp: true
portSecurityEnabled: true
propagateUplinkStatus: false
propagateUplinkStatus: true
status: DOWN
vnicType: direct
allowedAddressPairs:
Expand Down
2 changes: 1 addition & 1 deletion internal/controllers/port/tests/port-update/02-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ status:
name: port-update
adminStateUp: true
portSecurityEnabled: false
propagateUplinkStatus: false
propagateUplinkStatus: true
status: DOWN
vnicType: normal
conditions:
Expand Down
37 changes: 37 additions & 0 deletions internal/osclients/networking.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package osclients

import (
"context"
"encoding/json"
"fmt"
"iter"

Expand Down Expand Up @@ -58,6 +59,41 @@ type PortExt struct {
portsecurity.PortSecurityExt
portsbinding.PortsBindingExt
portstrustedvif.PortTrustedVIFExt

// PropagateUplinkStatusPtr is a pointer variant of ports.Port.PropagateUplinkStatus.
// The embedded field is a non-pointer bool that defaults to false, making it
// impossible to distinguish "extension not enabled" from "explicitly false".
// This pointer allows detecting whether the field was present in the API response.
// It won't be needed with Gophercloud v3.
PropagateUplinkStatusPtr *bool `json:"propagate_uplink_status,omitempty"`
}

// TODO(winiciusallan): Drop this custom unmarshaler once Gophercloud is
// on V3, so we have the following change
// https://github.com/gophercloud/gophercloud/pull/3609.
func (p *PortExt) UnmarshalJSON(b []byte) error {
Comment thread
mandre marked this conversation as resolved.
Comment thread
mandre marked this conversation as resolved.
if err := json.Unmarshal(b, &p.Port); err != nil {
return err
}
if err := json.Unmarshal(b, &p.PortSecurityExt); err != nil {
return err
}
if err := json.Unmarshal(b, &p.PortsBindingExt); err != nil {
return err
}
if err := json.Unmarshal(b, &p.PortTrustedVIFExt); err != nil {
return err
}

var tmp struct {
PropagateUplinkStatusPtr *bool `json:"propagate_uplink_status"`
}
if err := json.Unmarshal(b, &tmp); err != nil {
return err
}

p.PropagateUplinkStatusPtr = tmp.PropagateUplinkStatusPtr
return nil
}

type NetworkClient interface {
Expand Down Expand Up @@ -189,6 +225,7 @@ func (c networkClient) ListPort(ctx context.Context, opts ports.ListOptsBuilder)
}
return resources, nil
}

pager := ports.List(c.serviceClient, opts)
return func(yield func(*PortExt, error) bool) {
_ = pager.EachPage(ctx, yieldPage(extractPortExt, yield))
Expand Down
39 changes: 24 additions & 15 deletions pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go

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

3 changes: 3 additions & 0 deletions pkg/clients/applyconfiguration/internal/internal.go

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

1 change: 1 addition & 0 deletions website/docs/crd-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2785,6 +2785,7 @@ _Appears in:_
| `hostID` _[HostID](#hostid)_ | hostID specifies the host where the port will be bound.<br />Note that when the port is attached to a server, OpenStack may<br />rebind the port to the server's actual compute host, which may<br />differ from the specified hostID if no matching scheduler hint<br />is used. In this case the port's status will reflect the actual<br />binding host, not the value specified here. | | MaxProperties: 1 <br />MinProperties: 1 <br />Optional: \{\} <br /> |
| `trustedVIF` _boolean_ | trustedVIF indicates whether the VF for the port will become<br />trusted by physical function to perform some privileged<br />operations. Only admin users can create ports with this field. | | Optional: \{\} <br /> |
| `valueSpecs` _[PortValueSpec](#portvaluespec) array_ | valueSpecs are extra parameters to include in the API request<br />with OpenStack. This is an extension point for the API, so what<br />they do and if they are supported, depends on the specific<br />OpenStack implementation. This was meant to work similar to the<br />property on Heat port resource. Since this depends on the<br />underlying implementation, we can't predict its fields, and<br />therefore, we don't know how to reconcile them in advance. Use<br />this field wisely and be aware of the expected behavior. | | MaxItems: 128 <br />Optional: \{\} <br /> |
| `propagateUplinkStatus` _boolean_ | propagateUplinkStatus represents the uplink status propagation of<br />the port.<br />The field is now immutable due to a limitation on<br />Dalmatian (2024.2) release, we should address this later.<br />https://github.com/k-orc/openstack-resource-controller/pull/641#discussion_r2694783787 | | Optional: \{\} <br /> |


#### PortResourceStatus
Expand Down
Loading