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
This commit is contained in:
parent
0c1223862c
commit
64f9a58d91
@ -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')
|
@ -1 +1 @@
|
|||||||
44621190bc02
|
1f71e54a85e7
|
||||||
|
@ -39,7 +39,8 @@ def _make_segment_dict(record):
|
|||||||
api.SEGMENTATION_ID: record.segmentation_id}
|
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):
|
with session.begin(subtransactions=True):
|
||||||
record = models.NetworkSegment(
|
record = models.NetworkSegment(
|
||||||
id=uuidutils.generate_uuid(),
|
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),
|
network_type=segment.get(api.NETWORK_TYPE),
|
||||||
physical_network=segment.get(api.PHYSICAL_NETWORK),
|
physical_network=segment.get(api.PHYSICAL_NETWORK),
|
||||||
segmentation_id=segment.get(api.SEGMENTATION_ID),
|
segmentation_id=segment.get(api.SEGMENTATION_ID),
|
||||||
|
segment_index=segment_index,
|
||||||
is_dynamic=is_dynamic
|
is_dynamic=is_dynamic
|
||||||
)
|
)
|
||||||
session.add(record)
|
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):
|
def get_network_segments(session, network_id, filter_dynamic=False):
|
||||||
with session.begin(subtransactions=True):
|
with session.begin(subtransactions=True):
|
||||||
query = (session.query(models.NetworkSegment).
|
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:
|
if filter_dynamic is not None:
|
||||||
query = query.filter_by(is_dynamic=filter_dynamic)
|
query = query.filter_by(is_dynamic=filter_dynamic)
|
||||||
records = query.all()
|
records = query.all()
|
||||||
|
@ -152,10 +152,11 @@ class TypeManager(stevedore.named.NamedExtensionManager):
|
|||||||
with session.begin(subtransactions=True):
|
with session.begin(subtransactions=True):
|
||||||
network_id = network['id']
|
network_id = network['id']
|
||||||
if segments:
|
if segments:
|
||||||
for segment in segments:
|
for segment_index, segment in enumerate(segments):
|
||||||
segment = self.reserve_provider_segment(
|
segment = self.reserve_provider_segment(
|
||||||
session, segment)
|
session, segment)
|
||||||
db.add_network_segment(session, network_id, segment)
|
db.add_network_segment(session, network_id,
|
||||||
|
segment, segment_index)
|
||||||
else:
|
else:
|
||||||
segment = self.allocate_tenant_segment(session)
|
segment = self.allocate_tenant_segment(session)
|
||||||
db.add_network_segment(session, network_id, segment)
|
db.add_network_segment(session, network_id, segment)
|
||||||
|
@ -41,6 +41,7 @@ class NetworkSegment(model_base.BASEV2, models_v2.HasId):
|
|||||||
segmentation_id = sa.Column(sa.Integer)
|
segmentation_id = sa.Column(sa.Integer)
|
||||||
is_dynamic = sa.Column(sa.Boolean, default=False, nullable=False,
|
is_dynamic = sa.Column(sa.Boolean, default=False, nullable=False,
|
||||||
server_default=sa.sql.false())
|
server_default=sa.sql.false())
|
||||||
|
segment_index = sa.Column(sa.Integer, nullable=False, server_default='0')
|
||||||
|
|
||||||
|
|
||||||
class PortBinding(model_base.BASEV2):
|
class PortBinding(model_base.BASEV2):
|
||||||
|
@ -583,20 +583,24 @@ class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
|
|||||||
network_req = self.new_create_request('networks', data)
|
network_req = self.new_create_request('networks', data)
|
||||||
network = self.deserialize(self.fmt,
|
network = self.deserialize(self.fmt,
|
||||||
network_req.get_response(self.api))
|
network_req.get_response(self.api))
|
||||||
tz = network['network'][mpnet.SEGMENTS]
|
segments = network['network'][mpnet.SEGMENTS]
|
||||||
for tz in data['network'][mpnet.SEGMENTS]:
|
for segment_index, segment in enumerate(data['network']
|
||||||
|
[mpnet.SEGMENTS]):
|
||||||
for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
|
for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
|
||||||
pnet.SEGMENTATION_ID]:
|
pnet.SEGMENTATION_ID]:
|
||||||
self.assertEqual(tz.get(field), tz.get(field))
|
self.assertEqual(segment.get(field),
|
||||||
|
segments[segment_index][field])
|
||||||
|
|
||||||
# Tests get_network()
|
# Tests get_network()
|
||||||
net_req = self.new_show_request('networks', network['network']['id'])
|
net_req = self.new_show_request('networks', network['network']['id'])
|
||||||
network = self.deserialize(self.fmt, net_req.get_response(self.api))
|
network = self.deserialize(self.fmt, net_req.get_response(self.api))
|
||||||
tz = network['network'][mpnet.SEGMENTS]
|
segments = network['network'][mpnet.SEGMENTS]
|
||||||
for tz in data['network'][mpnet.SEGMENTS]:
|
for segment_index, segment in enumerate(data['network']
|
||||||
|
[mpnet.SEGMENTS]):
|
||||||
for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
|
for field in [pnet.NETWORK_TYPE, pnet.PHYSICAL_NETWORK,
|
||||||
pnet.SEGMENTATION_ID]:
|
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):
|
def test_create_network_with_provider_and_multiprovider_fail(self):
|
||||||
data = {'network': {'name': 'net1',
|
data = {'network': {'name': 'net1',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user