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:
zengfagao 2015-02-26 13:39:00 -08:00 committed by Kyle Mestery
parent d6cfd34e13
commit b978f90901
6 changed files with 269 additions and 1 deletions

View File

@ -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',

View 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

View File

@ -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,

View File

@ -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):

View 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)

View File

@ -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."""