Add Neutron subnetpool API
Add Neutron subnetpool listing, creating, updating, showing and deleting Client API. neutron subnetpool-list neutron subnetpool-create neutron subnetpool-update neutron subnetpool-show neutron subnetpool-delete Change-Id: I19a6782d33609609f43353df8293864e60ead817 Partially-Implements: blueprint subnet-allocation
This commit is contained in:
parent
d6cfd34e13
commit
b978f90901
@ -36,6 +36,7 @@ TYPE_DICT = "dict"
|
||||
PLURALS = {'networks': 'network',
|
||||
'ports': 'port',
|
||||
'subnets': 'subnet',
|
||||
'subnetpools': 'subnetpool',
|
||||
'dns_nameservers': 'dns_nameserver',
|
||||
'host_routes': 'host_route',
|
||||
'allocation_pools': 'allocation_pool',
|
||||
|
101
neutronclient/neutron/v2_0/subnetpool.py
Normal file
101
neutronclient/neutron/v2_0/subnetpool.py
Normal file
@ -0,0 +1,101 @@
|
||||
# Copyright 2015 OpenStack Foundation.
|
||||
# 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_updatable_arguments(parser):
|
||||
parser.add_argument(
|
||||
'--min-prefixlen', type=int,
|
||||
help=_('Subnetpool minimum prefix length.'))
|
||||
parser.add_argument(
|
||||
'--max-prefixlen', type=int,
|
||||
help=_('Subnetpool maximum prefix length.'))
|
||||
parser.add_argument(
|
||||
'--default-prefixlen', type=int,
|
||||
help=_('Subnetpool default prefix length.'))
|
||||
parser.add_argument(
|
||||
'--pool-prefix',
|
||||
action='append', dest='prefixes',
|
||||
help=_('Subnetpool prefixes (This option can be repeated).'))
|
||||
|
||||
|
||||
def updatable_args2body(parsed_args, body, for_create=True):
|
||||
neutronV20.update_dict(parsed_args, body['subnetpool'],
|
||||
['name', 'prefixes', 'default_prefixlen',
|
||||
'min_prefixlen', 'max_prefixlen'])
|
||||
|
||||
|
||||
class ListSubnetPool(neutronV20.ListCommand):
|
||||
"""List subnetpools that belong to a given tenant."""
|
||||
|
||||
resource = 'subnetpool'
|
||||
list_columns = ['id', 'name', 'prefixes',
|
||||
'default_prefixlen']
|
||||
pagination_support = True
|
||||
sorting_support = True
|
||||
|
||||
|
||||
class ShowSubnetPool(neutronV20.ShowCommand):
|
||||
"""Show information of a given subnetpool."""
|
||||
|
||||
resource = 'subnetpool'
|
||||
|
||||
|
||||
class CreateSubnetPool(neutronV20.CreateCommand):
|
||||
"""Create a subnetpool for a given tenant."""
|
||||
|
||||
resource = 'subnetpool'
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
add_updatable_arguments(parser)
|
||||
parser.add_argument(
|
||||
'--shared',
|
||||
action='store_true',
|
||||
help=_('Set the subnetpool as shared.'))
|
||||
parser.add_argument(
|
||||
'name',
|
||||
help=_('Name of subnetpool to create.'))
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {'subnetpool': {'prefixes': parsed_args.prefixes}}
|
||||
updatable_args2body(parsed_args, body)
|
||||
if parsed_args.shared:
|
||||
body['subnetpool']['shared'] = True
|
||||
return body
|
||||
|
||||
|
||||
class DeleteSubnetPool(neutronV20.DeleteCommand):
|
||||
"""Delete a given subnetpool."""
|
||||
|
||||
resource = 'subnetpool'
|
||||
|
||||
|
||||
class UpdateSubnetPool(neutronV20.UpdateCommand):
|
||||
"""Update subnetpool's information."""
|
||||
|
||||
resource = 'subnetpool'
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
add_updatable_arguments(parser)
|
||||
parser.add_argument('--name',
|
||||
help=_('Name of subnetpool to update.'))
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {'subnetpool': {}}
|
||||
updatable_args2body(parsed_args, body, for_create=False)
|
||||
return body
|
@ -76,6 +76,7 @@ from neutronclient.neutron.v2_0 import router
|
||||
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 ikepolicy
|
||||
from neutronclient.neutron.v2_0.vpn import ipsec_site_connection
|
||||
from neutronclient.neutron.v2_0.vpn import ipsecpolicy
|
||||
@ -142,6 +143,11 @@ COMMAND_V2 = {
|
||||
'subnet-create': subnet.CreateSubnet,
|
||||
'subnet-delete': subnet.DeleteSubnet,
|
||||
'subnet-update': subnet.UpdateSubnet,
|
||||
'subnetpool-list': subnetpool.ListSubnetPool,
|
||||
'subnetpool-show': subnetpool.ShowSubnetPool,
|
||||
'subnetpool-create': subnetpool.CreateSubnetPool,
|
||||
'subnetpool-delete': subnetpool.DeleteSubnetPool,
|
||||
'subnetpool-update': subnetpool.UpdateSubnetPool,
|
||||
'port-list': port.ListPort,
|
||||
'port-show': port.ShowPort,
|
||||
'port-create': port.CreatePort,
|
||||
|
@ -222,7 +222,7 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
'policy_profile', 'ikepolicy',
|
||||
'ipsecpolicy', 'metering_label',
|
||||
'metering_label_rule', 'net_partition',
|
||||
'fox_socket']
|
||||
'fox_socket', 'subnetpool']
|
||||
if not cmd_resource:
|
||||
cmd_resource = resource
|
||||
if (resource in non_admin_status_resources):
|
||||
|
132
neutronclient/tests/unit/test_cli20_subnetpool.py
Normal file
132
neutronclient/tests/unit/test_cli20_subnetpool.py
Normal file
@ -0,0 +1,132 @@
|
||||
# Copyright 2015 OpenStack Foundation.
|
||||
# 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 mox3 import mox
|
||||
|
||||
from neutronclient.common import exceptions
|
||||
from neutronclient.neutron.v2_0 import subnetpool
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20SubnetPoolJSON(test_cli20.CLITestV20Base):
|
||||
def setUp(self):
|
||||
super(CLITestV20SubnetPoolJSON, self).setUp(plurals={'tags': 'tag'})
|
||||
|
||||
def test_create_subnetpool_shared(self):
|
||||
"""Create subnetpool: myname."""
|
||||
resource = 'subnetpool'
|
||||
cmd = subnetpool.CreateSubnetPool(test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'myname'
|
||||
myid = 'myid'
|
||||
min_prefixlen = 30
|
||||
prefix1 = '10.11.12.0/24'
|
||||
prefix2 = '12.11.13.0/24'
|
||||
args = [name, '--min-prefixlen', str(min_prefixlen),
|
||||
'--pool-prefix', prefix1, '--pool-prefix', prefix2,
|
||||
'--shared']
|
||||
position_names = ['name', 'min_prefixlen', 'prefixes', 'shared']
|
||||
position_values = [name, min_prefixlen, [prefix1, prefix2], True]
|
||||
self._test_create_resource(resource, cmd, name, myid, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_subnetpool_not_shared(self):
|
||||
"""Create subnetpool: myname."""
|
||||
resource = 'subnetpool'
|
||||
cmd = subnetpool.CreateSubnetPool(test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'myname'
|
||||
myid = 'myid'
|
||||
min_prefixlen = 30
|
||||
prefix1 = '10.11.12.0/24'
|
||||
prefix2 = '12.11.13.0/24'
|
||||
args = [name, '--min-prefixlen', str(min_prefixlen),
|
||||
'--pool-prefix', prefix1, '--pool-prefix', prefix2]
|
||||
position_names = ['name', 'min_prefixlen', 'prefixes']
|
||||
position_values = [name, min_prefixlen, [prefix1, prefix2]]
|
||||
self._test_create_resource(resource, cmd, name, myid, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_subnetpool_with_unicode(self):
|
||||
"""Create subnetpool: u'\u7f51\u7edc'."""
|
||||
resource = 'subnetpool'
|
||||
cmd = subnetpool.CreateSubnetPool(test_cli20.MyApp(sys.stdout), None)
|
||||
name = u'\u7f51\u7edc'
|
||||
myid = 'myid'
|
||||
min_prefixlen = 30
|
||||
prefixes = '10.11.12.0/24'
|
||||
args = [name, '--min-prefixlen', str(min_prefixlen),
|
||||
'--pool-prefix', prefixes]
|
||||
position_names = ['name', 'min_prefixlen', 'prefixes']
|
||||
position_values = [name, min_prefixlen, [prefixes]]
|
||||
self._test_create_resource(resource, cmd, name, myid, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_list_subnetpool_pagination(self):
|
||||
cmd = subnetpool.ListSubnetPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self.mox.StubOutWithMock(subnetpool.ListSubnetPool, "extend_list")
|
||||
subnetpool.ListSubnetPool.extend_list(mox.IsA(list), mox.IgnoreArg())
|
||||
self._test_list_resources_with_pagination("subnetpools", cmd)
|
||||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
|
||||
def test_list_subnetpools_sort(self):
|
||||
"""List subnetpools: --sort-key name --sort-key id --sort-key asc
|
||||
--sort-key desc
|
||||
"""
|
||||
resources = "subnetpools"
|
||||
cmd = subnetpool.ListSubnetPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd,
|
||||
sort_key=["name", "id"],
|
||||
sort_dir=["asc", "desc"])
|
||||
|
||||
def test_list_subnetpools_limit(self):
|
||||
"""List subnetpools: -P."""
|
||||
resources = "subnetpools"
|
||||
cmd = subnetpool.ListSubnetPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
def test_update_subnetpool_exception(self):
|
||||
"""Update subnetpool: myid."""
|
||||
resource = 'subnetpool'
|
||||
cmd = subnetpool.UpdateSubnetPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self.assertRaises(exceptions.CommandError, self._test_update_resource,
|
||||
resource, cmd, 'myid', ['myid'], {})
|
||||
|
||||
def test_update_subnetpool(self):
|
||||
"""Update subnetpool: myid --name myname."""
|
||||
resource = 'subnetpool'
|
||||
cmd = subnetpool.UpdateSubnetPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'myname'],
|
||||
{'name': 'myname'}
|
||||
)
|
||||
|
||||
def test_show_subnetpool(self):
|
||||
"""Show subnetpool: --fields id --fields name myid."""
|
||||
resource = 'subnetpool'
|
||||
cmd = subnetpool.ShowSubnetPool(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_delete_subnetpool(self):
|
||||
"""Delete subnetpool: subnetpoolid."""
|
||||
resource = 'subnetpool'
|
||||
cmd = subnetpool.DeleteSubnetPool(test_cli20.MyApp(sys.stdout), None)
|
||||
myid = 'myid'
|
||||
args = [myid]
|
||||
self._test_delete_resource(resource, cmd, myid, args)
|
@ -339,6 +339,8 @@ class Client(ClientBase):
|
||||
port_path = "/ports/%s"
|
||||
subnets_path = "/subnets"
|
||||
subnet_path = "/subnets/%s"
|
||||
subnetpools_path = "/subnetpools"
|
||||
subnetpool_path = "/subnetpools/%s"
|
||||
quotas_path = "/quotas"
|
||||
quota_path = "/quotas/%s"
|
||||
extensions_path = "/extensions"
|
||||
@ -604,6 +606,32 @@ class Client(ClientBase):
|
||||
"""Deletes the specified subnet."""
|
||||
return self.delete(self.subnet_path % (subnet))
|
||||
|
||||
@APIParamsCall
|
||||
def list_subnetpools(self, retrieve_all=True, **_params):
|
||||
"""Fetches a list of all subnetpools for a tenant."""
|
||||
return self.list('subnetpools', self.subnetpools_path, retrieve_all,
|
||||
**_params)
|
||||
|
||||
@APIParamsCall
|
||||
def show_subnetpool(self, subnetpool, **_params):
|
||||
"""Fetches information of a certain subnetpool."""
|
||||
return self.get(self.subnetpool_path % (subnetpool), params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def create_subnetpool(self, body=None):
|
||||
"""Creates a new subnetpool."""
|
||||
return self.post(self.subnetpools_path, body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def update_subnetpool(self, subnetpool, body=None):
|
||||
"""Updates a subnetpool."""
|
||||
return self.put(self.subnetpool_path % (subnetpool), body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_subnetpool(self, subnetpool):
|
||||
"""Deletes the specified subnetpool."""
|
||||
return self.delete(self.subnetpool_path % (subnetpool))
|
||||
|
||||
@APIParamsCall
|
||||
def list_routers(self, retrieve_all=True, **_params):
|
||||
"""Fetches a list of all routers for a tenant."""
|
||||
|
Loading…
Reference in New Issue
Block a user