summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Haley <bhaley@redhat.com>2017-09-20 16:09:04 -0400
committerSlawek Kaplonski <slawek@kaplonski.pl>2017-10-04 21:09:28 +0000
commit4f627b4e8dfe699944a196fe90e0642cced6278f (patch)
tree76afa601e4bb75100be008e464b684b75afbbb1b
parentd2bf790a449b00a5bcb19ca7b1fcdf34da5a5551 (diff)
Change ip_lib network namespace code to use pyroute2
Change network namespace add/delete/list code to use pyroute2 library instead of calling /sbin/ip. Also changed all in-tree callers to use the new calls. Closes-bug: #1717582 Related-bug: #1492714 Change-Id: Id802e77543177fbb95ff15c2c7361172e8824633
Notes
Notes (review): Code-Review+1: Slawek Kaplonski <slawek@kaplonski.pl> Verified+1: Arista CI <arista-openstack-test@aristanetworks.com> Code-Review+1: Rodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com> Code-Review+2: Miguel Lavalle <miguel.lavalle@huawei.com> Code-Review+1: Swaminathan Vasudevan <SVasudevan@suse.com> Code-Review+1: Cuong Nguyen <cuongnv@vn.fujitsu.com> Code-Review+2: Ihar Hrachyshka <ihrachys@redhat.com> Workflow+1: Ihar Hrachyshka <ihrachys@redhat.com> Verified+2: Jenkins Submitted-by: Jenkins Submitted-at: Fri, 13 Oct 2017 22:53:20 +0000 Reviewed-on: https://review.openstack.org/505701 Project: openstack/neutron Branch: refs/heads/master
-rw-r--r--neutron/agent/dhcp_agent.py2
-rw-r--r--neutron/agent/l3/dvr_local_router.py6
-rw-r--r--neutron/agent/l3/l3_agent_extension_api.py3
-rw-r--r--neutron/agent/l3/namespace_manager.py3
-rw-r--r--neutron/agent/linux/dhcp.py5
-rw-r--r--neutron/agent/linux/ip_lib.py62
-rw-r--r--neutron/agent/linux/iptables_manager.py2
-rw-r--r--neutron/cmd/netns_cleanup.py2
-rw-r--r--neutron/cmd/sanity/checks.py21
-rw-r--r--neutron/debug/debug_agent.py5
-rw-r--r--neutron/privileged/agent/linux/ip_lib.py32
-rw-r--r--neutron/services/metering/drivers/iptables/iptables_driver.py5
-rw-r--r--neutron/tests/common/net_helpers.py3
-rw-r--r--neutron/tests/fullstack/base.py2
-rw-r--r--neutron/tests/fullstack/resources/machine.py3
-rw-r--r--neutron/tests/fullstack/resources/process.py5
-rw-r--r--neutron/tests/fullstack/test_l3_agent.py4
-rw-r--r--neutron/tests/functional/agent/l3/framework.py3
-rw-r--r--neutron/tests/functional/agent/l3/test_namespace_manager.py3
-rw-r--r--neutron/tests/functional/agent/test_dhcp_agent.py4
-rw-r--r--neutron/tests/functional/cmd/test_netns_cleanup.py2
-rw-r--r--neutron/tests/unit/agent/l3/test_agent.py16
-rw-r--r--neutron/tests/unit/agent/l3/test_dvr_snat_ns.py7
-rw-r--r--neutron/tests/unit/agent/l3/test_l3_agent_extension_api.py32
-rw-r--r--neutron/tests/unit/agent/l3/test_namespace_manager.py8
-rw-r--r--neutron/tests/unit/agent/linux/test_dhcp.py22
-rw-r--r--neutron/tests/unit/agent/linux/test_ip_lib.py90
-rw-r--r--neutron/tests/unit/agent/linux/test_iptables_manager.py4
-rw-r--r--neutron/tests/unit/cmd/test_netns_cleanup.py16
-rw-r--r--neutron/tests/unit/debug/test_commands.py9
-rw-r--r--neutron/tests/unit/services/metering/drivers/test_iptables.py2
31 files changed, 229 insertions, 154 deletions
diff --git a/neutron/agent/dhcp_agent.py b/neutron/agent/dhcp_agent.py
index cfb1576..48c07a1 100644
--- a/neutron/agent/dhcp_agent.py
+++ b/neutron/agent/dhcp_agent.py
@@ -34,12 +34,14 @@ def register_options(conf):
34 dhcp_config.register_agent_dhcp_opts(conf) 34 dhcp_config.register_agent_dhcp_opts(conf)
35 meta_conf.register_meta_conf_opts(meta_conf.SHARED_OPTS, conf) 35 meta_conf.register_meta_conf_opts(meta_conf.SHARED_OPTS, conf)
36 config.register_interface_opts(conf) 36 config.register_interface_opts(conf)
37 config.register_root_helper(conf)
37 38
38 39
39def main(): 40def main():
40 register_options(cfg.CONF) 41 register_options(cfg.CONF)
41 common_config.init(sys.argv[1:]) 42 common_config.init(sys.argv[1:])
42 config.setup_logging() 43 config.setup_logging()
44 config.setup_privsep()
43 server = neutron_service.Service.create( 45 server = neutron_service.Service.create(
44 binary='neutron-dhcp-agent', 46 binary='neutron-dhcp-agent',
45 topic=topics.DHCP_AGENT, 47 topic=topics.DHCP_AGENT,
diff --git a/neutron/agent/l3/dvr_local_router.py b/neutron/agent/l3/dvr_local_router.py
index d75a01f..94e2f80f 100644
--- a/neutron/agent/l3/dvr_local_router.py
+++ b/neutron/agent/l3/dvr_local_router.py
@@ -596,8 +596,7 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
596 def _delete_interface_route_in_fip_ns(self, router_port): 596 def _delete_interface_route_in_fip_ns(self, router_port):
597 rtr_2_fip_ip, fip_2_rtr_name = self.get_rtr_fip_ip_and_interface_name() 597 rtr_2_fip_ip, fip_2_rtr_name = self.get_rtr_fip_ip_and_interface_name()
598 fip_ns_name = self.fip_ns.get_name() 598 fip_ns_name = self.fip_ns.get_name()
599 ip_wrapper = ip_lib.IPWrapper(namespace=fip_ns_name) 599 if ip_lib.network_namespace_exists(fip_ns_name):
600 if ip_wrapper.netns.exists(fip_ns_name):
601 device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) 600 device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name)
602 if not device.exists(): 601 if not device.exists():
603 return 602 return
@@ -608,8 +607,7 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
608 def _add_interface_route_to_fip_ns(self, router_port): 607 def _add_interface_route_to_fip_ns(self, router_port):
609 rtr_2_fip_ip, fip_2_rtr_name = self.get_rtr_fip_ip_and_interface_name() 608 rtr_2_fip_ip, fip_2_rtr_name = self.get_rtr_fip_ip_and_interface_name()
610 fip_ns_name = self.fip_ns.get_name() 609 fip_ns_name = self.fip_ns.get_name()
611 ip_wrapper = ip_lib.IPWrapper(namespace=fip_ns_name) 610 if ip_lib.network_namespace_exists(fip_ns_name):
612 if ip_wrapper.netns.exists(fip_ns_name):
613 device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name) 611 device = ip_lib.IPDevice(fip_2_rtr_name, namespace=fip_ns_name)
614 if not device.exists(): 612 if not device.exists():
615 return 613 return
diff --git a/neutron/agent/l3/l3_agent_extension_api.py b/neutron/agent/l3/l3_agent_extension_api.py
index b125ad6..f04cc95 100644
--- a/neutron/agent/l3/l3_agent_extension_api.py
+++ b/neutron/agent/l3/l3_agent_extension_api.py
@@ -30,8 +30,7 @@ class L3AgentExtensionAPI(object):
30 self._router_info = router_info 30 self._router_info = router_info
31 31
32 def _local_namespaces(self): 32 def _local_namespaces(self):
33 root_ip = ip_lib.IPWrapper() 33 local_ns_list = ip_lib.list_network_namespaces()
34 local_ns_list = root_ip.get_namespaces()
35 return set(local_ns_list) 34 return set(local_ns_list)
36 35
37 def get_router_hosting_port(self, port_id): 36 def get_router_hosting_port(self, port_id):
diff --git a/neutron/agent/l3/namespace_manager.py b/neutron/agent/l3/namespace_manager.py
index bc42be9..98af154 100644
--- a/neutron/agent/l3/namespace_manager.py
+++ b/neutron/agent/l3/namespace_manager.py
@@ -114,8 +114,7 @@ class NamespaceManager(object):
114 def list_all(self): 114 def list_all(self):
115 """Get a set of all namespaces on host managed by this manager.""" 115 """Get a set of all namespaces on host managed by this manager."""
116 try: 116 try:
117 root_ip = ip_lib.IPWrapper() 117 namespaces = ip_lib.list_network_namespaces()
118 namespaces = root_ip.get_namespaces()
119 return set(ns for ns in namespaces if self.is_managed(ns)) 118 return set(ns for ns in namespaces if self.is_managed(ns))
120 except RuntimeError: 119 except RuntimeError:
121 LOG.exception('RuntimeError in obtaining namespace list for ' 120 LOG.exception('RuntimeError in obtaining namespace list for '
diff --git a/neutron/agent/linux/dhcp.py b/neutron/agent/linux/dhcp.py
index a46bc12..d823b2d 100644
--- a/neutron/agent/linux/dhcp.py
+++ b/neutron/agent/linux/dhcp.py
@@ -241,12 +241,11 @@ class DhcpLocalProcess(DhcpBase):
241 LOG.warning('Failed trying to delete interface: %s', 241 LOG.warning('Failed trying to delete interface: %s',
242 self.interface_name) 242 self.interface_name)
243 243
244 ns_ip = ip_lib.IPWrapper(namespace=self.network.namespace) 244 if not ip_lib.network_namespace_exists(self.network.namespace):
245 if not ns_ip.netns.exists(self.network.namespace):
246 LOG.debug("Namespace already deleted: %s", self.network.namespace) 245 LOG.debug("Namespace already deleted: %s", self.network.namespace)
247 return 246 return
248 try: 247 try:
249 ns_ip.netns.delete(self.network.namespace) 248 ip_lib.delete_network_namespace(self.network.namespace)
250 except RuntimeError: 249 except RuntimeError:
251 LOG.warning('Failed trying to delete namespace: %s', 250 LOG.warning('Failed trying to delete namespace: %s',
252 self.network.namespace) 251 self.network.namespace)
diff --git a/neutron/agent/linux/ip_lib.py b/neutron/agent/linux/ip_lib.py
index 601f982..d359864 100644
--- a/neutron/agent/linux/ip_lib.py
+++ b/neutron/agent/linux/ip_lib.py
@@ -17,6 +17,7 @@ import os
17import re 17import re
18import time 18import time
19 19
20from debtcollector import removals
20import eventlet 21import eventlet
21import netaddr 22import netaddr
22from neutron_lib import constants 23from neutron_lib import constants
@@ -24,6 +25,7 @@ from neutron_lib import exceptions
24from oslo_config import cfg 25from oslo_config import cfg
25from oslo_log import log as logging 26from oslo_log import log as logging
26from oslo_utils import excutils 27from oslo_utils import excutils
28from pyroute2 import netns
27import six 29import six
28 30
29from neutron._i18n import _ 31from neutron._i18n import _
@@ -256,12 +258,13 @@ class IPWrapper(SubProcessBase):
256 self._as_root([], 'link', cmd) 258 self._as_root([], 'link', cmd)
257 return (IPDevice(name, namespace=self.namespace)) 259 return (IPDevice(name, namespace=self.namespace))
258 260
261 @removals.remove(version='Queens', removal_version='Rocky',
262 message="This will be removed in the future. Please use "
263 "'neutron.agent.linux.ip_lib."
264 "list_network_namespaces' instead.")
259 @classmethod 265 @classmethod
260 def get_namespaces(cls): 266 def get_namespaces(cls):
261 output = cls._execute( 267 return list_network_namespaces()
262 [], 'netns', ('list',),
263 run_as_root=cfg.CONF.AGENT.use_helper_for_ns_read)
264 return [l.split()[0] for l in output.splitlines()]
265 268
266 269
267class IPDevice(SubProcessBase): 270class IPDevice(SubProcessBase):
@@ -863,14 +866,14 @@ class IpNetnsCommand(IpCommandBase):
863 COMMAND = 'netns' 866 COMMAND = 'netns'
864 867
865 def add(self, name): 868 def add(self, name):
866 self._as_root([], ('add', name), use_root_namespace=True) 869 create_network_namespace(name)
867 wrapper = IPWrapper(namespace=name) 870 wrapper = IPWrapper(namespace=name)
868 wrapper.netns.execute(['sysctl', '-w', 871 wrapper.netns.execute(['sysctl', '-w',
869 'net.ipv4.conf.all.promote_secondaries=1']) 872 'net.ipv4.conf.all.promote_secondaries=1'])
870 return wrapper 873 return wrapper
871 874
872 def delete(self, name): 875 def delete(self, name):
873 self._as_root([], ('delete', name), use_root_namespace=True) 876 delete_network_namespace(name)
874 877
875 def execute(self, cmds, addl_env=None, check_exit_code=True, 878 def execute(self, cmds, addl_env=None, check_exit_code=True,
876 log_fail_as_error=True, extra_ok_codes=None, 879 log_fail_as_error=True, extra_ok_codes=None,
@@ -891,13 +894,7 @@ class IpNetnsCommand(IpCommandBase):
891 log_fail_as_error=log_fail_as_error, **kwargs) 894 log_fail_as_error=log_fail_as_error, **kwargs)
892 895
893 def exists(self, name): 896 def exists(self, name):
894 output = self._parent._execute( 897 return network_namespace_exists(name)
895 ['o'], 'netns', ['list'],
896 run_as_root=cfg.CONF.AGENT.use_helper_for_ns_read)
897 for line in [l.split()[0] for l in output.splitlines()]:
898 if name == line:
899 return True
900 return False
901 898
902 899
903def vlan_in_use(segmentation_id, namespace=None): 900def vlan_in_use(segmentation_id, namespace=None):
@@ -1018,6 +1015,45 @@ def dump_neigh_entries(ip_version, device=None, namespace=None, **kwargs):
1018 **kwargs)) 1015 **kwargs))
1019 1016
1020 1017
1018def create_network_namespace(namespace, **kwargs):
1019 """Create a network namespace.
1020
1021 :param namespace: The name of the namespace to create
1022 :param kwargs: Callers add any filters they use as kwargs
1023 """
1024 privileged.create_netns(namespace, **kwargs)
1025
1026
1027def delete_network_namespace(namespace, **kwargs):
1028 """Delete a network namespace.
1029
1030 :param namespace: The name of the namespace to delete
1031 :param kwargs: Callers add any filters they use as kwargs
1032 """
1033 privileged.remove_netns(namespace, **kwargs)
1034
1035
1036def list_network_namespaces(**kwargs):
1037 """List all network namespace entries.
1038
1039 :param kwargs: Callers add any filters they use as kwargs
1040 """
1041 if cfg.CONF.AGENT.use_helper_for_ns_read:
1042 return privileged.list_netns(**kwargs)
1043 else:
1044 return netns.listnetns(**kwargs)
1045
1046
1047def network_namespace_exists(namespace, **kwargs):
1048 """Check if a network namespace exists.
1049
1050 :param namespace: The name of the namespace to check
1051 :param kwargs: Callers add any filters they use as kwargs
1052 """
1053 output = list_network_namespaces(**kwargs)
1054 return namespace in output
1055
1056
1021def ensure_device_is_ready(device_name, namespace=None): 1057def ensure_device_is_ready(device_name, namespace=None):
1022 dev = IPDevice(device_name, namespace=namespace) 1058 dev = IPDevice(device_name, namespace=namespace)
1023 dev.set_log_fail_as_error(False) 1059 dev.set_log_fail_as_error(False)
diff --git a/neutron/agent/linux/iptables_manager.py b/neutron/agent/linux/iptables_manager.py
index 78eee48..92874ed 100644
--- a/neutron/agent/linux/iptables_manager.py
+++ b/neutron/agent/linux/iptables_manager.py
@@ -523,7 +523,7 @@ class IptablesManager(object):
523 # exist. 523 # exist.
524 with excutils.save_and_reraise_exception() as ctx: 524 with excutils.save_and_reraise_exception() as ctx:
525 if (self.namespace and not 525 if (self.namespace and not
526 ip_lib.IPWrapper().netns.exists(self.namespace)): 526 ip_lib.network_namespace_exists(self.namespace)):
527 ctx.reraise = False 527 ctx.reraise = False
528 LOG.error("Namespace %s was deleted during IPTables " 528 LOG.error("Namespace %s was deleted during IPTables "
529 "operations.", self.namespace) 529 "operations.", self.namespace)
diff --git a/neutron/cmd/netns_cleanup.py b/neutron/cmd/netns_cleanup.py
index 729fa58..d65e438 100644
--- a/neutron/cmd/netns_cleanup.py
+++ b/neutron/cmd/netns_cleanup.py
@@ -256,7 +256,7 @@ def destroy_namespace(conf, namespace, force=False):
256def cleanup_network_namespaces(conf): 256def cleanup_network_namespaces(conf):
257 # Identify namespaces that are candidates for deletion. 257 # Identify namespaces that are candidates for deletion.
258 candidates = [ns for ns in 258 candidates = [ns for ns in
259 ip_lib.IPWrapper.get_namespaces() 259 ip_lib.list_network_namespaces()
260 if eligible_for_deletion(conf, ns, conf.force)] 260 if eligible_for_deletion(conf, ns, conf.force)]
261 261
262 if candidates: 262 if candidates:
diff --git a/neutron/cmd/sanity/checks.py b/neutron/cmd/sanity/checks.py
index 50854d9..3b42ded 100644
--- a/neutron/cmd/sanity/checks.py
+++ b/neutron/cmd/sanity/checks.py
@@ -181,15 +181,13 @@ def vf_extended_management_supported():
181 181
182 182
183def netns_read_requires_helper(): 183def netns_read_requires_helper():
184 ipw = ip_lib.IPWrapper()
185 nsname = "netnsreadtest-" + uuidutils.generate_uuid() 184 nsname = "netnsreadtest-" + uuidutils.generate_uuid()
186 ipw.netns.add(nsname) 185 ip_lib.create_network_namespace(nsname)
187 try: 186 try:
188 # read without root_helper. if exists, not required. 187 # read without root_helper. if exists, not required.
189 ipw_nohelp = ip_lib.IPWrapper() 188 exists = ip_lib.network_namespace_exists(nsname)
190 exists = ipw_nohelp.netns.exists(nsname)
191 finally: 189 finally:
192 ipw.netns.delete(nsname) 190 ip_lib.delete_network_namespace(nsname)
193 return not exists 191 return not exists
194 192
195 193
@@ -294,7 +292,7 @@ class KeepalivedIPv6Test(object):
294 common_utils.wait_until_true(_gw_vip_assigned) 292 common_utils.wait_until_true(_gw_vip_assigned)
295 293
296 def __enter__(self): 294 def __enter__(self):
297 ip_lib.IPWrapper().netns.add(self.nsname) 295 ip_lib.create_network_namespace(self.nsname)
298 return self 296 return self
299 297
300 def __exit__(self, exc_type, exc_value, exc_tb): 298 def __exit__(self, exc_type, exc_value, exc_tb):
@@ -304,7 +302,7 @@ class KeepalivedIPv6Test(object):
304 self.manager.disable() 302 self.manager.disable()
305 if self.config_path: 303 if self.config_path:
306 shutil.rmtree(self.config_path, ignore_errors=True) 304 shutil.rmtree(self.config_path, ignore_errors=True)
307 ip_lib.IPWrapper().netns.delete(self.nsname) 305 ip_lib.delete_network_namespace(self.nsname)
308 cfg.CONF.set_override('check_child_processes_interval', 306 cfg.CONF.set_override('check_child_processes_interval',
309 self.orig_interval, 'AGENT') 307 self.orig_interval, 'AGENT')
310 308
@@ -450,13 +448,12 @@ def _fix_ip_nonlocal_bind_root_value(original_value):
450 448
451 449
452def ip_nonlocal_bind(): 450def ip_nonlocal_bind():
453 ipw = ip_lib.IPWrapper()
454 nsname1 = "ipnonlocalbind1-" + uuidutils.generate_uuid() 451 nsname1 = "ipnonlocalbind1-" + uuidutils.generate_uuid()
455 nsname2 = "ipnonlocalbind2-" + uuidutils.generate_uuid() 452 nsname2 = "ipnonlocalbind2-" + uuidutils.generate_uuid()
456 453
457 ipw.netns.add(nsname1) 454 ip_lib.create_network_namespace(nsname1)
458 try: 455 try:
459 ipw.netns.add(nsname2) 456 ip_lib.create_network_namespace(nsname2)
460 try: 457 try:
461 original_value = ip_lib.get_ip_nonlocal_bind(namespace=None) 458 original_value = ip_lib.get_ip_nonlocal_bind(namespace=None)
462 try: 459 try:
@@ -470,7 +467,7 @@ def ip_nonlocal_bind():
470 "Exception: %s", e) 467 "Exception: %s", e)
471 return False 468 return False
472 finally: 469 finally:
473 ipw.netns.delete(nsname2) 470 ip_lib.delete_network_namespace(nsname2)
474 finally: 471 finally:
475 ipw.netns.delete(nsname1) 472 ip_lib.delete_network_namespace(nsname1)
476 return ns1_value == 0 473 return ns1_value == 0
diff --git a/neutron/debug/debug_agent.py b/neutron/debug/debug_agent.py
index d4fcaa9..aad29ea 100644
--- a/neutron/debug/debug_agent.py
+++ b/neutron/debug/debug_agent.py
@@ -98,14 +98,13 @@ class NeutronDebugAgent(object):
98 bridge = None 98 bridge = None
99 if network.external: 99 if network.external:
100 bridge = self.conf.external_network_bridge 100 bridge = self.conf.external_network_bridge
101 ip = ip_lib.IPWrapper()
102 namespace = self._get_namespace(port) 101 namespace = self._get_namespace(port)
103 if ip.netns.exists(namespace): 102 if ip_lib.network_namespace_exists(namespace):
104 self.driver.unplug(self.driver.get_device_name(port), 103 self.driver.unplug(self.driver.get_device_name(port),
105 bridge=bridge, 104 bridge=bridge,
106 namespace=namespace) 105 namespace=namespace)
107 try: 106 try:
108 ip.netns.delete(namespace) 107 ip_lib.delete_network_namespace(namespace)
109 except Exception: 108 except Exception:
110 LOG.warning('Failed to delete namespace %s', namespace) 109 LOG.warning('Failed to delete namespace %s', namespace)
111 else: 110 else:
diff --git a/neutron/privileged/agent/linux/ip_lib.py b/neutron/privileged/agent/linux/ip_lib.py
index 404dded..14738f7 100644
--- a/neutron/privileged/agent/linux/ip_lib.py
+++ b/neutron/privileged/agent/linux/ip_lib.py
@@ -17,6 +17,7 @@ import pyroute2
17from pyroute2.netlink import rtnl 17from pyroute2.netlink import rtnl
18from pyroute2.netlink.rtnl import ndmsg 18from pyroute2.netlink.rtnl import ndmsg
19from pyroute2 import NetlinkError 19from pyroute2 import NetlinkError
20from pyroute2 import netns
20 21
21from neutron._i18n import _ 22from neutron._i18n import _
22from neutron import privileged 23from neutron import privileged
@@ -175,3 +176,34 @@ def dump_neigh_entries(ip_version, device, namespace, **kwargs):
175 'lladdr': attrs.get('NDA_LLADDR'), 176 'lladdr': attrs.get('NDA_LLADDR'),
176 'device': device}] 177 'device': device}]
177 return entries 178 return entries
179
180
181@privileged.default.entrypoint
182def create_netns(name, **kwargs):
183 """Create a network namespace.
184
185 :param name: The name of the namespace to create
186 """
187 try:
188 netns.create(name, **kwargs)
189 except OSError as e:
190 if e.errno != errno.EEXIST:
191 raise
192
193
194@privileged.default.entrypoint
195def remove_netns(name, **kwargs):
196 """Remove a network namespace.
197
198 :param name: The name of the namespace to remove
199 """
200 netns.remove(name, **kwargs)
201
202
203@privileged.default.entrypoint
204def list_netns(**kwargs):
205 """List network namespaces.
206
207 Caller requires raised priveleges to list namespaces
208 """
209 return netns.listnetns(**kwargs)
diff --git a/neutron/services/metering/drivers/iptables/iptables_driver.py b/neutron/services/metering/drivers/iptables/iptables_driver.py
index e07f584..48b5eb7 100644
--- a/neutron/services/metering/drivers/iptables/iptables_driver.py
+++ b/neutron/services/metering/drivers/iptables/iptables_driver.py
@@ -81,7 +81,7 @@ class RouterWithMetering(object):
81 self.id) 81 self.id)
82 # Check for namespace existence before we assign the 82 # Check for namespace existence before we assign the
83 # snat_iptables_manager 83 # snat_iptables_manager
84 if ip_lib.IPWrapper().netns.exists(snat_ns_name): 84 if ip_lib.network_namespace_exists(snat_ns_name):
85 self.snat_iptables_manager = iptables_manager.IptablesManager( 85 self.snat_iptables_manager = iptables_manager.IptablesManager(
86 namespace=snat_ns_name, 86 namespace=snat_ns_name,
87 binary_name=WRAP_NAME, 87 binary_name=WRAP_NAME,
@@ -91,8 +91,7 @@ class RouterWithMetering(object):
91 # NOTE(Swami): If distributed routers, all external traffic on a 91 # NOTE(Swami): If distributed routers, all external traffic on a
92 # compute node will flow through the rfp interface in the router 92 # compute node will flow through the rfp interface in the router
93 # namespace. 93 # namespace.
94 ip_wrapper = ip_lib.IPWrapper(namespace=self.ns_name) 94 if ip_lib.network_namespace_exists(self.ns_name):
95 if ip_wrapper.netns.exists(self.ns_name):
96 self.iptables_manager = iptables_manager.IptablesManager( 95 self.iptables_manager = iptables_manager.IptablesManager(
97 namespace=self.ns_name, 96 namespace=self.ns_name,
98 binary_name=WRAP_NAME, 97 binary_name=WRAP_NAME,
diff --git a/neutron/tests/common/net_helpers.py b/neutron/tests/common/net_helpers.py
index 18d56af..729b605 100644
--- a/neutron/tests/common/net_helpers.py
+++ b/neutron/tests/common/net_helpers.py
@@ -658,8 +658,7 @@ class MacvtapFixture(fixtures.Fixture):
658 self.addCleanup(self.destroy) 658 self.addCleanup(self.destroy)
659 659
660 def destroy(self): 660 def destroy(self):
661 ip_wrapper = ip_lib.IPWrapper(self.ip_dev.namespace) 661 if (ip_lib.network_namespace_exists(self.ip_dev.namespace) or
662 if (ip_wrapper.netns.exists(self.ip_dev.namespace) or
663 self.ip_dev.namespace is None): 662 self.ip_dev.namespace is None):
664 try: 663 try:
665 self.ip_dev.link.delete() 664 self.ip_dev.link.delete()
diff --git a/neutron/tests/fullstack/base.py b/neutron/tests/fullstack/base.py
index e66c6e6..cf84b50 100644
--- a/neutron/tests/fullstack/base.py
+++ b/neutron/tests/fullstack/base.py
@@ -16,6 +16,7 @@ import os
16 16
17from oslo_config import cfg 17from oslo_config import cfg
18 18
19from neutron.conf.agent import common as config
19from neutron.tests import base as tests_base 20from neutron.tests import base as tests_base
20from neutron.tests.common import helpers 21from neutron.tests.common import helpers
21from neutron.tests.fullstack.resources import client as client_resource 22from neutron.tests.fullstack.resources import client as client_resource
@@ -60,6 +61,7 @@ class BaseFullStackTestCase(testlib_api.MySQLTestCaseMixin,
60 61
61 # configure test runner to use rootwrap 62 # configure test runner to use rootwrap
62 self.setup_rootwrap() 63 self.setup_rootwrap()
64 config.setup_privsep()
63 65
64 self.environment = environment 66 self.environment = environment
65 self.environment.test_name = self.get_name() 67 self.environment.test_name = self.get_name()
diff --git a/neutron/tests/fullstack/resources/machine.py b/neutron/tests/fullstack/resources/machine.py
index 35fd169..be91d4e 100644
--- a/neutron/tests/fullstack/resources/machine.py
+++ b/neutron/tests/fullstack/resources/machine.py
@@ -200,8 +200,7 @@ class FakeFullstackMachine(machine_fixtures.FakeMachineBase):
200 # All associated vlan interfaces are deleted too 200 # All associated vlan interfaces are deleted too
201 self.bridge.delete_port(self.port.name) 201 self.bridge.delete_port(self.port.name)
202 202
203 ip_wrap = ip_lib.IPWrapper(self.namespace) 203 ip_lib.delete_network_namespace(self.namespace)
204 ip_wrap.netns.delete(self.namespace)
205 204
206 205
207class FakeFullstackTrunkMachine(FakeFullstackMachine): 206class FakeFullstackTrunkMachine(FakeFullstackMachine):
diff --git a/neutron/tests/fullstack/resources/process.py b/neutron/tests/fullstack/resources/process.py
index 5ff3055..a24f017 100644
--- a/neutron/tests/fullstack/resources/process.py
+++ b/neutron/tests/fullstack/resources/process.py
@@ -348,11 +348,10 @@ class DhcpAgentFixture(fixtures.Fixture):
348 namespace suffix. 348 namespace suffix.
349 """ 349 """
350 350
351 ip_wrapper = ip_lib.IPWrapper() 351 for namespace in ip_lib.list_network_namespaces():
352 for namespace in ip_wrapper.get_namespaces():
353 if self.dhcp_namespace_pattern.match(namespace): 352 if self.dhcp_namespace_pattern.match(namespace):
354 try: 353 try:
355 ip_wrapper.netns.delete(namespace) 354 ip_lib.delete_network_namespace(namespace)
356 except RuntimeError: 355 except RuntimeError:
357 # Continue cleaning even if namespace deletions fails 356 # Continue cleaning even if namespace deletions fails
358 pass 357 pass
diff --git a/neutron/tests/fullstack/test_l3_agent.py b/neutron/tests/fullstack/test_l3_agent.py
index 087a53a..c6f1a83 100644
--- a/neutron/tests/fullstack/test_l3_agent.py
+++ b/neutron/tests/fullstack/test_l3_agent.py
@@ -93,8 +93,8 @@ class TestLegacyL3Agent(TestL3Agent):
93 return namespaces.build_ns_name(namespaces.NS_PREFIX, router_id) 93 return namespaces.build_ns_name(namespaces.NS_PREFIX, router_id)
94 94
95 def _assert_namespace_exists(self, ns_name): 95 def _assert_namespace_exists(self, ns_name):
96 ip = ip_lib.IPWrapper(ns_name) 96 common_utils.wait_until_true(
97 common_utils.wait_until_true(lambda: ip.netns.exists(ns_name)) 97 lambda: ip_lib.network_namespace_exists(ns_name))
98 98
99 def test_namespace_exists(self): 99 def test_namespace_exists(self):
100 tenant_id = uuidutils.generate_uuid() 100 tenant_id = uuidutils.generate_uuid()
diff --git a/neutron/tests/functional/agent/l3/framework.py b/neutron/tests/functional/agent/l3/framework.py
index 0acd885..54b70b7 100644
--- a/neutron/tests/functional/agent/l3/framework.py
+++ b/neutron/tests/functional/agent/l3/framework.py
@@ -340,8 +340,7 @@ class L3AgentTestFramework(base.BaseSudoTestCase):
340 ip_version, ipv6_subnet_modes, interface_id) 340 ip_version, ipv6_subnet_modes, interface_id)
341 341
342 def _namespace_exists(self, namespace): 342 def _namespace_exists(self, namespace):
343 ip = ip_lib.IPWrapper(namespace=namespace) 343 return ip_lib.network_namespace_exists(namespace)
344 return ip.netns.exists(namespace)
345 344
346 def _metadata_proxy_exists(self, conf, router): 345 def _metadata_proxy_exists(self, conf, router):
347 pm = external_process.ProcessManager( 346 pm = external_process.ProcessManager(
diff --git a/neutron/tests/functional/agent/l3/test_namespace_manager.py b/neutron/tests/functional/agent/l3/test_namespace_manager.py
index 9a5e801..b68d0fe 100644
--- a/neutron/tests/functional/agent/l3/test_namespace_manager.py
+++ b/neutron/tests/functional/agent/l3/test_namespace_manager.py
@@ -53,8 +53,7 @@ class NamespaceManagerTestFramework(base.BaseSudoTestCase):
53 raise e 53 raise e
54 54
55 def _namespace_exists(self, namespace): 55 def _namespace_exists(self, namespace):
56 ip = ip_lib.IPWrapper(namespace=namespace) 56 return ip_lib.network_namespace_exists(namespace)
57 return ip.netns.exists(namespace)
58 57
59 58
60class NamespaceManagerTestCase(NamespaceManagerTestFramework): 59class NamespaceManagerTestCase(NamespaceManagerTestFramework):
diff --git a/neutron/tests/functional/agent/test_dhcp_agent.py b/neutron/tests/functional/agent/test_dhcp_agent.py
index f242b51..7c83aa0 100644
--- a/neutron/tests/functional/agent/test_dhcp_agent.py
+++ b/neutron/tests/functional/agent/test_dhcp_agent.py
@@ -173,8 +173,8 @@ class DHCPAgentOVSTestFramework(base.BaseSudoTestCase):
173 self.assert_dhcp_device(network.namespace, iface_name, dhcp_enabled) 173 self.assert_dhcp_device(network.namespace, iface_name, dhcp_enabled)
174 174
175 def assert_dhcp_namespace(self, namespace, dhcp_enabled): 175 def assert_dhcp_namespace(self, namespace, dhcp_enabled):
176 ip = ip_lib.IPWrapper() 176 self.assertEqual(dhcp_enabled,
177 self.assertEqual(dhcp_enabled, ip.netns.exists(namespace)) 177 ip_lib.network_namespace_exists(namespace))
178 178
179 def assert_accept_ra_disabled(self, namespace): 179 def assert_accept_ra_disabled(self, namespace):
180 actual = ip_lib.IPWrapper(namespace=namespace).netns.execute( 180 actual = ip_lib.IPWrapper(namespace=namespace).netns.execute(
diff --git a/neutron/tests/functional/cmd/test_netns_cleanup.py b/neutron/tests/functional/cmd/test_netns_cleanup.py
index 7b40951..0529803 100644
--- a/neutron/tests/functional/cmd/test_netns_cleanup.py
+++ b/neutron/tests/functional/cmd/test_netns_cleanup.py
@@ -30,7 +30,7 @@ from neutron.tests.common import net_helpers
30from neutron.tests.functional import base 30from neutron.tests.functional import base
31from neutron.tests.functional.cmd import process_spawn 31from neutron.tests.functional.cmd import process_spawn
32 32
33GET_NAMESPACES = 'neutron.agent.linux.ip_lib.IPWrapper.get_namespaces' 33GET_NAMESPACES = 'neutron.agent.linux.ip_lib.list_network_namespaces'
34TEST_INTERFACE_DRIVER = 'neutron.agent.linux.interface.OVSInterfaceDriver' 34TEST_INTERFACE_DRIVER = 'neutron.agent.linux.interface.OVSInterfaceDriver'
35NUM_SUBPROCESSES = 6 35NUM_SUBPROCESSES = 6
36 36
diff --git a/neutron/tests/unit/agent/l3/test_agent.py b/neutron/tests/unit/agent/l3/test_agent.py
index d268208..d141e07 100644
--- a/neutron/tests/unit/agent/l3/test_agent.py
+++ b/neutron/tests/unit/agent/l3/test_agent.py
@@ -89,6 +89,10 @@ class BasicRouterOperationsFramework(base.BaseTestCase):
89 'neutron.agent.linux.ip_lib.device_exists') 89 'neutron.agent.linux.ip_lib.device_exists')
90 self.device_exists = self.device_exists_p.start() 90 self.device_exists = self.device_exists_p.start()
91 91
92 self.list_network_namespaces_p = mock.patch(
93 'neutron.agent.linux.ip_lib.list_network_namespaces')
94 self.list_network_namespaces = self.list_network_namespaces_p.start()
95
92 self.ensure_dir = mock.patch( 96 self.ensure_dir = mock.patch(
93 'oslo_utils.fileutils.ensure_tree').start() 97 'oslo_utils.fileutils.ensure_tree').start()
94 98
@@ -373,7 +377,7 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
373 for r_id in stale_router_ids] 377 for r_id in stale_router_ids]
374 namespace_list += [namespaces.NS_PREFIX + r['id'] 378 namespace_list += [namespaces.NS_PREFIX + r['id']
375 for r in active_routers] 379 for r in active_routers]
376 self.mock_ip.get_namespaces.return_value = namespace_list 380 self.list_network_namespaces.return_value = namespace_list
377 driver = metadata_driver.MetadataDriver 381 driver = metadata_driver.MetadataDriver
378 with mock.patch.object( 382 with mock.patch.object(
379 driver, 'destroy_monitored_metadata_proxy') as destroy_proxy: 383 driver, 'destroy_monitored_metadata_proxy') as destroy_proxy:
@@ -2327,7 +2331,7 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
2327 def test_destroy_namespace(self): 2331 def test_destroy_namespace(self):
2328 namespace = 'qrouter-bar' 2332 namespace = 'qrouter-bar'
2329 2333
2330 self.mock_ip.get_namespaces.return_value = [namespace] 2334 self.list_network_namespaces.return_value = [namespace]
2331 self.mock_ip.get_devices.return_value = [ 2335 self.mock_ip.get_devices.return_value = [
2332 l3_test_common.FakeDev('qr-aaaa'), 2336 l3_test_common.FakeDev('qr-aaaa'),
2333 l3_test_common.FakeDev('rfp-aaaa')] 2337 l3_test_common.FakeDev('rfp-aaaa')]
@@ -2356,7 +2360,7 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
2356 def test_destroy_snat_namespace(self): 2360 def test_destroy_snat_namespace(self):
2357 namespace = 'snat-bar' 2361 namespace = 'snat-bar'
2358 2362
2359 self.mock_ip.get_namespaces.return_value = [namespace] 2363 self.list_network_namespaces.return_value = [namespace]
2360 self.mock_ip.get_devices.return_value = [ 2364 self.mock_ip.get_devices.return_value = [
2361 l3_test_common.FakeDev('qg-aaaa'), 2365 l3_test_common.FakeDev('qg-aaaa'),
2362 l3_test_common.FakeDev('sg-aaaa')] 2366 l3_test_common.FakeDev('sg-aaaa')]
@@ -2614,9 +2618,9 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
2614 for r in router_list] 2618 for r in router_list]
2615 good_namespace_list += [dvr_snat_ns.SNAT_NS_PREFIX + r['id'] 2619 good_namespace_list += [dvr_snat_ns.SNAT_NS_PREFIX + r['id']
2616 for r in router_list] 2620 for r in router_list]
2617 self.mock_ip.get_namespaces.return_value = (stale_namespace_list + 2621 self.list_network_namespaces.return_value = (stale_namespace_list +
2618 good_namespace_list + 2622 good_namespace_list +
2619 other_namespaces) 2623 other_namespaces)
2620 2624
2621 agent = l3_agent.L3NATAgent(HOSTNAME, self.conf) 2625 agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
2622 2626
diff --git a/neutron/tests/unit/agent/l3/test_dvr_snat_ns.py b/neutron/tests/unit/agent/l3/test_dvr_snat_ns.py
index 2185d53..fa72709 100644
--- a/neutron/tests/unit/agent/l3/test_dvr_snat_ns.py
+++ b/neutron/tests/unit/agent/l3/test_dvr_snat_ns.py
@@ -18,6 +18,7 @@ from oslo_utils import uuidutils
18 18
19from neutron.agent.common import utils 19from neutron.agent.common import utils
20from neutron.agent.l3 import dvr_snat_ns 20from neutron.agent.l3 import dvr_snat_ns
21from neutron.agent.linux import ip_lib
21from neutron.tests import base 22from neutron.tests import base
22 23
23_uuid = uuidutils.generate_uuid 24_uuid = uuidutils.generate_uuid
@@ -37,7 +38,10 @@ class TestDvrSnatNs(base.BaseTestCase):
37 use_ipv6=False) 38 use_ipv6=False)
38 39
39 @mock.patch.object(utils, 'execute') 40 @mock.patch.object(utils, 'execute')
40 def test_create(self, execute): 41 @mock.patch.object(ip_lib, 'create_network_namespace')
42 @mock.patch.object(ip_lib, 'network_namespace_exists')
43 def test_create(self, exists, create, execute):
44 exists.return_value = False
41 self.snat_ns.create() 45 self.snat_ns.create()
42 46
43 netns_cmd = ['ip', 'netns', 'exec', self.snat_ns.name] 47 netns_cmd = ['ip', 'netns', 'exec', self.snat_ns.name]
@@ -46,4 +50,5 @@ class TestDvrSnatNs(base.BaseTestCase):
46 check_exit_code=True, extra_ok_codes=None, 50 check_exit_code=True, extra_ok_codes=None,
47 log_fail_as_error=True, run_as_root=True)] 51 log_fail_as_error=True, run_as_root=True)]
48 52
53 create.assert_called_once_with(self.snat_ns.name)
49 execute.assert_has_calls(expected) 54 execute.assert_has_calls(expected)
diff --git a/neutron/tests/unit/agent/l3/test_l3_agent_extension_api.py b/neutron/tests/unit/agent/l3/test_l3_agent_extension_api.py
index f4618af..56d1445 100644
--- a/neutron/tests/unit/agent/l3/test_l3_agent_extension_api.py
+++ b/neutron/tests/unit/agent/l3/test_l3_agent_extension_api.py
@@ -43,14 +43,14 @@ class TestL3AgentExtensionApi(base.BaseTestCase):
43 ports = [{'id': pid} for pid in port_ids] 43 ports = [{'id': pid} for pid in port_ids]
44 router_info, ri = self._prepare_router_data(ports) 44 router_info, ri = self._prepare_router_data(ports)
45 45
46 with mock.patch.object(ip_lib.IPWrapper, 46 with mock.patch.object(ip_lib,
47 'get_namespaces') as mock_get_namespaces: 47 'list_network_namespaces') as mock_list_netns:
48 48
49 mock_get_namespaces.return_value = [] 49 mock_list_netns.return_value = []
50 api_object = l3_agent_api.L3AgentExtensionAPI(router_info) 50 api_object = l3_agent_api.L3AgentExtensionAPI(router_info)
51 router = api_object.get_router_hosting_port(port_ids[0]) 51 router = api_object.get_router_hosting_port(port_ids[0])
52 52
53 mock_get_namespaces.assert_called_once_with() 53 mock_list_netns.assert_called_once_with()
54 self.assertFalse(router) 54 self.assertFalse(router)
55 55
56 def test_get_router_hosting_port_for_router_in_ns(self): 56 def test_get_router_hosting_port_for_router_in_ns(self):
@@ -58,9 +58,9 @@ class TestL3AgentExtensionApi(base.BaseTestCase):
58 ports = [{'id': pid} for pid in port_ids] 58 ports = [{'id': pid} for pid in port_ids]
59 router_info, ri = self._prepare_router_data(ports) 59 router_info, ri = self._prepare_router_data(ports)
60 60
61 with mock.patch.object(ip_lib.IPWrapper, 61 with mock.patch.object(ip_lib,
62 'get_namespaces') as mock_get_namespaces: 62 'list_network_namespaces') as mock_list_netns:
63 mock_get_namespaces.return_value = [ri.ns_name] 63 mock_list_netns.return_value = [ri.ns_name]
64 api_object = l3_agent_api.L3AgentExtensionAPI(router_info) 64 api_object = l3_agent_api.L3AgentExtensionAPI(router_info)
65 router = api_object.get_router_hosting_port(port_ids[0]) 65 router = api_object.get_router_hosting_port(port_ids[0])
66 self.assertEqual(ri, router) 66 self.assertEqual(ri, router)
@@ -68,9 +68,9 @@ class TestL3AgentExtensionApi(base.BaseTestCase):
68 def test_get_routers_in_project(self): 68 def test_get_routers_in_project(self):
69 router_info, ri = self._prepare_router_data() 69 router_info, ri = self._prepare_router_data()
70 70
71 with mock.patch.object(ip_lib.IPWrapper, 71 with mock.patch.object(ip_lib,
72 'get_namespaces') as mock_get_namespaces: 72 'list_network_namespaces') as mock_list_netns:
73 mock_get_namespaces.return_value = [ri.ns_name] 73 mock_list_netns.return_value = [ri.ns_name]
74 api_object = l3_agent_api.L3AgentExtensionAPI(router_info) 74 api_object = l3_agent_api.L3AgentExtensionAPI(router_info)
75 routers = api_object.get_routers_in_project(self.project_id) 75 routers = api_object.get_routers_in_project(self.project_id)
76 self.assertEqual([ri], routers) 76 self.assertEqual([ri], routers)
@@ -78,9 +78,9 @@ class TestL3AgentExtensionApi(base.BaseTestCase):
78 def test_is_router_in_namespace_for_in_ns(self): 78 def test_is_router_in_namespace_for_in_ns(self):
79 router_info, ri = self._prepare_router_data() 79 router_info, ri = self._prepare_router_data()
80 80
81 with mock.patch.object(ip_lib.IPWrapper, 81 with mock.patch.object(ip_lib,
82 'get_namespaces') as mock_get_namespaces: 82 'list_network_namespaces') as mock_list_netns:
83 mock_get_namespaces.return_value = [ri.ns_name] 83 mock_list_netns.return_value = [ri.ns_name]
84 api_object = l3_agent_api.L3AgentExtensionAPI(router_info) 84 api_object = l3_agent_api.L3AgentExtensionAPI(router_info)
85 router_in_ns = api_object.is_router_in_namespace(ri.router_id) 85 router_in_ns = api_object.is_router_in_namespace(ri.router_id)
86 self.assertTrue(router_in_ns) 86 self.assertTrue(router_in_ns)
@@ -88,9 +88,9 @@ class TestL3AgentExtensionApi(base.BaseTestCase):
88 def test_is_router_in_namespace_for_not_in_ns(self): 88 def test_is_router_in_namespace_for_not_in_ns(self):
89 router_info, ri = self._prepare_router_data() 89 router_info, ri = self._prepare_router_data()
90 90
91 with mock.patch.object(ip_lib.IPWrapper, 91 with mock.patch.object(ip_lib,
92 'get_namespaces') as mock_get_namespaces: 92 'list_network_namespaces') as mock_list_netns:
93 mock_get_namespaces.return_value = [uuidutils.generate_uuid()] 93 mock_list_netns.return_value = [uuidutils.generate_uuid()]
94 api_object = l3_agent_api.L3AgentExtensionAPI(router_info) 94 api_object = l3_agent_api.L3AgentExtensionAPI(router_info)
95 router_in_ns = api_object.is_router_in_namespace(ri.router_id) 95 router_in_ns = api_object.is_router_in_namespace(ri.router_id)
96 self.assertFalse(router_in_ns) 96 self.assertFalse(router_in_ns)
diff --git a/neutron/tests/unit/agent/l3/test_namespace_manager.py b/neutron/tests/unit/agent/l3/test_namespace_manager.py
index d861bfc..62fb363 100644
--- a/neutron/tests/unit/agent/l3/test_namespace_manager.py
+++ b/neutron/tests/unit/agent/l3/test_namespace_manager.py
@@ -77,7 +77,7 @@ class TestNamespaceManager(NamespaceManagerTestCaseFramework):
77 'dhcp-' + _uuid(), ] 77 'dhcp-' + _uuid(), ]
78 78
79 # Test the normal path 79 # Test the normal path
80 with mock.patch.object(ip_lib.IPWrapper, 'get_namespaces', 80 with mock.patch.object(ip_lib, 'list_network_namespaces',
81 return_value=ns_names): 81 return_value=ns_names):
82 retrieved_ns_names = self.ns_manager.list_all() 82 retrieved_ns_names = self.ns_manager.list_all()
83 self.assertEqual(len(ns_names) - 1, len(retrieved_ns_names)) 83 self.assertEqual(len(ns_names) - 1, len(retrieved_ns_names))
@@ -85,8 +85,8 @@ class TestNamespaceManager(NamespaceManagerTestCaseFramework):
85 self.assertIn(ns_names[i], retrieved_ns_names) 85 self.assertIn(ns_names[i], retrieved_ns_names)
86 self.assertNotIn(ns_names[-1], retrieved_ns_names) 86 self.assertNotIn(ns_names[-1], retrieved_ns_names)
87 87
88 # Test path where IPWrapper raises exception 88 # Test path where list_network_namespaces() raises exception
89 with mock.patch.object(ip_lib.IPWrapper, 'get_namespaces', 89 with mock.patch.object(ip_lib, 'list_network_namespaces',
90 side_effect=RuntimeError): 90 side_effect=RuntimeError):
91 retrieved_ns_names = self.ns_manager.list_all() 91 retrieved_ns_names = self.ns_manager.list_all()
92 self.assertFalse(retrieved_ns_names) 92 self.assertFalse(retrieved_ns_names)
@@ -104,7 +104,7 @@ class TestNamespaceManager(NamespaceManagerTestCaseFramework):
104 ns_names += [dvr_snat_ns.SNAT_NS_PREFIX + _uuid() for _ in range(5)] 104 ns_names += [dvr_snat_ns.SNAT_NS_PREFIX + _uuid() for _ in range(5)]
105 ns_names += [namespaces.NS_PREFIX + router_id, 105 ns_names += [namespaces.NS_PREFIX + router_id,
106 dvr_snat_ns.SNAT_NS_PREFIX + router_id] 106 dvr_snat_ns.SNAT_NS_PREFIX + router_id]
107 with mock.patch.object(ip_lib.IPWrapper, 'get_namespaces', 107 with mock.patch.object(ip_lib, 'list_network_namespaces',
108 return_value=ns_names), \ 108 return_value=ns_names), \
109 mock.patch.object(self.ns_manager, '_cleanup') as mock_cleanup: 109 mock.patch.object(self.ns_manager, '_cleanup') as mock_cleanup:
110 self.ns_manager.ensure_router_cleanup(router_id) 110 self.ns_manager.ensure_router_cleanup(router_id)
diff --git a/neutron/tests/unit/agent/linux/test_dhcp.py b/neutron/tests/unit/agent/linux/test_dhcp.py
index d155cc9..e890291 100644
--- a/neutron/tests/unit/agent/linux/test_dhcp.py
+++ b/neutron/tests/unit/agent/linux/test_dhcp.py
@@ -1096,7 +1096,9 @@ class TestDhcpLocalProcess(TestBase):
1096 self.assertTrue(lp.process_monitor.unregister.called) 1096 self.assertTrue(lp.process_monitor.unregister.called)
1097 self.assertTrue(self.external_process().disable.called) 1097 self.assertTrue(self.external_process().disable.called)
1098 1098
1099 def test_disable_not_active(self): 1099 @mock.patch('neutron.agent.linux.ip_lib.network_namespace_exists')
1100 def test_disable_not_active(self, namespace_exists):
1101 namespace_exists.return_value = False
1100 attrs_to_mock = dict([(a, mock.DEFAULT) for a in 1102 attrs_to_mock = dict([(a, mock.DEFAULT) for a in
1101 ['active', 'interface_name']]) 1103 ['active', 'interface_name']])
1102 with mock.patch.multiple(LocalChild, **attrs_to_mock) as mocks: 1104 with mock.patch.multiple(LocalChild, **attrs_to_mock) as mocks:
@@ -1121,30 +1123,38 @@ class TestDhcpLocalProcess(TestBase):
1121 lp.disable(retain_port=True) 1123 lp.disable(retain_port=True)
1122 self._assert_disabled(lp) 1124 self._assert_disabled(lp)
1123 1125
1124 def test_disable(self): 1126 @mock.patch('neutron.agent.linux.ip_lib.network_namespace_exists')
1127 def test_disable(self, namespace_exists):
1128 namespace_exists.return_value = True
1125 attrs_to_mock = {'active': mock.DEFAULT} 1129 attrs_to_mock = {'active': mock.DEFAULT}
1126 1130
1127 with mock.patch.multiple(LocalChild, **attrs_to_mock) as mocks: 1131 with mock.patch.multiple(LocalChild, **attrs_to_mock) as mocks:
1128 mocks['active'].__get__ = mock.Mock(return_value=False) 1132 mocks['active'].__get__ = mock.Mock(return_value=False)
1129 lp = LocalChild(self.conf, FakeDualNetwork()) 1133 lp = LocalChild(self.conf, FakeDualNetwork())
1130 with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip: 1134 with mock.patch('neutron.agent.linux.ip_lib.'
1135 'delete_network_namespace') as delete_ns:
1131 lp.disable() 1136 lp.disable()
1132 1137
1133 self._assert_disabled(lp) 1138 self._assert_disabled(lp)
1134 1139
1135 ip.return_value.netns.delete.assert_called_with('qdhcp-ns') 1140 delete_ns.assert_called_with('qdhcp-ns')
1136 1141
1137 def test_disable_config_dir_removed_after_destroy(self): 1142 @mock.patch('neutron.agent.linux.ip_lib.network_namespace_exists')
1143 def test_disable_config_dir_removed_after_destroy(self, namespace_exists):
1144 namespace_exists.return_value = True
1138 parent = mock.MagicMock() 1145 parent = mock.MagicMock()
1139 parent.attach_mock(self.rmtree, 'rmtree') 1146 parent.attach_mock(self.rmtree, 'rmtree')
1140 parent.attach_mock(self.mock_mgr, 'DeviceManager') 1147 parent.attach_mock(self.mock_mgr, 'DeviceManager')
1141 1148
1142 lp = LocalChild(self.conf, FakeDualNetwork()) 1149 lp = LocalChild(self.conf, FakeDualNetwork())
1143 lp.disable(retain_port=False) 1150 with mock.patch('neutron.agent.linux.ip_lib.'
1151 'delete_network_namespace') as delete_ns:
1152 lp.disable(retain_port=False)
1144 1153
1145 expected = [mock.call.DeviceManager().destroy(mock.ANY, mock.ANY), 1154 expected = [mock.call.DeviceManager().destroy(mock.ANY, mock.ANY),
1146 mock.call.rmtree(mock.ANY, ignore_errors=True)] 1155 mock.call.rmtree(mock.ANY, ignore_errors=True)]
1147 parent.assert_has_calls(expected) 1156 parent.assert_has_calls(expected)
1157 delete_ns.assert_called_with('qdhcp-ns')
1148 1158
1149 def test_get_interface_name(self): 1159 def test_get_interface_name(self):
1150 net = FakeDualNetwork() 1160 net = FakeDualNetwork()
diff --git a/neutron/tests/unit/agent/linux/test_ip_lib.py b/neutron/tests/unit/agent/linux/test_ip_lib.py
index 9999654..3bcd562 100644
--- a/neutron/tests/unit/agent/linux/test_ip_lib.py
+++ b/neutron/tests/unit/agent/linux/test_ip_lib.py
@@ -36,11 +36,6 @@ NETNS_SAMPLE = [
36 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 36 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
37 'cccccccc-cccc-cccc-cccc-cccccccccccc'] 37 'cccccccc-cccc-cccc-cccc-cccccccccccc']
38 38
39NETNS_SAMPLE_IPROUTE2_4 = [
40 '12345678-1234-5678-abcd-1234567890ab (id: 1)',
41 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb (id: 0)',
42 'cccccccc-cccc-cccc-cccc-cccccccccccc (id: 2)']
43
44LINK_SAMPLE = [ 39LINK_SAMPLE = [
45 '1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN \\' 40 '1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN \\'
46 'link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0', 41 'link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0',
@@ -318,29 +313,31 @@ class TestIpWrapper(base.BaseTestCase):
318 self.assertEqual(device_name, somedevice.name) 313 self.assertEqual(device_name, somedevice.name)
319 self.assertFalse(devices) 314 self.assertFalse(devices)
320 315
321 def test_get_namespaces_non_root(self): 316 @mock.patch.object(pyroute2.netns, 'listnetns')
317 @mock.patch.object(priv_lib, 'list_netns')
318 def test_get_namespaces_non_root(self, priv_listnetns, listnetns):
322 self.config(group='AGENT', use_helper_for_ns_read=False) 319 self.config(group='AGENT', use_helper_for_ns_read=False)
323 self.execute.return_value = '\n'.join(NETNS_SAMPLE) 320 listnetns.return_value = NETNS_SAMPLE
324 retval = ip_lib.IPWrapper.get_namespaces() 321 retval = ip_lib.list_network_namespaces()
325 self.assertEqual(retval, 322 self.assertEqual(retval,
326 ['12345678-1234-5678-abcd-1234567890ab', 323 ['12345678-1234-5678-abcd-1234567890ab',
327 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 324 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
328 'cccccccc-cccc-cccc-cccc-cccccccccccc']) 325 'cccccccc-cccc-cccc-cccc-cccccccccccc'])
326 self.assertEqual(1, listnetns.call_count)
327 self.assertFalse(priv_listnetns.called)
329 328
330 self.execute.assert_called_once_with([], 'netns', ('list',), 329 @mock.patch.object(pyroute2.netns, 'listnetns')
331 run_as_root=False) 330 @mock.patch.object(priv_lib, 'list_netns')
332 331 def test_get_namespaces_root(self, priv_listnetns, listnetns):
333 def test_get_namespaces_iproute2_4_root(self):
334 self.config(group='AGENT', use_helper_for_ns_read=True) 332 self.config(group='AGENT', use_helper_for_ns_read=True)
335 self.execute.return_value = '\n'.join(NETNS_SAMPLE_IPROUTE2_4) 333 priv_listnetns.return_value = NETNS_SAMPLE
336 retval = ip_lib.IPWrapper.get_namespaces() 334 retval = ip_lib.list_network_namespaces()
337 self.assertEqual(retval, 335 self.assertEqual(retval,
338 ['12345678-1234-5678-abcd-1234567890ab', 336 ['12345678-1234-5678-abcd-1234567890ab',
339 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 337 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
340 'cccccccc-cccc-cccc-cccc-cccccccccccc']) 338 'cccccccc-cccc-cccc-cccc-cccccccccccc'])
341 339 self.assertEqual(1, priv_listnetns.call_count)
342 self.execute.assert_called_once_with([], 'netns', ('list',), 340 self.assertFalse(listnetns.called)
343 run_as_root=True)
344 341
345 def test_add_tuntap(self): 342 def test_add_tuntap(self):
346 ip_lib.IPWrapper().add_tuntap('tap0') 343 ip_lib.IPWrapper().add_tuntap('tap0')
@@ -398,17 +395,16 @@ class TestIpWrapper(base.BaseTestCase):
398 self.assertEqual(dev.namespace, 'ns') 395 self.assertEqual(dev.namespace, 'ns')
399 self.assertEqual(dev.name, 'eth0') 396 self.assertEqual(dev.name, 'eth0')
400 397
401 def test_ensure_namespace(self): 398 @mock.patch.object(priv_lib, 'create_netns')
399 def test_ensure_namespace(self, create):
402 with mock.patch.object(ip_lib, 'IPDevice') as ip_dev: 400 with mock.patch.object(ip_lib, 'IPDevice') as ip_dev:
403 ip = ip_lib.IPWrapper() 401 ip = ip_lib.IPWrapper()
404 with mock.patch.object(ip.netns, 'exists') as ns_exists: 402 with mock.patch.object(ip.netns, 'exists') as ns_exists:
405 with mock.patch('neutron.agent.common.utils.execute'): 403 with mock.patch('neutron.agent.common.utils.execute'):
406 ns_exists.return_value = False 404 ns_exists.return_value = False
407 ip.ensure_namespace('ns') 405 ip.ensure_namespace('ns')
408 self.execute.assert_has_calls( 406 create.assert_called_once_with('ns')
409 [mock.call([], 'netns', ('add', 'ns'), 407 ns_exists.assert_called_once_with('ns')
410 run_as_root=True, namespace=None,
411 log_fail_as_error=True)])
412 ip_dev.assert_has_calls([mock.call('lo', namespace='ns'), 408 ip_dev.assert_has_calls([mock.call('lo', namespace='ns'),
413 mock.call().link.set_up()]) 409 mock.call().link.set_up()])
414 410
@@ -1235,10 +1231,11 @@ class TestIpNetnsCommand(TestIPCmdBase):
1235 self.command = 'netns' 1231 self.command = 'netns'
1236 self.netns_cmd = ip_lib.IpNetnsCommand(self.parent) 1232 self.netns_cmd = ip_lib.IpNetnsCommand(self.parent)
1237 1233
1238 def test_add_namespace(self): 1234 @mock.patch.object(priv_lib, 'create_netns')
1235 def test_add_namespace(self, create):
1239 with mock.patch('neutron.agent.common.utils.execute') as execute: 1236 with mock.patch('neutron.agent.common.utils.execute') as execute:
1240 ns = self.netns_cmd.add('ns') 1237 ns = self.netns_cmd.add('ns')
1241 self._assert_sudo([], ('add', 'ns'), use_root_namespace=True) 1238 create.assert_called_once_with('ns')
1242 self.assertEqual(ns.namespace, 'ns') 1239 self.assertEqual(ns.namespace, 'ns')
1243 execute.assert_called_once_with( 1240 execute.assert_called_once_with(
1244 ['ip', 'netns', 'exec', 'ns', 1241 ['ip', 'netns', 'exec', 'ns',
@@ -1246,36 +1243,35 @@ class TestIpNetnsCommand(TestIPCmdBase):
1246 run_as_root=True, check_exit_code=True, extra_ok_codes=None, 1243 run_as_root=True, check_exit_code=True, extra_ok_codes=None,
1247 log_fail_as_error=True) 1244 log_fail_as_error=True)
1248 1245
1249 def test_delete_namespace(self): 1246 @mock.patch.object(priv_lib, 'remove_netns')
1250 with mock.patch('neutron.agent.common.utils.execute'): 1247 def test_delete_namespace(self, remove):
1251 self.netns_cmd.delete('ns') 1248 self.netns_cmd.delete('ns')
1252 self._assert_sudo([], ('delete', 'ns'), use_root_namespace=True) 1249 remove.assert_called_once_with('ns')
1253 1250
1254 def test_namespace_exists_use_helper(self): 1251 @mock.patch.object(pyroute2.netns, 'listnetns')
1252 @mock.patch.object(priv_lib, 'list_netns')
1253 def test_namespace_exists_use_helper(self, priv_listnetns, listnetns):
1255 self.config(group='AGENT', use_helper_for_ns_read=True) 1254 self.config(group='AGENT', use_helper_for_ns_read=True)
1256 retval = '\n'.join(NETNS_SAMPLE) 1255 priv_listnetns.return_value = NETNS_SAMPLE
1257 # need another instance to avoid mocking 1256 # need another instance to avoid mocking
1258 netns_cmd = ip_lib.IpNetnsCommand(ip_lib.SubProcessBase()) 1257 netns_cmd = ip_lib.IpNetnsCommand(ip_lib.SubProcessBase())
1259 with mock.patch('neutron.agent.common.utils.execute') as execute: 1258 self.assertTrue(
1260 execute.return_value = retval 1259 netns_cmd.exists('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb'))
1261 self.assertTrue( 1260 self.assertEqual(1, priv_listnetns.call_count)
1262 netns_cmd.exists('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb')) 1261 self.assertFalse(listnetns.called)
1263 execute.assert_called_once_with(['ip', '-o', 'netns', 'list'], 1262
1264 run_as_root=True, 1263 @mock.patch.object(pyroute2.netns, 'listnetns')
1265 log_fail_as_error=True) 1264 @mock.patch.object(priv_lib, 'list_netns')
1266 1265 def test_namespace_does_not_exist_no_helper(self, priv_listnetns,
1267 def test_namespace_doest_not_exist_no_helper(self): 1266 listnetns):
1268 self.config(group='AGENT', use_helper_for_ns_read=False) 1267 self.config(group='AGENT', use_helper_for_ns_read=False)
1269 retval = '\n'.join(NETNS_SAMPLE) 1268 listnetns.return_value = NETNS_SAMPLE
1270 # need another instance to avoid mocking 1269 # need another instance to avoid mocking
1271 netns_cmd = ip_lib.IpNetnsCommand(ip_lib.SubProcessBase()) 1270 netns_cmd = ip_lib.IpNetnsCommand(ip_lib.SubProcessBase())
1272 with mock.patch('neutron.agent.common.utils.execute') as execute: 1271 self.assertFalse(
1273 execute.return_value = retval 1272 netns_cmd.exists('bbbbbbbb-1111-2222-3333-bbbbbbbbbbbb'))
1274 self.assertFalse( 1273 self.assertEqual(1, listnetns.call_count)
1275 netns_cmd.exists('bbbbbbbb-1111-2222-3333-bbbbbbbbbbbb')) 1274 self.assertFalse(priv_listnetns.called)
1276 execute.assert_called_once_with(['ip', '-o', 'netns', 'list'],
1277 run_as_root=False,
1278 log_fail_as_error=True)
1279 1275
1280 def test_execute(self): 1276 def test_execute(self):
1281 self.parent.namespace = 'ns' 1277 self.parent.namespace = 'ns'
diff --git a/neutron/tests/unit/agent/linux/test_iptables_manager.py b/neutron/tests/unit/agent/linux/test_iptables_manager.py
index 2dbc21e..715be72 100644
--- a/neutron/tests/unit/agent/linux/test_iptables_manager.py
+++ b/neutron/tests/unit/agent/linux/test_iptables_manager.py
@@ -990,11 +990,11 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
990 self.assertRaises(RuntimeError, 990 self.assertRaises(RuntimeError,
991 self.iptables._apply_synchronized) 991 self.iptables._apply_synchronized)
992 self.iptables.namespace = 'test' 992 self.iptables.namespace = 'test'
993 with mock.patch('neutron.agent.linux.ip_lib.IpNetnsCommand.exists', 993 with mock.patch('neutron.agent.linux.ip_lib.network_namespace_exists',
994 return_value=True): 994 return_value=True):
995 self.assertRaises(RuntimeError, 995 self.assertRaises(RuntimeError,
996 self.iptables._apply_synchronized) 996 self.iptables._apply_synchronized)
997 with mock.patch('neutron.agent.linux.ip_lib.IpNetnsCommand.exists', 997 with mock.patch('neutron.agent.linux.ip_lib.network_namespace_exists',
998 return_value=False): 998 return_value=False):
999 self.assertEqual([], self.iptables._apply_synchronized()) 999 self.assertEqual([], self.iptables._apply_synchronized())
1000 1000
diff --git a/neutron/tests/unit/cmd/test_netns_cleanup.py b/neutron/tests/unit/cmd/test_netns_cleanup.py
index ddd1793..3aff7fc 100644
--- a/neutron/tests/unit/cmd/test_netns_cleanup.py
+++ b/neutron/tests/unit/cmd/test_netns_cleanup.py
@@ -363,8 +363,9 @@ class TestNetnsCleanup(base.BaseTestCase):
363 363
364 def test_main(self): 364 def test_main(self):
365 namespaces = ['ns1', 'ns2'] 365 namespaces = ['ns1', 'ns2']
366 with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip_wrap: 366 with mock.patch('neutron.agent.linux.ip_lib.'
367 ip_wrap.get_namespaces.return_value = namespaces 367 'list_network_namespaces') as listnetns:
368 listnetns.return_value = namespaces
368 369
369 with mock.patch('time.sleep') as time_sleep: 370 with mock.patch('time.sleep') as time_sleep:
370 conf = mock.Mock() 371 conf = mock.Mock()
@@ -388,15 +389,15 @@ class TestNetnsCleanup(base.BaseTestCase):
388 [mock.call(conf, 'ns1', False), 389 [mock.call(conf, 'ns1', False),
389 mock.call(conf, 'ns2', False)]) 390 mock.call(conf, 'ns2', False)])
390 391
391 ip_wrap.assert_has_calls( 392 self.assertEqual(1, listnetns.call_count)
392 [mock.call.get_namespaces()])
393 393
394 time_sleep.assert_called_once_with(2) 394 time_sleep.assert_called_once_with(2)
395 395
396 def test_main_no_candidates(self): 396 def test_main_no_candidates(self):
397 namespaces = ['ns1', 'ns2'] 397 namespaces = ['ns1', 'ns2']
398 with mock.patch('neutron.agent.linux.ip_lib.IPWrapper') as ip_wrap: 398 with mock.patch('neutron.agent.linux.ip_lib.'
399 ip_wrap.get_namespaces.return_value = namespaces 399 'list_network_namespaces') as listnetns:
400 listnetns.return_value = namespaces
400 401
401 with mock.patch('time.sleep') as time_sleep: 402 with mock.patch('time.sleep') as time_sleep:
402 conf = mock.Mock() 403 conf = mock.Mock()
@@ -412,8 +413,7 @@ class TestNetnsCleanup(base.BaseTestCase):
412 with mock.patch('neutron.common.config.setup_logging'): 413 with mock.patch('neutron.common.config.setup_logging'):
413 util.main() 414 util.main()
414 415
415 ip_wrap.assert_has_calls( 416 self.assertEqual(1, listnetns.call_count)
416 [mock.call.get_namespaces()])
417 417
418 mocks['eligible_for_deletion'].assert_has_calls( 418 mocks['eligible_for_deletion'].assert_has_calls(
419 [mock.call(conf, 'ns1', False), 419 [mock.call(conf, 'ns1', False),
diff --git a/neutron/tests/unit/debug/test_commands.py b/neutron/tests/unit/debug/test_commands.py
index ec80674..abb5900 100644
--- a/neutron/tests/unit/debug/test_commands.py
+++ b/neutron/tests/unit/debug/test_commands.py
@@ -43,9 +43,12 @@ class TestDebugCommands(base.BaseTestCase):
43 device_exists_p = mock.patch( 43 device_exists_p = mock.patch(
44 'neutron.agent.linux.ip_lib.device_exists', return_value=False) 44 'neutron.agent.linux.ip_lib.device_exists', return_value=False)
45 device_exists_p.start() 45 device_exists_p.start()
46 namespace_p = mock.patch( 46 namespace_e_p = mock.patch(
47 'neutron.agent.linux.ip_lib.IpNetnsCommand') 47 'neutron.agent.linux.ip_lib.network_namespace_exists')
48 namespace_p.start() 48 namespace_e_p.start()
49 namespace_d_p = mock.patch(
50 'neutron.agent.linux.ip_lib.delete_network_namespace')
51 namespace_d_p.start()
49 ensure_namespace_p = mock.patch( 52 ensure_namespace_p = mock.patch(
50 'neutron.agent.linux.ip_lib.IPWrapper.ensure_namespace') 53 'neutron.agent.linux.ip_lib.IPWrapper.ensure_namespace')
51 ensure_namespace_p.start() 54 ensure_namespace_p.start()
diff --git a/neutron/tests/unit/services/metering/drivers/test_iptables.py b/neutron/tests/unit/services/metering/drivers/test_iptables.py
index 3ea0eb4..b04cdf8 100644
--- a/neutron/tests/unit/services/metering/drivers/test_iptables.py
+++ b/neutron/tests/unit/services/metering/drivers/test_iptables.py
@@ -134,7 +134,7 @@ class IptablesDriverTestCase(base.BaseTestCase):
134 self.v4filter_inst = mock.Mock() 134 self.v4filter_inst = mock.Mock()
135 self.v6filter_inst = mock.Mock() 135 self.v6filter_inst = mock.Mock()
136 self.namespace_exists_p = mock.patch( 136 self.namespace_exists_p = mock.patch(
137 'neutron.agent.linux.ip_lib.IpNetnsCommand.exists') 137 'neutron.agent.linux.ip_lib.network_namespace_exists')
138 self.namespace_exists = self.namespace_exists_p.start() 138 self.namespace_exists = self.namespace_exists_p.start()
139 self.snat_ns_name_p = mock.patch( 139 self.snat_ns_name_p = mock.patch(
140 'neutron.agent.l3.dvr_snat_ns.SnatNamespace.get_snat_ns_name') 140 'neutron.agent.l3.dvr_snat_ns.SnatNamespace.get_snat_ns_name')