support multi-delete for volume-type

Added the ability to delete multiple volume types at once. Note
there are no unit tests exist for v1 volume-types, so instead
a functional test was created.

Partial-Bug: #1592906
Change-Id: I99f3f22901ab35252b91a3072b14de7d19cb17ca
This commit is contained in:
Steve Martinelli 2016-06-16 14:25:33 -04:00
parent f5ae23ab86
commit 4e62e1e2e1
7 changed files with 88 additions and 17 deletions

View File

@ -48,18 +48,18 @@ Create new volume type
volume type delete
------------------
Delete volume type
Delete volume type(s)
.. program:: volume type delete
.. code:: bash
os volume type delete
<volume-type>
<volume-type> [<volume-type> ...]
.. _volume_type_delete-volume-type:
.. describe:: <volume-type>
Volume type to delete (name or ID)
Volume type(s) to delete (name or ID)
volume type list
----------------

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import time
import uuid
from functional.tests.volume.v1 import common
@ -59,3 +60,15 @@ class VolumeTypeTests(common.BaseVolumeTests):
self.assertEqual("", raw_output)
raw_output = self.openstack('volume type show ' + self.NAME + opts)
self.assertEqual("c='d'\n", raw_output)
def test_multi_delete(self):
vol_type1 = uuid.uuid4().hex
vol_type2 = uuid.uuid4().hex
self.openstack('volume type create ' + vol_type1)
time.sleep(5)
self.openstack('volume type create ' + vol_type2)
time.sleep(5)
cmd = 'volume type delete %s %s' % (vol_type1, vol_type2)
time.sleep(5)
raw_output = self.openstack(cmd)
self.assertOutput('', raw_output)

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import time
import uuid
from functional.tests.volume.v2 import common
@ -69,3 +70,15 @@ class VolumeTypeTests(common.BaseVolumeTests):
raw_output = self.openstack(
'volume type unset --project admin ' + self.NAME)
self.assertEqual("", raw_output)
def test_multi_delete(self):
vol_type1 = uuid.uuid4().hex
vol_type2 = uuid.uuid4().hex
self.openstack('volume type create ' + vol_type1)
time.sleep(5)
self.openstack('volume type create ' + vol_type2)
time.sleep(5)
cmd = 'volume type delete %s %s' % (vol_type1, vol_type2)
time.sleep(5)
raw_output = self.openstack(cmd)
self.assertOutput('', raw_output)

View File

@ -128,13 +128,13 @@ class TestTypeDelete(TestType):
self.volume_type.id
]
verifylist = [
("volume_type", self.volume_type.id)
("volume_types", [self.volume_type.id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.types_mock.delete.assert_called_with(self.volume_type.id)
self.types_mock.delete.assert_called_with(self.volume_type)
self.assertIsNone(result)

View File

@ -15,14 +15,20 @@
"""Volume v1 Type action implementations"""
import logging
from osc_lib.cli import parseractions
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
import six
from openstackclient.i18n import _
LOG = logging.getLogger(__name__)
class CreateVolumeType(command.ShowOne):
"""Create new volume type"""
@ -56,22 +62,39 @@ class CreateVolumeType(command.ShowOne):
class DeleteVolumeType(command.Command):
"""Delete volume type"""
"""Delete volume type(s)"""
def get_parser(self, prog_name):
parser = super(DeleteVolumeType, self).get_parser(prog_name)
parser.add_argument(
'volume_type',
'volume_types',
metavar='<volume-type>',
help=_('Volume type to delete (name or ID)'),
nargs='+',
help=_('Volume type(s) to delete (name or ID)'),
)
return parser
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume_type_id = utils.find_resource(
volume_client.volume_types, parsed_args.volume_type).id
volume_client.volume_types.delete(volume_type_id)
result = 0
for volume_type in parsed_args.volume_types:
try:
vol_type = utils.find_resource(volume_client.volume_types,
volume_type)
volume_client.volume_types.delete(vol_type)
except Exception as e:
result += 1
LOG.error(_("Failed to delete volume type with "
"name or ID '%(volume_type)s': %(e)s")
% {'volume_type': volume_type, 'e': e})
if result > 0:
total = len(parsed_args.volume_types)
msg = (_("%(result)s of %(total)s volume types failed "
"to delete.") % {'result': result, 'total': total})
raise exceptions.CommandError(msg)
class ListVolumeType(command.Lister):

View File

@ -92,22 +92,39 @@ class CreateVolumeType(command.ShowOne):
class DeleteVolumeType(command.Command):
"""Delete volume type"""
"""Delete volume type(s)"""
def get_parser(self, prog_name):
parser = super(DeleteVolumeType, self).get_parser(prog_name)
parser.add_argument(
"volume_type",
"volume_types",
metavar="<volume-type>",
help=_("Volume type to delete (name or ID)")
nargs="+",
help=_("Volume type(s) to delete (name or ID)")
)
return parser
def take_action(self, parsed_args):
volume_client = self.app.client_manager.volume
volume_type = utils.find_resource(
volume_client.volume_types, parsed_args.volume_type)
volume_client.volume_types.delete(volume_type.id)
result = 0
for volume_type in parsed_args.volume_types:
try:
vol_type = utils.find_resource(volume_client.volume_types,
volume_type)
volume_client.volume_types.delete(vol_type)
except Exception as e:
result += 1
LOG.error(_("Failed to delete volume type with "
"name or ID '%(volume_type)s': %(e)s")
% {'volume_type': volume_type, 'e': e})
if result > 0:
total = len(parsed_args.volume_types)
msg = (_("%(result)s of %(total)s volume types failed "
"to delete.") % {'result': result, 'total': total})
raise exceptions.CommandError(msg)
class ListVolumeType(command.Lister):

View File

@ -0,0 +1,5 @@
---
features:
- Support bulk deletion for ``volume type delete``.
[Bug `1592906 <https://bugs.launchpad.net/bugs/1592906>`_]