]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Nicira plugin: List ports on network gateways
authorSalvatore Orlando <salv.orlando@gmail.com>
Thu, 23 May 2013 09:09:19 +0000 (11:09 +0200)
committerSalvatore Orlando <salv.orlando@gmail.com>
Thu, 23 May 2013 18:41:44 +0000 (20:41 +0200)
Bug 1183277

This patch adds a read-only attribute to the network gateway API
extension. This attribute will return the list of ports connected to
a gateway, including their segmentation types and ids.
This patch now adds joined load for a gateway's connections, thus
avoiding extra queries to the db.

Change-Id: I2b22c94eed5bc02be16771660008d31c74a8628e

quantum/plugins/nicira/extensions/nvp_networkgw.py
quantum/plugins/nicira/nicira_networkgw_db.py
quantum/tests/unit/nicira/test_networkgw.py
quantum/tests/unit/nicira/test_nicira_plugin.py

index 2887fda2968e121205e3feac35fc9519c0536924..0bc6cf2e98d78d795b699924882499f3e6df7707 100644 (file)
@@ -48,6 +48,9 @@ RESOURCE_ATTRIBUTE_MAP = {
         'devices': {'allow_post': True, 'allow_put': False,
                     'validate': {'type:device_list': None},
                     'is_visible': True},
+        'ports': {'allow_post': False, 'allow_put': False,
+                  'default': [],
+                  'is_visible': True},
         'tenant_id': {'allow_post': True, 'allow_put': False,
                       'validate': {'type:string': None},
                       'required_by_policy': True,
index f50a0759dc160e911dcfe3f6de9c288445bd8ca3..9a89e8b9349ff828abf72d244ca156a3ebe5da56 100644 (file)
@@ -122,7 +122,7 @@ class NetworkGateway(model_base.BASEV2, models_v2.HasId,
     devices = orm.relationship(NetworkGatewayDevice,
                                backref='networkgateways',
                                cascade='all,delete')
-    network_connections = orm.relationship(NetworkConnection)
+    network_connections = orm.relationship(NetworkConnection, lazy='joined')
 
 
 class NetworkGatewayMixin(nvp_networkgw.NetworkGatewayPluginBase):
@@ -132,6 +132,11 @@ class NetworkGatewayMixin(nvp_networkgw.NetworkGatewayPluginBase):
     def _get_network_gateway(self, context, gw_id):
         return self._get_by_id(context, NetworkGateway, gw_id)
 
+    def _make_gw_connection_dict(self, gw_conn):
+        return {'port_id': gw_conn['port_id'],
+                'segmentation_type': gw_conn['segmentation_type'],
+                'segmentation_id': gw_conn['segmentation_id']}
+
     def _make_network_gateway_dict(self, network_gateway, fields=None):
         device_list = []
         for d in network_gateway['devices']:
@@ -142,7 +147,10 @@ class NetworkGatewayMixin(nvp_networkgw.NetworkGatewayPluginBase):
                'default': network_gateway['default'],
                'devices': device_list,
                'tenant_id': network_gateway['tenant_id']}
-        # NOTE(salvatore-orlando):perhaps return list of connected networks
+        # Query gateway connections only if needed
+        if (fields and 'ports' in fields) or not fields:
+            res['ports'] = [self._make_gw_connection_dict(conn)
+                            for conn in network_gateway.network_connections]
         return self._fields(res, fields)
 
     def _validate_network_mapping_info(self, network_mapping_info):
@@ -170,8 +178,8 @@ class NetworkGatewayMixin(nvp_networkgw.NetworkGatewayPluginBase):
             raise exceptions.InvalidInput(error_message=msg)
         return network_id
 
-    def _retrieve_gateway_connections(self, context, gateway_id, mapping_info,
-                                      only_one=False):
+    def _retrieve_gateway_connections(self, context, gateway_id,
+                                      mapping_info={}, only_one=False):
         filters = {'network_gateway_id': [gateway_id]}
         for k, v in mapping_info.iteritems():
             if v and k != NETWORK_ID:
@@ -224,8 +232,7 @@ class NetworkGatewayMixin(nvp_networkgw.NetworkGatewayPluginBase):
             if gw_db.default:
                 raise NetworkGatewayUnchangeable(gateway_id=id)
             # Ensure there is something to update before doing it
-            db_values_set = set([v for (k, v) in gw_db.iteritems()])
-            if not set(gw_data.values()).issubset(db_values_set):
+            if any([gw_db[k] != gw_data[k] for k in gw_data]):
                 gw_db.update(gw_data)
         LOG.debug(_("Updated network gateway with id:%s"), id)
         return self._make_network_gateway_dict(gw_db)
index c1fd33c92203136f625dfe8a1365ea0b68b82021..35a3a05dc2b9066359c9e46d300a008cc1e0efc7 100644 (file)
@@ -380,6 +380,45 @@ class NetworkGatewayDbTestCase(test_db_plugin.QuantumDbPluginV2TestCase):
                 self.assertEqual(res[key][1]['name'],
                                  gw2[self.resource]['name'])
 
+    def _test_list_network_gateway_with_multiple_connections(
+        self, expected_gateways=1):
+        with self._network_gateway() as gw:
+            with self.network() as net_1:
+                self._gateway_action('connect',
+                                     gw[self.resource]['id'],
+                                     net_1['network']['id'],
+                                     'vlan', 555)
+                self._gateway_action('connect',
+                                     gw[self.resource]['id'],
+                                     net_1['network']['id'],
+                                     'vlan', 777)
+                req = self.new_list_request(networkgw.COLLECTION_NAME)
+                res = self.deserialize('json', req.get_response(self.ext_api))
+                key = self.resource + 's'
+                self.assertEqual(len(res[key]), expected_gateways)
+                for item in res[key]:
+                    self.assertIn('ports', item)
+                    if item['id'] == gw[self.resource]['id']:
+                        gw_ports = item['ports']
+                self.assertEqual(len(gw_ports), 2)
+                segmentation_ids = [555, 777]
+                for gw_port in gw_ports:
+                    self.assertEqual('vlan', gw_port['segmentation_type'])
+                    self.assertIn(gw_port['segmentation_id'], segmentation_ids)
+                    segmentation_ids.remove(gw_port['segmentation_id'])
+                # Required cleanup
+                self._gateway_action('disconnect',
+                                     gw[self.resource]['id'],
+                                     net_1['network']['id'],
+                                     'vlan', 555)
+                self._gateway_action('disconnect',
+                                     gw[self.resource]['id'],
+                                     net_1['network']['id'],
+                                     'vlan', 777)
+
+    def test_list_network_gateway_with_multiple_connections(self):
+        self._test_list_network_gateway_with_multiple_connections()
+
     def test_connect_and_disconnect_network(self):
         self._test_connect_and_disconnect_network('flat')
 
index e98ebbd4e95e9b5f5c6f8252f016b03b4830db89..f52978f376c8e0e66f737a131bdd1ba57d8b2db1 100644 (file)
@@ -929,6 +929,10 @@ class TestNiciraNetworkGateway(test_l2_gw.NetworkGatewayDbTestCase,
                 self.assertEqual(res[key][2]['name'],
                                  gw2[self.resource]['name'])
 
+    def test_list_network_gateway_with_multiple_connections(self):
+        self._test_list_network_gateway_with_multiple_connections(
+            expected_gateways=2)
+
     def test_delete_network_gateway(self):
         # The default gateway must still be there
         self._test_delete_network_gateway(1)