]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Support external network in probe-create.
authorNachi Ueno <nachi@nttmcl.com>
Mon, 29 Oct 2012 20:05:48 +0000 (13:05 -0700)
committerNachi Ueno <nachi@nttmcl.com>
Mon, 29 Oct 2012 20:05:48 +0000 (13:05 -0700)
Fixes bug #1070960

Change-Id: Ic0d3c56a26fe44359a772f40a7c7d92086a49a28

quantum/debug/README
quantum/debug/debug_agent.py
quantum/debug/shell.py
quantum/tests/unit/test_debug_commands.py

index f782c70faae2b0be74b1c45a0b101503b6da902a..9ef1def447df3bd5f172a65b88603300e3d1ae5d 100644 (file)
@@ -1,7 +1,7 @@
 Debug Helper Script for Quantum
 
 - Configure
-export TEST_CONFIG_FILE=/etc/quantum/dhcp_agent.ini
+export TEST_CONFIG_FILE=/etc/quantum/debug.ini
 or
 export TEST_CONFIG_FILE=/etc/quantum/l3_agent.ini
 
@@ -10,7 +10,8 @@ you can also specify config file by --config-file option
 - Usage
 quantum-debug commands
 
-probe-create <net-id>  Create probe port - create port and interface, then plug it in.
+probe-create <net-id>
+  Create probe port - create port and interface, then plug it in.
   This commands returns a port id of a probe port. A probe port is a port which is used to test.
   The port id is probe id.
   We can have multiple probe probes in a network, in order to check connectivity between ports.
@@ -18,6 +19,10 @@ probe-create <net-id>  Create probe port - create port and interface, then plug
   quantum-debug probe-exec probe_id_1 'nc -l 192.168.100.3 22'
   quantum-debug probe-exec probe_id_2 'nc -vz 192.168.100.4 22'
 
+  Note: You should use a user and a tenant who has permission to
+   modify network and subnet if you want to probe. For example, you need to be admin user if you
+   want to probe external network.
+
 probe-delete <port-id>  Delete probe - delete port then uplug
 probe-exec <port-id> 'command'    Exec commands on the namespace of the probe
 `probe-exec <port-id>` 'interactive command' Exec interactive command (eg, ssh)
index 2daf19f0f93886da4ea5dbddd3dc5a27d27b1b7f..92dc452f9fc26b12a64c46a855060a8b2fb8aa12 100644 (file)
@@ -52,7 +52,9 @@ class QuantumDebugAgent():
         cfg.StrOpt('auth_region'),
         cfg.BoolOpt('use_namespaces', default=True),
         cfg.StrOpt('interface_driver',
-                   help="The driver used to manage the virtual interface.")
+                   help="The driver used to manage the virtual interface."),
+        cfg.StrOpt('external_network_bridge', default='br-ex',
+                   help="Name of bridge used for external network traffic."),
     ]
 
     def __init__(self, conf, client, driver):
@@ -65,6 +67,10 @@ class QuantumDebugAgent():
 
     def create_probe(self, network_id):
         network = self._get_network(network_id)
+        bridge = None
+        if network.external:
+            bridge = self.conf.external_network_bridge
+
         port = self._create_port(network)
         port.network = network
         interface_name = self.driver.get_device_name(port)
@@ -80,6 +86,7 @@ class QuantumDebugAgent():
                              port.id,
                              interface_name,
                              port.mac_address,
+                             bridge=bridge,
                              namespace=namespace)
         ip_cidrs = []
         for fixed_ip in port.fixed_ips:
@@ -97,6 +104,7 @@ class QuantumDebugAgent():
     def _get_network(self, network_id):
         network_dict = self.client.show_network(network_id)['network']
         network = DictModel(network_dict)
+        network.external = network_dict.get('router:external')
         obj_subnet = [self._get_subnet(s_id) for s_id in network.subnets]
         network.subnets = obj_subnet
         return network
@@ -110,14 +118,23 @@ class QuantumDebugAgent():
 
     def delete_probe(self, port_id):
         port = DictModel(self.client.show_port(port_id)['port'])
+        network = self._get_network(port.network_id)
+        bridge = None
+        if network.external:
+            bridge = self.conf.external_network_bridge
         ip = ip_lib.IPWrapper(self.conf.root_helper)
         namespace = self._get_namespace(port)
         if self.conf.use_namespaces and ip.netns.exists(namespace):
             self.driver.unplug(self.driver.get_device_name(port),
+                               bridge=bridge,
                                namespace=namespace)
-            ip.netns.delete(namespace)
+            try:
+                ip.netns.delete(namespace)
+            except:
+                LOG.warn(_('failed to delete namespace %s') % namespace)
         else:
-            self.driver.unplug(self.driver.get_device_name(port))
+            self.driver.unplug(self.driver.get_device_name(port),
+                               bridge=bridge)
         self.client.delete_port(port.id)
 
     def list_probes(self):
index da82c24b9c46b50a3f1173238617f92808348041..f2495d2e0f08d86aca603ebc9d992670e3bf102b 100644 (file)
@@ -59,8 +59,7 @@ class QuantumDebugShell(QuantumShell):
             '--config-file',
             default=env('TEST_CONFIG_FILE'),
             help='Config file for interface driver '
-                 '(You may also use either the '
-                 'l3_agent.ini or the dhcp_agent.ini)')
+                 '(You may also use l3_agent.ini)')
         return parser
 
     def initialize_app(self, argv):
