-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: workflow updates Nautobot Interface.status instead of device.custom_field.conected_to_network #249
Conversation
ae193e9
to
26aa1aa
Compare
@@ -263,14 +263,16 @@ def __network_name(self, network_id: str): | |||
return "tenant" | |||
|
|||
def _move_to_network(self, context): | |||
interface_uuid = context.current["id"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am afraid this won't be as simple, but I am not 100% sure on that.
The way I understand it:
- the ml2 driver calls
update_port_postcommit
with a relevant context that is of PortContext type - this gets passed to
_move_to_network
without modifications
Now, the problem I see here is that id
fields corresponds to the ID of a port as given by Neutron. Unless I'm wrong, these are completely different to what Nautobot expects to identify an Interface.
These IDs are automatically assigned when Ironic creates Neutron ports for each of its baremetal Ports.
At the moment, both baremetal ports and neutron port IDs will not match as they are both randomly allocated - on baremetal side during the node inspection, and on the neutron side when the code linked above is executed.
I think the easiest way around that situation may be to match using the MAC address. Alternatively, we will have to pre-create the neutron ports with specific IDs which may be tricky.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One clarification on this - even though Ironic initially copies the baremetal port attributes presumably including the baremetal port id, it won't be preserved because Python Openstack SDK (which is used to interface with Neutron), does not pass on that attribute.
Even if it did, Neutron API wouldn't accept it
root@openstack-admin-client:/tmp# cat create_port_with_id.json
{
"port": {
"id": "bc1ab041-13af-464c-81c6-87db1e15aaaa",
"admin_state_up": true,
"name": "private-port",
"network_id": "a0c267bf-33af-48b9-b540-daa6d41bff3f",
"port_security_enabled": false,
"allowed_address_pairs": []
}
}
root@openstack-admin-client:/tmp# curl -X POST -H "Content-Type: application/json" -H "X-Auth-Token: $TOKEN" http://neutron-server.openstack.svc.cluster.local:9696/v2.0/ports -d @create_port_with_id.json
{"NeutronError": {"type": "HTTPBadRequest", "message": "Attribute 'id' not allowed in POST", "detail": ""}}root@openstack-admin-client:/tmp#
root@openstack-admin-client:/tmp#
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought it was too good to be true when someone said "that is the ID you need". I reworked this in 35d1295 to find the interface by MAC address, we can revisit this in the future if we ever sync up the UUID values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@skrobul We can go directly to python-neutronclient instead of using the OpenStack SDK. I've noticed the OpenStack SDK is a bit too high level in a number of places. It aims to be a higher level simple interface and I guess that makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My comments doesn't matter because like you said, neutron rejects that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So won't block this being merged but I think this would be an improvement for the test.
def mock_context_data(file): | ||
ref = pathlib.Path(__file__).joinpath(filename) | ||
with ref.open("r") as f: | ||
return ContextDouble(json.load(f)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd probably add in some more magic with fixtures.
return ContextDouble(json.load(f)) | |
return ContextDouble(json.load(f)) | |
@pytest.fixture | |
def neutron_update_port_postcommit() -> ContextDouble: | |
return mock_context_data("fixtures/neutron_update_port_postcommit.json") |
def test_update_port_postcommit(mock_argo_client): | ||
context_data = mock_context_data( | ||
"fixtures/neutron_update_port_postcommit.json" | ||
) | ||
|
||
UnderstackDriver.update_port_postcommit(context_data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def test_update_port_postcommit(mock_argo_client): | |
context_data = mock_context_data( | |
"fixtures/neutron_update_port_postcommit.json" | |
) | |
UnderstackDriver.update_port_postcommit(context_data) | |
def test_update_port_postcommit(mock_argo_client, neutron_update_port_postcommit): | |
UnderstackDriver.update_port_postcommit(neutron_update_port_postcommit) |
"interface_uuid": "e5d5cd73-ca9a-4b74-9d52-43188d0cdcaa", | ||
"device_uuid": "41d18c6a-5548-4ee9-926f-4e3ebf43153f", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"interface_uuid": "e5d5cd73-ca9a-4b74-9d52-43188d0cdcaa", | |
"device_uuid": "41d18c6a-5548-4ee9-926f-4e3ebf43153f", | |
"interface_uuid": neutron_update_port_postcommit.current["id"], | |
"device_uuid": neutron_update_port_postcommit.current["device_id"], |
We used to flip a bit on the nautobot Device object for “connected_to_network” when changing a device from/to “provisioning” and “tenant” settings. We need this to be interface specific. Because of Ironic's knowlege of the interface that is being used for PXE boot, we are called with a server interface UUID. We update the nautobot status field of connected switch interface. This tells undersync which mode the port should be in - provisioning or tenant (normal). We also make a change to the switch IDs that are passed to undersync. This used to represnt the set of all switches to which the server is connected. This is sub-optimal if there are multiple fabrics connected to the same server. We drop this logic and instead just pass a single switch ID, which is the switch where PXE is happening. Undersync will always update both switches in the VPC pair (VLAN GROUP) in any case - passing the extra switch IDs was redundant.
The UUID in Nautobot is not the same as the UUID in ironic/nova so use the MAC address to find the required switch port. In the earlier milestones we should not encounter LAGs but this is something to watch out for in future: - it is not clear exactly what the rules are with interface in Nautobot but when interfaces belong to a LAG. Nautobot seems to report that the LAG and its members all share a MAC address. This means the MAC address is no longer guaranteed to uniquely identify an interface. We have also been talking about how to sync/store the various UUID values in nautobot, so perhaps this will eventually be solved that way.
We used to flip a bit on the nautobot Device object for “connected_to_network”
when changing a device from/to “provisioning” and “tenant” settings.
We need this to be interface specific. Because of Ironic's knowlege of the
interface that is being used for PXE boot, we are called with a server interface
UUID.
We update the nautobot status field of connected switch interface.
This tells undersync which mode the port should be in - provisioning or
tenant (normal).
This would be released in tandem with https://github.com/RSS-Engineering/undersync/pull/14 fixes PUC-425