Detect port-resource-request-groups neutron API extension
The new neutron API extension signals the format change of the resource_request field of the port. This patch only adds functions to detect the existence of such extension. Later patches will adapt Nova for the new format. Depends-On: https://review.opendev.org/c/openstack/neutron-lib/+/803905 Change-Id: I4b400d499b9f594798f2da6d16f21204371a9f42 blueprint: qos-minimum-guaranteed-packet-rate
This commit is contained in:
parent
f68d30bff3
commit
017b0a3d23
|
@ -29,6 +29,7 @@ MIGRATING_ATTR = 'migrating_to'
|
|||
L3_NETWORK_TYPES = ['vxlan', 'gre', 'geneve']
|
||||
ALLOCATION = 'allocation'
|
||||
RESOURCE_REQUEST = 'resource_request'
|
||||
REQUEST_GROUPS = 'request_groups'
|
||||
SEGMENT = 'Segment'
|
||||
NUMA_POLICY = 'numa_affinity_policy'
|
||||
RESOURCE_REQUEST_GROUPS_EXTENSION = "Port Resource Request Groups"
|
||||
|
|
|
@ -995,6 +995,13 @@ class API:
|
|||
|
||||
return requests_and_created_ports
|
||||
|
||||
def _has_resource_request(self, context, port, neutron):
|
||||
resource_request = port.get(constants.RESOURCE_REQUEST) or {}
|
||||
if self._has_extended_resource_request_extension(context, neutron):
|
||||
return bool(resource_request.get(constants.REQUEST_GROUPS, []))
|
||||
else:
|
||||
return bool(resource_request)
|
||||
|
||||
def allocate_for_instance(self, context, instance,
|
||||
requested_networks,
|
||||
security_groups=None, bind_host_id=None,
|
||||
|
@ -1270,6 +1277,14 @@ class API:
|
|||
self._refresh_neutron_extensions_cache(context, neutron=neutron)
|
||||
return constants.SEGMENT in self.extensions
|
||||
|
||||
# TODO(gibi): Remove all branches where this is False after Neutron made
|
||||
# the this extension mandatory. In Xena this extension will be optional to
|
||||
# support the scenario where Neutron upgraded first. So Neutron can mark
|
||||
# this mandatory earliest in Yoga.
|
||||
def _has_extended_resource_request_extension(self, context, neutron=None):
|
||||
self._refresh_neutron_extensions_cache(context, neutron=neutron)
|
||||
return constants.RESOURCE_REQUEST_GROUPS_EXTENSION in self.extensions
|
||||
|
||||
def supports_port_binding_extension(self, context):
|
||||
"""This is a simple check to see if the neutron "binding-extended"
|
||||
extension exists and is enabled.
|
||||
|
|
|
@ -6571,6 +6571,71 @@ class TestAPI(TestAPIBase):
|
|||
mock_debug.assert_called_with('No PCI device found for request %s',
|
||||
uuids.pci_request_id, instance=instance)
|
||||
|
||||
@mock.patch(
|
||||
'nova.network.neutron.API.'
|
||||
'_has_extended_resource_request_extension')
|
||||
def test__has_resource_request(self, mock_has_extended_res_req):
|
||||
# Old format, resource_request in None. That is Neutron current
|
||||
# behavior if the port has no QoS policy associated.
|
||||
mock_has_extended_res_req.return_value = False
|
||||
port_no_res_req = {"resource_request": None}
|
||||
self.assertFalse(self.api._has_resource_request(
|
||||
self.context, port_no_res_req, neutron=None)
|
||||
)
|
||||
# Old format, there is resource_request key but no resource is
|
||||
# requested. We should never get this from Neutron today but we
|
||||
# actually get it if there are QoS policy assigned to the port but
|
||||
# there is no rule in that policy requesting resources.
|
||||
port_old_empty_res_req = {"resource_request": {}}
|
||||
self.assertFalse(self.api._has_resource_request(
|
||||
self.context, port_old_empty_res_req, neutron=None)
|
||||
)
|
||||
# Old format, and the port has resource request.
|
||||
port_old_res_req = {
|
||||
"resource_request": {
|
||||
"resources": {
|
||||
"NET_BW_IGR_KILOBIT_PER_SEC": 1000,
|
||||
}
|
||||
}
|
||||
}
|
||||
self.assertTrue(self.api._has_resource_request(
|
||||
self.context, port_old_res_req, neutron=None)
|
||||
)
|
||||
# New format tests are starting here
|
||||
mock_has_extended_res_req.return_value = True
|
||||
# New format, port has no QoS policy assigned
|
||||
port_no_res_req = {"resource_request": None}
|
||||
self.assertFalse(self.api._has_resource_request(
|
||||
self.context, port_no_res_req, neutron=None)
|
||||
)
|
||||
# New format, port has a resource_request key but no resource is
|
||||
# requested. Neutron never sends this, it sends None instead. We keep
|
||||
# this here for completeness as the code actually handle this properly.
|
||||
port_new_empty_res_req = {
|
||||
"resource_request": {
|
||||
"request_groups": []
|
||||
}
|
||||
}
|
||||
self.assertFalse(self.api._has_resource_request(
|
||||
self.context, port_new_empty_res_req, neutron=None)
|
||||
)
|
||||
# New format, port has a resource request
|
||||
port_new_res_req = {
|
||||
"resource_request": {
|
||||
"request_groups": [
|
||||
{
|
||||
"resources": {
|
||||
"NET_KILOPACKET_PER_SEC": 1000
|
||||
}
|
||||
},
|
||||
],
|
||||
"same_subtree": [],
|
||||
}
|
||||
}
|
||||
self.assertTrue(self.api._has_resource_request(
|
||||
self.context, port_new_res_req, neutron=None)
|
||||
)
|
||||
|
||||
|
||||
class TestAPIModuleMethods(test.NoDBTestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue