From e10f406a653f3037109e2d7f59bed65bd54300a8 Mon Sep 17 00:00:00 2001 From: Akihiro Motoki Date: Sat, 22 Mar 2014 04:17:14 +0900 Subject: [PATCH] NEC plugin: Remove a colon from binding:profile key due to XML problem In XML specification, if a tag name contains a colon, a part before a colon is interpreted as namespace. If key names in binding:profile dict contains a colon, Neutron XML serializer sends them as-is. A colon in key names should be used only if XML namespace are used. NEC plugin uses a colon in key names and it leads to failures to XML deserialization. To avoid this problem, this commit removes a colon and prefix n key names in port binding:profile so that client XML deserializer decodes XML response successfully. Change-Id: Ie32a2417bbce03bfc6e8f7907c0b4090fbc9e7b6 Closes-Bug: #1294166 --- neutron/plugins/nec/common/exceptions.py | 4 +- neutron/plugins/nec/nec_plugin.py | 14 +++--- neutron/tests/unit/nec/test_portbindings.py | 50 ++++++++++----------- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/neutron/plugins/nec/common/exceptions.py b/neutron/plugins/nec/common/exceptions.py index 05a0e885a..375135586 100644 --- a/neutron/plugins/nec/common/exceptions.py +++ b/neutron/plugins/nec/common/exceptions.py @@ -57,13 +57,13 @@ class PortInfoNotFound(qexc.NotFound): class ProfilePortInfoInvalidDataPathId(qexc.InvalidInput): message = _('Invalid input for operation: ' - 'portinfo:datapath_id should be a hex string ' + 'datapath_id should be a hex string ' 'with at most 8 bytes') class ProfilePortInfoInvalidPortNo(qexc.InvalidInput): message = _('Invalid input for operation: ' - 'portinfo:port_no should be [0:65535]') + 'port_no should be [0:65535]') class RouterExternalGatewayNotSupported(qexc.BadRequest): diff --git a/neutron/plugins/nec/nec_plugin.py b/neutron/plugins/nec/nec_plugin.py index f19781fbb..43aaf1b03 100644 --- a/neutron/plugins/nec/nec_plugin.py +++ b/neutron/plugins/nec/nec_plugin.py @@ -406,24 +406,24 @@ class NECPluginV2(db_base_plugin_v2.NeutronDbPluginV2, def _extend_port_dict_binding_portinfo(self, port_res, portinfo): if portinfo: port_res[portbindings.PROFILE] = { - 'portinfo:datapath_id': portinfo['datapath_id'], - 'portinfo:port_no': portinfo['port_no'], + 'datapath_id': portinfo['datapath_id'], + 'port_no': portinfo['port_no'], } elif portbindings.PROFILE in port_res: del port_res[portbindings.PROFILE] def _validate_portinfo(self, profile): key_specs = { - 'portinfo:datapath_id': {'type:string': None, 'required': True}, - 'portinfo:port_no': {'type:non_negative': None, 'required': True, - 'convert_to': attrs.convert_to_int} + 'datapath_id': {'type:string': None, 'required': True}, + 'port_no': {'type:non_negative': None, 'required': True, + 'convert_to': attrs.convert_to_int} } msg = attrs._validate_dict_or_empty(profile, key_specs=key_specs) if msg: raise n_exc.InvalidInput(error_message=msg) - datapath_id = profile.get('portinfo:datapath_id') - port_no = profile.get('portinfo:port_no') + datapath_id = profile.get('datapath_id') + port_no = profile.get('port_no') try: dpid = int(datapath_id, 16) except ValueError: diff --git a/neutron/tests/unit/nec/test_portbindings.py b/neutron/tests/unit/nec/test_portbindings.py index 559f8aa56..d01a80738 100644 --- a/neutron/tests/unit/nec/test_portbindings.py +++ b/neutron/tests/unit/nec/test_portbindings.py @@ -51,24 +51,22 @@ class TestNecPortBindingHost( class TestNecPortBindingPortInfo(test_nec_plugin.NecPluginV2TestCase): - def _get_portinfo(self, datapath_id=None, port_no=None, prefix=None): + def _get_portinfo(self, datapath_id=None, port_no=None): if datapath_id is None: datapath_id = '0xabc' if port_no is None: port_no = 1 - if prefix is None: - prefix = 'portinfo:' - return {prefix + 'datapath_id': datapath_id, - prefix + 'port_no': port_no} + return {'datapath_id': datapath_id, + 'port_no': port_no} def _check_response_portbinding_profile(self, port, datapath_id=None, port_no=None): - expected = self._get_portinfo(datapath_id, port_no, prefix='') + expected = self._get_portinfo(datapath_id, port_no) profile = port[portbindings.PROFILE] self.assertEqual(len(profile), 2) - self.assertEqual(profile['portinfo:datapath_id'], + self.assertEqual(profile['datapath_id'], expected['datapath_id']) - self.assertEqual(profile['portinfo:port_no'], + self.assertEqual(profile['port_no'], expected['port_no']) def _check_response_portbinding_no_profile(self, port): @@ -267,8 +265,8 @@ class TestNecPortBindingPortInfo(test_nec_plugin.NecPluginV2TestCase): def test_port_create_portinfo_validation_called(self): # Check validate_portinfo is called. profile_arg = {portbindings.PROFILE: - {'portinfo:datapath_id': '0xabc', - 'portinfo:port_no': 0xffff + 1}} + {'datapath_id': '0xabc', + 'port_no': 0xffff + 1}} try: with self.port(arg_list=(portbindings.PROFILE,), expected_res_status=400, @@ -281,8 +279,8 @@ class TestNecPortBindingPortInfo(test_nec_plugin.NecPluginV2TestCase): class TestNecPortBindingValidatePortInfo(test_nec_plugin.NecPluginV2TestCase): def test_validate_portinfo_ok(self): - profile = {'portinfo:datapath_id': '0x1234567890abcdef', - 'portinfo:port_no': 123} + profile = {'datapath_id': '0x1234567890abcdef', + 'port_no': 123} portinfo = self.plugin._validate_portinfo(profile) # NOTE(mriedem): Handle long integer conversion universally. self.assertEqual( @@ -292,8 +290,8 @@ class TestNecPortBindingValidatePortInfo(test_nec_plugin.NecPluginV2TestCase): self.assertEqual(portinfo['port_no'], 123) def test_validate_portinfo_ok_without_0x(self): - profile = {'portinfo:datapath_id': '1234567890abcdef', - 'portinfo:port_no': 123} + profile = {'datapath_id': '1234567890abcdef', + 'port_no': 123} portinfo = self.plugin._validate_portinfo(profile) # NOTE(mriedem): Handle long integer conversion universally. self.assertEqual( @@ -311,36 +309,36 @@ class TestNecPortBindingValidatePortInfo(test_nec_plugin.NecPluginV2TestCase): expected_msg = ("Invalid input for operation: " "Validation of dictionary's keys failed.") - profile = {'portinfo:port_no': 123} + profile = {'port_no': 123} self._test_validate_exception(profile, expected_msg) - profile = {'portinfo:datapath_id': '0xabcdef'} + profile = {'datapath_id': '0xabcdef'} self._test_validate_exception(profile, expected_msg) def test_validate_portinfo_negative_port_number(self): - profile = {'portinfo:datapath_id': '0x1234567890abcdef', - 'portinfo:port_no': -1} + profile = {'datapath_id': '0x1234567890abcdef', + 'port_no': -1} expected_msg = ("Invalid input for operation: " "'-1' should be non-negative.") self._test_validate_exception(profile, expected_msg) def test_validate_portinfo_invalid_datapath_id(self): expected_msg = ("Invalid input for operation: " - "portinfo:datapath_id should be a hex string") + "datapath_id should be a hex string") # non hexidecimal datapath_id - profile = {'portinfo:datapath_id': 'INVALID', - 'portinfo:port_no': 123} + profile = {'datapath_id': 'INVALID', + 'port_no': 123} self._test_validate_exception(profile, expected_msg) # Too big datapath_id - profile = {'portinfo:datapath_id': '0x10000000000000000', - 'portinfo:port_no': 123} + profile = {'datapath_id': '0x10000000000000000', + 'port_no': 123} self._test_validate_exception(profile, expected_msg) def test_validate_portinfo_too_big_port_number(self): - profile = {'portinfo:datapath_id': '0x1234567890abcdef', - 'portinfo:port_no': 65536} + profile = {'datapath_id': '0x1234567890abcdef', + 'port_no': 65536} expected_msg = ("Invalid input for operation: " - "portinfo:port_no should be [0:65535]") + "port_no should be [0:65535]") self._test_validate_exception(profile, expected_msg) -- 2.45.2