Make VPN endpoint groups aware from API
There is no way to check whether the VPN endpoint groups feature is available without sending an API request at now. This commit split VPN endpoint groups feature as an extension. By doing so, API consumers including Horizon can know the feature is available through Neutron extension list API. Note that this commit touches only the API layer and does not touch the DB layer because the endpoint groups feature is the first citizen of VPNaaS API. Closes-Bug: #1515670 Change-Id: I82a3ab60b5a50eee2b4a84b54829a323cd2b3fb1
This commit is contained in:
parent
dcdfc8a2f9
commit
1afd7fc22a
|
@ -34,13 +34,16 @@ from sqlalchemy.orm import exc
|
|||
from neutron_vpnaas._i18n import _LW
|
||||
from neutron_vpnaas.db.vpn import vpn_models
|
||||
from neutron_vpnaas.db.vpn import vpn_validator
|
||||
from neutron_vpnaas.extensions import vpn_endpoint_groups
|
||||
from neutron_vpnaas.extensions import vpnaas
|
||||
from neutron_vpnaas.services.vpn.common import constants as v_constants
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class VPNPluginDb(vpnaas.VPNPluginBase, base_db.CommonDbMixin):
|
||||
class VPNPluginDb(vpnaas.VPNPluginBase,
|
||||
vpn_endpoint_groups.VPNEndpointGroupsPluginBase,
|
||||
base_db.CommonDbMixin):
|
||||
"""VPN plugin database class using SQLAlchemy models."""
|
||||
|
||||
def _get_validator(self):
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
# (c) Copyright 2015 NEC Corporation, 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.plugins.common import constants as nconstants
|
||||
|
||||
from neutron_vpnaas.services.vpn.common import constants
|
||||
|
||||
|
||||
RESOURCE_ATTRIBUTE_MAP = {
|
||||
|
||||
'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 Vpn_endpoint_groups(extensions.ExtensionDescriptor):
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return "VPN Endpoint Groups"
|
||||
|
||||
@classmethod
|
||||
def get_alias(cls):
|
||||
return "vpn-endpoint-groups"
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
return "VPN endpoint groups support"
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
return "2015-08-04T10:00:00-00:00"
|
||||
|
||||
@classmethod
|
||||
def get_resources(cls):
|
||||
plural_mappings = resource_helper.build_plural_mappings(
|
||||
{}, RESOURCE_ATTRIBUTE_MAP)
|
||||
attr.PLURALS.update(plural_mappings)
|
||||
return resource_helper.build_resource_info(plural_mappings,
|
||||
RESOURCE_ATTRIBUTE_MAP,
|
||||
nconstants.VPN,
|
||||
register_quota=True,
|
||||
translate_name=True)
|
||||
|
||||
def get_required_extensions(self):
|
||||
return ["vpnaas"]
|
||||
|
||||
def update_attributes_map(self, attributes):
|
||||
super(Vpn_endpoint_groups, 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 VPNEndpointGroupsPluginBase(object):
|
||||
|
||||
@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
|
|
@ -24,8 +24,6 @@ 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")
|
||||
|
@ -423,31 +421,6 @@ RESOURCE_ATTRIBUTE_MAP = {
|
|||
'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},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
@ -595,24 +568,3 @@ class VPNPluginBase(service_base.ServicePluginBase):
|
|||
@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
|
||||
|
|
|
@ -40,7 +40,9 @@ class VPNPlugin(vpn_db.VPNPluginDb):
|
|||
Most DB related works are implemented in class
|
||||
vpn_db.VPNPluginDb.
|
||||
"""
|
||||
supported_extension_aliases = ["vpnaas", "service-type"]
|
||||
supported_extension_aliases = ["vpnaas",
|
||||
"vpn-endpoint-groups",
|
||||
"service-type"]
|
||||
path_prefix = "/vpn"
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
# (c) Copyright 2015 NEC Corporation, 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 copy
|
||||
|
||||
import mock
|
||||
from oslo_utils import uuidutils
|
||||
from webob import exc
|
||||
|
||||
from neutron.plugins.common import constants as nconstants
|
||||
from neutron.tests.unit.api.v2 import test_base as test_api_v2
|
||||
|
||||
from neutron_vpnaas.extensions import vpn_endpoint_groups
|
||||
from neutron_vpnaas.extensions import vpnaas
|
||||
from neutron_vpnaas.services.vpn.common import constants
|
||||
from neutron_vpnaas.tests import base
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
_get_path = test_api_v2._get_path
|
||||
|
||||
|
||||
class VpnEndpointGroupsTestPlugin(
|
||||
vpnaas.VPNPluginBase,
|
||||
vpn_endpoint_groups.VPNEndpointGroupsPluginBase):
|
||||
pass
|
||||
|
||||
|
||||
class VpnEndpointGroupsTestCase(base.ExtensionTestCase):
|
||||
|
||||
fmt = 'json'
|
||||
|
||||
def setUp(self):
|
||||
super(VpnEndpointGroupsTestCase, self).setUp()
|
||||
plural_mappings = {'endpoint_group': 'endpoint-groups'}
|
||||
self._setUpExtension(
|
||||
'neutron_vpnaas.tests.unit.extensions.test_vpn_endpoint_groups.'
|
||||
'VpnEndpointGroupsTestPlugin',
|
||||
nconstants.VPN,
|
||||
vpn_endpoint_groups.RESOURCE_ATTRIBUTE_MAP,
|
||||
vpn_endpoint_groups.Vpn_endpoint_groups,
|
||||
'vpn', plural_mappings=plural_mappings,
|
||||
use_quota=True)
|
||||
|
||||
def helper_test_endpoint_group_create(self, data):
|
||||
"""Check that the endpoint_group_create works.
|
||||
|
||||
Uses passed in endpoint group information, which specifies an
|
||||
endpoint type and values.
|
||||
"""
|
||||
data['endpoint_group'].update({'tenant_id': _uuid(),
|
||||
'name': 'my endpoint group',
|
||||
'description': 'my description'})
|
||||
return_value = copy.copy(data['endpoint_group'])
|
||||
return_value.update({'id': _uuid()})
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.create_endpoint_group.return_value = return_value
|
||||
res = self.api.post(_get_path('vpn/endpoint-groups', fmt=self.fmt),
|
||||
self.serialize(data),
|
||||
content_type='application/%s' % self.fmt)
|
||||
instance.create_endpoint_group.assert_called_with(
|
||||
mock.ANY, endpoint_group=data)
|
||||
self.assertEqual(exc.HTTPCreated.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint_group', res)
|
||||
self.assertEqual(res['endpoint_group'], return_value)
|
||||
|
||||
def test_create_cidr_endpoint_group_create(self):
|
||||
"""Test creation of CIDR type endpoint group."""
|
||||
data = {'endpoint_group':
|
||||
{'type': constants.CIDR_ENDPOINT,
|
||||
'endpoints': ['10.10.10.0/24', '20.20.20.0/24']}}
|
||||
self.helper_test_endpoint_group_create(data)
|
||||
|
||||
def test_create_subnet_endpoint_group_create(self):
|
||||
"""Test creation of subnet type endpoint group."""
|
||||
data = {'endpoint_group':
|
||||
{'type': constants.SUBNET_ENDPOINT,
|
||||
'endpoints': [_uuid(), _uuid()]}}
|
||||
self.helper_test_endpoint_group_create(data)
|
||||
|
||||
def test_create_vlan_endpoint_group_create(self):
|
||||
"""Test creation of VLAN type endpoint group."""
|
||||
data = {'endpoint_group':
|
||||
{'type': constants.VLAN_ENDPOINT,
|
||||
'endpoints': ['100', '200', '300', '400']}}
|
||||
self.helper_test_endpoint_group_create(data)
|
||||
|
||||
def test_get_endpoint_group(self):
|
||||
"""Test show for endpoint group."""
|
||||
endpoint_group_id = _uuid()
|
||||
return_value = {'id': endpoint_group_id,
|
||||
'tenant_id': _uuid(),
|
||||
'name': 'my-endpoint-group',
|
||||
'description': 'my endpoint group',
|
||||
'type': constants.CIDR_ENDPOINT,
|
||||
'endpoints': ['10.10.10.0/24']}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_endpoint_group.return_value = return_value
|
||||
|
||||
res = self.api.get(_get_path('vpn/endpoint-groups',
|
||||
id=endpoint_group_id,
|
||||
fmt=self.fmt))
|
||||
|
||||
instance.get_endpoint_group.assert_called_with(mock.ANY,
|
||||
endpoint_group_id,
|
||||
fields=mock.ANY)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint_group', res)
|
||||
self.assertEqual(res['endpoint_group'], return_value)
|
||||
|
||||
def test_endpoint_group_list(self):
|
||||
"""Test listing all endpoint groups."""
|
||||
return_value = [{'id': _uuid(),
|
||||
'tenant_id': _uuid(),
|
||||
'name': 'my-endpoint-group',
|
||||
'description': 'my endpoint group',
|
||||
'type': constants.CIDR_ENDPOINT,
|
||||
'endpoints': ['10.10.10.0/24']},
|
||||
{'id': _uuid(),
|
||||
'tenant_id': _uuid(),
|
||||
'name': 'another-endpoint-group',
|
||||
'description': 'second endpoint group',
|
||||
'type': constants.VLAN_ENDPOINT,
|
||||
'endpoints': ['100', '200', '300']}]
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_endpoint_groups.return_value = return_value
|
||||
|
||||
res = self.api.get(_get_path('vpn/endpoint-groups', fmt=self.fmt))
|
||||
|
||||
instance.get_endpoint_groups.assert_called_with(mock.ANY,
|
||||
fields=mock.ANY,
|
||||
filters=mock.ANY)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
|
||||
def test_endpoint_group_delete(self):
|
||||
"""Test deleting an endpoint group."""
|
||||
self._test_entity_delete('endpoint_group')
|
||||
|
||||
def test_endpoint_group_update(self):
|
||||
"""Test updating endpoint_group."""
|
||||
endpoint_group_id = _uuid()
|
||||
update_data = {'endpoint_group': {'description': 'new description'}}
|
||||
return_value = {'id': endpoint_group_id,
|
||||
'tenant_id': _uuid(),
|
||||
'name': 'my-endpoint-group',
|
||||
'description': 'new_description',
|
||||
'type': constants.CIDR_ENDPOINT,
|
||||
'endpoints': ['10.10.10.0/24']}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.update_endpoint_group.return_value = return_value
|
||||
|
||||
res = self.api.put(_get_path('vpn/endpoint-groups',
|
||||
id=endpoint_group_id,
|
||||
fmt=self.fmt),
|
||||
self.serialize(update_data))
|
||||
|
||||
instance.update_endpoint_group.assert_called_with(
|
||||
mock.ANY, endpoint_group_id, endpoint_group=update_data)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint_group', res)
|
||||
self.assertEqual(res['endpoint_group'], return_value)
|
||||
|
||||
def test_fail_updating_endpoints_in_endpoint_group(self):
|
||||
"""Test fails to update the endpoints in an endpoint group.
|
||||
|
||||
This documents that we are not allowing endpoints to be updated
|
||||
(currently), as doing so, implies that the connection using the
|
||||
enclosing endpoint group would also need to be updated. For now,
|
||||
a new endpoint group can be created, and the connection can be
|
||||
updated to point to the new endpoint group.
|
||||
"""
|
||||
endpoint_group_id = _uuid()
|
||||
update_data = {'endpoint_group': {'endpoints': ['10.10.10.0/24']}}
|
||||
res = self.api.put(_get_path('vpn/endpoint-groups',
|
||||
id=endpoint_group_id,
|
||||
fmt=self.fmt),
|
||||
params=self.serialize(update_data),
|
||||
expect_errors=True)
|
||||
self.assertEqual(exc.HTTPBadRequest.code, res.status_int)
|
|
@ -21,7 +21,6 @@ from oslo_utils import uuidutils
|
|||
from webob import exc
|
||||
|
||||
from neutron_vpnaas.extensions import vpnaas
|
||||
from neutron_vpnaas.services.vpn.common import constants
|
||||
from neutron_vpnaas.tests import base
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
|
@ -567,146 +566,3 @@ class VpnaasExtensionTestCase(base.ExtensionTestCase):
|
|||
def test_ipsec_site_connection_delete(self):
|
||||
"""Test case to delete a ipsec_site_connection."""
|
||||
self._test_entity_delete('ipsec_site_connection')
|
||||
|
||||
def helper_test_endpoint_group_create(self, data):
|
||||
"""Check that the endpoint_group_create works.
|
||||
|
||||
Uses passed in endpoint group information, which specifies an
|
||||
endpoint type and values.
|
||||
"""
|
||||
data['endpoint_group'].update({'tenant_id': _uuid(),
|
||||
'name': 'my endpoint group',
|
||||
'description': 'my description'})
|
||||
return_value = copy.copy(data['endpoint_group'])
|
||||
return_value.update({'id': _uuid()})
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.create_endpoint_group.return_value = return_value
|
||||
res = self.api.post(_get_path('vpn/endpoint-groups', fmt=self.fmt),
|
||||
self.serialize(data),
|
||||
content_type='application/%s' % self.fmt)
|
||||
instance.create_endpoint_group.assert_called_with(
|
||||
mock.ANY, endpoint_group=data)
|
||||
self.assertEqual(exc.HTTPCreated.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint_group', res)
|
||||
self.assertEqual(res['endpoint_group'], return_value)
|
||||
|
||||
def test_create_cidr_endpoint_group_create(self):
|
||||
"""Test creation of CIDR type endpoint group."""
|
||||
data = {'endpoint_group':
|
||||
{'type': constants.CIDR_ENDPOINT,
|
||||
'endpoints': ['10.10.10.0/24', '20.20.20.0/24']}}
|
||||
self.helper_test_endpoint_group_create(data)
|
||||
|
||||
def test_create_subnet_endpoint_group_create(self):
|
||||
"""Test creation of subnet type endpoint group."""
|
||||
data = {'endpoint_group':
|
||||
{'type': constants.SUBNET_ENDPOINT,
|
||||
'endpoints': [_uuid(), _uuid()]}}
|
||||
self.helper_test_endpoint_group_create(data)
|
||||
|
||||
def test_create_vlan_endpoint_group_create(self):
|
||||
"""Test creation of VLAN type endpoint group."""
|
||||
data = {'endpoint_group':
|
||||
{'type': constants.VLAN_ENDPOINT,
|
||||
'endpoints': ['100', '200', '300', '400']}}
|
||||
self.helper_test_endpoint_group_create(data)
|
||||
|
||||
def test_get_endpoint_group(self):
|
||||
"""Test show for endpoint group."""
|
||||
endpoint_group_id = _uuid()
|
||||
return_value = {'id': endpoint_group_id,
|
||||
'tenant_id': _uuid(),
|
||||
'name': 'my-endpoint-group',
|
||||
'description': 'my endpoint group',
|
||||
'type': constants.CIDR_ENDPOINT,
|
||||
'endpoints': ['10.10.10.0/24']}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_endpoint_group.return_value = return_value
|
||||
|
||||
res = self.api.get(_get_path('vpn/endpoint-groups',
|
||||
id=endpoint_group_id,
|
||||
fmt=self.fmt))
|
||||
|
||||
instance.get_endpoint_group.assert_called_with(mock.ANY,
|
||||
endpoint_group_id,
|
||||
fields=mock.ANY)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint_group', res)
|
||||
self.assertEqual(res['endpoint_group'], return_value)
|
||||
|
||||
def test_endpoint_group_list(self):
|
||||
"""Test listing all endpoint groups."""
|
||||
return_value = [{'id': _uuid(),
|
||||
'tenant_id': _uuid(),
|
||||
'name': 'my-endpoint-group',
|
||||
'description': 'my endpoint group',
|
||||
'type': constants.CIDR_ENDPOINT,
|
||||
'endpoints': ['10.10.10.0/24']},
|
||||
{'id': _uuid(),
|
||||
'tenant_id': _uuid(),
|
||||
'name': 'another-endpoint-group',
|
||||
'description': 'second endpoint group',
|
||||
'type': constants.VLAN_ENDPOINT,
|
||||
'endpoints': ['100', '200', '300']}]
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.get_endpoint_groups.return_value = return_value
|
||||
|
||||
res = self.api.get(_get_path('vpn/endpoint-groups', fmt=self.fmt))
|
||||
|
||||
instance.get_endpoint_groups.assert_called_with(mock.ANY,
|
||||
fields=mock.ANY,
|
||||
filters=mock.ANY)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
|
||||
def test_endpoint_group_delete(self):
|
||||
"""Test deleting an endpoint group."""
|
||||
self._test_entity_delete('endpoint_group')
|
||||
|
||||
def test_endpoint_group_update(self):
|
||||
"""Test updating endpoint_group."""
|
||||
endpoint_group_id = _uuid()
|
||||
update_data = {'endpoint_group': {'description': 'new description'}}
|
||||
return_value = {'id': endpoint_group_id,
|
||||
'tenant_id': _uuid(),
|
||||
'name': 'my-endpoint-group',
|
||||
'description': 'new_description',
|
||||
'type': constants.CIDR_ENDPOINT,
|
||||
'endpoints': ['10.10.10.0/24']}
|
||||
|
||||
instance = self.plugin.return_value
|
||||
instance.update_endpoint_group.return_value = return_value
|
||||
|
||||
res = self.api.put(_get_path('vpn/endpoint-groups',
|
||||
id=endpoint_group_id,
|
||||
fmt=self.fmt),
|
||||
self.serialize(update_data))
|
||||
|
||||
instance.update_endpoint_group.assert_called_with(
|
||||
mock.ANY, endpoint_group_id, endpoint_group=update_data)
|
||||
self.assertEqual(res.status_int, exc.HTTPOk.code)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint_group', res)
|
||||
self.assertEqual(res['endpoint_group'], return_value)
|
||||
|
||||
def test_fail_updating_endpoints_in_endpoint_group(self):
|
||||
"""Test fails to update the endpoints in an endpoint group.
|
||||
|
||||
This documents that we are not allowing endpoints to be updated
|
||||
(currently), as doing so, implies that the connection using the
|
||||
enclosing endpoint group would also need to be updated. For now,
|
||||
a new endpoint group can be created, and the connection can be
|
||||
updated to point to the new endpoint group.
|
||||
"""
|
||||
endpoint_group_id = _uuid()
|
||||
update_data = {'endpoint_group': {'endpoints': ['10.10.10.0/24']}}
|
||||
res = self.api.put(_get_path('vpn/endpoint-groups',
|
||||
id=endpoint_group_id,
|
||||
fmt=self.fmt),
|
||||
params=self.serialize(update_data),
|
||||
expect_errors=True)
|
||||
self.assertEqual(exc.HTTPBadRequest.code, res.status_int)
|
||||
|
|
Loading…
Reference in New Issue