[Subnet pool] Add 'subnet pool set' command support

This patch supports setting a new name, pool prefix,
default prefix length, minimum prefix length,
and maximum prefix length for a subnet pool.

Change-Id: I65bd71e0f54f2f65acefbc542df67a1b1ec26397
Partial-Bug: #1544591
Related-to: blueprint neutron-client
This commit is contained in:
Tang Chen 2016-03-07 11:51:39 +08:00
parent 762c4c9bdf
commit f2fb007e82
5 changed files with 227 additions and 6 deletions

View File

@ -35,6 +35,48 @@ List subnet pools
List additional fields in output List additional fields in output
subnet pool set
---------------
Set subnet pool properties
.. program:: subnet pool set
.. code:: bash
os subnet pool set
[--name <name>]
[--pool-prefix <pool-prefix> [...]]
[--default-prefix-length <default-prefix-length>]
[--min-prefix-length <min-prefix-length>]
[--max-prefix-length <max-prefix-length>]
<subnet-pool>
.. option:: --name <name>
Set subnet pool name
.. option:: --pool-prefix <pool-prefix>
Set subnet pool prefixes (in CIDR notation).
Repeat this option to set multiple prefixes.
.. option:: --default-prefix-length <default-prefix-length>
Set subnet pool default prefix length
.. option:: --min-prefix-length <min-prefix-length>
Set subnet pool minimum prefix length
.. option:: --max-prefix-length <max-prefix-length>
Set subnet pool maximum prefix length
.. _subnet_pool_set-subnet-pool:
.. describe:: <subnet-pool>
Subnet pool to modify (name or ID)
subnet pool show subnet pool show
---------------- ----------------

View File

@ -14,6 +14,8 @@
"""Subnet pool action implementations""" """Subnet pool action implementations"""
from openstackclient.common import command from openstackclient.common import command
from openstackclient.common import exceptions
from openstackclient.common import parseractions
from openstackclient.common import utils from openstackclient.common import utils
@ -30,6 +32,51 @@ _formatters = {
} }
def _get_attrs(parsed_args):
attrs = {}
if parsed_args.name is not None:
attrs['name'] = str(parsed_args.name)
if parsed_args.prefixes is not None:
attrs['prefixes'] = parsed_args.prefixes
if parsed_args.default_prefix_length is not None:
attrs['default_prefix_length'] = parsed_args.default_prefix_length
if parsed_args.min_prefix_length is not None:
attrs['min_prefix_length'] = parsed_args.min_prefix_length
if parsed_args.max_prefix_length is not None:
attrs['max_prefix_length'] = parsed_args.max_prefix_length
return attrs
def _add_prefix_options(parser):
parser.add_argument(
'--pool-prefix',
metavar='<pool-prefix>',
dest='prefixes',
action='append',
help='Set subnet pool prefixes (in CIDR notation). '
'Repeat this option to set multiple prefixes.',
)
parser.add_argument(
'--default-prefix-length',
metavar='<default-prefix-length>',
action=parseractions.NonNegativeAction,
help='Set subnet pool default prefix length',
)
parser.add_argument(
'--min-prefix-length',
metavar='<min-prefix-length>',
action=parseractions.NonNegativeAction,
help='Set subnet pool minimum prefix length',
)
parser.add_argument(
'--max-prefix-length',
metavar='<max-prefix-length>',
action=parseractions.NonNegativeAction,
help='Set subnet pool maximum prefix length',
)
class DeleteSubnetPool(command.Command): class DeleteSubnetPool(command.Command):
"""Delete subnet pool""" """Delete subnet pool"""
@ -37,8 +84,8 @@ class DeleteSubnetPool(command.Command):
parser = super(DeleteSubnetPool, self).get_parser(prog_name) parser = super(DeleteSubnetPool, self).get_parser(prog_name)
parser.add_argument( parser.add_argument(
'subnet_pool', 'subnet_pool',
metavar="<subnet-pool>", metavar='<subnet-pool>',
help=("Subnet pool to delete (name or ID)") help='Subnet pool to delete (name or ID)'
) )
return parser return parser
@ -98,6 +145,42 @@ class ListSubnetPool(command.Lister):
) for s in data)) ) for s in data))
class SetSubnetPool(command.Command):
"""Set subnet pool properties"""
def get_parser(self, prog_name):
parser = super(SetSubnetPool, self).get_parser(prog_name)
parser.add_argument(
'subnet_pool',
metavar='<subnet-pool>',
help='Subnet pool to modify (name or ID)'
)
parser.add_argument(
'--name',
metavar='<name>',
help='Set subnet pool name',
)
_add_prefix_options(parser)
return parser
def take_action(self, parsed_args):
client = self.app.client_manager.network
obj = client.find_subnet_pool(parsed_args.subnet_pool,
ignore_missing=False)
attrs = _get_attrs(parsed_args)
if attrs == {}:
msg = "Nothing specified to be set"
raise exceptions.CommandError(msg)
# Existing prefixes must be a subset of the new prefixes.
if 'prefixes' in attrs:
attrs['prefixes'].extend(obj.prefixes)
client.update_subnet_pool(obj, **attrs)
class ShowSubnetPool(command.ShowOne): class ShowSubnetPool(command.ShowOne):
"""Display subnet pool details""" """Display subnet pool details"""
@ -105,8 +188,8 @@ class ShowSubnetPool(command.ShowOne):
parser = super(ShowSubnetPool, self).get_parser(prog_name) parser = super(ShowSubnetPool, self).get_parser(prog_name)
parser.add_argument( parser.add_argument(
'subnet_pool', 'subnet_pool',
metavar="<subnet-pool>", metavar='<subnet-pool>',
help=("Subnet pool to display (name or ID)") help='Subnet pool to display (name or ID)'
) )
return parser return parser

