Relocate Security Group DB models

This patch will separate security group db models from mixins for OVO
implementation work.

Change-Id: Ie38d3cc2efa5f580261f207748affb5840ba23c9
Partial-Bug: #1597913
This commit is contained in:
Victor Morales 2016-08-10 12:33:43 -05:00 committed by Ihar Hrachyshka
parent 04b3b4dfa8
commit a92647300d
7 changed files with 150 additions and 120 deletions

View File

@ -39,6 +39,7 @@ from neutron.db import l3_gwmode_db # noqa
from neutron.db import l3_hamode_db # noqa
from neutron.db.metering import metering_db # noqa
from neutron.db import model_base
from neutron.db.models import securitygroup # noqa
from neutron.db import models_v2 # noqa
from neutron.db.port_security import models # noqa
from neutron.db import portbindings_db # noqa
@ -46,7 +47,6 @@ from neutron.db import provisioning_blocks # noqa
from neutron.db.qos import models as qos_models # noqa
from neutron.db.quota import models # noqa
from neutron.db import rbac_db_models # noqa
from neutron.db import securitygroups_db # noqa
from neutron.db import segments_db # noqa
from neutron.db import servicetype_db # noqa
from neutron.db import tag_db # noqa

View File

@ -0,0 +1,91 @@
# Copyright 2012 VMware, 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 sqlalchemy import orm
from neutron.api.v2 import attributes
from neutron.db import model_base
from neutron.db import models_v2
class SecurityGroup(model_base.HasStandardAttributes, model_base.BASEV2,
model_base.HasId, model_base.HasProject):
"""Represents a v2 neutron security group."""
name = sa.Column(sa.String(attributes.NAME_MAX_LEN))
class DefaultSecurityGroup(model_base.BASEV2, model_base.HasProjectPrimaryKey):
__tablename__ = 'default_security_group'
security_group_id = sa.Column(sa.String(36),
sa.ForeignKey("securitygroups.id",
ondelete="CASCADE"),
nullable=False)
security_group = orm.relationship(
SecurityGroup, lazy='joined',
backref=orm.backref('default_security_group', cascade='all,delete'),
primaryjoin="SecurityGroup.id==DefaultSecurityGroup.security_group_id",
)
class SecurityGroupPortBinding(model_base.BASEV2):
"""Represents binding between neutron ports and security profiles."""
port_id = sa.Column(sa.String(36),
sa.ForeignKey("ports.id",
ondelete='CASCADE'),
primary_key=True)
security_group_id = sa.Column(sa.String(36),
sa.ForeignKey("securitygroups.id"),
primary_key=True)
revises_on_change = ('ports', )
# Add a relationship to the Port model in order to instruct SQLAlchemy to
# eagerly load security group bindings
ports = orm.relationship(
models_v2.Port,
backref=orm.backref("security_groups",
lazy='joined', cascade='delete'))
class SecurityGroupRule(model_base.HasStandardAttributes, model_base.BASEV2,
model_base.HasId, model_base.HasProject):
"""Represents a v2 neutron security group rule."""
security_group_id = sa.Column(sa.String(36),
sa.ForeignKey("securitygroups.id",
ondelete="CASCADE"),
nullable=False)
remote_group_id = sa.Column(sa.String(36),
sa.ForeignKey("securitygroups.id",
ondelete="CASCADE"),
nullable=True)
revises_on_change = ('security_group', )
direction = sa.Column(sa.Enum('ingress', 'egress',
name='securitygrouprules_direction'))
ethertype = sa.Column(sa.String(40))
protocol = sa.Column(sa.String(40))
port_range_min = sa.Column(sa.Integer)
port_range_max = sa.Column(sa.Integer)
remote_ip_prefix = sa.Column(sa.String(255))
security_group = orm.relationship(
SecurityGroup,
backref=orm.backref('rules', cascade='all,delete', lazy='joined'),
primaryjoin="SecurityGroup.id==SecurityGroupRule.security_group_id")
source_group = orm.relationship(
SecurityGroup,
backref=orm.backref('source_rules', cascade='all,delete'),
primaryjoin="SecurityGroup.id==SecurityGroupRule.remote_group_id")

