Correction of a typo in the 'sub_ports' field
Problem: In the "_extend_port_trunk_details_bulk" method for the trunk plugin, the search of subports takes place using the key 'subports' instead 'sub_ports'. That cause the mac address field has never added to the subports. It also leads to consistency with the documented API: https://docs.openstack.org/api-ref/network/v2/index.html#show-trunk-details Closes-Bug: #2020552 Change-Id: I113714a21692bfb6be9a21586de172a62191619f
This commit is contained in:
@@ -93,7 +93,7 @@ class TrunkPlugin(service_base.ServicePluginBase):
|
|||||||
for port in ports:
|
for port in ports:
|
||||||
subports[port['id']]['mac_address'] = port['mac_address']
|
subports[port['id']]['mac_address'] = port['mac_address']
|
||||||
trunk_details = {'trunk_id': port_db.trunk_port.id,
|
trunk_details = {'trunk_id': port_db.trunk_port.id,
|
||||||
'sub_ports': list(subports.values())}
|
trunk_apidef.SUB_PORTS: list(subports.values())}
|
||||||
port_res['trunk_details'] = trunk_details
|
port_res['trunk_details'] = trunk_details
|
||||||
|
|
||||||
return port_res
|
return port_res
|
||||||
@@ -112,9 +112,10 @@ class TrunkPlugin(service_base.ServicePluginBase):
|
|||||||
subport_ids = []
|
subport_ids = []
|
||||||
trunk_ports = []
|
trunk_ports = []
|
||||||
for p in ports_res:
|
for p in ports_res:
|
||||||
if 'trunk_details' in p and 'subports' in p['trunk_details']:
|
if 'trunk_details' in p and \
|
||||||
|
trunk_apidef.SUB_PORTS in p['trunk_details']:
|
||||||
trunk_ports.append(p)
|
trunk_ports.append(p)
|
||||||
for subp in p['trunk_details']['subports']:
|
for subp in p['trunk_details'][trunk_apidef.SUB_PORTS]:
|
||||||
subport_ids.append(subp['port_id'])
|
subport_ids.append(subp['port_id'])
|
||||||
if not subport_ids:
|
if not subport_ids:
|
||||||
return ports_res
|
return ports_res
|
||||||
@@ -125,7 +126,7 @@ class TrunkPlugin(service_base.ServicePluginBase):
|
|||||||
subport_macs = {p['id']: p['mac_address'] for p in subports}
|
subport_macs = {p['id']: p['mac_address'] for p in subports}
|
||||||
|
|
||||||
for tp in trunk_ports:
|
for tp in trunk_ports:
|
||||||
for subp in tp['trunk_details']['subports']:
|
for subp in tp['trunk_details'][trunk_apidef.SUB_PORTS]:
|
||||||
subp['mac_address'] = subport_macs[subp['port_id']]
|
subp['mac_address'] = subport_macs[subp['port_id']]
|
||||||
|
|
||||||
return ports_res
|
return ports_res
|
||||||
@@ -203,8 +204,10 @@ class TrunkPlugin(service_base.ServicePluginBase):
|
|||||||
trunk_details['port_id'] = trunk_validator.validate(context)
|
trunk_details['port_id'] = trunk_validator.validate(context)
|
||||||
|
|
||||||
subports_validator = rules.SubPortsValidator(
|
subports_validator = rules.SubPortsValidator(
|
||||||
self._segmentation_types, trunk['sub_ports'], trunk['port_id'])
|
self._segmentation_types, trunk[trunk_apidef.SUB_PORTS],
|
||||||
trunk_details['sub_ports'] = subports_validator.validate(context)
|
trunk['port_id'])
|
||||||
|
trunk_details[trunk_apidef.SUB_PORTS] = (
|
||||||
|
subports_validator.validate(context))
|
||||||
return trunk_details
|
return trunk_details
|
||||||
|
|
||||||
def get_plugin_description(self):
|
def get_plugin_description(self):
|
||||||
@@ -240,7 +243,7 @@ class TrunkPlugin(service_base.ServicePluginBase):
|
|||||||
port_id=p['port_id'],
|
port_id=p['port_id'],
|
||||||
segmentation_id=p['segmentation_id'],
|
segmentation_id=p['segmentation_id'],
|
||||||
segmentation_type=p['segmentation_type'])
|
segmentation_type=p['segmentation_type'])
|
||||||
for p in trunk['sub_ports']]
|
for p in trunk[trunk_apidef.SUB_PORTS]]
|
||||||
admin_state_up = trunk.get('admin_state_up', True)
|
admin_state_up = trunk.get('admin_state_up', True)
|
||||||
# NOTE(status_police): a trunk is created in DOWN status. Depending
|
# NOTE(status_police): a trunk is created in DOWN status. Depending
|
||||||
# on the nature of the create request, a driver may set the status
|
# on the nature of the create request, a driver may set the status
|
||||||
@@ -334,7 +337,7 @@ class TrunkPlugin(service_base.ServicePluginBase):
|
|||||||
|
|
||||||
# Check for basic validation since the request body here is not
|
# Check for basic validation since the request body here is not
|
||||||
# automatically validated by the API layer.
|
# automatically validated by the API layer.
|
||||||
subports = subports['sub_ports']
|
subports = subports[trunk_apidef.SUB_PORTS]
|
||||||
subports_validator = rules.SubPortsValidator(
|
subports_validator = rules.SubPortsValidator(
|
||||||
self._segmentation_types, subports, trunk['port_id'])
|
self._segmentation_types, subports, trunk['port_id'])
|
||||||
subports = subports_validator.validate(
|
subports = subports_validator.validate(
|
||||||
@@ -364,7 +367,7 @@ class TrunkPlugin(service_base.ServicePluginBase):
|
|||||||
segmentation_type=subport['segmentation_type'],
|
segmentation_type=subport['segmentation_type'],
|
||||||
segmentation_id=subport['segmentation_id'])
|
segmentation_id=subport['segmentation_id'])
|
||||||
obj.create()
|
obj.create()
|
||||||
trunk['sub_ports'].append(obj)
|
trunk[trunk_apidef.SUB_PORTS].append(obj)
|
||||||
added_subports.append(obj)
|
added_subports.append(obj)
|
||||||
payload = events.DBEventPayload(context, resource_id=trunk_id,
|
payload = events.DBEventPayload(context, resource_id=trunk_id,
|
||||||
states=(original_trunk, trunk,),
|
states=(original_trunk, trunk,),
|
||||||
@@ -387,7 +390,7 @@ class TrunkPlugin(service_base.ServicePluginBase):
|
|||||||
@db_base_plugin_common.convert_result_to_dict
|
@db_base_plugin_common.convert_result_to_dict
|
||||||
def remove_subports(self, context, trunk_id, subports):
|
def remove_subports(self, context, trunk_id, subports):
|
||||||
"""Remove one or more subports from trunk."""
|
"""Remove one or more subports from trunk."""
|
||||||
subports = subports['sub_ports']
|
subports = subports[trunk_apidef.SUB_PORTS]
|
||||||
with db_api.CONTEXT_WRITER.using(context):
|
with db_api.CONTEXT_WRITER.using(context):
|
||||||
trunk = self._get_trunk(context, trunk_id)
|
trunk = self._get_trunk(context, trunk_id)
|
||||||
original_trunk = copy.deepcopy(trunk)
|
original_trunk = copy.deepcopy(trunk)
|
||||||
@@ -446,7 +449,7 @@ class TrunkPlugin(service_base.ServicePluginBase):
|
|||||||
def get_subports(self, context, trunk_id, fields=None):
|
def get_subports(self, context, trunk_id, fields=None):
|
||||||
"""Return subports for the specified trunk."""
|
"""Return subports for the specified trunk."""
|
||||||
trunk = self.get_trunk(context, trunk_id)
|
trunk = self.get_trunk(context, trunk_id)
|
||||||
return {'sub_ports': trunk['sub_ports']}
|
return {trunk_apidef.SUB_PORTS: trunk[trunk_apidef.SUB_PORTS]}
|
||||||
|
|
||||||
def _get_trunk(self, context, trunk_id):
|
def _get_trunk(self, context, trunk_id):
|
||||||
"""Return the trunk object or raise if not found."""
|
"""Return the trunk object or raise if not found."""
|
||||||
|
@@ -367,6 +367,31 @@ class TrunkPluginTestCase(test_plugin.Ml2PluginV2TestCase):
|
|||||||
self.assertEqual(final_trunk_status, current_trunk.status)
|
self.assertEqual(final_trunk_status, current_trunk.status)
|
||||||
return trunk, current_trunk
|
return trunk, current_trunk
|
||||||
|
|
||||||
|
def test_get_trunk_subport(self):
|
||||||
|
|
||||||
|
with self.port() as parent_port, self.port() as child_port:
|
||||||
|
trunk = self._create_test_trunk(parent_port)
|
||||||
|
subport = create_subport_dict(child_port['port']['id'])
|
||||||
|
self.trunk_plugin.add_subports(
|
||||||
|
self.context, trunk['id'], {'sub_ports': [subport]})
|
||||||
|
|
||||||
|
portid = parent_port['port']['id']
|
||||||
|
pl = directory.get_plugin()
|
||||||
|
res = pl.get_ports(self.context, filters={'id': [portid]})
|
||||||
|
|
||||||
|
expected_trunk_details = {
|
||||||
|
'trunk_id': trunk['id'],
|
||||||
|
'sub_ports': [
|
||||||
|
{
|
||||||
|
'segmentation_id': subport['segmentation_id'],
|
||||||
|
'port_id': subport['port_id'],
|
||||||
|
'segmentation_type': subport['segmentation_type'],
|
||||||
|
'mac_address': child_port['port']['mac_address'],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
self.assertEqual(expected_trunk_details, res[0]['trunk_details'])
|
||||||
|
|
||||||
|
|
||||||
class TrunkPluginCompatDriversTestCase(test_plugin.Ml2PluginV2TestCase):
|
class TrunkPluginCompatDriversTestCase(test_plugin.Ml2PluginV2TestCase):
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user