Revisit (add|remove)_subports request body

The neutronclient [1] expects to serialize a dictionary any
time there is a body in the request. The (add|remove)_subports
methods were expecting a list of dicts instead.

This patch rectifies the issue by assuming a dict in the
body of the format {'sub_ports': [<my-subports]}. This is
indeed the most conventional way to pass request data to
Neutron server, and it was overlooked during a past review.

This was discovered during development of the client side
patch [2].

[1] https://github.com/openstack/python-neutronclient/blob/master/neutronclient/v2_0/client.py#L292
[2] https://review.openstack.org/#/c/340624/

Partially-implements: blueprint vlan-aware-vms
Change-Id: I8d36c61dd877d0ccb73c18702ed64897b71f001b
This commit is contained in:
Armando Migliaccio 2016-07-20 23:06:26 -07:00
parent a51e87abe8
commit b8f870d007
3 changed files with 5 additions and 3 deletions

View File

@ -149,6 +149,7 @@ class TrunkPlugin(service_base.ServicePluginBase,
"""Add one or more subports to trunk."""
# Check for basic validation since the request body here is not
# automatically validated by the API layer.
subports = subports['sub_ports']
subports_validator = rules.SubPortsValidator(
self._segmentation_types, subports)
subports = subports_validator.validate(context, basic_validation=True)
@ -176,6 +177,7 @@ class TrunkPlugin(service_base.ServicePluginBase,
@db_base_plugin_common.convert_result_to_dict
def remove_subports(self, context, trunk_id, subports):
"""Remove one or more subports from trunk."""
subports = subports['sub_ports']
with db_api.autonested_transaction(context.session):
trunk = self._get_trunk(context, trunk_id)
rules.trunk_can_be_managed(context, trunk)

View File

@ -713,7 +713,7 @@ class NetworkClientJSON(service_client.RestClient):
def _subports_action(self, action, trunk_id, subports):
uri = '%s/trunks/%s/%s' % (self.uri_prefix, trunk_id, action)
resp, body = self.put(uri, jsonutils.dumps(subports))
resp, body = self.put(uri, jsonutils.dumps({'sub_ports': subports}))
body = self.deserialize_single(body)
self.expected_success(200, resp.status)
return service_client.ResponseBody(resp, body)

View File

@ -74,10 +74,10 @@ class TrunkPluginTestCase(test_plugin.Ml2PluginV2TestCase):
subport = create_subport_dict(child_port['port']['id'])
callback = register_mock_callback(constants.SUBPORTS, event)
self.trunk_plugin.add_subports(
self.context, trunk['id'], [subport])
self.context, trunk['id'], {'sub_ports': [subport]})
subport_obj = self._get_subport_obj(subport['port_id'])
self.trunk_plugin.remove_subports(
self.context, trunk['id'], [subport])
self.context, trunk['id'], {'sub_ports': [subport]})
payload = {payload_key: [subport_obj]}
callback.assert_called_once_with(
constants.SUBPORTS, event, self.trunk_plugin, **payload)