7ba17a3155
Implements support for multiple local subnets for IPSec site to site connections, using the new Endpoint Group API. The implementation supports backwards compatibility as follows. If a VPN service is created with a subnet, then the older API is assumed and the user must specify the peer CIDRs for any IPSec connections and cannot specify multiple local subnets. If a subnet is not provided for the VPN service, then the user must use the newer API and provide a local and peer endpoint group IDs for the IPSec connection (and cannot specify the peer CIDRs in the IPSec connection API). Implication here is that the subnet will be an optional argument for the VPN service API. With this feature, when an endpoint group is deleted, a check is made to ensure that there are no IPSec connections using the group. Migration will move the subnet from VPN service API to a new endpoint group, and specify the group in any connections using the service. The peer CIDR(s) will be moved from each connection to an endpoint group, with the group ID specified in the connection. Note: As part of testing the database methods for this feature, several more tests were created to test database access only, instead of doing a round trip test. In a separate commit, these tests can be expanded, and the existing round trip tests removed. Note: Tests for building the dict used in sync requests was enhanced, as part of supporting this feature. The previous tests didn't check that the peer CIDR information was correct, so were enhanced as well. Note: The service driver passes the local CIDR(s) in a new field, called local_cidrs. This field is used for the older API, as well, passing the subnet's CIDR, and allowing consistent consumption by the device driver. The IP version is also passed, rather than obtaining it from the subnet info (so both new and old API use the same fields). Note: to support rolling upgrades, where an agent may be using the older release, after the server has been updated, the subnet CIDR field passed from the service driver to device driver, will be populated from the first local endpoint from the first connection (there has to be at least one connection, when sending data to the agent). Note: In the device driver, I noticed that the local CIDR's IP version can change the config file output, so I added test cases for IPv6, as part of enhancing the tests for multiple local CIDRs. Change-Id: I7a011e3170d7db463a6561e550b2ead3e3311125 Partial-Bug: 1459423
619 lines
23 KiB
Python
619 lines
23 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
|
|
|
|
import six
|
|
|
|
from neutron.api import extensions
|
|
from neutron.api.v2 import attributes as attr
|
|
from neutron.api.v2 import resource_helper
|
|
from neutron.common import exceptions as nexception
|
|
from neutron.plugins.common import constants as nconstants
|
|
from neutron.services import service_base
|
|
|
|
from neutron_vpnaas.services.vpn.common import constants
|
|
|
|
|
|
class VPNServiceNotFound(nexception.NotFound):
|
|
message = _("VPNService %(vpnservice_id)s could not be found")
|
|
|
|
|
|
class IPsecSiteConnectionNotFound(nexception.NotFound):
|
|
message = _("ipsec_site_connection %(ipsec_site_conn_id)s not found")
|
|
|
|
|
|
class IPsecSiteConnectionDpdIntervalValueError(nexception.InvalidInput):
|
|
message = _("ipsec_site_connection %(attr)s is "
|
|
"equal to or less than dpd_interval")
|
|
|
|
|
|
class IPsecSiteConnectionMtuError(nexception.InvalidInput):
|
|
message = _("ipsec_site_connection MTU %(mtu)d is too small "
|
|
"for ipv%(version)s")
|
|
|
|
|
|
class IKEPolicyNotFound(nexception.NotFound):
|
|
message = _("IKEPolicy %(ikepolicy_id)s could not be found")
|
|
|
|
|
|
class IPsecPolicyNotFound(nexception.NotFound):
|
|
message = _("IPsecPolicy %(ipsecpolicy_id)s could not be found")
|
|
|
|
|
|
class IKEPolicyInUse(nexception.InUse):
|
|
message = _("IKEPolicy %(ikepolicy_id)s is in use by existing "
|
|
"IPsecSiteConnection and can't be updated or deleted")
|
|
|
|
|
|
class VPNServiceInUse(nexception.InUse):
|
|
message = _("VPNService %(vpnservice_id)s is still in use")
|
|
|
|
|
|
class SubnetInUseByVPNService(nexception.InUse):
|
|
message = _("Subnet %(subnet_id)s is used by VPNService %(vpnservice_id)s")
|
|
|
|
|
|
class SubnetInUseByEndpointGroup(nexception.InUse):
|
|
message = _("Subnet %(subnet_id)s is used by endpoint group %(group_id)s")
|
|
|
|
|
|
class VPNStateInvalidToUpdate(nexception.BadRequest):
|
|
message = _("Invalid state %(state)s of vpnaas resource %(id)s"
|
|
" for updating")
|
|
|
|
|
|
class IPsecPolicyInUse(nexception.InUse):
|
|
message = _("IPsecPolicy %(ipsecpolicy_id)s is in use by existing "
|
|
"IPsecSiteConnection and can't be updated or deleted")
|
|
|
|
|
|
class DeviceDriverImportError(nexception.NeutronException):
|
|
message = _("Can not load driver :%(device_driver)s")
|
|
|
|
|
|
class SubnetIsNotConnectedToRouter(nexception.BadRequest):
|
|
message = _("Subnet %(subnet_id)s is not "
|
|
"connected to Router %(router_id)s")
|
|
|
|
|
|
class RouterIsNotExternal(nexception.BadRequest):
|
|
message = _("Router %(router_id)s has no external network gateway set")
|
|
|
|
|
|
class VPNPeerAddressNotResolved(nexception.InvalidInput):
|
|
message = _("Peer address %(peer_address)s cannot be resolved")
|
|
|
|
|
|
class ExternalNetworkHasNoSubnet(nexception.BadRequest):
|
|
message = _("Router's %(router_id)s external network has "
|
|
"no %(ip_version)s subnet")
|
|
|
|
|
|
class VPNEndpointGroupNotFound(nexception.NotFound):
|
|
message = _("Endpoint group %(endpoint_group_id)s could not be found")
|
|
|
|
|
|
class InvalidEndpointInEndpointGroup(nexception.InvalidInput):
|
|
message = _("Endpoint '%(endpoint)s' is invalid for group "
|
|
"type '%(group_type)s': %(why)s")
|
|
|
|
|
|
class MissingEndpointForEndpointGroup(nexception.BadRequest):
|
|
message = _("No endpoints specified for endpoint group '%(group)s'")
|
|
|
|
|
|
class NonExistingSubnetInEndpointGroup(nexception.InvalidInput):
|
|
message = _("Subnet %(subnet)s in endpoint group does not exist")
|
|
|
|
|
|
class MixedIPVersionsForIPSecEndpoints(nexception.BadRequest):
|
|
message = _("Endpoints in group %(group)s do not have the same IP "
|
|
"version, as required for IPSec site-to-site connection")
|
|
|
|
|
|
class MixedIPVersionsForPeerCidrs(nexception.BadRequest):
|
|
message = _("Peer CIDRs do not have the same IP version, as required "
|
|
"for IPSec site-to-site connection")
|
|
|
|
|
|
class MixedIPVersionsForIPSecConnection(nexception.BadRequest):
|
|
message = _("IP versions are not compatible between peer and local "
|
|
"endpoints")
|
|
|
|
|
|
class InvalidEndpointGroup(nexception.BadRequest):
|
|
message = _("Endpoint group%(suffix)s %(which)s cannot be specified, "
|
|
"when VPN Service has subnet specified")
|
|
|
|
|
|
class WrongEndpointGroupType(nexception.BadRequest):
|
|
message = _("Endpoint group %(which)s type is '%(group_type)s' and "
|
|
"should be '%(expected)s'")
|
|
|
|
|
|
class PeerCidrsInvalid(nexception.BadRequest):
|
|
message = _("Peer CIDRs cannot be specified, when using endpoint "
|
|
"groups")
|
|
|
|
|
|
class MissingPeerCidrs(nexception.BadRequest):
|
|
message = _("Missing peer CIDRs for IPsec site-to-site connection")
|
|
|
|
|
|
class MissingRequiredEndpointGroup(nexception.BadRequest):
|
|
message = _("Missing endpoint group%(suffix)s %(which)s for IPSec "
|
|
"site-to-site connection")
|
|
|
|
|
|
class EndpointGroupInUse(nexception.BadRequest):
|
|
message = _("Endpoint group %(group_id)s is in use and cannot be deleted")
|
|
|
|
|
|
def _validate_subnet_list_or_none(data, key_specs=None):
|
|
if data is not None:
|
|
attr._validate_subnet_list(data, key_specs)
|
|
|
|
attr.validators['type:subnet_list_or_none'] = _validate_subnet_list_or_none
|
|
|
|
vpn_supported_initiators = ['bi-directional', 'response-only']
|
|
vpn_supported_encryption_algorithms = ['3des', 'aes-128',
|
|
'aes-192', 'aes-256']
|
|
vpn_dpd_supported_actions = [
|
|
'hold', 'clear', 'restart', 'restart-by-peer', 'disabled'
|
|
]
|
|
vpn_supported_transform_protocols = ['esp', 'ah', 'ah-esp']
|
|
vpn_supported_encapsulation_mode = ['tunnel', 'transport']
|
|
#TODO(nati) add kilobytes when we support it
|
|
vpn_supported_lifetime_units = ['seconds']
|
|
vpn_supported_pfs = ['group2', 'group5', 'group14']
|
|
vpn_supported_ike_versions = ['v1', 'v2']
|
|
vpn_supported_auth_mode = ['psk']
|
|
vpn_supported_auth_algorithms = ['sha1']
|
|
vpn_supported_phase1_negotiation_mode = ['main']
|
|
|
|
vpn_lifetime_limits = (60, attr.UNLIMITED)
|
|
positive_int = (0, attr.UNLIMITED)
|
|
|
|
RESOURCE_ATTRIBUTE_MAP = {
|
|
|
|
'vpnservices': {
|
|
'id': {'allow_post': False, 'allow_put': False,
|
|
'validate': {'type:uuid': None},
|
|
'is_visible': True,
|
|
'primary_key': True},
|
|
'tenant_id': {'allow_post': True, 'allow_put': False,
|
|
'validate': {'type:string': None},
|
|
'required_by_policy': True,
|
|
'is_visible': True},
|
|
'name': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': None},
|
|
'is_visible': True, 'default': ''},
|
|
'description': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': None},
|
|
'is_visible': True, 'default': ''},
|
|
'subnet_id': {'allow_post': True, 'allow_put': False,
|
|
'validate': {'type:uuid_or_none': None},
|
|
'is_visible': True, 'default': None},
|
|
'router_id': {'allow_post': True, 'allow_put': False,
|
|
'validate': {'type:uuid': None},
|
|
'is_visible': True},
|
|
'admin_state_up': {'allow_post': True, 'allow_put': True,
|
|
'default': True,
|
|
'convert_to': attr.convert_to_boolean,
|
|
'is_visible': True},
|
|
'external_v4_ip': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'external_v6_ip': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'status': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True}
|
|
},
|
|
|
|
'ipsec_site_connections': {
|
|
'id': {'allow_post': False, 'allow_put': False,
|
|
'validate': {'type:uuid': None},
|
|
'is_visible': True,
|
|
'primary_key': True},
|
|
'tenant_id': {'allow_post': True, 'allow_put': False,
|
|
'validate': {'type:string': None},
|
|
'required_by_policy': True,
|
|
'is_visible': True},
|
|
'name': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': None},
|
|
'is_visible': True, 'default': ''},
|
|
'description': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': None},
|
|
'is_visible': True, 'default': ''},
|
|
'peer_address': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': None},
|
|
'is_visible': True},
|
|
'peer_id': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': None},
|
|
'is_visible': True},
|
|
'peer_cidrs': {'allow_post': True, 'allow_put': True,
|
|
'convert_to': attr.convert_to_list,
|
|
'validate': {'type:subnet_list_or_none': None},
|
|
'is_visible': True,
|
|
'default': None},
|
|
'local_ep_group_id': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:uuid_or_none': None},
|
|
'is_visible': True, 'default': None},
|
|
'peer_ep_group_id': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:uuid_or_none': None},
|
|
'is_visible': True, 'default': None},
|
|
'route_mode': {'allow_post': False, 'allow_put': False,
|
|
'default': 'static',
|
|
'is_visible': True},
|
|
'mtu': {'allow_post': True, 'allow_put': True,
|
|
'default': '1500',
|
|
'validate': {'type:range': positive_int},
|
|
'convert_to': attr.convert_to_int,
|
|
'is_visible': True},
|
|
'initiator': {'allow_post': True, 'allow_put': True,
|
|
'default': 'bi-directional',
|
|
'validate': {'type:values': vpn_supported_initiators},
|
|
'is_visible': True},
|
|
'auth_mode': {'allow_post': False, 'allow_put': False,
|
|
'default': 'psk',
|
|
'validate': {'type:values': vpn_supported_auth_mode},
|
|
'is_visible': True},
|
|
'psk': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': None},
|
|
'is_visible': True},
|
|
'dpd': {'allow_post': True, 'allow_put': True,
|
|
'convert_to': attr.convert_none_to_empty_dict,
|
|
'is_visible': True,
|
|
'default': {},
|
|
'validate': {
|
|
'type:dict_or_empty': {
|
|
'actions': {
|
|
'type:values': vpn_dpd_supported_actions,
|
|
},
|
|
'interval': {
|
|
'type:range': positive_int
|
|
},
|
|
'timeout': {
|
|
'type:range': positive_int
|
|
}}}},
|
|
'admin_state_up': {'allow_post': True, 'allow_put': True,
|
|
'default': True,
|
|
'convert_to': attr.convert_to_boolean,
|
|
'is_visible': True},
|
|
'status': {'allow_post': False, 'allow_put': False,
|
|
'is_visible': True},
|
|
'vpnservice_id': {'allow_post': True, 'allow_put': False,
|
|
'validate': {'type:uuid': None},
|
|
'is_visible': True},
|
|
'ikepolicy_id': {'allow_post': True, 'allow_put': False,
|
|
'validate': {'type:uuid': None},
|
|
'is_visible': True},
|
|
'ipsecpolicy_id': {'allow_post': True, 'allow_put': False,
|
|
'validate': {'type:uuid': None},
|
|
'is_visible': True}
|
|
},
|
|
|
|
'ipsecpolicies': {
|
|
'id': {'allow_post': False, 'allow_put': False,
|
|
'validate': {'type:uuid': None},
|
|
'is_visible': True,
|
|
'primary_key': True},
|
|
'tenant_id': {'allow_post': True, 'allow_put': False,
|
|
'validate': {'type:string': None},
|
|
'required_by_policy': True,
|
|
'is_visible': True},
|
|
'name': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': None},
|
|
'is_visible': True, 'default': ''},
|
|
'description': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': None},
|
|
'is_visible': True, 'default': ''},
|
|
'transform_protocol': {
|
|
'allow_post': True,
|
|
'allow_put': True,
|
|
'default': 'esp',
|
|
'validate': {
|
|
'type:values': vpn_supported_transform_protocols},
|
|
'is_visible': True},
|
|
'auth_algorithm': {
|
|
'allow_post': True,
|
|
'allow_put': True,
|
|
'default': 'sha1',
|
|
'validate': {
|
|
'type:values': vpn_supported_auth_algorithms
|
|
},
|
|
'is_visible': True},
|
|
'encryption_algorithm': {
|
|
'allow_post': True,
|
|
'allow_put': True,
|
|
'default': 'aes-128',
|
|
'validate': {
|
|
'type:values': vpn_supported_encryption_algorithms
|
|
},
|
|
'is_visible': True},
|
|
'encapsulation_mode': {
|
|
'allow_post': True,
|
|
'allow_put': True,
|
|
'default': 'tunnel',
|
|
'validate': {
|
|
'type:values': vpn_supported_encapsulation_mode
|
|
},
|
|
'is_visible': True},
|
|
'lifetime': {'allow_post': True, 'allow_put': True,
|
|
'convert_to': attr.convert_none_to_empty_dict,
|
|
'default': {},
|
|
'validate': {
|
|
'type:dict_or_empty': {
|
|
'units': {
|
|
'type:values': vpn_supported_lifetime_units,
|
|
},
|
|
'value': {
|
|
'type:range': vpn_lifetime_limits
|
|
}}},
|
|
'is_visible': True},
|
|
'pfs': {'allow_post': True, 'allow_put': True,
|
|
'default': 'group5',
|
|
'validate': {'type:values': vpn_supported_pfs},
|
|
'is_visible': True}
|
|
},
|
|
|
|
'ikepolicies': {
|
|
'id': {'allow_post': False, 'allow_put': False,
|
|
'validate': {'type:uuid': None},
|
|
'is_visible': True,
|
|
'primary_key': True},
|
|
'tenant_id': {'allow_post': True, 'allow_put': False,
|
|
'validate': {'type:string': None},
|
|
'required_by_policy': True,
|
|
'is_visible': True},
|
|
'name': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': None},
|
|
'is_visible': True, 'default': ''},
|
|
'description': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': None},
|
|
'is_visible': True, 'default': ''},
|
|
'auth_algorithm': {'allow_post': True, 'allow_put': True,
|
|
'default': 'sha1',
|
|
'validate': {
|
|
'type:values': vpn_supported_auth_algorithms},
|
|
'is_visible': True},
|
|
'encryption_algorithm': {
|
|
'allow_post': True, 'allow_put': True,
|
|
'default': 'aes-128',
|
|
'validate': {'type:values': vpn_supported_encryption_algorithms},
|
|
'is_visible': True},
|
|
'phase1_negotiation_mode': {
|
|
'allow_post': True, 'allow_put': True,
|
|
'default': 'main',
|
|
'validate': {
|
|
'type:values': vpn_supported_phase1_negotiation_mode
|
|
},
|
|
'is_visible': True},
|
|
'lifetime': {'allow_post': True, 'allow_put': True,
|
|
'convert_to': attr.convert_none_to_empty_dict,
|
|
'default': {},
|
|
'validate': {
|
|
'type:dict_or_empty': {
|
|
'units': {
|
|
'type:values': vpn_supported_lifetime_units,
|
|
},
|
|
'value': {
|
|
'type:range': vpn_lifetime_limits,
|
|
}}},
|
|
'is_visible': True},
|
|
'ike_version': {'allow_post': True, 'allow_put': True,
|
|
'default': 'v1',
|
|
'validate': {
|
|
'type:values': vpn_supported_ike_versions},
|
|
'is_visible': True},
|
|
'pfs': {'allow_post': True, 'allow_put': True,
|
|
'default': 'group5',
|
|
'validate': {'type:values': vpn_supported_pfs},
|
|
'is_visible': True}
|
|
},
|
|
|
|
'endpoint_groups': {
|
|
'id': {'allow_post': False, 'allow_put': False,
|
|
'validate': {'type:uuid': None},
|
|
'is_visible': True,
|
|
'primary_key': True},
|
|
'tenant_id': {'allow_post': True, 'allow_put': False,
|
|
'validate': {'type:string': attr.TENANT_ID_MAX_LEN},
|
|
'required_by_policy': True,
|
|
'is_visible': True},
|
|
'name': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': attr.NAME_MAX_LEN},
|
|
'is_visible': True, 'default': ''},
|
|
'description': {'allow_post': True, 'allow_put': True,
|
|
'validate': {'type:string': attr.DESCRIPTION_MAX_LEN},
|
|
'is_visible': True, 'default': ''},
|
|
'type': {'allow_post': True, 'allow_put': False,
|
|
'validate': {
|
|
'type:values': constants.VPN_SUPPORTED_ENDPOINT_TYPES,
|
|
},
|
|
'is_visible': True},
|
|
'endpoints': {'allow_post': True, 'allow_put': False,
|
|
'convert_to': attr.convert_to_list,
|
|
'is_visible': True},
|
|
},
|
|
}
|
|
|
|
|
|
class Vpnaas(extensions.ExtensionDescriptor):
|
|
|
|
@classmethod
|
|
def get_name(cls):
|
|
return "VPN service"
|
|
|
|
@classmethod
|
|
def get_alias(cls):
|
|
return "vpnaas"
|
|
|
|
@classmethod
|
|
def get_description(cls):
|
|
return "Extension for VPN service"
|
|
|
|
@classmethod
|
|
def get_namespace(cls):
|
|
return "https://wiki.openstack.org/Neutron/VPNaaS"
|
|
|
|
@classmethod
|
|
def get_updated(cls):
|
|
return "2013-05-29T10:00:00-00:00"
|
|
|
|
@classmethod
|
|
def get_resources(cls):
|
|
special_mappings = {'ikepolicies': 'ikepolicy',
|
|
'ipsecpolicies': 'ipsecpolicy'}
|
|
plural_mappings = resource_helper.build_plural_mappings(
|
|
special_mappings, RESOURCE_ATTRIBUTE_MAP)
|
|
plural_mappings['peer_cidrs'] = 'peer_cidr'
|
|
attr.PLURALS.update(plural_mappings)
|
|
return resource_helper.build_resource_info(plural_mappings,
|
|
RESOURCE_ATTRIBUTE_MAP,
|
|
nconstants.VPN,
|
|
register_quota=True,
|
|
translate_name=True)
|
|
|
|
@classmethod
|
|
def get_plugin_interface(cls):
|
|
return VPNPluginBase
|
|
|
|
def update_attributes_map(self, attributes):
|
|
super(Vpnaas, self).update_attributes_map(
|
|
attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP)
|
|
|
|
def get_extended_resources(self, version):
|
|
if version == "2.0":
|
|
return RESOURCE_ATTRIBUTE_MAP
|
|
else:
|
|
return {}
|
|
|
|
|
|
@six.add_metaclass(abc.ABCMeta)
|
|
class VPNPluginBase(service_base.ServicePluginBase):
|
|
|
|
def get_plugin_name(self):
|
|
return nconstants.VPN
|
|
|
|
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
|
|
|
|
@abc.abstractmethod
|
|
def create_endpoint_group(self, context, endpoint_group):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def update_endpoint_group(self, context, endpoint_group_id,
|
|
endpoint_group):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def delete_endpoint_group(self, context, endpoint_group_id):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_endpoint_group(self, context, endpoint_group_id, fields=None):
|
|
pass
|
|
|
|
@abc.abstractmethod
|
|
def get_endpoint_groups(self, context, filters=None, fields=None):
|
|
pass
|