Support deleting multi address scopes in networkv2
This patch adds support for deleting multi address scopes by using "address scope delete" command. Change-Id: Ic8d3ebc17db44ca5d42c336d2c4d5633f70d4e8b Partially-Implements: blueprint multi-argument-network
This commit is contained in:
parent
9da02d14ea
commit
537f5cbe8a
@ -50,18 +50,18 @@ Create new address scope
|
|||||||
address scope delete
|
address scope delete
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Delete an address scope
|
Delete address scope(s)
|
||||||
|
|
||||||
.. program:: address scope delete
|
.. program:: address scope delete
|
||||||
.. code:: bash
|
.. code:: bash
|
||||||
|
|
||||||
os address scope delete
|
os address scope delete
|
||||||
<address-scope>
|
<address-scope> [<address-scope> ...]
|
||||||
|
|
||||||
.. _address_scope_delete-address-scope:
|
.. _address_scope_delete-address-scope:
|
||||||
.. describe:: <address-scope>
|
.. describe:: <address-scope>
|
||||||
|
|
||||||
Address scope to delete (name or ID)
|
Address scope(s) to delete (name or ID)
|
||||||
|
|
||||||
address scope list
|
address scope list
|
||||||
------------------
|
------------------
|
||||||
|
@ -98,22 +98,38 @@ class CreateAddressScope(command.ShowOne):
|
|||||||
|
|
||||||
|
|
||||||
class DeleteAddressScope(command.Command):
|
class DeleteAddressScope(command.Command):
|
||||||
"""Delete an address scope"""
|
"""Delete address scope(s)"""
|
||||||
|
|
||||||
def get_parser(self, prog_name):
|
def get_parser(self, prog_name):
|
||||||
parser = super(DeleteAddressScope, self).get_parser(prog_name)
|
parser = super(DeleteAddressScope, self).get_parser(prog_name)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'address_scope',
|
'address_scope',
|
||||||
metavar="<address-scope>",
|
metavar="<address-scope>",
|
||||||
help=_("Address scope to delete (name or ID)")
|
nargs='+',
|
||||||
|
help=_("Address scope(s) to delete (name or ID)")
|
||||||
)
|
)
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
client = self.app.client_manager.network
|
client = self.app.client_manager.network
|
||||||
obj = client.find_address_scope(parsed_args.address_scope)
|
result = 0
|
||||||
|
|
||||||
|
for scope in parsed_args.address_scope:
|
||||||
|
try:
|
||||||
|
obj = client.find_address_scope(scope, ignore_missing=False)
|
||||||
client.delete_address_scope(obj)
|
client.delete_address_scope(obj)
|
||||||
|
except Exception as e:
|
||||||
|
result += 1
|
||||||
|
self.app.log.error(_("Failed to delete address scope with "
|
||||||
|
"name or ID '%(scope)s': %(e)s")
|
||||||
|
% {'scope': scope, 'e': e})
|
||||||
|
|
||||||
|
if result > 0:
|
||||||
|
total = len(parsed_args.address_scope)
|
||||||
|
msg = (_("%(result)s of %(total)s address scopes failed "
|
||||||
|
"to delete.") % {'result': result, 'total': total})
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
|
||||||
class ListAddressScope(command.Lister):
|
class ListAddressScope(command.Lister):
|
||||||
|
@ -127,6 +127,25 @@ class FakeAddressScope(object):
|
|||||||
|
|
||||||
return address_scopes
|
return address_scopes
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_address_scopes(address_scopes=None, count=2):
|
||||||
|
"""Get an iterable MagicMock object with a list of faked address scopes.
|
||||||
|
|
||||||
|
If address scopes list is provided, then initialize the Mock object
|
||||||
|
with the list. Otherwise create one.
|
||||||
|
|
||||||
|
:param List address scopes:
|
||||||
|
A list of FakeResource objects faking address scopes
|
||||||
|
:param int count:
|
||||||
|
The number of address scopes to fake
|
||||||
|
:return:
|
||||||
|
An iterable Mock object with side_effect set to a list of faked
|
||||||
|
address scopes
|
||||||
|
"""
|
||||||
|
if address_scopes is None:
|
||||||
|
address_scopes = FakeAddressScope.create_address_scopes(count)
|
||||||
|
return mock.MagicMock(side_effect=address_scopes)
|
||||||
|
|
||||||
|
|
||||||
class FakeAvailabilityZone(object):
|
class FakeAvailabilityZone(object):
|
||||||
"""Fake one or more network availability zones (AZs)."""
|
"""Fake one or more network availability zones (AZs)."""
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
import copy
|
import copy
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from mock import call
|
||||||
from openstackclient.common import exceptions
|
from openstackclient.common import exceptions
|
||||||
from openstackclient.network.v2 import address_scope
|
from openstackclient.network.v2 import address_scope
|
||||||
from openstackclient.tests import fakes
|
from openstackclient.tests import fakes
|
||||||
@ -168,33 +169,86 @@ class TestCreateAddressScope(TestAddressScope):
|
|||||||
class TestDeleteAddressScope(TestAddressScope):
|
class TestDeleteAddressScope(TestAddressScope):
|
||||||
|
|
||||||
# The address scope to delete.
|
# The address scope to delete.
|
||||||
_address_scope = (
|
_address_scopes = (
|
||||||
network_fakes.FakeAddressScope.create_one_address_scope())
|
network_fakes.FakeAddressScope.create_address_scopes(count=2))
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestDeleteAddressScope, self).setUp()
|
super(TestDeleteAddressScope, self).setUp()
|
||||||
self.network.delete_address_scope = mock.Mock(return_value=None)
|
self.network.delete_address_scope = mock.Mock(return_value=None)
|
||||||
self.network.find_address_scope = mock.Mock(
|
self.network.find_address_scope = (
|
||||||
return_value=self._address_scope)
|
network_fakes.FakeAddressScope.get_address_scopes(
|
||||||
|
address_scopes=self._address_scopes)
|
||||||
|
)
|
||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = address_scope.DeleteAddressScope(self.app, self.namespace)
|
self.cmd = address_scope.DeleteAddressScope(self.app, self.namespace)
|
||||||
|
|
||||||
def test_delete(self):
|
def test_address_scope_delete(self):
|
||||||
arglist = [
|
arglist = [
|
||||||
self._address_scope.name,
|
self._address_scopes[0].name,
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
('address_scope', self._address_scope.name),
|
('address_scope', [self._address_scopes[0].name]),
|
||||||
]
|
]
|
||||||
|
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
result = self.cmd.take_action(parsed_args)
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
self.network.find_address_scope.assert_called_once_with(
|
||||||
|
self._address_scopes[0].name, ignore_missing=False)
|
||||||
self.network.delete_address_scope.assert_called_once_with(
|
self.network.delete_address_scope.assert_called_once_with(
|
||||||
self._address_scope)
|
self._address_scopes[0])
|
||||||
self.assertIsNone(result)
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
def test_multi_address_scopes_delete(self):
|
||||||
|
arglist = []
|
||||||
|
verifylist = []
|
||||||
|
|
||||||
|
for a in self._address_scopes:
|
||||||
|
arglist.append(a.name)
|
||||||
|
verifylist = [
|
||||||
|
('address_scope', arglist),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
result = self.cmd.take_action(parsed_args)
|
||||||
|
|
||||||
|
calls = []
|
||||||
|
for a in self._address_scopes:
|
||||||
|
calls.append(call(a))
|
||||||
|
self.network.delete_address_scope.assert_has_calls(calls)
|
||||||
|
self.assertIsNone(result)
|
||||||
|
|
||||||
|
def test_multi_address_scopes_delete_with_exception(self):
|
||||||
|
arglist = [
|
||||||
|
self._address_scopes[0].name,
|
||||||
|
'unexist_address_scope',
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('address_scope',
|
||||||
|
[self._address_scopes[0].name, 'unexist_address_scope']),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
find_mock_result = [self._address_scopes[0], exceptions.CommandError]
|
||||||
|
self.network.find_address_scope = (
|
||||||
|
mock.MagicMock(side_effect=find_mock_result)
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.cmd.take_action(parsed_args)
|
||||||
|
self.fail('CommandError should be raised.')
|
||||||
|
except exceptions.CommandError as e:
|
||||||
|
self.assertEqual('1 of 2 address scopes failed to delete.', str(e))
|
||||||
|
|
||||||
|
self.network.find_address_scope.assert_any_call(
|
||||||
|
self._address_scopes[0].name, ignore_missing=False)
|
||||||
|
self.network.find_address_scope.assert_any_call(
|
||||||
|
'unexist_address_scope', ignore_missing=False)
|
||||||
|
self.network.delete_address_scope.assert_called_once_with(
|
||||||
|
self._address_scopes[0]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestListAddressScope(TestAddressScope):
|
class TestListAddressScope(TestAddressScope):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user