Port: add propagationUplinkStatus field#641
Port: add propagationUplinkStatus field#641winiciusallan wants to merge 5 commits intok-orc:mainfrom
Conversation
|
weird... the uplink_status_propagation extension was not added to the devstack deployment. I tested locally and it only works by setting Has anyone ever seen something like this? |
8cbef64 to
4d21547
Compare
|
Ok, here we go. I needed to add the neutron plugin on CI so that devstack can run this line and enable uplink-status-propagation accordingly. However, it looks like that Dalmatian release doesn't enable the ability to update About the job failing on Flamingo I really don't get the why. The E2E job has failed in cc. @mandre I'll wait for you feedback before making any additional change. |
api/v1alpha1/port_types.go
Outdated
| // the port. | ||
| // +optional | ||
| PropagateUplinkStatus *bool `json:"propagateUplinkStatus,omitempty"` | ||
| PropagateUplinkStatus bool `json:"propagateUplinkStatus,omitempty"` |
There was a problem hiding this comment.
I believe we want to keep the pointer, don't we? This signifies that neutron doesn't have enable the uplink-status-propagation extension.
There was a problem hiding this comment.
Yep, we do. I'll change it together with making the field immutable.
| // propagateUplinkStatus represents the uplink status propagation of | ||
| // the port. | ||
| // +optional | ||
| PropagateUplinkStatus *bool `json:"propagateUplinkStatus,omitempty"` |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Yes, you're absolutely right. I'll add this comment.
| enable_workaround_docker_io: 'false' | ||
| branch: ${{ matrix.openstack_version }} | ||
| enabled_services: "openstack-cli-server" | ||
| enabled_services: "openstack-cli-server,neutron-uplink-status-propagation" |
There was a problem hiding this comment.
Interesting, the dalmatian job still failed?
There was a problem hiding this comment.
Yep. I don't know the why, but there is two extensions - one for enable the field, and one for make it mutable. In dalmatian, the devstack configuration enable just the first one, so the jobs are failing on port-update test.
For reference, compare these two [1][2]
Since we're making this field immutable, this wouldn't be a problem for now.
[1] https://github.com/openstack/neutron/blob/master/devstack/lib/uplink_status_propagation
[2] https://github.com/openstack/neutron/blob/stable/2024.2/devstack/lib/uplink_status_propagation
There was a problem hiding this comment.
Gotcha, thanks for the explanation.
There was a problem hiding this comment.
So according to the commit in neutron, openstack/neutron@498be54 we'll need neutron-lib >= v3.16.0, which we don't have in Dalmatian. I believe we'll have to make the field immutable until we drop support for Dalmatian.
There was a problem hiding this comment.
Gazpacho will be released in the end of march, so will take a little long to remove Dalmatian from the CI, it worth to merge this with this field as immutable indeed.
I'll re-changed things.
I re-ran this job and the error is gone. I was most likely a flake (bound to happen as we add more tests). |
We have a missing pointer on Gophercloud, this is causing a misbehavior. For workarouding purposes, was added a new struct to support a pointer for that field. Tests were also fixed.
|
@mandre let me know when you think it is ready to go, I can squash the commits to make the PR cleaner. :) |
internal/osclients/networking.go
Outdated
| ports.Port | ||
| portsecurity.PortSecurityExt | ||
| portsbinding.PortsBindingExt | ||
| PortTmpExt //nolint:govet |
There was a problem hiding this comment.
The nolint marker silenced the error with golangci-lint, however we're still getting an error when running go vet directly:
❯ make vet
go vet ./...
# github.com/k-orc/openstack-resource-controller/v2/internal/osclients
internal/osclients/networking.go:67:2: struct field PropagateUplinkStatusPtr repeats json tag "propagate_uplink_status" also at ../../../../../go/pkg/mod/github.com/gophe
rcloud/gophercloud/v2@v2.10.0/openstack/networking/v2/ports/results.go:115
make: *** [Makefile:111: vet] Error 1
I suggest removing the workaround since we don't allow mutability now.
There was a problem hiding this comment.
We need the workaround to be able to not return the field if the extension is not enabled.
edit: I didn't find any way to suppress vet warning. Do you have any suggestion?
There was a problem hiding this comment.
I think it should work if you add the field at the top level instead of embedding:
| PortTmpExt //nolint:govet | |
| PropagateUplinkStatusPtr *bool `json:"propagate_uplink_status,omitempty"` |
See this small test.
There was a problem hiding this comment.
In 87a3ecf I added the Unmarshal function that we discussed in DM, but I had to change the logic for ListPort because it was not able to unmarshal ports when importing from OpenStack.
Just to be clear, I had a little help from Claude :)
| // propagateUplinkStatus represents the uplink status propagation of | ||
| // the port. | ||
| // +optional | ||
| PropagateUplinkStatus *bool `json:"propagateUplinkStatus,omitempty"` |
There was a problem hiding this comment.
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.
| adminStateUp: true | ||
| portSecurityEnabled: true | ||
| propagateUplinkStatus: false | ||
| propagateUplinkStatus: true |
There was a problem hiding this comment.
So the default is still true, contrary to what the PR description says. The value changed from false to true in this test because we've enabled the neutron-uplink-status-propagation extension in devstack.
There was a problem hiding this comment.
Yes. Since we enabled the extension and added the custom struct with the field as a pointer, we're now able to have this value as nil without the extension, and as true (default) if enabled.
I'll change the PR description to avoid confusion.
| PropagateUplinkStatusPtr *bool `json:"propagate_uplink_status,omitempty"` | ||
| } | ||
|
|
||
| func (p *PortExt) UnmarshalJSON(b []byte) error { |
There was a problem hiding this comment.
This custom unmarshaller omits portsecurity.PortSecurityExt or portsbinding.PortsBindingExt meaning that they'll always have the zero value (it's weird that we do not detect this bug via the tests, don't we have coverage for those fields?).
There was a problem hiding this comment.
It is something that I was in doubt about... I'm not sure, and if you can correct me if I'm wrong, I'll appreciate it, but it looks like Gophercloud uses reflection to populate the result rather than simply using a json.Unmarshal, am I wrong?
https://github.com/gophercloud/gophercloud/blob/main/results.go#L70
You're right that they will always have the zero value, but maybe in the above phase, the fields are populated using reflection. I need to better understand this. Any initial thought?
There was a problem hiding this comment.
A well crafted test should give us the answer.
| @@ -172,13 +191,30 @@ func (c networkClient) UpdateFloatingIP(ctx context.Context, id string, opts flo | |||
|
|
|||
| func (c networkClient) ListPort(ctx context.Context, opts ports.ListOptsBuilder) iter.Seq2[*PortExt, error] { | |||
There was a problem hiding this comment.
We shouldn't have to update ListPort I believe.
There was a problem hiding this comment.
IIRC, there was a failing test, and the solution was to change the ListPort function, but I'll double-check this to confirm what exactly the error was.
This PR introduces the propagationUplinkStatus
https://docs.openstack.org/api-ref/network/v2/index.html#uplink-status-propagation
Notes:
false, even if the doc says that the default value istrue. The reason is that in environments where this extension is not enabled, we can't update that field and it always returns false, so if we enforce it as true, it may raise an error. So if the user wants to enable it, they must explicitly define it.Partial #616