View File

@ -12,13 +12,13 @@
# License for the specific language governing permissions and limitations
# under the License.
import sys
import netaddr
from neutron_lib.api import validators
from neutron_lib import constants
from oslo_log import log as logging
from oslo_utils import uuidutils
import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.orm import exc
from sqlalchemy.orm import scoped_session
@ -28,89 +28,18 @@ from neutron.callbacks import events
from neutron.callbacks import exceptions
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.common import _deprecate
from neutron.common import constants as n_const
from neutron.common import utils
from neutron.db import api as db_api
from neutron.db import db_base_plugin_v2
from neutron.db import model_base
from neutron.db import models_v2
from neutron.db.models import securitygroup as sg_models
from neutron.extensions import securitygroup as ext_sg
LOG = logging.getLogger(__name__)
class SecurityGroup(model_base.HasStandardAttributes, model_base.BASEV2,
model_base.HasId, model_base.HasProject):
"""Represents a v2 neutron security group."""
name = sa.Column(sa.String(attributes.NAME_MAX_LEN))
class DefaultSecurityGroup(model_base.BASEV2, model_base.HasProjectPrimaryKey):
__tablename__ = 'default_security_group'
security_group_id = sa.Column(sa.String(36),
sa.ForeignKey("securitygroups.id",
ondelete="CASCADE"),
nullable=False)
security_group = orm.relationship(
SecurityGroup, lazy='joined',
backref=orm.backref('default_security_group', cascade='all,delete'),
primaryjoin="SecurityGroup.id==DefaultSecurityGroup.security_group_id",
)
class SecurityGroupPortBinding(model_base.BASEV2):
"""Represents binding between neutron ports and security profiles."""
port_id = sa.Column(sa.String(36),
sa.ForeignKey("ports.id",
ondelete='CASCADE'),
primary_key=True)
security_group_id = sa.Column(sa.String(36),
sa.ForeignKey("securitygroups.id"),
primary_key=True)
revises_on_change = ('ports', )
# Add a relationship to the Port model in order to instruct SQLAlchemy to
# eagerly load security group bindings
ports = orm.relationship(
models_v2.Port,
backref=orm.backref("security_groups",
lazy='joined', cascade='delete'))
class SecurityGroupRule(model_base.HasStandardAttributes, model_base.BASEV2,
model_base.HasId, model_base.HasProject):
"""Represents a v2 neutron security group rule."""
security_group_id = sa.Column(sa.String(36),
sa.ForeignKey("securitygroups.id",
ondelete="CASCADE"),
nullable=False)
remote_group_id = sa.Column(sa.String(36),
sa.ForeignKey("securitygroups.id",
ondelete="CASCADE"),
nullable=True)
revises_on_change = ('security_group', )
direction = sa.Column(sa.Enum('ingress', 'egress',
name='securitygrouprules_direction'))
ethertype = sa.Column(sa.String(40))
protocol = sa.Column(sa.String(40))
port_range_min = sa.Column(sa.Integer)
port_range_max = sa.Column(sa.Integer)
remote_ip_prefix = sa.Column(sa.String(255))
security_group = orm.relationship(
SecurityGroup,
backref=orm.backref('rules', cascade='all,delete', lazy='joined'),
primaryjoin="SecurityGroup.id==SecurityGroupRule.security_group_id")
source_group = orm.relationship(
SecurityGroup,
backref=orm.backref('source_rules', cascade='all,delete'),
primaryjoin="SecurityGroup.id==SecurityGroupRule.remote_group_id")
class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
"""Mixin class to add security group to db_base_plugin_v2."""
@ -154,20 +83,20 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
self._ensure_default_security_group(context, tenant_id)
with db_api.autonested_transaction(context.session):
security_group_db = SecurityGroup(id=s.get('id') or (
security_group_db = sg_models.SecurityGroup(id=s.get('id') or (
uuidutils.generate_uuid()),
description=s['description'],
tenant_id=tenant_id,
name=s['name'])
context.session.add(security_group_db)
if default_sg:
context.session.add(DefaultSecurityGroup(
context.session.add(sg_models.DefaultSecurityGroup(
security_group=security_group_db,
tenant_id=security_group_db['tenant_id']))
for ethertype in ext_sg.sg_supported_ethertypes:
if default_sg:
# Allow intercommunication
ingress_rule = SecurityGroupRule(
ingress_rule = sg_models.SecurityGroupRule(
id=uuidutils.generate_uuid(), tenant_id=tenant_id,
security_group=security_group_db,
direction='ingress',
@ -175,7 +104,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
source_group=security_group_db)
context.session.add(ingress_rule)
egress_rule = SecurityGroupRule(
egress_rule = sg_models.SecurityGroupRule(
id=uuidutils.generate_uuid(), tenant_id=tenant_id,
security_group=security_group_db,
direction='egress',
@ -212,7 +141,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
marker_obj = self._get_marker_obj(context, 'security_group', limit,
marker)
return self._get_collection(context,
SecurityGroup,
sg_models.SecurityGroup,
self._make_security_group_dict,
filters=filters, fields=fields,
sorts=sorts,
@ -220,7 +149,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
page_reverse=page_reverse)
def get_security_groups_count(self, context, filters=None):
return self._get_collection_count(context, SecurityGroup,
return self._get_collection_count(context, sg_models.SecurityGroup,
filters=filters)
def get_security_group(self, context, id, fields=None, tenant_id=None):
@ -245,8 +174,8 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
def _get_security_group(self, context, id):
try:
query = self._model_query(context, SecurityGroup)
sg = query.filter(SecurityGroup.id == id).one()
query = self._model_query(context, sg_models.SecurityGroup)
sg = query.filter(sg_models.SecurityGroup.id == id).one()
except exc.NoResultFound:
raise ext_sg.SecurityGroupNotFound(id=id)
@ -328,21 +257,21 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
def _create_port_security_group_binding(self, context, port_id,
security_group_id):
with context.session.begin(subtransactions=True):
db = SecurityGroupPortBinding(port_id=port_id,
db = sg_models.SecurityGroupPortBinding(port_id=port_id,
security_group_id=security_group_id)
context.session.add(db)
def _get_port_security_group_bindings(self, context,
filters=None, fields=None):
return self._get_collection(context,
SecurityGroupPortBinding,
sg_models.SecurityGroupPortBinding,
self._make_security_group_binding_dict,
filters=filters, fields=fields)
def _delete_port_security_group_bindings(self, context, port_id):
query = self._model_query(context, SecurityGroupPortBinding)
query = self._model_query(context, sg_models.SecurityGroupPortBinding)
bindings = query.filter(
SecurityGroupPortBinding.port_id == port_id)
sg_models.SecurityGroupPortBinding.port_id == port_id)
with context.session.begin(subtransactions=True):
for binding in bindings:
context.session.delete(binding)
@ -388,7 +317,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
exc_cls=ext_sg.SecurityGroupConflict, **kwargs)
with context.session.begin(subtransactions=True):
db = SecurityGroupRule(
db = sg_models.SecurityGroupRule(
id=(rule_dict.get('id') or uuidutils.generate_uuid()),
tenant_id=rule_dict['tenant_id'],
security_group_id=rule_dict['security_group_id'],
@ -631,7 +560,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
marker_obj = self._get_marker_obj(context, 'security_group_rule',
limit, marker)
return self._get_collection(context,
SecurityGroupRule,
sg_models.SecurityGroupRule,
self._make_security_group_rule_dict,
filters=filters, fields=fields,
sorts=sorts,
@ -639,7 +568,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
page_reverse=page_reverse)
def get_security_group_rules_count(self, context, filters=None):
return self._get_collection_count(context, SecurityGroupRule,
return self._get_collection_count(context, sg_models.SecurityGroupRule,
filters=filters)
def get_security_group_rule(self, context, id, fields=None):
@ -648,8 +577,8 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
def _get_security_group_rule(self, context, id):
try:
query = self._model_query(context, SecurityGroupRule)
sgr = query.filter(SecurityGroupRule.id == id).one()
query = self._model_query(context, sg_models.SecurityGroupRule)
sgr = query.filter(sg_models.SecurityGroupRule.id == id).one()
except exc.NoResultFound:
raise ext_sg.SecurityGroupRuleNotFound(id=id)
return sgr
@ -664,8 +593,9 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
exc_cls=ext_sg.SecurityGroupRuleInUse, **kwargs)
with context.session.begin(subtransactions=True):
query = self._model_query(context, SecurityGroupRule).filter(
SecurityGroupRule.id == id)
query = self._model_query(context,
sg_models.SecurityGroupRule).filter(
sg_models.SecurityGroupRule.id == id)
self._registry_notify(resources.SECURITY_GROUP_RULE,
events.PRECOMMIT_DELETE,
@ -713,7 +643,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
:returns: the default security group id for given tenant.
"""
try:
query = self._model_query(context, DefaultSecurityGroup)
query = self._model_query(context, sg_models.DefaultSecurityGroup)
default_group = query.filter_by(tenant_id=tenant_id).one()
return default_group['security_group_id']
except exc.NoResultFound:
@ -811,3 +741,9 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
updated_port[ext_sg.SECURITYGROUPS] = (
original_port[ext_sg.SECURITYGROUPS])
return need_notify
# WARNING: THESE MUST BE THE LAST TWO LINES IN THIS MODULE
_OLD_REF = sys.modules[__name__]
sys.modules[__name__] = _deprecate._DeprecateSubset(globals(), sg_models)
# WARNING: THESE MUST BE THE LAST TWO LINES IN THIS MODULE

View File

@ -22,6 +22,7 @@ from neutron._i18n import _, _LW
from neutron.common import ipv6_utils as ipv6
from neutron.common import utils
from neutron.db.allowed_address_pairs import models as addr_pair
from neutron.db.models import securitygroup as sg_models
from neutron.db import models_v2
from neutron.db import securitygroups_db as sg_db
from neutron.extensions import securitygroup as ext_sg
@ -234,8 +235,8 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
def _select_sg_ids_for_ports(self, context, ports):
if not ports:
return []
sg_binding_port = sg_db.SecurityGroupPortBinding.port_id
sg_binding_sgid = sg_db.SecurityGroupPortBinding.security_group_id
sg_binding_port = sg_models.SecurityGroupPortBinding.port_id
sg_binding_sgid = sg_models.SecurityGroupPortBinding.security_group_id
query = context.session.query(sg_binding_sgid)
query = query.filter(sg_binding_port.in_(ports.keys()))
return query.all()
@ -243,14 +244,14 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
def _select_rules_for_ports(self, context, ports):
if not ports:
return []
sg_binding_port = sg_db.SecurityGroupPortBinding.port_id
sg_binding_sgid = sg_db.SecurityGroupPortBinding.security_group_id
sg_binding_port = sg_models.SecurityGroupPortBinding.port_id
sg_binding_sgid = sg_models.SecurityGroupPortBinding.security_group_id
sgr_sgid = sg_db.SecurityGroupRule.security_group_id
sgr_sgid = sg_models.SecurityGroupRule.security_group_id
query = context.session.query(sg_binding_port,
sg_db.SecurityGroupRule)
query = query.join(sg_db.SecurityGroupRule,
sg_models.SecurityGroupRule)
query = query.join(sg_models.SecurityGroupRule,
sgr_sgid == sg_binding_sgid)
query = query.filter(sg_binding_port.in_(ports.keys()))
return query.all()
@ -263,8 +264,8 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
ips_by_group[remote_group_id] = set()
ip_port = models_v2.IPAllocation.port_id
sg_binding_port = sg_db.SecurityGroupPortBinding.port_id
sg_binding_sgid = sg_db.SecurityGroupPortBinding.security_group_id
sg_binding_port = sg_models.SecurityGroupPortBinding.port_id
sg_binding_sgid = sg_models.SecurityGroupPortBinding.security_group_id
# Join the security group binding table directly to the IP allocation
# table instead of via the Port table skip an unnecessary intermediary

View File

@ -23,8 +23,8 @@ from sqlalchemy import or_
from sqlalchemy.orm import exc
from neutron._i18n import _LE
from neutron.db.models import securitygroup as sg_models
from neutron.db import models_v2
from neutron.db import securitygroups_db as sg_db
from neutron.db import segments_db
from neutron.extensions import portbindings
from neutron import manager
@ -209,7 +209,7 @@ def get_ports_and_sgs(context, port_ids):
def get_sg_ids_grouped_by_port(context, port_ids):
sg_ids_grouped_by_port = {}
sg_binding_port = sg_db.SecurityGroupPortBinding.port_id
sg_binding_port = sg_models.SecurityGroupPortBinding.port_id
with context.session.begin(subtransactions=True):
# partial UUIDs must be individually matched with startswith.
@ -223,8 +223,9 @@ def get_sg_ids_grouped_by_port(context, port_ids):
or_criteria.append(models_v2.Port.id.in_(full_uuids))
query = context.session.query(
models_v2.Port, sg_db.SecurityGroupPortBinding.security_group_id)
query = query.outerjoin(sg_db.SecurityGroupPortBinding,
models_v2.Port,
sg_models.SecurityGroupPortBinding.security_group_id)
query = query.outerjoin(sg_models.SecurityGroupPortBinding,
models_v2.Port.id == sg_binding_port)
query = query.filter(or_(*or_criteria))

View File

@ -56,10 +56,10 @@ from neutron.db import db_base_plugin_v2
from neutron.db import dvr_mac_db
from neutron.db import external_net_db
from neutron.db import extradhcpopt_db
from neutron.db.models import securitygroup as sg_models
from neutron.db import models_v2
from neutron.db import provisioning_blocks
from neutron.db.quota import driver # noqa
from neutron.db import securitygroups_db
from neutron.db import securitygroups_rpc_base as sg_db_rpc
from neutron.db import segments_db
from neutron.db import vlantransparent_db
@ -148,8 +148,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
port=models_v2.Port,
subnet=models_v2.Subnet,
subnetpool=models_v2.SubnetPool,
security_group=securitygroups_db.SecurityGroup,
security_group_rule=securitygroups_db.SecurityGroupRule)
security_group=sg_models.SecurityGroup,
security_group_rule=sg_models.SecurityGroupRule)
def __init__(self):
# First load drivers, then initialize DB, then initialize drivers
self.type_manager = managers.TypeManager()

View File

@ -50,8 +50,8 @@ from neutron.db import api as db_api
from neutron.db import db_base_plugin_common
from neutron.db import ipam_backend_mixin
from neutron.db import l3_db
from neutron.db.models import securitygroup as sg_models
from neutron.db import models_v2
from neutron.db import securitygroups_db as sgdb
from neutron import manager
from neutron.tests import base
from neutron.tests import tools
@ -6027,11 +6027,12 @@ class DbModelMixin(object):
def _make_security_group_and_rule(self, ctx):
with ctx.session.begin():
sg = sgdb.SecurityGroup(name='sg', description='sg')
rule = sgdb.SecurityGroupRule(security_group=sg, port_range_min=1,
port_range_max=2, protocol='TCP',
ethertype='v4', direction='ingress',
remote_ip_prefix='0.0.0.0/0')
sg = sg_models.SecurityGroup(name='sg', description='sg')
rule = sg_models.SecurityGroupRule(
security_group=sg, port_range_min=1,
port_range_max=2, protocol='TCP',
ethertype='v4', direction='ingress',
remote_ip_prefix='0.0.0.0/0')
ctx.session.add(sg)
ctx.session.add(rule)
return sg, rule
@ -6110,9 +6111,9 @@ class DbModelMixin(object):
ctx = context.get_admin_context()
sg, rule = self._make_security_group_and_rule(ctx)
self._test_staledata_error_on_concurrent_object_update(
sgdb.SecurityGroup, sg['id'])
sg_models.SecurityGroup, sg['id'])
self._test_staledata_error_on_concurrent_object_update(
sgdb.SecurityGroupRule, rule['id'])
sg_models.SecurityGroupRule, rule['id'])
def _test_staledata_error_on_concurrent_object_update(self, model, dbid):
"""Test revision compare and swap update breaking on concurrent update.