From 7b9bc3902495f78f5c0db42f58bfdf0b11c4cfdd Mon Sep 17 00:00:00 2001 From: Michael Still Date: Tue, 4 Dec 2018 12:00:34 +1100 Subject: [PATCH] Move binding ips to privsep. Change-Id: If76fc076e964c9492727dabdc1f5d7e9c295c7fe --- nova/network/linux_net.py | 10 +++----- nova/privsep/linux_net.py | 11 +++++++++ nova/tests/functional/integrated_helpers.py | 5 ++++ .../notification_sample_base.py | 5 ++++ nova/tests/unit/network/test_manager.py | 23 ++++++++++++------- nova/tests/unit/test_quota.py | 6 +++-- 6 files changed, 43 insertions(+), 17 deletions(-) diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index 45ca30e6f0d6..c94fcc49a8be 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -666,10 +666,7 @@ def send_arp_for_ip(ip, device, count): def bind_floating_ip(floating_ip, device): """Bind IP to public interface.""" - _execute('ip', 'addr', 'add', str(floating_ip) + '/32', - 'dev', device, - run_as_root=True, check_exit_code=[0, 2, 254]) - + nova.privsep.linux_net.bind_ip(device, floating_ip) if CONF.send_arp_for_ha and CONF.send_arp_for_ha_count > 0: send_arp_for_ip(floating_ip, device, CONF.send_arp_for_ha_count) @@ -683,9 +680,8 @@ def unbind_floating_ip(floating_ip, device): def ensure_metadata_ip(): """Sets up local metadata IP.""" - _execute('ip', 'addr', 'add', '169.254.169.254/32', - 'scope', 'link', 'dev', 'lo', - run_as_root=True, check_exit_code=[0, 2, 254]) + nova.privsep.linux_net.bind_ip('lo', '169.254.169.254', + scope_is_link=True) def ensure_vpn_forward(public_ip, port, private_ip): diff --git a/nova/privsep/linux_net.py b/nova/privsep/linux_net.py index 0579a8e3ec6a..4bd615428e3c 100644 --- a/nova/privsep/linux_net.py +++ b/nova/privsep/linux_net.py @@ -106,6 +106,17 @@ def set_device_macaddr(dev, mac_addr, port_state=None): check_exit_code=[0, 2, 254]) +@nova.privsep.sys_admin_pctxt.entrypoint +def bind_ip(device, ip, scope_is_link=False): + if not scope_is_link: + processutils.execute('ip', 'addr', 'add', str(ip) + '/32', + 'dev', device, check_exit_code=[0, 2, 254]) + else: + processutils.execute('ip', 'addr', 'add', str(ip) + '/32', + 'scope', 'link', 'dev', device, + check_exit_code=[0, 2, 254]) + + @nova.privsep.sys_admin_pctxt.entrypoint def create_veth_pair(dev1_name, dev2_name, mtu=None): """Create a pair of veth devices with the specified names, diff --git a/nova/tests/functional/integrated_helpers.py b/nova/tests/functional/integrated_helpers.py index 083a85598e29..18edc4878e32 100644 --- a/nova/tests/functional/integrated_helpers.py +++ b/nova/tests/functional/integrated_helpers.py @@ -84,6 +84,11 @@ class _IntegratedTestBase(test.TestCase): # TODO(mriedem): Fix the functional tests to work with Neutron. self.flags(use_neutron=self.USE_NEUTRON) + # NOTE(mikal): this is used to stub away privsep helpers + def fake_noop(*args, **kwargs): + return None + self.stub_out('nova.privsep.linux_net.bind_ip', fake_noop) + nova.tests.unit.image.fake.stub_out_image_service(self) self.useFixture(cast_as_call.CastAsCall(self)) diff --git a/nova/tests/functional/notification_sample_tests/notification_sample_base.py b/nova/tests/functional/notification_sample_tests/notification_sample_base.py index 2600785dfa22..1e247002443e 100644 --- a/nova/tests/functional/notification_sample_tests/notification_sample_base.py +++ b/nova/tests/functional/notification_sample_tests/notification_sample_base.py @@ -81,6 +81,11 @@ class NotificationSampleTestBase(test.TestCase, self.useFixture(utils_fixture.TimeFixture(test_services.fake_utcnow())) + # NOTE(mikal): this is used to stub away privsep helpers + def fake_noop(*args, **kwargs): + return None + self.stub_out('nova.privsep.linux_net.bind_ip', fake_noop) + # the image fake backend needed for image discovery nova.tests.unit.image.fake.stub_out_image_service(self) self.addCleanup(nova.tests.unit.image.fake.FakeImageService_reset) diff --git a/nova/tests/unit/network/test_manager.py b/nova/tests/unit/network/test_manager.py index 1c3be5756115..8a852ecc5a76 100644 --- a/nova/tests/unit/network/test_manager.py +++ b/nova/tests/unit/network/test_manager.py @@ -883,7 +883,8 @@ class FlatDHCPNetworkTestCase(test.TestCase): @mock.patch('nova.objects.fixed_ip.FixedIP.get_by_id') @mock.patch('nova.objects.floating_ip.FloatingIPList.get_by_host') @mock.patch('nova.network.linux_net.iptables_manager._apply') - def test_init_host_iptables_defer_apply(self, iptable_apply, + @mock.patch('nova.privsep.linux_net.bind_ip') + def test_init_host_iptables_defer_apply(self, bind_ip, iptable_apply, floating_get_by_host, fixed_get_by_id): def get_by_id(context, fixed_ip_id, **kwargs): @@ -1733,8 +1734,9 @@ class VlanNetworkTestCase(test.TestCase): @mock.patch('nova.db.api.fixed_ip_get_by_address') @mock.patch('nova.db.api.network_get') - def test_ip_association_and_allocation_of_other_project(self, net_get, - fixed_get): + @mock.patch('nova.privsep.linux_net.bind_ip') + def test_ip_association_and_allocation_of_other_project( + self, bind_ip, net_get, fixed_get): """Makes sure that we cannot deallocaate or disassociate a public IP of other project. """ @@ -2054,7 +2056,8 @@ class VlanNetworkTestCase(test.TestCase): @mock.patch('nova.objects.fixed_ip.FixedIP.get_by_id') @mock.patch('nova.objects.floating_ip.FloatingIPList.get_by_host') @mock.patch('nova.network.linux_net.iptables_manager._apply') - def test_init_host_iptables_defer_apply(self, iptable_apply, + @mock.patch('nova.privsep.linux_net.bind_ip') + def test_init_host_iptables_defer_apply(self, bind_ip, iptable_apply, floating_get_by_host, fixed_get_by_id): def get_by_id(context, fixed_ip_id, **kwargs): @@ -2748,7 +2751,8 @@ class CommonNetworkTestCase(test.TestCase): for line in expected_lines: self.assertIn(line, new_lines) - def test_flatdhcpmanager_dynamic_fixed_range(self): + @mock.patch('nova.privsep.linux_net.bind_ip') + def test_flatdhcpmanager_dynamic_fixed_range(self, mock_bind_ip): """Test FlatDHCPManager NAT rules for fixed_range.""" # Set the network manager self.network = network_manager.FlatDHCPManager(host=HOST) @@ -2759,7 +2763,8 @@ class CommonNetworkTestCase(test.TestCase): # Determine networks to NAT based on lookup self._test_init_host_dynamic_fixed_range(self.network) - def test_vlanmanager_dynamic_fixed_range(self): + @mock.patch('nova.privsep.linux_net.bind_ip') + def test_vlanmanager_dynamic_fixed_range(self, mock_bind_ip): """Test VlanManager NAT rules for fixed_range.""" # Set the network manager self.network = network_manager.VlanManager(host=HOST) @@ -2840,8 +2845,10 @@ class AllocateTestCase(test.TestCase): @mock.patch('nova.privsep.linux_net.set_device_mtu') @mock.patch('nova.privsep.linux_net.set_device_enabled') @mock.patch('nova.privsep.linux_net.set_device_macaddr') - def test_allocate_for_instance(self, mock_set_macaddr, mock_set_enabled, - mock_set_mtu, mock_add_bridge): + @mock.patch('nova.privsep.linux_net.bind_ip') + def test_allocate_for_instance(self, mock_bind, mock_set_macaddr, + mock_set_enabled, mock_set_mtu, + mock_add_bridge): address = "10.10.10.10" self.flags(auto_assign_floating_ip=True) diff --git a/nova/tests/unit/test_quota.py b/nova/tests/unit/test_quota.py index 5b8801ee945c..7a9aead58bda 100644 --- a/nova/tests/unit/test_quota.py +++ b/nova/tests/unit/test_quota.py @@ -153,7 +153,8 @@ class QuotaIntegrationTestCase(test.TestCase): for i in range(3): self._create_instance(flavor_name='m1.xlarge') - def test_too_many_addresses(self): + @mock.patch('nova.privsep.linux_net.bind_ip') + def test_too_many_addresses(self, mock_bind_ip): # This test is specifically relying on nova-network. self.flags(use_neutron=False, network_manager='nova.network.manager.FlatDHCPManager') @@ -172,7 +173,8 @@ class QuotaIntegrationTestCase(test.TestCase): self.project_id) db.floating_ip_destroy(context.get_admin_context(), address) - def test_auto_assigned(self): + @mock.patch('nova.privsep.linux_net.bind_ip') + def test_auto_assigned(self, mock_bind_ip): # This test is specifically relying on nova-network. self.flags(use_neutron=False, network_manager='nova.network.manager.FlatDHCPManager')