CRUD for VPN endpoint group API
This contains the create, delete, update, show, and list client APIs for the new VPN endpoint group API. The API syntax is: vpn-endpoint-group-create [--name name] [--description desc] \ --type {subnet|cidr|vlan} --value <value1> [--value <value2>...] vpn-endpoint-group-delete <name-or-uuid> vpn-endpoint-group-show <name-or-uuid> vpn-endpoint-group-update <name-or-uuid> [--name name] [--description desc] vpn-endpoint-group-list Notes: Using prefix "vpn-" on commands, so that there is no conflict with other neutron commands. Note: Using --type and --value, instead of --endpoint_type and --endpoint, which are already used (and must be globally unique). For example, if latter re used, see error "Must specify new values to update endpoint_group". The --value may be repeated multiple times, as a list of endpoints can be added to a group. There must be at least one. For --type=subnet, the user may enter the name or UUID of subnet, which must already exist. Client will translate names to UUIDs. As shown, the endpoints cannot be modified. A new endpoint group must be formed, and then can be used by VPN (once support is in place). When updating, either name or description must be provided (otherwise there is nothing to update). Added unit tests for the new API. DocImpact Change-Id: Ic696674d97474f8bbf3f895aa21b1585a04dc2fe Partial-Bug: 1459423 Depends-On: Ia729bd0c6967fa2b8c698495aa360f340b42d98a Depends-On: I6e10590a988312eafca076a14be38b19e2d44a87
This commit is contained in:
100
neutronclient/neutron/v2_0/vpn/endpoint_group.py
Normal file
100
neutronclient/neutron/v2_0/vpn/endpoint_group.py
Normal file
@@ -0,0 +1,100 @@
|
||||
# (c) Copyright 2015 Cisco Systems, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from neutronclient.i18n import _
|
||||
from neutronclient.neutron import v2_0 as neutronv20
|
||||
|
||||
|
||||
def add_known_endpoint_group_arguments(parser, is_create=True):
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
help=_('Set a name for the endpoint group.'))
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
help=_('Set a description for the endpoint group.'))
|
||||
if is_create:
|
||||
parser.add_argument(
|
||||
'--type',
|
||||
required=is_create,
|
||||
help=_('Type of endpoints in group (e.g. subnet, cidr, vlan).'))
|
||||
parser.add_argument(
|
||||
'--value',
|
||||
action='append', dest='endpoints',
|
||||
required=is_create,
|
||||
help=_('Endpoint(s) for the group. Must all be of the same type.'))
|
||||
|
||||
|
||||
class ListEndpointGroup(neutronv20.ListCommand):
|
||||
"""List VPN endpoint groups that belong to a given tenant."""
|
||||
|
||||
resource = 'endpoint_group'
|
||||
list_columns = ['id', 'name', 'type', 'endpoints']
|
||||
_formatters = {}
|
||||
pagination_support = True
|
||||
sorting_support = True
|
||||
|
||||
|
||||
class ShowEndpointGroup(neutronv20.ShowCommand):
|
||||
"""Show a specific VPN endpoint group."""
|
||||
|
||||
resource = 'endpoint_group'
|
||||
|
||||
|
||||
class CreateEndpointGroup(neutronv20.CreateCommand):
|
||||
"""Create a VPN endpoint group."""
|
||||
resource = 'endpoint_group'
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
add_known_endpoint_group_arguments(parser)
|
||||
|
||||
def subnet_name2id(self, endpoint):
|
||||
return neutronv20.find_resourceid_by_name_or_id(self.get_client(),
|
||||
'subnet', endpoint)
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
if parsed_args.type == 'subnet':
|
||||
endpoints = [self.subnet_name2id(ep)
|
||||
for ep in parsed_args.endpoints]
|
||||
else:
|
||||
endpoints = parsed_args.endpoints
|
||||
|
||||
body = {'endpoints': endpoints}
|
||||
|
||||
neutronv20.update_dict(parsed_args, body,
|
||||
['name', 'description',
|
||||
'tenant_id', 'type'])
|
||||
return {self.resource: body}
|
||||
|
||||
|
||||
class UpdateEndpointGroup(neutronv20.UpdateCommand):
|
||||
"""Update a given VPN endpoint group."""
|
||||
|
||||
resource = 'endpoint_group'
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
add_known_endpoint_group_arguments(parser, is_create=False)
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {}
|
||||
neutronv20.update_dict(parsed_args, body,
|
||||
['name', 'description'])
|
||||
return {self.resource: body}
|
||||
|
||||
|
||||
class DeleteEndpointGroup(neutronv20.DeleteCommand):
|
||||
"""Delete a given VPN endpoint group."""
|
||||
|
||||
resource = 'endpoint_group'
|
@@ -78,6 +78,7 @@ from neutronclient.neutron.v2_0 import securitygroup
|
||||
from neutronclient.neutron.v2_0 import servicetype
|
||||
from neutronclient.neutron.v2_0 import subnet
|
||||
from neutronclient.neutron.v2_0 import subnetpool
|
||||
from neutronclient.neutron.v2_0.vpn import endpoint_group
|
||||
from neutronclient.neutron.v2_0.vpn import ikepolicy
|
||||
from neutronclient.neutron.v2_0.vpn import ipsec_site_connection
|
||||
from neutronclient.neutron.v2_0.vpn import ipsecpolicy
|
||||
@@ -317,6 +318,11 @@ COMMAND_V2 = {
|
||||
'ipsec-site-connection-delete': (
|
||||
ipsec_site_connection.DeleteIPsecSiteConnection
|
||||
),
|
||||
'vpn-endpoint-group-list': endpoint_group.ListEndpointGroup,
|
||||
'vpn-endpoint-group-show': endpoint_group.ShowEndpointGroup,
|
||||
'vpn-endpoint-group-create': endpoint_group.CreateEndpointGroup,
|
||||
'vpn-endpoint-group-update': endpoint_group.UpdateEndpointGroup,
|
||||
'vpn-endpoint-group-delete': endpoint_group.DeleteEndpointGroup,
|
||||
'vpn-service-list': vpnservice.ListVPNService,
|
||||
'vpn-service-show': vpnservice.ShowVPNService,
|
||||
'vpn-service-create': vpnservice.CreateVPNService,
|
||||
|
148
neutronclient/tests/unit/vpn/test_cli20_endpoint_group.py
Normal file
148
neutronclient/tests/unit/vpn/test_cli20_endpoint_group.py
Normal file
@@ -0,0 +1,148 @@
|
||||
# (c) Copyright 2015 Cisco Systems, Inc.
|
||||
# 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 sys
|
||||
|
||||
from neutronclient.neutron.v2_0.vpn import endpoint_group
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20VpnEndpointGroupJSON(test_cli20.CLITestV20Base):
|
||||
|
||||
def setUp(self):
|
||||
super(CLITestV20VpnEndpointGroupJSON, self).setUp()
|
||||
self.register_non_admin_status_resource('endpoint_group')
|
||||
|
||||
def test_create_endpoint_group_with_cidrs(self):
|
||||
"""vpn-endpoint-group-create with CIDR endpoints."""
|
||||
resource = 'endpoint_group'
|
||||
cmd = endpoint_group.CreateEndpointGroup(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
tenant_id = 'mytenant-id'
|
||||
my_id = 'my-id'
|
||||
name = 'my-endpoint-group'
|
||||
description = 'my endpoint group'
|
||||
endpoint_type = 'cidr'
|
||||
endpoints = ['10.0.0.0/24', '20.0.0.0/24']
|
||||
|
||||
args = ['--name', name,
|
||||
'--description', description,
|
||||
'--tenant-id', tenant_id,
|
||||
'--type', endpoint_type,
|
||||
'--value', '10.0.0.0/24',
|
||||
'--value', '20.0.0.0/24']
|
||||
|
||||
position_names = ['name', 'description', 'tenant_id',
|
||||
'type', 'endpoints']
|
||||
|
||||
position_values = [name, description, tenant_id,
|
||||
endpoint_type, endpoints]
|
||||
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_endpoint_group_with_subnets(self):
|
||||
"""vpn-endpoint-group-create with subnet endpoints."""
|
||||
resource = 'endpoint_group'
|
||||
cmd = endpoint_group.CreateEndpointGroup(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
tenant_id = 'mytenant-id'
|
||||
my_id = 'my-id'
|
||||
endpoint_type = 'subnet'
|
||||
subnet = 'subnet-id'
|
||||
endpoints = [subnet]
|
||||
|
||||
args = ['--type', endpoint_type,
|
||||
'--value', subnet,
|
||||
'--tenant-id', tenant_id]
|
||||
|
||||
position_names = ['type', 'endpoints', 'tenant_id']
|
||||
|
||||
position_values = [endpoint_type, endpoints, tenant_id]
|
||||
|
||||
self._test_create_resource(resource, cmd, None, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_list_endpoint_group(self):
|
||||
"""vpn-endpoint-group-list."""
|
||||
resources = "endpoint_groups"
|
||||
cmd = endpoint_group.ListEndpointGroup(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_list_endpoint_group_pagination(self):
|
||||
"""vpn-endpoint-group-list."""
|
||||
resources = "endpoint_groups"
|
||||
cmd = endpoint_group.ListEndpointGroup(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources_with_pagination(resources, cmd)
|
||||
|
||||
def test_list_endpoint_group_sort(self):
|
||||
"""vpn-endpoint-group-list --sort-key name --sort-key id
|
||||
--sort-key asc --sort-key desc
|
||||
"""
|
||||
resources = "endpoint_groups"
|
||||
cmd = endpoint_group.ListEndpointGroup(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_list_endpoint_group_limit(self):
|
||||
"""vpn-endpoint-group-list -P."""
|
||||
resources = "endpoint_groups"
|
||||
cmd = endpoint_group.ListEndpointGroup(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
def test_show_endpoint_group_id(self):
|
||||
"""vpn-endpoint-group-show test_id."""
|
||||
resource = 'endpoint_group'
|
||||
cmd = endpoint_group.ShowEndpointGroup(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_show_endpoint_group_id_name(self):
|
||||
"""vpn-endpoint-group-show."""
|
||||
resource = 'endpoint_group'
|
||||
cmd = endpoint_group.ShowEndpointGroup(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_update_endpoint_group(self):
|
||||
"""vpn-endpoint-group-update myid --name newname
|
||||
--description newdesc.
|
||||
"""
|
||||
resource = 'endpoint_group'
|
||||
cmd = endpoint_group.UpdateEndpointGroup(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'newname',
|
||||
'--description', 'newdesc'],
|
||||
{'name': 'newname',
|
||||
'description': 'newdesc'})
|
||||
|
||||
def test_delete_endpoint_group(self):
|
||||
"""vpn-endpoint-group-delete my-id."""
|
||||
resource = 'endpoint_group'
|
||||
cmd = endpoint_group.DeleteEndpointGroup(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
@@ -355,6 +355,8 @@ class Client(ClientBase):
|
||||
security_group_path = "/security-groups/%s"
|
||||
security_group_rules_path = "/security-group-rules"
|
||||
security_group_rule_path = "/security-group-rules/%s"
|
||||
endpoint_groups_path = "/vpn/endpoint-groups"
|
||||
endpoint_group_path = "/vpn/endpoint-groups/%s"
|
||||
vpnservices_path = "/vpn/vpnservices"
|
||||
vpnservice_path = "/vpn/vpnservices/%s"
|
||||
ipsecpolicies_path = "/vpn/ipsecpolicies"
|
||||
@@ -439,6 +441,7 @@ class Client(ClientBase):
|
||||
'ikepolicies': 'ikepolicy',
|
||||
'ipsec_site_connections': 'ipsec_site_connection',
|
||||
'vpnservices': 'vpnservice',
|
||||
'endpoint_groups': 'endpoint_group',
|
||||
'vips': 'vip',
|
||||
'pools': 'pool',
|
||||
'members': 'member',
|
||||
@@ -794,6 +797,33 @@ class Client(ClientBase):
|
||||
return self.get(self.security_group_rule_path % (security_group_rule),
|
||||
params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def list_endpoint_groups(self, retrieve_all=True, **_params):
|
||||
"""Fetches a list of all VPN endpoint groups for a tenant."""
|
||||
return self.list('endpoint_groups', self.endpoint_groups_path,
|
||||
retrieve_all, **_params)
|
||||
|
||||
@APIParamsCall
|
||||
def show_endpoint_group(self, endpointgroup, **_params):
|
||||
"""Fetches information for a specific VPN endpoint group."""
|
||||
return self.get(self.endpoint_group_path % endpointgroup,
|
||||
params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def create_endpoint_group(self, body=None):
|
||||
"""Creates a new VPN endpoint group."""
|
||||
return self.post(self.endpoint_groups_path, body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def update_endpoint_group(self, endpoint_group, body=None):
|
||||
"""Updates a VPN endpoint group."""
|
||||
return self.put(self.endpoint_group_path % endpoint_group, body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_endpoint_group(self, endpoint_group):
|
||||
"""Deletes the specified VPN endpoint group."""
|
||||
return self.delete(self.endpoint_group_path % endpoint_group)
|
||||
|
||||
@APIParamsCall
|
||||
def list_vpnservices(self, retrieve_all=True, **_params):
|
||||
"""Fetches a list of all configured VPN services for a tenant."""
|
||||
|
Reference in New Issue
Block a user