From 2f85ddf2e8b2e5d14554f5dc210254fdeb87598e Mon Sep 17 00:00:00 2001 From: Paul Michali Date: Mon, 24 Aug 2015 13:02:14 +0000 Subject: [PATCH] VPNaaS: Splitting out models from database class SInce additional models are going to be added to VPNaaS for the endpoint groups and multiple local subnets feature, this is an opportune time to split out the models into a new module. Change-Id: Ia729bd0c6967fa2b8c698495aa360f340b42d98a Related-Bug: 1459423 --- neutron_vpnaas/db/vpn/vpn_db.py | 287 +++++------------- neutron_vpnaas/db/vpn/vpn_models.py | 143 +++++++++ .../vpn/service_drivers/cisco_csr_db.py | 21 +- .../vpn/service_drivers/cisco_ipsec.py | 14 +- .../tests/unit/db/vpn/test_vpn_db.py | 5 +- 5 files changed, 243 insertions(+), 227 deletions(-) create mode 100644 neutron_vpnaas/db/vpn/vpn_models.py diff --git a/neutron_vpnaas/db/vpn/vpn_db.py b/neutron_vpnaas/db/vpn/vpn_db.py index 6591b1cdb..3c97368df 100644 --- a/neutron_vpnaas/db/vpn/vpn_db.py +++ b/neutron_vpnaas/db/vpn/vpn_db.py @@ -21,9 +21,6 @@ from neutron.callbacks import resources from neutron.common import constants as n_constants from neutron.db import common_db_mixin as base_db from neutron.db import l3_agentschedulers_db as l3_agent_db -from neutron.db import l3_db -from neutron.db import model_base -from neutron.db import models_v2 from neutron.extensions import l3 as l3_exception from neutron.i18n import _LW from neutron import manager @@ -32,138 +29,15 @@ from neutron.plugins.common import utils from oslo_log import log as logging from oslo_utils import excutils from oslo_utils import uuidutils -import sqlalchemy as sa -from sqlalchemy import orm from sqlalchemy.orm import exc +from neutron_vpnaas.db.vpn import vpn_models from neutron_vpnaas.db.vpn import vpn_validator from neutron_vpnaas.extensions import vpnaas LOG = logging.getLogger(__name__) -class IPsecPeerCidr(model_base.BASEV2): - """Internal representation of a IPsec Peer Cidrs.""" - - cidr = sa.Column(sa.String(32), nullable=False, primary_key=True) - ipsec_site_connection_id = sa.Column( - sa.String(36), - sa.ForeignKey('ipsec_site_connections.id', - ondelete="CASCADE"), - primary_key=True) - - -class IPsecPolicy(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant): - """Represents a v2 IPsecPolicy Object.""" - __tablename__ = 'ipsecpolicies' - name = sa.Column(sa.String(255)) - description = sa.Column(sa.String(255)) - transform_protocol = sa.Column(sa.Enum("esp", "ah", "ah-esp", - name="ipsec_transform_protocols"), - nullable=False) - auth_algorithm = sa.Column(sa.Enum("sha1", - name="vpn_auth_algorithms"), - nullable=False) - encryption_algorithm = sa.Column(sa.Enum("3des", "aes-128", - "aes-256", "aes-192", - name="vpn_encrypt_algorithms"), - nullable=False) - encapsulation_mode = sa.Column(sa.Enum("tunnel", "transport", - name="ipsec_encapsulations"), - nullable=False) - lifetime_units = sa.Column(sa.Enum("seconds", "kilobytes", - name="vpn_lifetime_units"), - nullable=False) - lifetime_value = sa.Column(sa.Integer, nullable=False) - pfs = sa.Column(sa.Enum("group2", "group5", "group14", - name="vpn_pfs"), nullable=False) - - -class IKEPolicy(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant): - """Represents a v2 IKEPolicy Object.""" - __tablename__ = 'ikepolicies' - name = sa.Column(sa.String(255)) - description = sa.Column(sa.String(255)) - auth_algorithm = sa.Column(sa.Enum("sha1", - name="vpn_auth_algorithms"), - nullable=False) - encryption_algorithm = sa.Column(sa.Enum("3des", "aes-128", - "aes-256", "aes-192", - name="vpn_encrypt_algorithms"), - nullable=False) - phase1_negotiation_mode = sa.Column(sa.Enum("main", - name="ike_phase1_mode"), - nullable=False) - lifetime_units = sa.Column(sa.Enum("seconds", "kilobytes", - name="vpn_lifetime_units"), - nullable=False) - lifetime_value = sa.Column(sa.Integer, nullable=False) - ike_version = sa.Column(sa.Enum("v1", "v2", name="ike_versions"), - nullable=False) - pfs = sa.Column(sa.Enum("group2", "group5", "group14", - name="vpn_pfs"), nullable=False) - - -class IPsecSiteConnection(model_base.BASEV2, - models_v2.HasId, models_v2.HasTenant): - """Represents a IPsecSiteConnection Object.""" - __tablename__ = 'ipsec_site_connections' - name = sa.Column(sa.String(255)) - description = sa.Column(sa.String(255)) - peer_address = sa.Column(sa.String(255), nullable=False) - peer_id = sa.Column(sa.String(255), nullable=False) - route_mode = sa.Column(sa.String(8), nullable=False) - mtu = sa.Column(sa.Integer, nullable=False) - initiator = sa.Column(sa.Enum("bi-directional", "response-only", - name="vpn_initiators"), nullable=False) - auth_mode = sa.Column(sa.String(16), nullable=False) - psk = sa.Column(sa.String(255), nullable=False) - dpd_action = sa.Column(sa.Enum("hold", "clear", - "restart", "disabled", - "restart-by-peer", name="vpn_dpd_actions"), - nullable=False) - dpd_interval = sa.Column(sa.Integer, nullable=False) - dpd_timeout = sa.Column(sa.Integer, nullable=False) - status = sa.Column(sa.String(16), nullable=False) - admin_state_up = sa.Column(sa.Boolean(), nullable=False) - vpnservice_id = sa.Column(sa.String(36), - sa.ForeignKey('vpnservices.id'), - nullable=False) - ipsecpolicy_id = sa.Column(sa.String(36), - sa.ForeignKey('ipsecpolicies.id'), - nullable=False) - ikepolicy_id = sa.Column(sa.String(36), - sa.ForeignKey('ikepolicies.id'), - nullable=False) - ipsecpolicy = orm.relationship( - IPsecPolicy, backref='ipsec_site_connection') - ikepolicy = orm.relationship(IKEPolicy, backref='ipsec_site_connection') - peer_cidrs = orm.relationship(IPsecPeerCidr, - backref='ipsec_site_connection', - lazy='joined', - cascade='all, delete, delete-orphan') - - -class VPNService(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant): - """Represents a v2 VPNService Object.""" - name = sa.Column(sa.String(255)) - description = sa.Column(sa.String(255)) - status = sa.Column(sa.String(16), nullable=False) - admin_state_up = sa.Column(sa.Boolean(), nullable=False) - external_v4_ip = sa.Column(sa.String(16)) - external_v6_ip = sa.Column(sa.String(64)) - subnet_id = sa.Column(sa.String(36), sa.ForeignKey('subnets.id'), - nullable=False) - router_id = sa.Column(sa.String(36), sa.ForeignKey('routers.id'), - nullable=False) - subnet = orm.relationship(models_v2.Subnet) - router = orm.relationship(l3_db.Router) - ipsec_site_connections = orm.relationship( - IPsecSiteConnection, - backref='vpnservice', - cascade="all, delete-orphan") - - class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): """VPN plugin database class using SQLAlchemy models.""" @@ -188,15 +62,15 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): r = self._get_by_id(context, model, v_id) except exc.NoResultFound: with excutils.save_and_reraise_exception(reraise=False) as ctx: - if issubclass(model, IPsecSiteConnection): + if issubclass(model, vpn_models.IPsecSiteConnection): raise vpnaas.IPsecSiteConnectionNotFound( ipsec_site_conn_id=v_id ) - elif issubclass(model, IKEPolicy): + elif issubclass(model, vpn_models.IKEPolicy): raise vpnaas.IKEPolicyNotFound(ikepolicy_id=v_id) - elif issubclass(model, IPsecPolicy): + elif issubclass(model, vpn_models.IPsecPolicy): raise vpnaas.IPsecPolicyNotFound(ipsecpolicy_id=v_id) - elif issubclass(model, VPNService): + elif issubclass(model, vpn_models.VPNService): raise vpnaas.VPNServiceNotFound(vpnservice_id=v_id) ctx.reraise = True return r @@ -249,14 +123,11 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): tenant_id = self._get_tenant_id_for_create(context, ipsec_sitecon) with context.session.begin(subtransactions=True): #Check permissions - self._get_resource(context, - VPNService, + self._get_resource(context, vpn_models.VPNService, ipsec_sitecon['vpnservice_id']) - self._get_resource(context, - IKEPolicy, + self._get_resource(context, vpn_models.IKEPolicy, ipsec_sitecon['ikepolicy_id']) - self._get_resource(context, - IPsecPolicy, + self._get_resource(context, vpn_models.IPsecPolicy, ipsec_sitecon['ipsecpolicy_id']) vpnservice_id = ipsec_sitecon['vpnservice_id'] ip_version = self._get_subnet_ip_version(context, vpnservice_id) @@ -265,7 +136,7 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): ip_version) vpnservice = self._get_vpnservice(context, vpnservice_id) validator.resolve_peer_address(ipsec_sitecon, vpnservice.router) - ipsec_site_conn_db = IPsecSiteConnection( + ipsec_site_conn_db = vpn_models.IPsecSiteConnection( id=uuidutils.generate_uuid(), tenant_id=tenant_id, name=ipsec_sitecon['name'], @@ -288,7 +159,7 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): ) context.session.add(ipsec_site_conn_db) for cidr in ipsec_sitecon['peer_cidrs']: - peer_cidr_db = IPsecPeerCidr( + peer_cidr_db = vpn_models.IPsecPeerCidr( cidr=cidr, ipsec_site_connection_id=ipsec_site_conn_db['id'] ) @@ -303,9 +174,7 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): validator = self._get_validator() with context.session.begin(subtransactions=True): ipsec_site_conn_db = self._get_resource( - context, - IPsecSiteConnection, - ipsec_site_conn_id) + context, vpn_models.IPsecSiteConnection, ipsec_site_conn_id) vpnservice_id = ipsec_site_conn_db['vpnservice_id'] ip_version = self._get_subnet_ip_version(context, vpnservice_id) validator.assign_sensible_ipsec_sitecon_defaults( @@ -333,7 +202,7 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): for peer_cidr in old_peer_cidr_set - new_peer_cidr_set: context.session.delete(old_peer_cidr_dict[peer_cidr]) for peer_cidr in new_peer_cidr_set - old_peer_cidr_set: - pcidr = IPsecPeerCidr( + pcidr = vpn_models.IPsecPeerCidr( cidr=peer_cidr, ipsec_site_connection_id=ipsec_site_conn_id) context.session.add(pcidr) @@ -348,14 +217,13 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): def delete_ipsec_site_connection(self, context, ipsec_site_conn_id): with context.session.begin(subtransactions=True): ipsec_site_conn_db = self._get_resource( - context, IPsecSiteConnection, ipsec_site_conn_id - ) + context, vpn_models.IPsecSiteConnection, ipsec_site_conn_id) context.session.delete(ipsec_site_conn_db) def _get_ipsec_site_connection( self, context, ipsec_site_conn_id): return self._get_resource( - context, IPsecSiteConnection, ipsec_site_conn_id) + context, vpn_models.IPsecSiteConnection, ipsec_site_conn_id) def get_ipsec_site_connection(self, context, ipsec_site_conn_id, fields=None): @@ -365,7 +233,7 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): ipsec_site_conn_db, fields) def get_ipsec_site_connections(self, context, filters=None, fields=None): - return self._get_collection(context, IPsecSiteConnection, + return self._get_collection(context, vpn_models.IPsecSiteConnection, self._make_ipsec_site_connection_dict, filters=filters, fields=fields) @@ -414,7 +282,7 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): lifetime_value = lifetime_info.get('value', 3600) with context.session.begin(subtransactions=True): - ike_db = IKEPolicy( + ike_db = vpn_models.IKEPolicy( id=uuidutils.generate_uuid(), tenant_id=tenant_id, name=ike['name'], @@ -434,11 +302,11 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): def update_ikepolicy(self, context, ikepolicy_id, ikepolicy): ike = ikepolicy['ikepolicy'] with context.session.begin(subtransactions=True): - ikepolicy = context.session.query(IPsecSiteConnection).filter_by( - ikepolicy_id=ikepolicy_id).first() - if ikepolicy: + if context.session.query(vpn_models.IPsecSiteConnection).filter_by( + ikepolicy_id=ikepolicy_id).first(): raise vpnaas.IKEPolicyInUse(ikepolicy_id=ikepolicy_id) - ike_db = self._get_resource(context, IKEPolicy, ikepolicy_id) + ike_db = self._get_resource( + context, vpn_models.IKEPolicy, ikepolicy_id) if ike: lifetime_info = ike.get('lifetime') if lifetime_info: @@ -451,19 +319,20 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): def delete_ikepolicy(self, context, ikepolicy_id): with context.session.begin(subtransactions=True): - ikepolicy = context.session.query(IPsecSiteConnection).filter_by( - ikepolicy_id=ikepolicy_id).first() - if ikepolicy: + if context.session.query(vpn_models.IPsecSiteConnection).filter_by( + ikepolicy_id=ikepolicy_id).first(): raise vpnaas.IKEPolicyInUse(ikepolicy_id=ikepolicy_id) - ike_db = self._get_resource(context, IKEPolicy, ikepolicy_id) + ike_db = self._get_resource( + context, vpn_models.IKEPolicy, ikepolicy_id) context.session.delete(ike_db) def get_ikepolicy(self, context, ikepolicy_id, fields=None): - ike_db = self._get_resource(context, IKEPolicy, ikepolicy_id) + ike_db = self._get_resource( + context, vpn_models.IKEPolicy, ikepolicy_id) return self._make_ikepolicy_dict(ike_db, fields) def get_ikepolicies(self, context, filters=None, fields=None): - return self._get_collection(context, IKEPolicy, + return self._get_collection(context, vpn_models.IKEPolicy, self._make_ikepolicy_dict, filters=filters, fields=fields) @@ -494,33 +363,29 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): lifetime_value = lifetime_info.get('value', 3600) with context.session.begin(subtransactions=True): - ipsecp_db = IPsecPolicy(id=uuidutils.generate_uuid(), - tenant_id=tenant_id, - name=ipsecp['name'], - description=ipsecp['description'], - transform_protocol=ipsecp['transform_' - 'protocol'], - auth_algorithm=ipsecp['auth_algorithm'], - encryption_algorithm=ipsecp['encryption_' - 'algorithm'], - encapsulation_mode=ipsecp['encapsulation_' - 'mode'], - lifetime_units=lifetime_units, - lifetime_value=lifetime_value, - pfs=ipsecp['pfs']) + ipsecp_db = vpn_models.IPsecPolicy( + id=uuidutils.generate_uuid(), + tenant_id=tenant_id, + name=ipsecp['name'], + description=ipsecp['description'], + transform_protocol=ipsecp['transform_protocol'], + auth_algorithm=ipsecp['auth_algorithm'], + encryption_algorithm=ipsecp['encryption_algorithm'], + encapsulation_mode=ipsecp['encapsulation_mode'], + lifetime_units=lifetime_units, + lifetime_value=lifetime_value, + pfs=ipsecp['pfs']) context.session.add(ipsecp_db) return self._make_ipsecpolicy_dict(ipsecp_db) def update_ipsecpolicy(self, context, ipsecpolicy_id, ipsecpolicy): ipsecp = ipsecpolicy['ipsecpolicy'] with context.session.begin(subtransactions=True): - ipsecpolicy = context.session.query(IPsecSiteConnection).filter_by( - ipsecpolicy_id=ipsecpolicy_id).first() - if ipsecpolicy: + if context.session.query(vpn_models.IPsecSiteConnection).filter_by( + ipsecpolicy_id=ipsecpolicy_id).first(): raise vpnaas.IPsecPolicyInUse(ipsecpolicy_id=ipsecpolicy_id) - ipsecp_db = self._get_resource(context, - IPsecPolicy, - ipsecpolicy_id) + ipsecp_db = self._get_resource( + context, vpn_models.IPsecPolicy, ipsecpolicy_id) if ipsecp: lifetime_info = ipsecp.get('lifetime') if lifetime_info: @@ -533,19 +398,20 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): def delete_ipsecpolicy(self, context, ipsecpolicy_id): with context.session.begin(subtransactions=True): - ipsecpolicy = context.session.query(IPsecSiteConnection).filter_by( - ipsecpolicy_id=ipsecpolicy_id).first() - if ipsecpolicy: + if context.session.query(vpn_models.IPsecSiteConnection).filter_by( + ipsecpolicy_id=ipsecpolicy_id).first(): raise vpnaas.IPsecPolicyInUse(ipsecpolicy_id=ipsecpolicy_id) - ipsec_db = self._get_resource(context, IPsecPolicy, ipsecpolicy_id) + ipsec_db = self._get_resource( + context, vpn_models.IPsecPolicy, ipsecpolicy_id) context.session.delete(ipsec_db) def get_ipsecpolicy(self, context, ipsecpolicy_id, fields=None): - ipsec_db = self._get_resource(context, IPsecPolicy, ipsecpolicy_id) + ipsec_db = self._get_resource( + context, vpn_models.IPsecPolicy, ipsecpolicy_id) return self._make_ipsecpolicy_dict(ipsec_db, fields) def get_ipsecpolicies(self, context, filters=None, fields=None): - return self._get_collection(context, IPsecPolicy, + return self._get_collection(context, vpn_models.IPsecPolicy, self._make_ipsecpolicy_dict, filters=filters, fields=fields) @@ -568,14 +434,15 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): validator = self._get_validator() with context.session.begin(subtransactions=True): validator.validate_vpnservice(context, vpns) - vpnservice_db = VPNService(id=uuidutils.generate_uuid(), - tenant_id=tenant_id, - name=vpns['name'], - description=vpns['description'], - subnet_id=vpns['subnet_id'], - router_id=vpns['router_id'], - admin_state_up=vpns['admin_state_up'], - status=constants.PENDING_CREATE) + vpnservice_db = vpn_models.VPNService( + id=uuidutils.generate_uuid(), + tenant_id=tenant_id, + name=vpns['name'], + description=vpns['description'], + subnet_id=vpns['subnet_id'], + router_id=vpns['router_id'], + admin_state_up=vpns['admin_state_up'], + status=constants.PENDING_CREATE) context.session.add(vpnservice_db) return self._make_vpnservice_dict(vpnservice_db) @@ -584,14 +451,16 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): """Update the external tunnel IP(s) for service.""" vpns = {'external_v4_ip': v4_ip, 'external_v6_ip': v6_ip} with context.session.begin(subtransactions=True): - vpns_db = self._get_resource(context, VPNService, vpnservice_id) + vpns_db = self._get_resource(context, vpn_models.VPNService, + vpnservice_id) vpns_db.update(vpns) return self._make_vpnservice_dict(vpns_db) def update_vpnservice(self, context, vpnservice_id, vpnservice): vpns = vpnservice['vpnservice'] with context.session.begin(subtransactions=True): - vpns_db = self._get_resource(context, VPNService, vpnservice_id) + vpns_db = self._get_resource(context, vpn_models.VPNService, + vpnservice_id) self.assert_update_allowed(vpns_db) if vpns: vpns_db.update(vpns) @@ -599,22 +468,25 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): def delete_vpnservice(self, context, vpnservice_id): with context.session.begin(subtransactions=True): - if context.session.query(IPsecSiteConnection).filter_by( + if context.session.query(vpn_models.IPsecSiteConnection).filter_by( vpnservice_id=vpnservice_id ).first(): raise vpnaas.VPNServiceInUse(vpnservice_id=vpnservice_id) - vpns_db = self._get_resource(context, VPNService, vpnservice_id) + vpns_db = self._get_resource(context, vpn_models.VPNService, + vpnservice_id) context.session.delete(vpns_db) def _get_vpnservice(self, context, vpnservice_id): - return self._get_resource(context, VPNService, vpnservice_id) + return self._get_resource(context, vpn_models.VPNService, + vpnservice_id) def get_vpnservice(self, context, vpnservice_id, fields=None): - vpns_db = self._get_resource(context, VPNService, vpnservice_id) + vpns_db = self._get_resource(context, vpn_models.VPNService, + vpnservice_id) return self._make_vpnservice_dict(vpns_db, fields) def get_vpnservices(self, context, filters=None, fields=None): - return self._get_collection(context, VPNService, + return self._get_collection(context, vpn_models.VPNService, self._make_vpnservice_dict, filters=filters, fields=fields) @@ -632,9 +504,8 @@ class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin): def check_subnet_in_use(self, context, subnet_id): with context.session.begin(subtransactions=True): - vpnservices = context.session.query(VPNService).filter_by( - subnet_id=subnet_id - ).first() + vpnservices = context.session.query( + vpn_models.VPNService).filter_by(subnet_id=subnet_id).first() if vpnservices: raise vpnaas.SubnetInUseByVPNService( subnet_id=subnet_id, @@ -655,14 +526,14 @@ class VPNPluginRpcDbMixin(object): agent_mode = agent_conf.get('agent_mode', 'legacy') if not agent.admin_state_up or agent_mode == 'dvr': return [] - query = context.session.query(VPNService) - query = query.join(IPsecSiteConnection) - query = query.join(IKEPolicy) - query = query.join(IPsecPolicy) - query = query.join(IPsecPeerCidr) + query = context.session.query(vpn_models.VPNService) + query = query.join(vpn_models.IPsecSiteConnection) + query = query.join(vpn_models.IKEPolicy) + query = query.join(vpn_models.IPsecPolicy) + query = query.join(vpn_models.IPsecPeerCidr) query = query.join(l3_agent_db.RouterL3AgentBinding, l3_agent_db.RouterL3AgentBinding.router_id == - VPNService.router_id) + vpn_models.VPNService.router_id) query = query.filter( l3_agent_db.RouterL3AgentBinding.l3_agent_id == agent.id) return query diff --git a/neutron_vpnaas/db/vpn/vpn_models.py b/neutron_vpnaas/db/vpn/vpn_models.py new file mode 100644 index 000000000..27fe7ab54 --- /dev/null +++ b/neutron_vpnaas/db/vpn/vpn_models.py @@ -0,0 +1,143 @@ +# (c) Copyright 2013 Hewlett-Packard Development Company, L.P. +# 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.db import l3_db +from neutron.db import model_base +from neutron.db import models_v2 + +import sqlalchemy as sa +from sqlalchemy import orm + + +class IPsecPeerCidr(model_base.BASEV2): + """Internal representation of a IPsec Peer Cidrs.""" + + cidr = sa.Column(sa.String(32), nullable=False, primary_key=True) + ipsec_site_connection_id = sa.Column( + sa.String(36), + sa.ForeignKey('ipsec_site_connections.id', + ondelete="CASCADE"), + primary_key=True) + + +class IPsecPolicy(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant): + """Represents a v2 IPsecPolicy Object.""" + __tablename__ = 'ipsecpolicies' + name = sa.Column(sa.String(255)) + description = sa.Column(sa.String(255)) + transform_protocol = sa.Column(sa.Enum("esp", "ah", "ah-esp", + name="ipsec_transform_protocols"), + nullable=False) + auth_algorithm = sa.Column(sa.Enum("sha1", + name="vpn_auth_algorithms"), + nullable=False) + encryption_algorithm = sa.Column(sa.Enum("3des", "aes-128", + "aes-256", "aes-192", + name="vpn_encrypt_algorithms"), + nullable=False) + encapsulation_mode = sa.Column(sa.Enum("tunnel", "transport", + name="ipsec_encapsulations"), + nullable=False) + lifetime_units = sa.Column(sa.Enum("seconds", "kilobytes", + name="vpn_lifetime_units"), + nullable=False) + lifetime_value = sa.Column(sa.Integer, nullable=False) + pfs = sa.Column(sa.Enum("group2", "group5", "group14", + name="vpn_pfs"), nullable=False) + + +class IKEPolicy(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant): + """Represents a v2 IKEPolicy Object.""" + __tablename__ = 'ikepolicies' + name = sa.Column(sa.String(255)) + description = sa.Column(sa.String(255)) + auth_algorithm = sa.Column(sa.Enum("sha1", + name="vpn_auth_algorithms"), + nullable=False) + encryption_algorithm = sa.Column(sa.Enum("3des", "aes-128", + "aes-256", "aes-192", + name="vpn_encrypt_algorithms"), + nullable=False) + phase1_negotiation_mode = sa.Column(sa.Enum("main", + name="ike_phase1_mode"), + nullable=False) + lifetime_units = sa.Column(sa.Enum("seconds", "kilobytes", + name="vpn_lifetime_units"), + nullable=False) + lifetime_value = sa.Column(sa.Integer, nullable=False) + ike_version = sa.Column(sa.Enum("v1", "v2", name="ike_versions"), + nullable=False) + pfs = sa.Column(sa.Enum("group2", "group5", "group14", + name="vpn_pfs"), nullable=False) + + +class IPsecSiteConnection(model_base.BASEV2, + models_v2.HasId, models_v2.HasTenant): + """Represents a IPsecSiteConnection Object.""" + __tablename__ = 'ipsec_site_connections' + name = sa.Column(sa.String(255)) + description = sa.Column(sa.String(255)) + peer_address = sa.Column(sa.String(255), nullable=False) + peer_id = sa.Column(sa.String(255), nullable=False) + route_mode = sa.Column(sa.String(8), nullable=False) + mtu = sa.Column(sa.Integer, nullable=False) + initiator = sa.Column(sa.Enum("bi-directional", "response-only", + name="vpn_initiators"), nullable=False) + auth_mode = sa.Column(sa.String(16), nullable=False) + psk = sa.Column(sa.String(255), nullable=False) + dpd_action = sa.Column(sa.Enum("hold", "clear", + "restart", "disabled", + "restart-by-peer", name="vpn_dpd_actions"), + nullable=False) + dpd_interval = sa.Column(sa.Integer, nullable=False) + dpd_timeout = sa.Column(sa.Integer, nullable=False) + status = sa.Column(sa.String(16), nullable=False) + admin_state_up = sa.Column(sa.Boolean(), nullable=False) + vpnservice_id = sa.Column(sa.String(36), + sa.ForeignKey('vpnservices.id'), + nullable=False) + ipsecpolicy_id = sa.Column(sa.String(36), + sa.ForeignKey('ipsecpolicies.id'), + nullable=False) + ikepolicy_id = sa.Column(sa.String(36), + sa.ForeignKey('ikepolicies.id'), + nullable=False) + ipsecpolicy = orm.relationship( + IPsecPolicy, backref='ipsec_site_connection') + ikepolicy = orm.relationship(IKEPolicy, backref='ipsec_site_connection') + peer_cidrs = orm.relationship(IPsecPeerCidr, + backref='ipsec_site_connection', + lazy='joined', + cascade='all, delete, delete-orphan') + + +class VPNService(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant): + """Represents a v2 VPNService Object.""" + name = sa.Column(sa.String(255)) + description = sa.Column(sa.String(255)) + status = sa.Column(sa.String(16), nullable=False) + admin_state_up = sa.Column(sa.Boolean(), nullable=False) + external_v4_ip = sa.Column(sa.String(16)) + external_v6_ip = sa.Column(sa.String(64)) + subnet_id = sa.Column(sa.String(36), sa.ForeignKey('subnets.id'), + nullable=False) + router_id = sa.Column(sa.String(36), sa.ForeignKey('routers.id'), + nullable=False) + subnet = orm.relationship(models_v2.Subnet) + router = orm.relationship(l3_db.Router) + ipsec_site_connections = orm.relationship( + IPsecSiteConnection, + backref='vpnservice', + cascade="all, delete-orphan") diff --git a/neutron_vpnaas/services/vpn/service_drivers/cisco_csr_db.py b/neutron_vpnaas/services/vpn/service_drivers/cisco_csr_db.py index 5e136728e..66380d2e8 100644 --- a/neutron_vpnaas/services/vpn/service_drivers/cisco_csr_db.py +++ b/neutron_vpnaas/services/vpn/service_drivers/cisco_csr_db.py @@ -21,7 +21,7 @@ from oslo_log import log as logging import sqlalchemy as sa from sqlalchemy.orm import exc as sql_exc -from neutron_vpnaas.db.vpn import vpn_db +from neutron_vpnaas.db.vpn import vpn_models LOG = logging.getLogger(__name__) @@ -105,23 +105,23 @@ def get_next_available_ipsec_policy_id(session): def find_conn_with_policy(policy_field, policy_id, conn_id, session): """Return ID of another conneciton (if any) that uses same policy ID.""" - qry = session.query(vpn_db.IPsecSiteConnection.id) + qry = session.query(vpn_models.IPsecSiteConnection.id) match = qry.filter_request( policy_field == policy_id, - vpn_db.IPsecSiteConnection.id != conn_id).first() + vpn_models.IPsecSiteConnection.id != conn_id).first() if match: return match[0] def find_connection_using_ike_policy(ike_policy_id, conn_id, session): """Return ID of another connection that uses same IKE policy ID.""" - return find_conn_with_policy(vpn_db.IPsecSiteConnection.ikepolicy_id, + return find_conn_with_policy(vpn_models.IPsecSiteConnection.ikepolicy_id, ike_policy_id, conn_id, session) def find_connection_using_ipsec_policy(ipsec_policy_id, conn_id, session): """Return ID of another connection that uses same IPSec policy ID.""" - return find_conn_with_policy(vpn_db.IPsecSiteConnection.ipsecpolicy_id, + return find_conn_with_policy(vpn_models.IPsecSiteConnection.ipsecpolicy_id, ipsec_policy_id, conn_id, session) @@ -167,17 +167,18 @@ def determine_csr_policy_id(policy_type, conn_policy_field, map_policy_field, def determine_csr_ike_policy_id(ike_policy_id, conn_id, session): """Use existing, or reserve a new IKE policy ID for Cisco CSR.""" return determine_csr_policy_id(IKE_POLICY, - vpn_db.IPsecSiteConnection.ikepolicy_id, + vpn_models.IPsecSiteConnection.ikepolicy_id, IdentifierMap.csr_ike_policy_id, ike_policy_id, conn_id, session) def determine_csr_ipsec_policy_id(ipsec_policy_id, conn_id, session): """Use existing, or reserve a new IPSec policy ID for Cisco CSR.""" - return determine_csr_policy_id(IPSEC_POLICY, - vpn_db.IPsecSiteConnection.ipsecpolicy_id, - IdentifierMap.csr_ipsec_policy_id, - ipsec_policy_id, conn_id, session) + return determine_csr_policy_id( + IPSEC_POLICY, + vpn_models.IPsecSiteConnection.ipsecpolicy_id, + IdentifierMap.csr_ipsec_policy_id, + ipsec_policy_id, conn_id, session) def get_tunnel_mapping_for(conn_id, session): diff --git a/neutron_vpnaas/services/vpn/service_drivers/cisco_ipsec.py b/neutron_vpnaas/services/vpn/service_drivers/cisco_ipsec.py index 17e0072b2..c5e336bb3 100644 --- a/neutron_vpnaas/services/vpn/service_drivers/cisco_ipsec.py +++ b/neutron_vpnaas/services/vpn/service_drivers/cisco_ipsec.py @@ -16,7 +16,7 @@ from neutron.common import rpc as n_rpc from oslo_log import log as logging import oslo_messaging -from neutron_vpnaas.db.vpn import vpn_db +from neutron_vpnaas.db.vpn import vpn_models from neutron_vpnaas.services.vpn.common import topics from neutron_vpnaas.services.vpn import service_drivers from neutron_vpnaas.services.vpn.service_drivers import base_ipsec @@ -55,12 +55,12 @@ class CiscoCsrIPsecVpnDriverCallBack(object): return n_rpc.PluginRpcDispatcher([self]) def get_vpn_services_using(self, context, router_id): - query = context.session.query(vpn_db.VPNService) - query = query.join(vpn_db.IPsecSiteConnection) - query = query.join(vpn_db.IKEPolicy) - query = query.join(vpn_db.IPsecPolicy) - query = query.join(vpn_db.IPsecPeerCidr) - query = query.filter(vpn_db.VPNService.router_id == router_id) + query = context.session.query(vpn_models.VPNService) + query = query.join(vpn_models.IPsecSiteConnection) + query = query.join(vpn_models.IKEPolicy) + query = query.join(vpn_models.IPsecPolicy) + query = query.join(vpn_models.IPsecPeerCidr) + query = query.filter(vpn_models.VPNService.router_id == router_id) return query.all() def get_vpn_services_on_host(self, context, host=None): diff --git a/neutron_vpnaas/tests/unit/db/vpn/test_vpn_db.py b/neutron_vpnaas/tests/unit/db/vpn/test_vpn_db.py index 98dde8424..dadf4dc51 100644 --- a/neutron_vpnaas/tests/unit/db/vpn/test_vpn_db.py +++ b/neutron_vpnaas/tests/unit/db/vpn/test_vpn_db.py @@ -38,6 +38,7 @@ import six import webob.exc from neutron_vpnaas.db.vpn import vpn_db +from neutron_vpnaas.db.vpn import vpn_models from neutron_vpnaas.services.vpn import plugin as vpn_plugin from neutron_vpnaas.tests import base @@ -952,7 +953,7 @@ class TestVpnaas(VPNPluginDbTestCase): keys.append(('router_id', vpnservice['vpnservice']['router_id'])) data = {'vpnservice': {'name': name}} - self._set_active(vpn_db.VPNService, + self._set_active(vpn_models.VPNService, vpnservice['vpnservice']['id']) req = self.new_update_request( 'vpnservices', @@ -1309,7 +1310,7 @@ class TestVpnaas(VPNPluginDbTestCase): data = {'ipsec_site_connection': update} if keys.get('make_active', None): self._set_active( - vpn_db.IPsecSiteConnection, + vpn_models.IPsecSiteConnection, (ipsec_site_connection['ipsec_site_connection'] ['id'])) req = self.new_update_request(