index f271ba7f348c81bc7424e0d9ffa39a14c130ff55..8f47d9195cf97aa21c1b6a6f3f6666a8ec179633 100644 (file)
@@ -46,7 +46,7 @@ class TestDebugCommands(unittest.TestCase):
 
         self.addCleanup(mock.patch.stopall)
         device_exists_p = mock.patch(
-            'quantum.agent.linux.ip_lib.device_exists')
+            'quantum.agent.linux.ip_lib.device_exists', return_value=False)
         device_exists_p.start()
         namespace_p = mock.patch(
             'quantum.agent.linux.ip_lib.IpNetnsCommand')
@@ -124,7 +124,49 @@ class TestDebugCommands(unittest.TestCase):
                                       mock.call.show_subnet('fake_subnet'),
                                       mock.call.create_port(fake_port),
                                       mock.call.show_subnet('fake_subnet')])
-        self.driver.assert_has_calls([mock.call.init_l3('tap12345678-12',
+        self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
+                                      mock.call.plug('fake_net',
+                                                     'fake_port',
+                                                     'tap12345678-12',
+                                                     'aa:bb:cc:dd:ee:ffa',
+                                                     bridge=None,
+                                                     namespace=namespace),
+                                      mock.call.init_l3('tap12345678-12',
+                                                        ['10.0.0.3/24'],
+                                                        namespace=namespace
+                                                        )])
+
+    def test_create_probe_external(self):
+        fake_network = {'network': {'id': 'fake_net',
+                                    'tenant_id': 'fake_tenant',
+                                    'router:external': True,
+                                    'subnets': ['fake_subnet']}}
+        self.client.show_network.return_value = fake_network
+        cmd = commands.CreateProbe(self.app, None)
+        cmd_parser = cmd.get_parser('create_probe')
+        args = ['fake_net']
+        parsed_args = cmd_parser.parse_args(args)
+        cmd.run(parsed_args)
+        fake_port = {'port':
+                    {'device_owner': DEVICE_OWNER_PROBE,
+                     'admin_state_up': True,
+                     'network_id': 'fake_net',
+                     'tenant_id': 'fake_tenant',
+                     'fixed_ips': [{'subnet_id': 'fake_subnet'}],
+                     'device_id': socket.gethostname()}}
+        namespace = 'qprobe-fake_port'
+        self.client.assert_has_calls([mock.call.show_network('fake_net'),
+                                      mock.call.show_subnet('fake_subnet'),
+                                      mock.call.create_port(fake_port),
+                                      mock.call.show_subnet('fake_subnet')])
+        self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
+                                      mock.call.plug('fake_net',
+                                                     'fake_port',
+                                                     'tap12345678-12',
+                                                     'aa:bb:cc:dd:ee:ffa',
+                                                     bridge='br-ex',
+                                                     namespace=namespace),
+                                      mock.call.init_l3('tap12345678-12',
                                                         ['10.0.0.3/24'],
                                                         namespace=namespace
                                                         )])
@@ -137,10 +179,34 @@ class TestDebugCommands(unittest.TestCase):
         cmd.run(parsed_args)
         namespace = 'qprobe-fake_port'
         self.client.assert_has_calls([mock.call.show_port('fake_port'),
+                                      mock.call.show_network('fake_net'),
+                                      mock.call.show_subnet('fake_subnet'),
                                       mock.call.delete_port('fake_port')])
         self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
                                       mock.call.unplug('tap12345678-12',
-                                      namespace=namespace)])
+                                      namespace=namespace,
+                                      bridge=None)])
+
+    def test_delete_probe_external(self):
+        fake_network = {'network': {'id': 'fake_net',
+                                    'tenant_id': 'fake_tenant',
+                                    'router:external': True,
+                                    'subnets': ['fake_subnet']}}
+        self.client.show_network.return_value = fake_network
+        cmd = commands.DeleteProbe(self.app, None)
+        cmd_parser = cmd.get_parser('delete_probe')
+        args = ['fake_port']
+        parsed_args = cmd_parser.parse_args(args)
+        cmd.run(parsed_args)
+        namespace = 'qprobe-fake_port'
+        self.client.assert_has_calls([mock.call.show_port('fake_port'),
+                                      mock.call.show_network('fake_net'),
+                                      mock.call.show_subnet('fake_subnet'),
+                                      mock.call.delete_port('fake_port')])
+        self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
+                                      mock.call.unplug('tap12345678-12',
+                                      namespace=namespace,
+                                      bridge='br-ex')])
 
     def test_delete_probe_without_namespace(self):
         cfg.CONF.set_override('use_namespaces', False)
@@ -150,9 +216,12 @@ class TestDebugCommands(unittest.TestCase):
         parsed_args = cmd_parser.parse_args(args)
         cmd.run(parsed_args)
         self.client.assert_has_calls([mock.call.show_port('fake_port'),
+                                      mock.call.show_network('fake_net'),
+                                      mock.call.show_subnet('fake_subnet'),
                                       mock.call.delete_port('fake_port')])
         self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
-                                      mock.call.unplug('tap12345678-12')])
+                                      mock.call.unplug('tap12345678-12',
+                                                       bridge=None)])
 
     def test_list_probe(self):
         cmd = commands.ListProbe(self.app, None)
@@ -195,10 +264,13 @@ class TestDebugCommands(unittest.TestCase):
                                       device_id=socket.gethostname(),
                                       device_owner=DEVICE_OWNER_PROBE),
                                       mock.call.show_port('fake_port'),
+                                      mock.call.show_network('fake_net'),
+                                      mock.call.show_subnet('fake_subnet'),
                                       mock.call.delete_port('fake_port')])
         self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
                                       mock.call.unplug('tap12345678-12',
-                                                       namespace=namespace)])
+                                                       namespace=namespace,
+                                                       bridge=None)])
 
     def test_ping_all_with_ensure_port(self):
         fake_ports = self.fake_ports