diff --git a/neutronclient/neutron/v2_0/vpn/endpoint_group.py b/neutronclient/neutron/v2_0/vpn/endpoint_group.py new file mode 100644 index 000000000..e28e167fa --- /dev/null +++ b/neutronclient/neutron/v2_0/vpn/endpoint_group.py @@ -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' diff --git a/neutronclient/shell.py b/neutronclient/shell.py index 9dbc69dd6..2c25c8365 100644 --- a/neutronclient/shell.py +++ b/neutronclient/shell.py @@ -81,6 +81,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 @@ -332,6 +333,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, diff --git a/neutronclient/tests/unit/vpn/test_cli20_endpoint_group.py b/neutronclient/tests/unit/vpn/test_cli20_endpoint_group.py new file mode 100644 index 000000000..948c14406 --- /dev/null +++ b/neutronclient/tests/unit/vpn/test_cli20_endpoint_group.py @@ -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) diff --git a/neutronclient/v2_0/client.py b/neutronclient/v2_0/client.py index ce6a8b1e4..e1f4faac7 100644 --- a/neutronclient/v2_0/client.py +++ b/neutronclient/v2_0/client.py @@ -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" @@ -447,6 +449,7 @@ class Client(ClientBase): 'ikepolicies': 'ikepolicy', 'ipsec_site_connections': 'ipsec_site_connection', 'vpnservices': 'vpnservice', + 'endpoint_groups': 'endpoint_group', 'vips': 'vip', 'pools': 'pool', 'members': 'member', @@ -802,6 +805,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."""