![Bodo Petermann](/assets/img/avatar_default.png)
Adds VPNaaS support for OVN. Add a new stand-alone VPN agent to support OVN+VPN. Add OVN-specific service and device drivers that support this new VPN agent. This will have no impact on the existing VPN solution for ML2/OVS, the existing L3 agent and its VPN extension will still work. Add a new VPN agent scheduler that will schedule VPN services to VPN agents on a per-router basis. Add two new database tables: vpn_ext_gws (to store extra port IDs) and routervpnagentbindings (to store VPN agent ID per router). More details see spec (neutron-specs/specs/xena/vpnaas-ovn.rst). This work is based on work of MingShuan Xian (xianms@cn.ibm.com), see https://bugs.launchpad.net/networking-ovn/+bug/1586253 Depends-On: https://review.opendev.org/c/openstack/neutron/+/847005 Depends-On: https://review.opendev.org/c/openstack/neutron-tempest-plugin/+/847007 Closes-Bug: #1905391 Change-Id: I632f86762d63edbfe225727db11ea21bbb1ffc25
161 lines
4.6 KiB
Python
161 lines
4.6 KiB
Python
# (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.
|
|
|
|
import abc
|
|
|
|
from neutron_lib.api.definitions import vpn
|
|
from neutron_lib.api import extensions
|
|
from neutron_lib import exceptions as nexception
|
|
from neutron_lib.plugins import constants as nconstants
|
|
from neutron_lib.services import base as service_base
|
|
|
|
from neutron.api.v2 import resource_helper
|
|
|
|
from neutron_vpnaas._i18n import _
|
|
|
|
|
|
class RouteInUseByVPN(nexception.InUse):
|
|
"""Operational error indicating a route is used for VPN.
|
|
|
|
:param destinations: Destination CIDRs that are peers for VPN
|
|
"""
|
|
message = _("Route(s) to %(destinations)s are used for VPN")
|
|
|
|
|
|
class VPNGatewayNotReady(nexception.BadRequest):
|
|
message = _("VPN gateway not ready")
|
|
|
|
|
|
class VPNGatewayInError(nexception.Conflict):
|
|
message = _("VPN gateway is in ERROR state. "
|
|
"Please remove all errored VPN services and try again.")
|
|
|
|
|
|
class NoVPNAgentAvailable(nexception.ServiceUnavailable):
|
|
message = _("No VPN agent available")
|
|
|
|
|
|
class Vpnaas(extensions.APIExtensionDescriptor):
|
|
api_definition = vpn
|
|
|
|
@classmethod
|
|
def get_resources(cls):
|
|
special_mappings = {'ikepolicies': 'ikepolicy',
|
|
'ipsecpolicies': 'ipsecpolicy'}
|
|
plural_mappings = resource_helper.build_plural_mappings(
|
|
special_mappings, vpn.RESOURCE_ATTRIBUTE_MAP)
|
|
plural_mappings['peer_cidrs'] = 'peer_cidr'
|
|
return resource_helper.build_resource_info(
|
|
plural_mappings,
|
|
vpn.RESOURCE_ATTRIBUTE_MAP,
|
|
nconstants.VPN,
|
|
register_quota=True,
|
|
translate_name=True)
|
|
|
|
@classmethod
|
|
def get_plugin_interface(cls):
|
|
return VPNPluginBase
|
|
|
|
|
|
class VPNPluginBase(service_base.ServicePluginBase, metaclass=abc.ABCMeta):
|
|
|
|
def get_plugin_type(self):
|
|
return nconstants.VPN
|
|
|
|
def get_plugin_description(self):
|
|
return 'VPN service plugin'
|
|
|
|
@abc.abstractmethod
|
|
def get_vpnservices(self, context, filters=None, fields=None):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_vpnservice(self, context, vpnservice_id, fields=None):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def create_vpnservice(self, context, vpnservice):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def update_vpnservice(self, context, vpnservice_id, vpnservice):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def delete_vpnservice(self, context, vpnservice_id):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_ipsec_site_connections(self, context, filters=None, fields=None):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_ipsec_site_connection(self, context,
|
|
ipsecsite_conn_id, fields=None):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def create_ipsec_site_connection(self, context, ipsec_site_connection):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def update_ipsec_site_connection(self, context,
|
|
ipsecsite_conn_id, ipsec_site_connection):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def delete_ipsec_site_connection(self, context, ipsecsite_conn_id):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_ikepolicy(self, context, ikepolicy_id, fields=None):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_ikepolicies(self, context, filters=None, fields=None):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def create_ikepolicy(self, context, ikepolicy):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def update_ikepolicy(self, context, ikepolicy_id, ikepolicy):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def delete_ikepolicy(self, context, ikepolicy_id):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_ipsecpolicies(self, context, filters=None, fields=None):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_ipsecpolicy(self, context, ipsecpolicy_id, fields=None):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def create_ipsecpolicy(self, context, ipsecpolicy):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def update_ipsecpolicy(self, context, ipsecpolicy_id, ipsecpolicy):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def delete_ipsecpolicy(self, context, ipsecpolicy_id):
|
|
pass
|