From e0b3665280a136bec4ccc70b4ca13fc59319e471 Mon Sep 17 00:00:00 2001 From: James Anziano Date: Mon, 8 Feb 2016 22:35:42 +0000 Subject: [PATCH] Stops update_network handling updates it shouldn't Currently update_network() attempts to update the network table with any parameters that belong to a network, even if those attributes are stored in a separate database table. This was causing certain update commands to fail (such as updating dns_domain). The actual update to dns_domain is handled by extensions called by the ml2 plugin, but this function was also trying to process it and causing an error. This patch ensures the network variable is only updated with attributes that are actually in the networks table by filtering out any parameters that don't match fields in the Network class model. Change-Id: I54a736d91de52dda85c559b9e6103199f914abdf Closes-bug: 1541560 --- neutron/db/db_base_plugin_v2.py | 6 +++++- neutron/tests/unit/extensions/test_dns.py | 24 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/neutron/db/db_base_plugin_v2.py b/neutron/db/db_base_plugin_v2.py index 529d71f0538..bf8a3c7f4f5 100644 --- a/neutron/db/db_base_plugin_v2.py +++ b/neutron/db/db_base_plugin_v2.py @@ -356,7 +356,11 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon, elif not update_shared and entry: context.session.delete(entry) context.session.expire(network, ['rbac_entries']) - network.update(n) + # The filter call removes attributes from the body received from + # the API that are logically tied to network resources but are + # stored in other database tables handled by extensions + network.update(self._filter_non_model_columns(n, + models_v2.Network)) return self._make_network_dict(network, context=context) def delete_network(self, context, id): diff --git a/neutron/tests/unit/extensions/test_dns.py b/neutron/tests/unit/extensions/test_dns.py index 6e9ec969564..64fc3c47eb9 100644 --- a/neutron/tests/unit/extensions/test_dns.py +++ b/neutron/tests/unit/extensions/test_dns.py @@ -57,6 +57,19 @@ class DnsExtensionTestCase(test_db_base_plugin_v2.TestNetworksV2): ext_mgr = DnsExtensionManager() super(DnsExtensionTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr) + def _create_network(self, fmt, name, admin_state_up, + arg_list=None, set_context=False, tenant_id=None, + **kwargs): + new_arg_list = ('dns_domain',) + if arg_list is not None: + new_arg_list = arg_list + new_arg_list + return super(DnsExtensionTestCase, + self)._create_network(fmt, name, admin_state_up, + arg_list=new_arg_list, + set_context=set_context, + tenant_id=tenant_id, + **kwargs) + def _create_port(self, fmt, net_id, expected_res_status=None, arg_list=None, set_context=False, tenant_id=None, **kwargs): @@ -474,3 +487,14 @@ class DnsExtensionTestCase(test_db_base_plugin_v2.TestNetworksV2): res = self._create_port(self.fmt, net_id=network['network']['id'], dns_name=dns_name) self.assertEqual(201, res.status_code) + + def test_update_network_dns_domain(self): + with self.network() as network: + data = {'network': {'dns_domain': 'my-domain.org.'}} + req = self.new_update_request('networks', + data, + network['network']['id']) + res = req.get_response(self.api) + self.assertEqual(200, res.status_code) + self.assertNotIn('dns_domain', + self.deserialize(self.fmt, res)['network'])