From 600a0db48a766437a91b427da8eeb3f066963db2 Mon Sep 17 00:00:00 2001 From: Pavel Bondar Date: Fri, 30 Oct 2015 14:59:09 +0300 Subject: [PATCH] Fix incorrect passing port dict in pluggable IPAM _ipam_allocate_ips expects to receive port dict as a third argument, but 'changes' were passed instead. This issue affects only third-party vendors who implement own IPAM driver with custom AddressRequestFactory and uses port dict in it. Updated arguments passed to _ipam_allocate_ips to include port dict as a third argument. Change-Id: I25eb86f46e5412cfacad9a751a94f7720f1a7bd0 Closes-Bug: #1511707 --- neutron/db/ipam_pluggable_backend.py | 2 +- .../unit/db/test_ipam_pluggable_backend.py | 46 ++++++++++++++++--- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/neutron/db/ipam_pluggable_backend.py b/neutron/db/ipam_pluggable_backend.py index 29e371e34..865d05558 100644 --- a/neutron/db/ipam_pluggable_backend.py +++ b/neutron/db/ipam_pluggable_backend.py @@ -284,7 +284,7 @@ class IpamPluggableBackend(ipam_backend_mixin.IpamBackendMixin): changes.remove) if to_add: added = self._ipam_allocate_ips(context, ipam_driver, - changes, to_add) + port, to_add) return self.Changes(add=added, original=changes.original, remove=removed) diff --git a/neutron/tests/unit/db/test_ipam_pluggable_backend.py b/neutron/tests/unit/db/test_ipam_pluggable_backend.py index dd5d11112..97e79f561 100644 --- a/neutron/tests/unit/db/test_ipam_pluggable_backend.py +++ b/neutron/tests/unit/db/test_ipam_pluggable_backend.py @@ -63,7 +63,10 @@ class TestDbBasePluginIpam(test_db_base.NeutronDbPluginV2TestCase): self.tenant_id = uuidutils.generate_uuid() self.subnet_id = uuidutils.generate_uuid() - def _prepare_mocks(self): + def _prepare_mocks(self, address_factory=None): + if address_factory is None: + address_factory = ipam_req.AddressRequestFactory + mocks = { 'driver': mock.Mock(), 'subnet': mock.Mock(), @@ -76,10 +79,10 @@ class TestDbBasePluginIpam(test_db_base.NeutronDbPluginV2TestCase): } mocks['driver'].get_subnet.return_value = mocks['subnet'] mocks['driver'].allocate_subnet.return_value = mocks['subnet'] - mocks['driver'].get_subnet_request_factory = ( + mocks['driver'].get_subnet_request_factory.return_value = ( ipam_req.SubnetRequestFactory) - mocks['driver'].get_address_request_factory = ( - ipam_req.AddressRequestFactory) + mocks['driver'].get_address_request_factory.return_value = ( + address_factory) mocks['subnet'].get_details.return_value = mocks['subnet_request'] return mocks @@ -88,8 +91,8 @@ class TestDbBasePluginIpam(test_db_base.NeutronDbPluginV2TestCase): mocks['ipam'] = ipam_pluggable_backend.IpamPluggableBackend() return mocks - def _prepare_mocks_with_pool_mock(self, pool_mock): - mocks = self._prepare_mocks() + def _prepare_mocks_with_pool_mock(self, pool_mock, address_factory=None): + mocks = self._prepare_mocks(address_factory=address_factory) pool_mock.get_instance.return_value = mocks['driver'] return mocks @@ -509,3 +512,34 @@ class TestDbBasePluginIpam(test_db_base.NeutronDbPluginV2TestCase): ips = port['port']['fixed_ips'] self.assertEqual(1, len(ips)) self.assertEqual(ips[0]['ip_address'], ip) + + @mock.patch('neutron.ipam.driver.Pool') + def test_update_ips_for_port_passes_port_dict_to_factory(self, pool_mock): + address_factory = mock.Mock() + mocks = self._prepare_mocks_with_pool_mock( + pool_mock, address_factory=address_factory) + context = mock.Mock() + new_ips = mock.Mock() + original_ips = mock.Mock() + mac = mock.Mock() + + ip_dict = {'ip_address': '192.1.1.10', + 'subnet_id': uuidutils.generate_uuid()} + changes = ipam_pluggable_backend.IpamPluggableBackend.Changes( + add=[ip_dict], original=[], remove=[]) + changes_mock = mock.Mock(return_value=changes) + fixed_ips_mock = mock.Mock(return_value=changes.add) + mocks['ipam'] = ipam_pluggable_backend.IpamPluggableBackend() + mocks['ipam']._get_changed_ips_for_port = changes_mock + mocks['ipam']._test_fixed_ips_for_port = fixed_ips_mock + + port_dict = {'device_owner': uuidutils.generate_uuid(), + 'network_id': uuidutils.generate_uuid()} + + mocks['ipam']._update_ips_for_port(context, port_dict, + original_ips, new_ips, mac) + mocks['driver'].get_address_request_factory.assert_called_once_with() + # Validate port_dict is passed into address_factory + address_factory.get_request.assert_called_once_with(context, + port_dict, + ip_dict) -- 2.45.2