VPN as a Service (VPNaaS) API and DataModel
implements:blueprint VPNaaS-Python-API It provides the basic API and DataModel for the "VPN As A Service" feature that includes: * VPNService * IPsecSiteConnection * IKEPolicy * IPsecPolicy Change-Id: I059d4db05118a4eecd388b8e8db0d714a8f9cb8f
This commit is contained in:
parent
de0db3bd97
commit
4439ffb535
18
neutron/db/vpn/__init__.py
Normal file
18
neutron/db/vpn/__init__.py
Normal file
@ -0,0 +1,18 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# (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.
|
||||
#
|
||||
# @author: Swaminathan Vasudevan, Hewlett-Packard.
|
591
neutron/db/vpn/vpn_db.py
Normal file
591
neutron/db/vpn/vpn_db.py
Normal file
@ -0,0 +1,591 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# (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.
|
||||
#
|
||||
# @author: Swaminathan Vasudevan, Hewlett-Packard.
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import orm
|
||||
from sqlalchemy.orm import exc
|
||||
|
||||
from neutron.common import constants as q_constants
|
||||
from neutron.db import agentschedulers_db as agent_db
|
||||
from neutron.db import api as qdbapi
|
||||
from neutron.db import db_base_plugin_v2 as base_db
|
||||
from neutron.db import l3_db
|
||||
from neutron.db import model_base
|
||||
from neutron.db import models_v2
|
||||
from neutron.extensions import vpnaas
|
||||
from neutron.extensions.vpnaas import VPNPluginBase
|
||||
from neutron import manager
|
||||
from neutron.openstack.common import log as logging
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.common import constants
|
||||
|
||||
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(64), 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)
|
||||
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(VPNPluginBase, base_db.CommonDbMixin):
|
||||
"""VPN plugin database class using SQLAlchemy models."""
|
||||
|
||||
def __init__(self):
|
||||
"""Do the initialization for the vpn service plugin here."""
|
||||
qdbapi.register_models()
|
||||
|
||||
def update_status(self, context, model, v_id, status):
|
||||
with context.session.begin(subtransactions=True):
|
||||
v_db = self._get_resource(context, model, v_id)
|
||||
v_db.update({'status': status})
|
||||
|
||||
def _get_resource(self, context, model, v_id):
|
||||
try:
|
||||
r = self._get_by_id(context, model, v_id)
|
||||
except exc.NoResultFound:
|
||||
if issubclass(model, IPsecSiteConnection):
|
||||
raise vpnaas.IPsecSiteConnectionNotFound(
|
||||
ipsec_site_conn_id=v_id
|
||||
)
|
||||
elif issubclass(model, IKEPolicy):
|
||||
raise vpnaas.IKEPolicyNotFound(ikepolicy_id=v_id)
|
||||
elif issubclass(model, IPsecPolicy):
|
||||
raise vpnaas.IPsecPolicyNotFound(ipsecpolicy_id=v_id)
|
||||
elif issubclass(model, VPNService):
|
||||
raise vpnaas.VPNServiceNotFound(vpnservice_id=v_id)
|
||||
else:
|
||||
raise
|
||||
return r
|
||||
|
||||
def assert_update_allowed(self, obj):
|
||||
status = getattr(obj, 'status', None)
|
||||
if status != constants.ACTIVE:
|
||||
raise vpnaas.VPNStateInvalid(id=id, state=status)
|
||||
|
||||
def _make_ipsec_site_connection_dict(self, ipsec_site_conn, fields=None):
|
||||
|
||||
res = {'id': ipsec_site_conn['id'],
|
||||
'tenant_id': ipsec_site_conn['tenant_id'],
|
||||
'name': ipsec_site_conn['name'],
|
||||
'description': ipsec_site_conn['description'],
|
||||
'peer_address': ipsec_site_conn['peer_address'],
|
||||
'peer_id': ipsec_site_conn['peer_id'],
|
||||
'route_mode': ipsec_site_conn['route_mode'],
|
||||
'mtu': ipsec_site_conn['mtu'],
|
||||
'auth_mode': ipsec_site_conn['auth_mode'],
|
||||
'psk': ipsec_site_conn['psk'],
|
||||
'initiator': ipsec_site_conn['initiator'],
|
||||
'dpd': {
|
||||
'action': ipsec_site_conn['dpd_action'],
|
||||
'interval': ipsec_site_conn['dpd_interval'],
|
||||
'timeout': ipsec_site_conn['dpd_timeout']
|
||||
},
|
||||
'admin_state_up': ipsec_site_conn['admin_state_up'],
|
||||
'status': ipsec_site_conn['status'],
|
||||
'vpnservice_id': ipsec_site_conn['vpnservice_id'],
|
||||
'ikepolicy_id': ipsec_site_conn['ikepolicy_id'],
|
||||
'ipsecpolicy_id': ipsec_site_conn['ipsecpolicy_id'],
|
||||
'peer_cidrs': [pcidr['cidr']
|
||||
for pcidr in ipsec_site_conn['peer_cidrs']]
|
||||
}
|
||||
|
||||
return self._fields(res, fields)
|
||||
|
||||
def create_ipsec_site_connection(self, context, ipsec_site_connection):
|
||||
ipsec_sitecon = ipsec_site_connection['ipsec_site_connection']
|
||||
dpd = ipsec_sitecon['dpd']
|
||||
ipsec_sitecon['dpd_action'] = dpd.get('action', 'hold')
|
||||
ipsec_sitecon['dpd_interval'] = dpd.get('interval', 30)
|
||||
ipsec_sitecon['dpd_timeout'] = dpd.get('timeout', 120)
|
||||
tenant_id = self._get_tenant_id_for_create(context, ipsec_sitecon)
|
||||
if ipsec_sitecon['dpd_timeout'] < ipsec_sitecon['dpd_interval']:
|
||||
raise vpnaas.IPsecSiteConnectionDpdIntervalValueError(
|
||||
attribute_a='dpd_timeout')
|
||||
with context.session.begin(subtransactions=True):
|
||||
#Check permissions
|
||||
self._get_resource(context,
|
||||
VPNService,
|
||||
ipsec_sitecon['vpnservice_id'])
|
||||
self._get_resource(context,
|
||||
IKEPolicy,
|
||||
ipsec_sitecon['ikepolicy_id'])
|
||||
self._get_resource(context,
|
||||
IPsecPolicy,
|
||||
ipsec_sitecon['ipsecpolicy_id'])
|
||||
ipsec_site_conn_db = IPsecSiteConnection(
|
||||
id=uuidutils.generate_uuid(),
|
||||
tenant_id=tenant_id,
|
||||
name=ipsec_sitecon['name'],
|
||||
description=ipsec_sitecon['description'],
|
||||
peer_address=ipsec_sitecon['peer_address'],
|
||||
peer_id=ipsec_sitecon['peer_id'],
|
||||
route_mode='static',
|
||||
mtu=ipsec_sitecon['mtu'],
|
||||
auth_mode='psk',
|
||||
psk=ipsec_sitecon['psk'],
|
||||
initiator=ipsec_sitecon['initiator'],
|
||||
dpd_action=ipsec_sitecon['dpd_action'],
|
||||
dpd_interval=ipsec_sitecon['dpd_interval'],
|
||||
dpd_timeout=ipsec_sitecon['dpd_timeout'],
|
||||
admin_state_up=ipsec_sitecon['admin_state_up'],
|
||||
status=constants.PENDING_CREATE,
|
||||
vpnservice_id=ipsec_sitecon['vpnservice_id'],
|
||||
ikepolicy_id=ipsec_sitecon['ikepolicy_id'],
|
||||
ipsecpolicy_id=ipsec_sitecon['ipsecpolicy_id']
|
||||
)
|
||||
context.session.add(ipsec_site_conn_db)
|
||||
for cidr in ipsec_sitecon['peer_cidrs']:
|
||||
peer_cidr_db = IPsecPeerCidr(
|
||||
cidr=cidr,
|
||||
ipsec_site_connection_id=ipsec_site_conn_db['id']
|
||||
)
|
||||
context.session.add(peer_cidr_db)
|
||||
return self._make_ipsec_site_connection_dict(ipsec_site_conn_db)
|
||||
|
||||
def update_ipsec_site_connection(
|
||||
self, context,
|
||||
ipsec_site_conn_id, ipsec_site_connection):
|
||||
ipsec_sitecon = ipsec_site_connection['ipsec_site_connection']
|
||||
dpd = ipsec_sitecon.get('dpd', {})
|
||||
if dpd.get('action'):
|
||||
ipsec_sitecon['dpd_action'] = dpd.get('action')
|
||||
if dpd.get('interval'):
|
||||
ipsec_sitecon['dpd_interval'] = dpd.get('interval')
|
||||
if dpd.get('timeout'):
|
||||
ipsec_sitecon['dpd_timeout'] = dpd.get('timeout')
|
||||
changed_peer_cidrs = False
|
||||
with context.session.begin(subtransactions=True):
|
||||
ipsec_site_conn_db = self._get_resource(
|
||||
context,
|
||||
IPsecSiteConnection,
|
||||
ipsec_site_conn_id)
|
||||
self.assert_update_allowed(ipsec_site_conn_db)
|
||||
if "peer_cidrs" in ipsec_sitecon:
|
||||
changed_peer_cidrs = True
|
||||
old_peer_cidr_list = ipsec_site_conn_db['peer_cidrs']
|
||||
old_peer_cidr_dict = dict(
|
||||
(peer_cidr['cidr'], peer_cidr)
|
||||
for peer_cidr in old_peer_cidr_list)
|
||||
new_peer_cidr_set = set(ipsec_sitecon["peer_cidrs"])
|
||||
old_peer_cidr_set = set(old_peer_cidr_dict)
|
||||
|
||||
new_peer_cidrs = list(new_peer_cidr_set)
|
||||
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(
|
||||
cidr=peer_cidr,
|
||||
ipsec_site_connection_id=ipsec_site_conn_id)
|
||||
context.session.add(pcidr)
|
||||
del ipsec_sitecon["peer_cidrs"]
|
||||
if ipsec_sitecon:
|
||||
ipsec_site_conn_db.update(ipsec_sitecon)
|
||||
result = self._make_ipsec_site_connection_dict(ipsec_site_conn_db)
|
||||
if changed_peer_cidrs:
|
||||
result['peer_cidrs'] = new_peer_cidrs
|
||||
return result
|
||||
|
||||
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.session.delete(ipsec_site_conn_db)
|
||||
|
||||
def get_ipsec_site_connection(self, context,
|
||||
ipsec_site_conn_id, fields=None):
|
||||
ipsec_site_conn_db = self._get_resource(
|
||||
context, IPsecSiteConnection, ipsec_site_conn_id
|
||||
)
|
||||
return self._make_ipsec_site_connection_dict(
|
||||
ipsec_site_conn_db, fields)
|
||||
|
||||
def get_ipsec_site_connections(self, context, filters=None, fields=None):
|
||||
return self._get_collection(context, IPsecSiteConnection,
|
||||
self._make_ipsec_site_connection_dict,
|
||||
filters=filters, fields=fields)
|
||||
|
||||
def _make_ikepolicy_dict(self, ikepolicy, fields=None):
|
||||
res = {'id': ikepolicy['id'],
|
||||
'tenant_id': ikepolicy['tenant_id'],
|
||||
'name': ikepolicy['name'],
|
||||
'description': ikepolicy['description'],
|
||||
'auth_algorithm': ikepolicy['auth_algorithm'],
|
||||
'encryption_algorithm': ikepolicy['encryption_algorithm'],
|
||||
'phase1_negotiation_mode': ikepolicy['phase1_negotiation_mode'],
|
||||
'lifetime': {
|
||||
'units': ikepolicy['lifetime_units'],
|
||||
'value': ikepolicy['lifetime_value'],
|
||||
},
|
||||
'ike_version': ikepolicy['ike_version'],
|
||||
'pfs': ikepolicy['pfs']
|
||||
}
|
||||
|
||||
return self._fields(res, fields)
|
||||
|
||||
def create_ikepolicy(self, context, ikepolicy):
|
||||
ike = ikepolicy['ikepolicy']
|
||||
tenant_id = self._get_tenant_id_for_create(context, ike)
|
||||
lifetime_info = ike.get('lifetime', [])
|
||||
lifetime_units = lifetime_info.get('unit', 'seconds')
|
||||
lifetime_value = lifetime_info.get('value', 3600)
|
||||
|
||||
with context.session.begin(subtransactions=True):
|
||||
ike_db = IKEPolicy(
|
||||
id=uuidutils.generate_uuid(),
|
||||
tenant_id=tenant_id,
|
||||
name=ike['name'],
|
||||
description=ike['description'],
|
||||
auth_algorithm=ike['auth_algorithm'],
|
||||
encryption_algorithm=ike['encryption_algorithm'],
|
||||
phase1_negotiation_mode=ike['phase1_negotiation_mode'],
|
||||
lifetime_units=lifetime_units,
|
||||
lifetime_value=lifetime_value,
|
||||
ike_version=ike['ike_version'],
|
||||
pfs=ike['pfs']
|
||||
)
|
||||
|
||||
context.session.add(ike_db)
|
||||
return self._make_ikepolicy_dict(ike_db)
|
||||
|
||||
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:
|
||||
raise vpnaas.IKEPolicyInUse(ikepolicy_id=ikepolicy_id)
|
||||
ike_db = self._get_resource(context, IKEPolicy, ikepolicy_id)
|
||||
if ike:
|
||||
lifetime_info = ike.get('lifetime')
|
||||
if lifetime_info:
|
||||
if lifetime_info.get('units'):
|
||||
ike['lifetime_units'] = lifetime_info['units']
|
||||
if lifetime_info.get('value'):
|
||||
ike['lifetime_value'] = lifetime_info['value']
|
||||
ike_db.update(ike)
|
||||
return self._make_ikepolicy_dict(ike_db)
|
||||
|
||||
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:
|
||||
raise vpnaas.IKEPolicyInUse(ikepolicy_id=ikepolicy_id)
|
||||
ike_db = self._get_resource(context, 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)
|
||||
return self._make_ikepolicy_dict(ike_db, fields)
|
||||
|
||||
def get_ikepolicies(self, context, filters=None, fields=None):
|
||||
return self._get_collection(context, IKEPolicy,
|
||||
self._make_ikepolicy_dict,
|
||||
filters=filters, fields=fields)
|
||||
|
||||
def _make_ipsecpolicy_dict(self, ipsecpolicy, fields=None):
|
||||
|
||||
res = {'id': ipsecpolicy['id'],
|
||||
'tenant_id': ipsecpolicy['tenant_id'],
|
||||
'name': ipsecpolicy['name'],
|
||||
'description': ipsecpolicy['description'],
|
||||
'transform_protocol': ipsecpolicy['transform_protocol'],
|
||||
'auth_algorithm': ipsecpolicy['auth_algorithm'],
|
||||
'encryption_algorithm': ipsecpolicy['encryption_algorithm'],
|
||||
'encapsulation_mode': ipsecpolicy['encapsulation_mode'],
|
||||
'lifetime': {
|
||||
'units': ipsecpolicy['lifetime_units'],
|
||||
'value': ipsecpolicy['lifetime_value'],
|
||||
},
|
||||
'pfs': ipsecpolicy['pfs']
|
||||
}
|
||||
|
||||
return self._fields(res, fields)
|
||||
|
||||
def create_ipsecpolicy(self, context, ipsecpolicy):
|
||||
ipsecp = ipsecpolicy['ipsecpolicy']
|
||||
tenant_id = self._get_tenant_id_for_create(context, ipsecp)
|
||||
lifetime_info = ipsecp['lifetime']
|
||||
lifetime_units = lifetime_info.get('units', 'seconds')
|
||||
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'])
|
||||
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:
|
||||
raise vpnaas.IPsecPolicyInUse(ipsecpolicy_id=ipsecpolicy_id)
|
||||
ipsecp_db = self._get_resource(context,
|
||||
IPsecPolicy,
|
||||
ipsecpolicy_id)
|
||||
if ipsecp:
|
||||
lifetime_info = ipsecp.get('lifetime')
|
||||
if lifetime_info:
|
||||
if lifetime_info.get('units'):
|
||||
ipsecp['lifetime_units'] = lifetime_info['units']
|
||||
if lifetime_info('value'):
|
||||
ipsecp['lifetime_value'] = lifetime_info['value']
|
||||
ipsecp_db.update(ipsecp)
|
||||
return self._make_ipsecpolicy_dict(ipsecp_db)
|
||||
|
||||
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:
|
||||
raise vpnaas.IPsecPolicyInUse(ipsecpolicy_id=ipsecpolicy_id)
|
||||
ipsec_db = self._get_resource(context, 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)
|
||||
return self._make_ipsecpolicy_dict(ipsec_db, fields)
|
||||
|
||||
def get_ipsecpolicies(self, context, filters=None, fields=None):
|
||||
return self._get_collection(context, IPsecPolicy,
|
||||
self._make_ipsecpolicy_dict,
|
||||
filters=filters, fields=fields)
|
||||
|
||||
def _make_vpnservice_dict(self, vpnservice, fields=None):
|
||||
res = {'id': vpnservice['id'],
|
||||
'name': vpnservice['name'],
|
||||
'description': vpnservice['description'],
|
||||
'tenant_id': vpnservice['tenant_id'],
|
||||
'subnet_id': vpnservice['subnet_id'],
|
||||
'router_id': vpnservice['router_id'],
|
||||
'admin_state_up': vpnservice['admin_state_up'],
|
||||
'status': vpnservice['status']}
|
||||
return self._fields(res, fields)
|
||||
|
||||
def create_vpnservice(self, context, vpnservice):
|
||||
vpns = vpnservice['vpnservice']
|
||||
tenant_id = self._get_tenant_id_for_create(context, vpns)
|
||||
with context.session.begin(subtransactions=True):
|
||||
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)
|
||||
context.session.add(vpnservice_db)
|
||||
return self._make_vpnservice_dict(vpnservice_db)
|
||||
|
||||
def update_vpnservice(self, context, vpnservice_id, vpnservice):
|
||||
vpns = vpnservice['vpnservice']
|
||||
with context.session.begin(subtransactions=True):
|
||||
vpnservice = context.session.query(IPsecSiteConnection).filter_by(
|
||||
vpnservice_id=vpnservice_id).first()
|
||||
if vpnservice:
|
||||
raise vpnaas.VPNServiceInUse(vpnservice_id=vpnservice_id)
|
||||
vpns_db = self._get_resource(context, VPNService, vpnservice_id)
|
||||
self.assert_update_allowed(vpns_db)
|
||||
if vpns:
|
||||
vpns_db.update(vpns)
|
||||
return self._make_vpnservice_dict(vpns_db)
|
||||
|
||||
def delete_vpnservice(self, context, vpnservice_id):
|
||||
with context.session.begin(subtransactions=True):
|
||||
if context.session.query(IPsecSiteConnection).filter_by(
|
||||
vpnservice_id=vpnservice_id
|
||||
).first():
|
||||
raise vpnaas.VPNServiceInUse(vpnservice_id=vpnservice_id)
|
||||
vpns_db = self._get_resource(context, VPNService, vpnservice_id)
|
||||
context.session.delete(vpns_db)
|
||||
|
||||
def _get_vpnservice(self, context, vpnservice_id):
|
||||
return self._get_resource(context, VPNService, vpnservice_id)
|
||||
|
||||
def get_vpnservice(self, context, vpnservice_id, fields=None):
|
||||
vpns_db = self._get_resource(context, 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,
|
||||
self._make_vpnservice_dict,
|
||||
filters=filters, fields=fields)
|
||||
|
||||
|
||||
class VPNPluginRpcDbMixin():
|
||||
def _get_agent_hosting_vpn_services(self, context, host):
|
||||
|
||||
plugin = manager.NeutronManager.get_plugin()
|
||||
agent = plugin._get_agent_by_type_and_host(
|
||||
context, q_constants.AGENT_TYPE_L3, host)
|
||||
if not agent.admin_state_up:
|
||||
return []
|
||||
query = context.session.query(VPNService)
|
||||
query = query.join(IPsecSiteConnection)
|
||||
query = query.join(IKEPolicy)
|
||||
query = query.join(IPsecPolicy)
|
||||
query = query.join(IPsecPeerCidr)
|
||||
query = query.join(agent_db.RouterL3AgentBinding,
|
||||
agent_db.RouterL3AgentBinding.router_id ==
|
||||
VPNService.router_id)
|
||||
query = query.filter(
|
||||
agent_db.RouterL3AgentBinding.l3_agent_id == agent.id)
|
||||
return query
|
||||
|
||||
def update_status_on_host(self, context, host, active_services):
|
||||
with context.session.begin(subtransactions=True):
|
||||
vpnservices = self._get_agent_hosting_vpn_services(
|
||||
context, host)
|
||||
for vpnservice in vpnservices:
|
||||
if vpnservice.id in active_services:
|
||||
if vpnservice.status != constants.ACTIVE:
|
||||
vpnservice.status = constants.ACTIVE
|
||||
else:
|
||||
if vpnservice.status != constants.ERROR:
|
||||
vpnservice.status = constants.ERROR
|
18
neutron/services/vpn/__init__.py
Normal file
18
neutron/services/vpn/__init__.py
Normal file
@ -0,0 +1,18 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# (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.
|
||||
#
|
||||
# @author: Swaminathan Vasudevan, Hewlett-Packard
|
32
neutron/services/vpn/plugin.py
Normal file
32
neutron/services/vpn/plugin.py
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# (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.
|
||||
#
|
||||
# @author: Swaminathan Vasudevan, Hewlett-Packard
|
||||
|
||||
from neutron.db.vpn import vpn_db
|
||||
|
||||
|
||||
class VPNPlugin(vpn_db.VPNPluginDb):
|
||||
|
||||
"""Implementation of the VPN Service Plugin.
|
||||
|
||||
This class manages the workflow of VPNaaS request/response.
|
||||
Most DB related works are implemented in class
|
||||
vpn_db.VPNPluginDb.
|
||||
"""
|
||||
supported_extension_aliases = ["vpnaas"]
|
17
neutron/tests/unit/db/vpn/__init__.py
Normal file
17
neutron/tests/unit/db/vpn/__init__.py
Normal file
@ -0,0 +1,17 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# (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.
|
||||
# @author: Swaminathan Vasudevan, Hewlett-Packard.
|
1541
neutron/tests/unit/db/vpn/test_db_vpnaas.py
Normal file
1541
neutron/tests/unit/db/vpn/test_db_vpnaas.py
Normal file
File diff suppressed because it is too large
Load Diff
17
neutron/tests/unit/services/vpn/__init__.py
Normal file
17
neutron/tests/unit/services/vpn/__init__.py
Normal file
@ -0,0 +1,17 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# (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.
|
||||
# @author: Swaminathan Vasudevan, Hewlett-Packard.
|
592
neutron/tests/unit/services/vpn/test_vpnaas_extension.py
Normal file
592
neutron/tests/unit/services/vpn/test_vpnaas_extension.py
Normal file
@ -0,0 +1,592 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# (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.
|
||||
#
|
||||
# @author: Swaminathan Vasudevan, Hewlett-Packard.
|
||||
|
||||
import copy
|
||||
|
||||
import mock
|
||||
from oslo.config import cfg
|
||||
from webob import exc
|
||||
import webtest
|
||||
|
||||
from neutron.api import extensions
|
||||
from neutron.api.v2 import attributes
|
||||
from neutron.common import config
|
||||
from neutron.extensions import vpnaas
|
||||
from neutron import manager
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.common import constants
|
||||
from neutron.tests.unit import test_api_v2
|
||||
from neutron.tests.unit import test_extensions
|
||||
from neutron.tests.unit import testlib_api
|
||||
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
_get_path = test_api_v2._get_path
|
||||
|
||||
|
||||
class VpnaasTestExtensionManager(object):
|
||||
|
||||
def get_resources(self):
|
||||
# Add the resources to the global attribute map
|
||||
# This is done here as the setup process won't
|
||||
# initialize the main API router which extends
|
||||
# the global attribute map
|
||||
attributes.RESOURCE_ATTRIBUTE_MAP.update(
|
||||
vpnaas.RESOURCE_ATTRIBUTE_MAP)
|
||||
return vpnaas.Vpnaas.get_resources()
|
||||
|
||||
def get_actions(self):
|
||||
return []
|
||||
|
||||
def get_request_extensions(self):
|
||||
return []
|
||||
|
||||
|
||||
class VpnaasExtensionTestCase(testlib_api.WebTestCase):
|
||||
fmt = 'json'
|
||||
|
||||
def setUp(self):
|
||||
super(VpnaasExtensionTestCase, self).setUp()
|
||||
plugin = 'neutron.extensions.vpnaas.VPNPluginBase'
|
||||
# Ensure 'stale' patched copies of the plugin are never returned
|
||||
manager.NeutronManager._instance = None
|
||||
|
||||
# Ensure existing ExtensionManager is not used
|
||||
extensions.PluginAwareExtensionManager._instance = None
|
||||
|
||||
# Create the default configurations
|
||||
args = ['--config-file', test_api_v2.etcdir('neutron.conf.test')]
|
||||
config.parse(args)
|
||||
|
||||
#just stubbing core plugin with LoadBalancer plugin
|
||||
cfg.CONF.set_override('core_plugin', plugin)
|
||||
cfg.CONF.set_override('service_plugins', [plugin])
|
||||
|
||||
self._plugin_patcher = mock.patch(plugin, autospec=True)
|
||||
self.plugin = self._plugin_patcher.start()
|
||||
instance = self.plugin.return_value
|
||||
instance.get_plugin_type.return_value = constants.VPN
|
||||
|
||||
ext_mgr = VpnaasTestExtensionManager()
|
||||
self.ext_mdw = test_extensions.setup_extensions_middleware(ext_mgr)
|
||||
self.api = webtest.TestApp(self.ext_mdw)
|
||||
super(VpnaasExtensionTestCase, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
self._plugin_patcher.stop()
|
||||
self.api = None
|
||||
self.plugin = None
|
||||
cfg.CONF.reset()
|
||||
super(VpnaasExtensionTestCase, self).tearDown()
|
||||
|
||||
def test_ikepolicy_create(self):
|
||||
"""Test case to create an ikepolicy."""
|
||||
ikepolicy_id = _uuid()
|
||||
data = {'ikepolicy': {'name': 'ikepolicy1',
|
||||
'description': 'myikepolicy1',
|
||||
'auth_algorithm': 'sha1',
|
||||
'encryption_algorithm': 'aes-128',
|
||||
'phase1_negotiation_mode': 'main',
|
||||
'lifetime': {
|
||||
'units': 'seconds',
|
||||
'value': 3600},
|
||||
'ike_version': 'v1',
|
||||
'pfs': 'group5',
|
||||
'tenant_id': _uuid()}}
|
||||
|
||||
return_value = copy.copy(data['ikepolicy'])
|
||||
return_value.update({'id': ikepolicy_id})
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.create_ikepolicy.return_value = return_value
|
||||
res = self.api.post(_get_path('vpn/ikepolicies', fmt=self.fmt),
|
||||
self.serialize(data),
|
||||
content_type='application/%s' % self.fmt)
|
||||
instance.create_ikepolicy.assert_called_with(mock.ANY,
|
||||
ikepolicy=data)
|
||||
self.assertEqual(res.status_int, exc.HTTPCreated.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('ikepolicy', res)
|
||||
self.assertEqual(res['ikepolicy'], return_value)
|
||||
|
||||
def test_ikepolicy_list(self):
|
||||
"""Test case to list all ikepolicies."""
|
||||
ikepolicy_id = _uuid()
|
||||
return_value = [{'name': 'ikepolicy1',
|
||||
'auth_algorithm': 'sha1',
|
||||
'encryption_algorithm': 'aes-128',
|
||||
'pfs': 'group5',
|
||||
'ike_version': 'v1',
|
||||
'id': ikepolicy_id}]
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_ikepolicies.return_value = return_value
|
||||
|
||||
res = self.api.get(_get_path('vpn/ikepolicies', fmt=self.fmt))
|
||||
|
||||
instance.get_ikepolicies.assert_called_with(mock.ANY,
|
||||
fields=mock.ANY,
|
||||
filters=mock.ANY)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
|
||||
def test_ikepolicy_update(self):
|
||||
"""Test case to update an ikepolicy."""
|
||||
ikepolicy_id = _uuid()
|
||||
update_data = {'ikepolicy': {'name': 'ikepolicy1',
|
||||
'encryption_algorithm': 'aes-256'}}
|
||||
return_value = {'name': 'ikepolicy1',
|
||||
'auth_algorithm': 'sha1',
|
||||
'encryption_algorithm': 'aes-256',
|
||||
'phase1_negotiation_mode': 'main',
|
||||
'lifetime': {
|
||||
'units': 'seconds',
|
||||
'value': 3600},
|
||||
'ike_version': 'v1',
|
||||
'pfs': 'group5',
|
||||
'tenant_id': _uuid(),
|
||||
'id': ikepolicy_id}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.update_ikepolicy.return_value = return_value
|
||||
|
||||
res = self.api.put(_get_path('vpn/ikepolicies', id=ikepolicy_id,
|
||||
fmt=self.fmt),
|
||||
self.serialize(update_data))
|
||||
|
||||
instance.update_ikepolicy.assert_called_with(mock.ANY, ikepolicy_id,
|
||||
ikepolicy=update_data)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('ikepolicy', res)
|
||||
self.assertEqual(res['ikepolicy'], return_value)
|
||||
|
||||
def test_ikepolicy_get(self):
|
||||
"""Test case to get or show an ikepolicy."""
|
||||
ikepolicy_id = _uuid()
|
||||
return_value = {'name': 'ikepolicy1',
|
||||
'auth_algorithm': 'sha1',
|
||||
'encryption_algorithm': 'aes-128',
|
||||
'phase1_negotiation_mode': 'main',
|
||||
'lifetime': {
|
||||
'units': 'seconds',
|
||||
'value': 3600},
|
||||
'ike_version': 'v1',
|
||||
'pfs': 'group5',
|
||||
'tenant_id': _uuid(),
|
||||
'id': ikepolicy_id}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_ikepolicy.return_value = return_value
|
||||
|
||||
res = self.api.get(_get_path('vpn/ikepolicies', id=ikepolicy_id,
|
||||
fmt=self.fmt))
|
||||
|
||||
instance.get_ikepolicy.assert_called_with(mock.ANY,
|
||||
ikepolicy_id,
|
||||
fields=mock.ANY)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('ikepolicy', res)
|
||||
self.assertEqual(res['ikepolicy'], return_value)
|
||||
|
||||
def test_ikepolicy_delete(self):
|
||||
"""Test case to delete an ikepolicy."""
|
||||
self._test_entity_delete('ikepolicy')
|
||||
|
||||
def test_ipsecpolicy_create(self):
|
||||
"""Test case to create an ipsecpolicy."""
|
||||
ipsecpolicy_id = _uuid()
|
||||
data = {'ipsecpolicy': {'name': 'ipsecpolicy1',
|
||||
'description': 'myipsecpolicy1',
|
||||
'auth_algorithm': 'sha1',
|
||||
'encryption_algorithm': 'aes-128',
|
||||
'encapsulation_mode': 'tunnel',
|
||||
'lifetime': {
|
||||
'units': 'seconds',
|
||||
'value': 3600},
|
||||
'transform_protocol': 'esp',
|
||||
'pfs': 'group5',
|
||||
'tenant_id': _uuid()}}
|
||||
return_value = copy.copy(data['ipsecpolicy'])
|
||||
return_value.update({'id': ipsecpolicy_id})
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.create_ipsecpolicy.return_value = return_value
|
||||
res = self.api.post(_get_path('vpn/ipsecpolicies', fmt=self.fmt),
|
||||
self.serialize(data),
|
||||
content_type='application/%s' % self.fmt)
|
||||
instance.create_ipsecpolicy.assert_called_with(mock.ANY,
|
||||
ipsecpolicy=data)
|
||||
self.assertEqual(res.status_int, exc.HTTPCreated.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('ipsecpolicy', res)
|
||||
self.assertEqual(res['ipsecpolicy'], return_value)
|
||||
|
||||
def test_ipsecpolicy_list(self):
|
||||
"""Test case to list an ipsecpolicy."""
|
||||
ipsecpolicy_id = _uuid()
|
||||
return_value = [{'name': 'ipsecpolicy1',
|
||||
'auth_algorithm': 'sha1',
|
||||
'encryption_algorithm': 'aes-128',
|
||||
'pfs': 'group5',
|
||||
'id': ipsecpolicy_id}]
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_ipsecpolicies.return_value = return_value
|
||||
|
||||
res = self.api.get(_get_path('vpn/ipsecpolicies', fmt=self.fmt))
|
||||
|
||||
instance.get_ipsecpolicies.assert_called_with(mock.ANY,
|
||||
fields=mock.ANY,
|
||||
filters=mock.ANY)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
|
||||
def test_ipsecpolicy_update(self):
|
||||
"""Test case to update an ipsecpolicy."""
|
||||
ipsecpolicy_id = _uuid()
|
||||
update_data = {'ipsecpolicy': {'name': 'ipsecpolicy1',
|
||||
'encryption_algorithm': 'aes-256'}}
|
||||
return_value = {'name': 'ipsecpolicy1',
|
||||
'auth_algorithm': 'sha1',
|
||||
'encryption_algorithm': 'aes-128',
|
||||
'encapsulation_mode': 'tunnel',
|
||||
'lifetime': {
|
||||
'units': 'seconds',
|
||||
'value': 3600},
|
||||
'transform_protocol': 'esp',
|
||||
'pfs': 'group5',
|
||||
'tenant_id': _uuid(),
|
||||
'id': ipsecpolicy_id}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.update_ipsecpolicy.return_value = return_value
|
||||
|
||||
res = self.api.put(_get_path('vpn/ipsecpolicies',
|
||||
id=ipsecpolicy_id,
|
||||
fmt=self.fmt),
|
||||
self.serialize(update_data))
|
||||
|
||||
instance.update_ipsecpolicy.assert_called_with(mock.ANY,
|
||||
ipsecpolicy_id,
|
||||
ipsecpolicy=update_data)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('ipsecpolicy', res)
|
||||
self.assertEqual(res['ipsecpolicy'], return_value)
|
||||
|
||||
def test_ipsecpolicy_get(self):
|
||||
"""Test case to get or show an ipsecpolicy."""
|
||||
ipsecpolicy_id = _uuid()
|
||||
return_value = {'name': 'ipsecpolicy1',
|
||||
'auth_algorithm': 'sha1',
|
||||
'encryption_algorithm': 'aes-128',
|
||||
'encapsulation_mode': 'tunnel',
|
||||
'lifetime': {
|
||||
'units': 'seconds',
|
||||
'value': 3600},
|
||||
'transform_protocol': 'esp',
|
||||
'pfs': 'group5',
|
||||
'tenant_id': _uuid(),
|
||||
'id': ipsecpolicy_id}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_ipsecpolicy.return_value = return_value
|
||||
|
||||
res = self.api.get(_get_path('vpn/ipsecpolicies',
|
||||
id=ipsecpolicy_id,
|
||||
fmt=self.fmt))
|
||||
|
||||
instance.get_ipsecpolicy.assert_called_with(mock.ANY,
|
||||
ipsecpolicy_id,
|
||||
fields=mock.ANY)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('ipsecpolicy', res)
|
||||
self.assertEqual(res['ipsecpolicy'], return_value)
|
||||
|
||||
def test_ipsecpolicy_delete(self):
|
||||
"""Test case to delete an ipsecpolicy."""
|
||||
self._test_entity_delete('ipsecpolicy')
|
||||
|
||||
def test_vpnservice_create(self):
|
||||
"""Test case to create a vpnservice."""
|
||||
vpnservice_id = _uuid()
|
||||
data = {'vpnservice': {'name': 'vpnservice1',
|
||||
'description': 'descr_vpn1',
|
||||
'subnet_id': _uuid(),
|
||||
'router_id': _uuid(),
|
||||
'admin_state_up': True,
|
||||
'tenant_id': _uuid()}}
|
||||
return_value = copy.copy(data['vpnservice'])
|
||||
return_value.update({'status': "ACTIVE", 'id': vpnservice_id})
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.create_vpnservice.return_value = return_value
|
||||
res = self.api.post(_get_path('vpn/vpnservices', fmt=self.fmt),
|
||||
self.serialize(data),
|
||||
content_type='application/%s' % self.fmt)
|
||||
instance.create_vpnservice.assert_called_with(mock.ANY,
|
||||
vpnservice=data)
|
||||
self.assertEqual(res.status_int, exc.HTTPCreated.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('vpnservice', res)
|
||||
self.assertEqual(res['vpnservice'], return_value)
|
||||
|
||||
def test_vpnservice_list(self):
|
||||
"""Test case to list all vpnservices."""
|
||||
vpnservice_id = _uuid()
|
||||
return_value = [{'name': 'vpnservice1',
|
||||
'tenant_id': _uuid(),
|
||||
'status': 'ACTIVE',
|
||||
'id': vpnservice_id}]
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_vpnservice.return_value = return_value
|
||||
|
||||
res = self.api.get(_get_path('vpn/vpnservices', fmt=self.fmt))
|
||||
|
||||
instance.get_vpnservices.assert_called_with(mock.ANY,
|
||||
fields=mock.ANY,
|
||||
filters=mock.ANY)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
|
||||
def test_vpnservice_update(self):
|
||||
"""Test case to update a vpnservice."""
|
||||
vpnservice_id = _uuid()
|
||||
update_data = {'vpnservice': {'admin_state_up': False}}
|
||||
return_value = {'name': 'vpnservice1',
|
||||
'admin_state_up': False,
|
||||
'subnet_id': _uuid(),
|
||||
'router_id': _uuid(),
|
||||
'tenant_id': _uuid(),
|
||||
'status': "ACTIVE",
|
||||
'id': vpnservice_id}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.update_vpnservice.return_value = return_value
|
||||
|
||||
res = self.api.put(_get_path('vpn/vpnservices',
|
||||
id=vpnservice_id,
|
||||
fmt=self.fmt),
|
||||
self.serialize(update_data))
|
||||
|
||||
instance.update_vpnservice.assert_called_with(mock.ANY,
|
||||
vpnservice_id,
|
||||
vpnservice=update_data)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('vpnservice', res)
|
||||
self.assertEqual(res['vpnservice'], return_value)
|
||||
|
||||
def test_vpnservice_get(self):
|
||||
"""Test case to get or show a vpnservice."""
|
||||
vpnservice_id = _uuid()
|
||||
return_value = {'name': 'vpnservice1',
|
||||
'admin_state_up': True,
|
||||
'subnet_id': _uuid(),
|
||||
'router_id': _uuid(),
|
||||
'tenant_id': _uuid(),
|
||||
'status': "ACTIVE",
|
||||
'id': vpnservice_id}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_vpnservice.return_value = return_value
|
||||
|
||||
res = self.api.get(_get_path('vpn/vpnservices',
|
||||
id=vpnservice_id,
|
||||
fmt=self.fmt))
|
||||
|
||||
instance.get_vpnservice.assert_called_with(mock.ANY,
|
||||
vpnservice_id,
|
||||
fields=mock.ANY)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('vpnservice', res)
|
||||
self.assertEqual(res['vpnservice'], return_value)
|
||||
|
||||
def _test_entity_delete(self, entity):
|
||||
"""does the entity deletion based on naming convention."""
|
||||
entity_id = _uuid()
|
||||
path_map = {'ipsecpolicy': 'vpn/ipsecpolicies',
|
||||
'ikepolicy': 'vpn/ikepolicies',
|
||||
'ipsec_site_connection': 'vpn/ipsec-site-connections'}
|
||||
path = path_map.get(entity, 'vpn/' + entity + 's')
|
||||
res = self.api.delete(_get_path(path,
|
||||
id=entity_id,
|
||||
fmt=self.fmt))
|
||||
delete_entity = getattr(self.plugin.return_value, "delete_" + entity)
|
||||
delete_entity.assert_called_with(mock.ANY, entity_id)
|
||||
self.assertEqual(res.status_int, exc.HTTPNoContent.code)
|
||||
|
||||
def test_vpnservice_delete(self):
|
||||
"""Test case to delete a vpnservice."""
|
||||
self._test_entity_delete('vpnservice')
|
||||
|
||||
def test_ipsec_site_connection_create(self):
|
||||
"""Test case to create a ipsec_site_connection."""
|
||||
ipsecsite_con_id = _uuid()
|
||||
ikepolicy_id = _uuid()
|
||||
ipsecpolicy_id = _uuid()
|
||||
data = {
|
||||
'ipsec_site_connection': {'name': 'connection1',
|
||||
'description': 'Remote-connection1',
|
||||
'peer_address': '192.168.1.10',
|
||||
'peer_id': '192.168.1.10',
|
||||
'peer_cidrs': ['192.168.2.0/24',
|
||||
'192.168.3.0/24'],
|
||||
'mtu': 1500,
|
||||
'psk': 'abcd',
|
||||
'initiator': 'bi-directional',
|
||||
'dpd': {
|
||||
'action': 'hold',
|
||||
'interval': 30,
|
||||
'timeout': 120},
|
||||
'ikepolicy_id': ikepolicy_id,
|
||||
'ipsecpolicy_id': ipsecpolicy_id,
|
||||
'vpnservice_id': _uuid(),
|
||||
'admin_state_up': True,
|
||||
'tenant_id': _uuid()}
|
||||
}
|
||||
return_value = copy.copy(data['ipsec_site_connection'])
|
||||
return_value.update({'status': "ACTIVE", 'id': ipsecsite_con_id})
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.create_ipsec_site_connection.return_value = return_value
|
||||
res = self.api.post(_get_path('vpn/ipsec-site-connections',
|
||||
fmt=self.fmt),
|
||||
self.serialize(data),
|
||||
content_type='application/%s' % self.fmt)
|
||||
instance.create_ipsec_site_connection.assert_called_with(
|
||||
mock.ANY, ipsec_site_connection=data
|
||||
)
|
||||
self.assertEqual(res.status_int, exc.HTTPCreated.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('ipsec_site_connection', res)
|
||||
self.assertEqual(res['ipsec_site_connection'], return_value)
|
||||
|
||||
def test_ipsec_site_connection_list(self):
|
||||
"""Test case to list all ipsec_site_connections."""
|
||||
ipsecsite_con_id = _uuid()
|
||||
return_value = [{'name': 'connection1',
|
||||
'peer_address': '192.168.1.10',
|
||||
'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'],
|
||||
'route_mode': 'static',
|
||||
'auth_mode': 'psk',
|
||||
'tenant_id': _uuid(),
|
||||
'status': 'ACTIVE',
|
||||
'id': ipsecsite_con_id}]
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_ipsec_site_connections.return_value = return_value
|
||||
|
||||
res = self.api.get(
|
||||
_get_path('vpn/ipsec-site-connections', fmt=self.fmt))
|
||||
|
||||
instance.get_ipsec_site_connections.assert_called_with(
|
||||
mock.ANY, fields=mock.ANY, filters=mock.ANY
|
||||
)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
|
||||
def test_ipsec_site_connection_update(self):
|
||||
"""Test case to update a ipsec_site_connection."""
|
||||
ipsecsite_con_id = _uuid()
|
||||
update_data = {'ipsec_site_connection': {'admin_state_up': False}}
|
||||
return_value = {'name': 'connection1',
|
||||
'description': 'Remote-connection1',
|
||||
'peer_address': '192.168.1.10',
|
||||
'peer_id': '192.168.1.10',
|
||||
'peer_cidrs': ['192.168.2.0/24', '192.168.3.0/24'],
|
||||
'mtu': 1500,
|
||||
'psk': 'abcd',
|
||||
'initiator': 'bi-directional',
|
||||
'dpd': {
|
||||
'action': 'hold',
|
||||
'interval': 30,
|
||||
'timeout': 120},
|
||||
'ikepolicy_id': _uuid(),
|
||||
'ipsecpolicy_id': _uuid(),
|
||||
'vpnservice_id': _uuid(),
|
||||
'admin_state_up': False,
|
||||
'tenant_id': _uuid(),
|
||||
'status': 'ACTIVE',
|
||||
'id': ipsecsite_con_id}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.update_ipsec_site_connection.return_value = return_value
|
||||
|
||||
res = self.api.put(_get_path('vpn/ipsec-site-connections',
|
||||
id=ipsecsite_con_id,
|
||||
fmt=self.fmt),
|
||||
self.serialize(update_data))
|
||||
|
||||
instance.update_ipsec_site_connection.assert_called_with(
|
||||
mock.ANY, ipsecsite_con_id, ipsec_site_connection=update_data
|
||||
)
|
||||
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('ipsec_site_connection', res)
|
||||
self.assertEqual(res['ipsec_site_connection'], return_value)
|
||||
|
||||
def test_ipsec_site_connection_get(self):
|
||||
"""Test case to get or show a ipsec_site_connection."""
|
||||
ipsecsite_con_id = _uuid()
|
||||
return_value = {'name': 'connection1',
|
||||
'description': 'Remote-connection1',
|
||||
'peer_address': '192.168.1.10',
|
||||
'peer_id': '192.168.1.10',
|
||||
'peer_cidrs': ['192.168.2.0/24',
|
||||
'192.168.3.0/24'],
|
||||
'mtu': 1500,
|
||||
'psk': 'abcd',
|
||||
'initiator': 'bi-directional',
|
||||
'dpd': {
|
||||
'action': 'hold',
|
||||
'interval': 30,
|
||||
'timeout': 120},
|
||||
'ikepolicy_id': _uuid(),
|
||||
'ipsecpolicy_id': _uuid(),
|
||||
'vpnservice_id': _uuid(),
|
||||
'admin_state_up': True,
|
||||
'tenant_id': _uuid(),
|
||||
'status': 'ACTIVE',
|
||||
'id': ipsecsite_con_id}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_ipsec_site_connection.return_value = return_value
|
||||
|
||||
res = self.api.get(_get_path('vpn/ipsec-site-connections',
|
||||
id=ipsecsite_con_id,
|
||||
fmt=self.fmt))
|
||||
|
||||
instance.get_ipsec_site_connection.assert_called_with(
|
||||
mock.ANY, ipsecsite_con_id, fields=mock.ANY
|
||||
)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('ipsec_site_connection', res)
|
||||
self.assertEqual(res['ipsec_site_connection'], return_value)
|
||||
|
||||
def test_ipsec_site_connection_delete(self):
|
||||
"""Test case to delete a ipsec_site_connection."""
|
||||
self._test_entity_delete('ipsec_site_connection')
|
||||
|
||||
|
||||
class VpnaasExtensionTestCaseXML(VpnaasExtensionTestCase):
|
||||
fmt = 'xml'
|
Loading…
Reference in New Issue
Block a user