View File

@ -11,8 +11,10 @@
# under the License. # under the License.
# #
import argparse
import mock import mock
from openstackclient.common import exceptions
from openstackclient.common import utils from openstackclient.common import utils
from openstackclient.network.v2 import subnet_pool from openstackclient.network.v2 import subnet_pool
from openstackclient.tests.network.v2 import fakes as network_fakes from openstackclient.tests.network.v2 import fakes as network_fakes
@ -129,6 +131,96 @@ class TestListSubnetPool(TestSubnetPool):
self.assertEqual(self.data_long, list(data)) self.assertEqual(self.data_long, list(data))
class TestSetSubnetPool(TestSubnetPool):
# The subnet_pool to set.
_subnet_pool = network_fakes.FakeSubnetPool.create_one_subnet_pool()
def setUp(self):
super(TestSetSubnetPool, self).setUp()
self.network.update_subnet_pool = mock.Mock(return_value=None)
self.network.find_subnet_pool = mock.Mock(
return_value=self._subnet_pool)
# Get the command object to test
self.cmd = subnet_pool.SetSubnetPool(self.app, self.namespace)
def test_set_this(self):
arglist = [
self._subnet_pool.name,
'--name', 'noob',
'--default-prefix-length', '8',
'--min-prefix-length', '8',
]
verifylist = [
('subnet_pool', self._subnet_pool.name),
('name', 'noob'),
('default_prefix_length', '8'),
('min_prefix_length', '8'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
attrs = {
'name': 'noob',
'default_prefix_length': '8',
'min_prefix_length': '8',
}
self.network.update_subnet_pool.assert_called_with(
self._subnet_pool, **attrs)
self.assertIsNone(result)
def test_set_that(self):
arglist = [
self._subnet_pool.name,
'--pool-prefix', '10.0.1.0/24',
'--pool-prefix', '10.0.2.0/24',
'--max-prefix-length', '16',
]
verifylist = [
('subnet_pool', self._subnet_pool.name),
('prefixes', ['10.0.1.0/24', '10.0.2.0/24']),
('max_prefix_length', '16'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
prefixes = ['10.0.1.0/24', '10.0.2.0/24']
prefixes.extend(self._subnet_pool.prefixes)
attrs = {
'prefixes': prefixes,
'max_prefix_length': '16',
}
self.network.update_subnet_pool.assert_called_with(
self._subnet_pool, **attrs)
self.assertIsNone(result)
def test_set_nothing(self):
arglist = [self._subnet_pool.name, ]
verifylist = [('subnet_pool', self._subnet_pool.name), ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
parsed_args)
def test_set_len_negative(self):
arglist = [
self._subnet_pool.name,
'--max-prefix-length', '-16',
]
verifylist = [
('subnet_pool', self._subnet_pool.name),
('max_prefix_length', '-16'),
]
self.assertRaises(argparse.ArgumentTypeError, self.check_parser,
self.cmd, arglist, verifylist)
class TestShowSubnetPool(TestSubnetPool): class TestShowSubnetPool(TestSubnetPool):
# The subnet_pool to set. # The subnet_pool to set.
@ -189,14 +281,13 @@ class TestShowSubnetPool(TestSubnetPool):
verifylist = [ verifylist = [
('subnet_pool', self._subnet_pool.name), ('subnet_pool', self._subnet_pool.name),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args) columns, data = self.cmd.take_action(parsed_args)
self.network.find_subnet_pool.assert_called_with( self.network.find_subnet_pool.assert_called_with(
self._subnet_pool.name, self._subnet_pool.name,
ignore_missing=False ignore_missing=False
) )
self.assertEqual(self.columns, columns) self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data) self.assertEqual(self.data, data)

View File

@ -0,0 +1,4 @@
---
features:
- Add ``subnet pool set`` command.
[Bug `1544591 <https://bugs.launchpad.net/python-openstackclient/+bug/1544591>`_]

View File

@ -356,6 +356,7 @@ openstack.network.v2 =
subnet_pool_delete = openstackclient.network.v2.subnet_pool:DeleteSubnetPool subnet_pool_delete = openstackclient.network.v2.subnet_pool:DeleteSubnetPool
subnet_pool_list = openstackclient.network.v2.subnet_pool:ListSubnetPool subnet_pool_list = openstackclient.network.v2.subnet_pool:ListSubnetPool
subnet_pool_set = openstackclient.network.v2.subnet_pool:SetSubnetPool
subnet_pool_show = openstackclient.network.v2.subnet_pool:ShowSubnetPool subnet_pool_show = openstackclient.network.v2.subnet_pool:ShowSubnetPool
openstack.object_store.v1 = openstack.object_store.v1 =