Merge "Data models for vlan-aware-vms"

This commit is contained in:
Jenkins 2016-04-26 00:11:50 +00:00 committed by Gerrit Code Review
commit 307353be59
9 changed files with 231 additions and 1 deletions

View File

@ -1 +1 @@
45f8dd33480b
5abc0278ca73

View File

@ -0,0 +1,49 @@
# 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.
#
revision = '5abc0278ca73'
down_revision = '45f8dd33480b'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table('trunks',
sa.Column('tenant_id', sa.String(length=255), nullable=True,
index=True),
sa.Column('id', sa.String(length=36), nullable=False),
sa.Column('port_id', sa.String(length=36), nullable=False),
sa.Column('standard_attr_id', sa.BigInteger(), nullable=False),
sa.ForeignKeyConstraint(['port_id'], ['ports.id'],
ondelete='CASCADE'),
sa.ForeignKeyConstraint(['standard_attr_id'],
['standardattributes.id'],
ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('port_id'),
sa.UniqueConstraint('standard_attr_id')
)
op.create_table('subports',
sa.Column('port_id', sa.String(length=36), nullable=False),
sa.Column('trunk_id', sa.String(length=36), nullable=False),
sa.Column('segmentation_type', sa.String(length=32), nullable=False),
sa.Column('segmentation_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['port_id'], ['ports.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['trunk_id'], ['trunks.id'],
ondelete='CASCADE'),
sa.PrimaryKeyConstraint('port_id', 'trunk_id'),
sa.UniqueConstraint('port_id'),
sa.UniqueConstraint('trunk_id', 'segmentation_type', 'segmentation_id',
name='uniq_subport0trunk_id0segmentation_type0segmentation_id')
)

View File

@ -59,6 +59,7 @@ from neutron.plugins.ml2.drivers import type_vlan # noqa
from neutron.plugins.ml2.drivers import type_vxlan # noqa
from neutron.plugins.ml2 import models # noqa
from neutron.services.auto_allocate import models # noqa
from neutron.services.trunk import models # noqa
def get_metadata():

View File

View File

@ -0,0 +1,35 @@
# Copyright 2016 Hewlett Packard Enterprise Development Company, LP
#
# All Rights Reserved.
#
# 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.
from oslo_db import exception as db_exc
from oslo_utils import uuidutils
from neutron.services.trunk import exceptions
from neutron.services.trunk import models
def create_trunk(context, port_id, description=None):
"""Create a trunk (with description) given the parent port uuid."""
try:
with context.session.begin(subtransactions=True):
context.session.add(
models.Trunk(
id=uuidutils.generate_uuid(),
tenant_id=context.tenant_id,
port_id=port_id,
description=description))
except db_exc.DBDuplicateEntry:
raise exceptions.TrunkPortInUse(port_id=port_id)

View File

@ -0,0 +1,22 @@
# Copyright 2016 Hewlett Packard Enterprise Development Company, LP
#
# All Rights Reserved.
#
# 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.
from neutron._i18n import _
from neutron_lib import exceptions as n_exc
class TrunkPortInUse(n_exc.InUse):
message = _("Port %(port_id)s is in use by another trunk.")

View File

@ -0,0 +1,73 @@
# Copyright 2016 Red Hat Inc.
# All Rights Reserved.
#
# 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.
import sqlalchemy as sa
from neutron.db import model_base
from neutron.db import models_v2
class Trunk(model_base.HasStandardAttributes, model_base.BASEV2,
model_base.HasId, model_base.HasTenant):
port_id = sa.Column(sa.String(36),
sa.ForeignKey('ports.id',
ondelete='CASCADE'),
nullable=False,
unique=True)
port = sa.orm.relationship(
models_v2.Port,
backref=sa.orm.backref('trunk_port', lazy='joined', uselist=False,
cascade='delete'))
class SubPort(model_base.BASEV2):
port_id = sa.Column(sa.String(36),
sa.ForeignKey('ports.id',
ondelete='CASCADE'),
nullable=False,
unique=True,
primary_key=True)
port = sa.orm.relationship(
models_v2.Port,
backref=sa.orm.backref('sub_port', lazy='joined', uselist=False,
cascade='delete'))
trunk_id = sa.Column(sa.String(36),
sa.ForeignKey('trunks.id',
ondelete='CASCADE'),
nullable=False,
primary_key=True)
segmentation_type = sa.Column(sa.String(32), nullable=False)
segmentation_id = sa.Column(sa.Integer, nullable=False)
__table_args__ = (
sa.UniqueConstraint(
'trunk_id',
'segmentation_type',
'segmentation_id',
name='uniq_subport0trunk_id0segmentation_type0segmentation_id'),
model_base.BASEV2.__table_args__
)
# NOTE(armax) constraints like the following are implemented via
# business logic rules:
#
# Deletion of a trunk automatically deletes all of its subports;
# Deletion of a (child) port referred by a subport is forbidden;
# Deletion of a (parent) port referred by a trunk is forbidden;
# A port cannot be a subport and a trunk port at the same time (nested).

View File

@ -0,0 +1,50 @@
# Copyright 2016 Hewlett Packard Enterprise Development Company, LP
#
# 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.
from neutron import context
from neutron.db import models_v2
from neutron.services.trunk import db
from neutron.services.trunk import exceptions
from neutron.tests.unit import testlib_api
class TrunkDBTestCase(testlib_api.SqlTestCase):
def setUp(self):
super(TrunkDBTestCase, self).setUp()
self.ctx = context.get_admin_context()
def _add_network(self, net_id):
with self.ctx.session.begin(subtransactions=True):
self.ctx.session.add(models_v2.Network(id=net_id))
def _add_port(self, net_id, port_id):
with self.ctx.session.begin(subtransactions=True):
port = models_v2.Port(id=port_id,
network_id=net_id,
mac_address='foo_mac_%s' % port_id,
admin_state_up=True,
status='DOWN',
device_id='',
device_owner='')
self.ctx.session.add(port)
def test_create_trunk_raise_port_in_use(self):
self._add_network('foo_net')
self._add_port('foo_net', 'foo_port')
db.create_trunk(self.ctx, 'foo_port')
self.assertRaises(exceptions.TrunkPortInUse,
db.create_trunk,
self.ctx, 'foo_port')