Browse Source

Schema enhancement to support MultiSegment Network

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
tags/2015.1.0b1
Romil Gupta 5 years ago
parent
commit
db5e370b0d

+ 40
- 0
neutron/db/migration/alembic_migrations/versions/1f71e54a85e7_ml2_net_seg_model.py View File

@@ -0,0 +1,40 @@
1
+# Copyright 2014 OpenStack Foundation
2
+#
3
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+#    not use this file except in compliance with the License. You may obtain
5
+#    a copy of the License at
6
+#
7
+#         http://www.apache.org/licenses/LICENSE-2.0
8
+#
9
+#    Unless required by applicable law or agreed to in writing, software
10
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+#    License for the specific language governing permissions and limitations
13
+#    under the License.
14
+#
15
+
16
+"""ml2_network_segments models change for multi-segment network.
17
+
18
+Revision ID: 1f71e54a85e7
19
+Revises: 44621190bc02
20
+Create Date: 2014-10-15 18:30:51.395295
21
+
22
+"""
23
+
24
+# revision identifiers, used by Alembic.
25
+revision = '1f71e54a85e7'
26
+down_revision = '44621190bc02'
27
+
28
+
29
+from alembic import op
30
+import sqlalchemy as sa
31
+
32
+
33
+def upgrade():
34
+    op.add_column('ml2_network_segments',
35
+                  sa.Column('segment_index', sa.Integer(), nullable=False,
36
+                  server_default='0'))
37
+
38
+
39
+def downgrade():
40
+    op.drop_column('ml2_network_segments', 'segment_index')

+ 1
- 1
neutron/db/migration/alembic_migrations/versions/HEAD View File

@@ -1 +1 @@
1
-44621190bc02
1
+1f71e54a85e7

+ 5
- 2
neutron/plugins/ml2/db.py View File

@@ -39,7 +39,8 @@ def _make_segment_dict(record):
39 39
             api.SEGMENTATION_ID: record.segmentation_id}
40 40
 
41 41
 
42
-def add_network_segment(session, network_id, segment, is_dynamic=False):
42
+def add_network_segment(session, network_id, segment, segment_index=0,
43
+                        is_dynamic=False):
43 44
     with session.begin(subtransactions=True):
44 45
         record = models.NetworkSegment(
45 46
             id=uuidutils.generate_uuid(),
@@ -47,6 +48,7 @@ def add_network_segment(session, network_id, segment, is_dynamic=False):
47 48
             network_type=segment.get(api.NETWORK_TYPE),
48 49
             physical_network=segment.get(api.PHYSICAL_NETWORK),
49 50
             segmentation_id=segment.get(api.SEGMENTATION_ID),
51
+            segment_index=segment_index,
50 52
             is_dynamic=is_dynamic
51 53
         )
52 54
         session.add(record)
@@ -61,7 +63,8 @@ def add_network_segment(session, network_id, segment, is_dynamic=False):
61 63
 def get_network_segments(session, network_id, filter_dynamic=False):
62 64
     with session.begin(subtransactions=True):
63 65
         query = (session.query(models.NetworkSegment).
64
-                 filter_by(network_id=network_id))
66
+                 filter_by(network_id=network_id).
67
+                 order_by(models.NetworkSegment.segment_index))
65 68
         if filter_dynamic is not None:
66 69
             query = query.filter_by(is_dynamic=filter_dynamic)
67 70
         records = query.all()

+ 3
- 2
neutron/plugins/ml2/managers.py View File

@@ -152,10 +152,11 @@ class TypeManager(stevedore.named.NamedExtensionManager):
152 152
         with session.begin(subtransactions=True):
153 153
             network_id = network['id']
154 154
             if segments:
155
-                for segment in segments:
155
+                for segment_index, segment in enumerate(segments):
156 156
                     segment = self.reserve_provider_segment(
157 157
                         session, segment)
158
-                    db.add_network_segment(session, network_id, segment)
158
+                    db.add_network_segment(session, network_id,
159
+                                           segment, segment_index)
159 160
             else:
160 161
                 segment = self.allocate_tenant_segment(session)
161 162
                 db.add_network_segment(session, network_id, segment)

+ 1
- 0
neutron/plugins/ml2/models.py View File

@@ -41,6 +41,7 @@ class NetworkSegment(model_base.BASEV2, models_v2.HasId):
41 41
     segmentation_id = sa.Column(sa.Integer)
42 42
     is_dynamic = sa.Column(sa.Boolean, default=False, nullable=False,
43 43
                            server_default=sa.sql.false())
44
+    segment_index = sa.Column(sa.Integer, nullable=False, server_default='0')
44 45
 
45 46
 
46 47
 class PortBinding(model_base.BASEV2):

+ 10
- 6
neutron/tests/unit/ml2/test_ml2_plugin.py View File

@@ -583,20 +583,24 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
583 583
         network_req = self.new_create_request('networks', data)
584 584
         network = self.deserialize(self.fmt,
585 585
                                    network_req.get_response(self.api))
586
-        tz = network['network'][mpnet.SEGMENTS]
587
-        for tz in data['network'][mpnet.SEGMENTS]:
586
+        segments = network['network'][mpnet.SEGMENTS]
587
+        for segment_index, segment in enumerate(data['network']
588
+                                                [mpnet.SEGMENTS]):
588 589
             for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
589 590
                           pnet.SEGMENTATION_ID]:
590
-                self.assertEqual(tz.get(field), tz.get(field))
591
+                self.assertEqual(segment.get(field),
592
+                            segments[segment_index][field])
591 593
 
592 594
         # Tests get_network()
593 595
         net_req = self.new_show_request('networks', network['network']['id'])
594 596
         network = self.deserialize(self.fmt, net_req.get_response(self.api))
595
-        tz = network['network'][mpnet.SEGMENTS]
596
-        for tz in data['network'][mpnet.SEGMENTS]:
597
+        segments = network['network'][mpnet.SEGMENTS]
598
+        for segment_index, segment in enumerate(data['network']
599
+                                                [mpnet.SEGMENTS]):
597 600
             for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
598 601
                           pnet.SEGMENTATION_ID]:
599
-                self.assertEqual(tz.get(field), tz.get(field))
602
+                self.assertEqual(segment.get(field),
603
+                            segments[segment_index][field])
600 604
 
601 605
     def test_create_network_with_provider_and_multiprovider_fail(self):
602 606
         data = {'network': {'name': 'net1',

Loading…
Cancel
Save