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
--- /dev/null
+# 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')
-44621190bc02
+1f71e54a85e7
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(),
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)
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()
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)
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):
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',