]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Schema enhancement to support MultiSegment Network
authorRomil Gupta <romilg@hp.com>
Mon, 30 Jun 2014 12:35:08 +0000 (05:35 -0700)
committerRomil Gupta <romilg@hp.com>
Sun, 19 Oct 2014 19:49:48 +0000 (12:49 -0700)
Description:
Currently, there is nothing in the schema that ensures segments
for a network are returned in the same order they were specified
when the network was created, or even in a deterministic order.

Solution:
We need to add another field named 'segment_index' in
'ml2_network_segment' table containing a numeric position index.
With segment_index field we can retrieve the segments in the
order in which user created.

This patch set also fixes ML2 invalid unit test case in
test_create_network_multiprovider().

Closes-Bug: #1224978
Closes-Bug: #1377346

Change-Id: I560c34c6fe1c5425469ccdf9b8b4905c123d496d

neutron/db/migration/alembic_migrations/versions/1f71e54a85e7_ml2_net_seg_model.py [new file with mode: 0644]
neutron/db/migration/alembic_migrations/versions/HEAD
neutron/plugins/ml2/db.py
neutron/plugins/ml2/managers.py
neutron/plugins/ml2/models.py
neutron/tests/unit/ml2/test_ml2_plugin.py

diff --git a/neutron/db/migration/alembic_migrations/versions/1f71e54a85e7_ml2_net_seg_model.py b/neutron/db/migration/alembic_migrations/versions/1f71e54a85e7_ml2_net_seg_model.py
new file mode 100644 (file)
index 0000000..f72fbf0
--- /dev/null
@@ -0,0 +1,40 @@
+# Copyright 2014 OpenStack Foundation
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+#
+
+"""ml2_network_segments models change for multi-segment network.
+
+Revision ID: 1f71e54a85e7
+Revises: 44621190bc02
+Create Date: 2014-10-15 18:30:51.395295
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '1f71e54a85e7'
+down_revision = '44621190bc02'
+
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+    op.add_column('ml2_network_segments',
+                  sa.Column('segment_index', sa.Integer(), nullable=False,
+                  server_default='0'))
+
+
+def downgrade():
+    op.drop_column('ml2_network_segments', 'segment_index')
index 8c20ac433be0bab21486aeb4e49977ea37aad2a6..daed716e185237ad3457348e65e74050951546dd 100644 (file)
@@ -1 +1 @@
-44621190bc02
+1f71e54a85e7
index d8caa9384af1bb8567a20e1421adca9df3be3c3e..37e91bc791c5c8ccdbf6f0065eb7089d77b05d4e 100644 (file)
@@ -39,7 +39,8 @@ def _make_segment_dict(record):
             api.SEGMENTATION_ID: record.segmentation_id}
 
 
-def add_network_segment(session, network_id, segment, is_dynamic=False):
+def add_network_segment(session, network_id, segment, segment_index=0,
+                        is_dynamic=False):
     with session.begin(subtransactions=True):
         record = models.NetworkSegment(
             id=uuidutils.generate_uuid(),
@@ -47,6 +48,7 @@ def add_network_segment(session, network_id, segment, is_dynamic=False):
             network_type=segment.get(api.NETWORK_TYPE),
             physical_network=segment.get(api.PHYSICAL_NETWORK),
             segmentation_id=segment.get(api.SEGMENTATION_ID),
+            segment_index=segment_index,
             is_dynamic=is_dynamic
         )
         session.add(record)
@@ -61,7 +63,8 @@ def add_network_segment(session, network_id, segment, is_dynamic=False):
 def get_network_segments(session, network_id, filter_dynamic=False):
     with session.begin(subtransactions=True):
         query = (session.query(models.NetworkSegment).
-                 filter_by(network_id=network_id))
+                 filter_by(network_id=network_id).
+                 order_by(models.NetworkSegment.segment_index))
         if filter_dynamic is not None:
             query = query.filter_by(is_dynamic=filter_dynamic)
         records = query.all()
index 9c6c6fc514e026c52cdec9cf809a56253f4992d4..8700934fe6414e5d9e704b4e7179d03e13cc1172 100644 (file)
@@ -152,10 +152,11 @@ class TypeManager(stevedore.named.NamedExtensionManager):
         with session.begin(subtransactions=True):
             network_id = network['id']
             if segments:
-                for segment in segments:
+                for segment_index, segment in enumerate(segments):
                     segment = self.reserve_provider_segment(
                         session, segment)
-                    db.add_network_segment(session, network_id, segment)
+                    db.add_network_segment(session, network_id,
+                                           segment, segment_index)
             else:
                 segment = self.allocate_tenant_segment(session)
                 db.add_network_segment(session, network_id, segment)
index 80ae1bbb6a33349f717f3465c1aaaacb9a982ecd..350c34e4f7707df7a12fa09981120ea4579ce66b 100644 (file)
@@ -41,6 +41,7 @@ class NetworkSegment(model_base.BASEV2, models_v2.HasId):
     segmentation_id = sa.Column(sa.Integer)
     is_dynamic = sa.Column(sa.Boolean, default=False, nullable=False,
                            server_default=sa.sql.false())
+    segment_index = sa.Column(sa.Integer, nullable=False, server_default='0')
 
 
 class PortBinding(model_base.BASEV2):
index 9bd8ccd9f61e96b29954f289902564b9f2b6d830..d1729194c7359365b47e8769cc20092e5cb56a4c 100644 (file)
@@ -583,20 +583,24 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
         network_req = self.new_create_request('networks', data)
         network = self.deserialize(self.fmt,
                                    network_req.get_response(self.api))
-        tz = network['network'][mpnet.SEGMENTS]
-        for tz in data['network'][mpnet.SEGMENTS]:
+        segments = network['network'][mpnet.SEGMENTS]
+        for segment_index, segment in enumerate(data['network']
+                                                [mpnet.SEGMENTS]):
             for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
                           pnet.SEGMENTATION_ID]:
-                self.assertEqual(tz.get(field), tz.get(field))
+                self.assertEqual(segment.get(field),
+                            segments[segment_index][field])
 
         # Tests get_network()
         net_req = self.new_show_request('networks', network['network']['id'])
         network = self.deserialize(self.fmt, net_req.get_response(self.api))
-        tz = network['network'][mpnet.SEGMENTS]
-        for tz in data['network'][mpnet.SEGMENTS]:
+        segments = network['network'][mpnet.SEGMENTS]
+        for segment_index, segment in enumerate(data['network']
+                                                [mpnet.SEGMENTS]):
             for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
                           pnet.SEGMENTATION_ID]:
-                self.assertEqual(tz.get(field), tz.get(field))
+                self.assertEqual(segment.get(field),
+                            segments[segment_index][field])
 
     def test_create_network_with_provider_and_multiprovider_fail(self):
         data = {'network': {'name': 'net1',