summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/tests/volume/v2/__init__.py0
-rw-r--r--openstackclient/tests/volume/v2/fakes.py136
-rw-r--r--openstackclient/tests/volume/v2/test_backup.py82
-rw-r--r--openstackclient/tests/volume/v2/test_snapshot.py82
-rw-r--r--openstackclient/tests/volume/v2/test_type.py82
-rw-r--r--openstackclient/tests/volume/v2/test_volume.py82
-rw-r--r--openstackclient/volume/client.py3
-rw-r--r--openstackclient/volume/v2/__init__.py0
-rw-r--r--openstackclient/volume/v2/backup.py70
-rw-r--r--openstackclient/volume/v2/snapshot.py71
-rw-r--r--openstackclient/volume/v2/volume.py83
-rw-r--r--openstackclient/volume/v2/volume_type.py68
12 files changed, 758 insertions, 1 deletions
diff --git a/openstackclient/tests/volume/v2/__init__.py b/openstackclient/tests/volume/v2/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/openstackclient/tests/volume/v2/__init__.py
diff --git a/openstackclient/tests/volume/v2/fakes.py b/openstackclient/tests/volume/v2/fakes.py
new file mode 100644
index 00000000..3eade391
--- /dev/null
+++ b/openstackclient/tests/volume/v2/fakes.py
@@ -0,0 +1,136 @@
+#
+# 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 mock
+
+from openstackclient.tests import fakes
+from openstackclient.tests.identity.v2_0 import fakes as identity_fakes
+from openstackclient.tests import utils
+
+volume_id = "ce26708d-a7f8-4b4b-9861-4a80256615a6"
+volume_name = "fake_volume"
+volume_description = "fake description"
+volume_status = "available"
+volume_size = 20
+volume_type = "fake_lvmdriver-1"
+volume_metadata = {
+ "foo": "bar"
+}
+volume_snapshot_id = 1
+volume_availability_zone = "nova"
+volume_attachments = ["fake_attachments"]
+
+VOLUME = {
+ "id": volume_id,
+ "name": volume_name,
+ "description": volume_description,
+ "status": volume_status,
+ "size": volume_size,
+ "volume_type": volume_type,
+ "metadata": volume_metadata,
+ "snapshot_id": volume_snapshot_id,
+ "availability_zone": volume_availability_zone,
+ "attachments": volume_attachments
+}
+
+VOLUME_columns = tuple(sorted(VOLUME))
+VOLUME_data = tuple((VOLUME[x] for x in sorted(VOLUME)))
+
+
+snapshot_id = "cb2d364e-4d1c-451a-8c68-b5bbcb340fb2"
+snapshot_name = "fake_snapshot"
+snapshot_description = "fake description"
+snapshot_size = 10
+snapshot_metadata = {
+ "foo": "bar"
+}
+snapshot_volume_id = "bdbae8dc-e6ca-43c0-8076-951cc1b093a4"
+
+SNAPSHOT = {
+ "id": snapshot_id,
+ "name": snapshot_name,
+ "description": snapshot_description,
+ "size": snapshot_size,
+ "metadata": snapshot_metadata
+}
+
+SNAPSHOT_columns = tuple(sorted(SNAPSHOT))
+SNAPSHOT_data = tuple((SNAPSHOT[x] for x in sorted(SNAPSHOT)))
+
+
+type_id = "5520dc9e-6f9b-4378-a719-729911c0f407"
+type_description = "fake description"
+type_name = "fake-lvmdriver-1"
+type_extra_specs = {
+ "foo": "bar"
+}
+
+TYPE = {
+ 'id': type_id,
+ 'name': type_name,
+ 'description': type_description,
+ 'extra_specs': type_extra_specs
+}
+
+TYPE_columns = tuple(sorted(TYPE))
+TYPE_data = tuple((TYPE[x] for x in sorted(TYPE)))
+
+backup_id = "3c409fe6-4d03-4a06-aeab-18bdcdf3c8f4"
+backup_volume_id = "bdbae8dc-e6ca-43c0-8076-951cc1b093a4"
+backup_name = "fake_backup"
+backup_description = "fake description"
+backup_object_count = None
+backup_container = None
+backup_size = 10
+
+BACKUP = {
+ "id": backup_id,
+ "name": backup_name,
+ "volume_id": backup_volume_id,
+ "description": backup_description,
+ "object_count": backup_object_count,
+ "container": backup_container,
+ "size": backup_size
+}
+
+BACKUP_columns = tuple(sorted(BACKUP))
+BACKUP_data = tuple((BACKUP[x] for x in sorted(BACKUP)))
+
+
+class FakeVolumeClient(object):
+ def __init__(self, **kwargs):
+ self.volumes = mock.Mock()
+ self.volumes.resource_class = fakes.FakeResource(None, {})
+ self.volume_snapshots = mock.Mock()
+ self.volume_snapshots.resource_class = fakes.FakeResource(None, {})
+ self.backups = mock.Mock()
+ self.backups.resource_class = fakes.FakeResource(None, {})
+ self.volume_types = mock.Mock()
+ self.volume_types.resource_class = fakes.FakeResource(None, {})
+ self.auth_token = kwargs['token']
+ self.management_url = kwargs['endpoint']
+
+
+class TestVolume(utils.TestCommand):
+ def setUp(self):
+ super(TestVolume, self).setUp()
+
+ self.app.client_manager.volume = FakeVolumeClient(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN
+ )
+ self.app.client_manager.identity = identity_fakes.FakeIdentityv2Client(
+ endpoint=fakes.AUTH_URL,
+ token=fakes.AUTH_TOKEN
+ )
diff --git a/openstackclient/tests/volume/v2/test_backup.py b/openstackclient/tests/volume/v2/test_backup.py
new file mode 100644
index 00000000..e24cac3c
--- /dev/null
+++ b/openstackclient/tests/volume/v2/test_backup.py
@@ -0,0 +1,82 @@
+#
+# 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 copy
+
+from openstackclient.tests import fakes
+from openstackclient.tests.volume.v2 import fakes as volume_fakes
+from openstackclient.volume.v2 import backup
+
+
+class TestBackup(volume_fakes.TestVolume):
+
+ def setUp(self):
+ super(TestBackup, self).setUp()
+
+ self.backups_mock = self.app.client_manager.volume.backups
+ self.backups_mock.reset_mock()
+
+
+class TestBackupShow(TestBackup):
+ def setUp(self):
+ super(TestBackupShow, self).setUp()
+
+ self.backups_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(volume_fakes.BACKUP),
+ loaded=True)
+ # Get the command object to test
+ self.cmd = backup.ShowBackup(self.app, None)
+
+ def test_backup_show(self):
+ arglist = [
+ volume_fakes.backup_id
+ ]
+ verifylist = [
+ ("backup", volume_fakes.backup_id)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.backups_mock.get.assert_called_with(volume_fakes.backup_id)
+
+ self.assertEqual(volume_fakes.BACKUP_columns, columns)
+ self.assertEqual(volume_fakes.BACKUP_data, data)
+
+
+class TestBackupDelete(TestBackup):
+ def setUp(self):
+ super(TestBackupDelete, self).setUp()
+
+ self.backups_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(volume_fakes.BACKUP),
+ loaded=True)
+ self.backups_mock.delete.return_value = None
+
+ # Get the command object to mock
+ self.cmd = backup.DeleteBackup(self.app, None)
+
+ def test_backup_delete(self):
+ arglist = [
+ volume_fakes.backup_id
+ ]
+ verifylist = [
+ ("backups", [volume_fakes.backup_id])
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+ self.backups_mock.delete.assert_called_with(volume_fakes.backup_id)
diff --git a/openstackclient/tests/volume/v2/test_snapshot.py b/openstackclient/tests/volume/v2/test_snapshot.py
new file mode 100644
index 00000000..91015410
--- /dev/null
+++ b/openstackclient/tests/volume/v2/test_snapshot.py
@@ -0,0 +1,82 @@
+#
+# 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 copy
+
+from openstackclient.tests import fakes
+from openstackclient.tests.volume.v2 import fakes as volume_fakes
+from openstackclient.volume.v2 import snapshot
+
+
+class TestSnapshot(volume_fakes.TestVolume):
+
+ def setUp(self):
+ super(TestSnapshot, self).setUp()
+
+ self.snapshots_mock = self.app.client_manager.volume.volume_snapshots
+ self.snapshots_mock.reset_mock()
+
+
+class TestSnapshotShow(TestSnapshot):
+ def setUp(self):
+ super(TestSnapshotShow, self).setUp()
+
+ self.snapshots_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(volume_fakes.SNAPSHOT),
+ loaded=True)
+ # Get the command object to test
+ self.cmd = snapshot.ShowSnapshot(self.app, None)
+
+ def test_snapshot_show(self):
+ arglist = [
+ volume_fakes.snapshot_id
+ ]
+ verifylist = [
+ ("snapshot", volume_fakes.snapshot_id)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.snapshots_mock.get.assert_called_with(volume_fakes.snapshot_id)
+
+ self.assertEqual(volume_fakes.SNAPSHOT_columns, columns)
+ self.assertEqual(volume_fakes.SNAPSHOT_data, data)
+
+
+class TestSnapshotDelete(TestSnapshot):
+ def setUp(self):
+ super(TestSnapshotDelete, self).setUp()
+
+ self.snapshots_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(volume_fakes.SNAPSHOT),
+ loaded=True)
+ self.snapshots_mock.delete.return_value = None
+
+ # Get the command object to mock
+ self.cmd = snapshot.DeleteSnapshot(self.app, None)
+
+ def test_snapshot_delete(self):
+ arglist = [
+ volume_fakes.snapshot_id
+ ]
+ verifylist = [
+ ("snapshots", [volume_fakes.snapshot_id])
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+ self.snapshots_mock.delete.assert_called_with(volume_fakes.snapshot_id)
diff --git a/openstackclient/tests/volume/v2/test_type.py b/openstackclient/tests/volume/v2/test_type.py
new file mode 100644
index 00000000..6cc988b2
--- /dev/null
+++ b/openstackclient/tests/volume/v2/test_type.py
@@ -0,0 +1,82 @@
+#
+# 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 copy
+
+from openstackclient.tests import fakes
+from openstackclient.tests.volume.v2 import fakes as volume_fakes
+from openstackclient.volume.v2 import volume_type
+
+
+class TestType(volume_fakes.TestVolume):
+
+ def setUp(self):
+ super(TestType, self).setUp()
+
+ self.types_mock = self.app.client_manager.volume.volume_types
+ self.types_mock.reset_mock()
+
+
+class TestTypeShow(TestType):
+ def setUp(self):
+ super(TestTypeShow, self).setUp()
+
+ self.types_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(volume_fakes.TYPE),
+ loaded=True)
+ # Get the command object to test
+ self.cmd = volume_type.ShowVolumeType(self.app, None)
+
+ def test_type_show(self):
+ arglist = [
+ volume_fakes.type_id
+ ]
+ verifylist = [
+ ("volume_type", volume_fakes.type_id)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.types_mock.get.assert_called_with(volume_fakes.type_id)
+
+ self.assertEqual(volume_fakes.TYPE_columns, columns)
+ self.assertEqual(volume_fakes.TYPE_data, data)
+
+
+class TestTypeDelete(TestType):
+ def setUp(self):
+ super(TestTypeDelete, self).setUp()
+
+ self.types_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(volume_fakes.TYPE),
+ loaded=True)
+ self.types_mock.delete.return_value = None
+
+ # Get the command object to mock
+ self.cmd = volume_type.DeleteVolumeType(self.app, None)
+
+ def test_type_delete(self):
+ arglist = [
+ volume_fakes.type_id
+ ]
+ verifylist = [
+ ("volume_type", volume_fakes.type_id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+ self.types_mock.delete.assert_called_with(volume_fakes.type_id)
diff --git a/openstackclient/tests/volume/v2/test_volume.py b/openstackclient/tests/volume/v2/test_volume.py
new file mode 100644
index 00000000..9e991b72
--- /dev/null
+++ b/openstackclient/tests/volume/v2/test_volume.py
@@ -0,0 +1,82 @@
+#
+# 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 copy
+
+from openstackclient.tests import fakes
+from openstackclient.tests.volume.v2 import fakes as volume_fakes
+from openstackclient.volume.v2 import volume
+
+
+class TestVolume(volume_fakes.TestVolume):
+
+ def setUp(self):
+ super(TestVolume, self).setUp()
+
+ self.volumes_mock = self.app.client_manager.volume.volumes
+ self.volumes_mock.reset_mock()
+
+
+class TestVolumeShow(TestVolume):
+ def setUp(self):
+ super(TestVolumeShow, self).setUp()
+
+ self.volumes_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(volume_fakes.VOLUME),
+ loaded=True)
+ # Get the command object to test
+ self.cmd = volume.ShowVolume(self.app, None)
+
+ def test_volume_show(self):
+ arglist = [
+ volume_fakes.volume_id
+ ]
+ verifylist = [
+ ("volume", volume_fakes.volume_id)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.volumes_mock.get.assert_called_with(volume_fakes.volume_id)
+
+ self.assertEqual(volume_fakes.VOLUME_columns, columns)
+ self.assertEqual(volume_fakes.VOLUME_data, data)
+
+
+class TestVolumeDelete(TestVolume):
+ def setUp(self):
+ super(TestVolumeDelete, self).setUp()
+
+ self.volumes_mock.get.return_value = fakes.FakeResource(
+ None,
+ copy.deepcopy(volume_fakes.VOLUME),
+ loaded=True)
+ self.volumes_mock.delete.return_value = None
+
+ # Get the command object to mock
+ self.cmd = volume.DeleteVolume(self.app, None)
+
+ def test_volume_delete(self):
+ arglist = [
+ volume_fakes.volume_id
+ ]
+ verifylist = [
+ ("volumes", [volume_fakes.volume_id])
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+ self.volumes_mock.delete.assert_called_with(volume_fakes.volume_id)
diff --git a/openstackclient/volume/client.py b/openstackclient/volume/client.py
index a7b64def..1038c407 100644
--- a/openstackclient/volume/client.py
+++ b/openstackclient/volume/client.py
@@ -23,7 +23,8 @@ DEFAULT_VOLUME_API_VERSION = '1'
API_VERSION_OPTION = 'os_volume_api_version'
API_NAME = "volume"
API_VERSIONS = {
- "1": "cinderclient.v1.client.Client"
+ "1": "cinderclient.v1.client.Client",
+ "2": "cinderclient.v2.client.Client"
}
diff --git a/openstackclient/volume/v2/__init__.py b/openstackclient/volume/v2/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/openstackclient/volume/v2/__init__.py
diff --git a/openstackclient/volume/v2/backup.py b/openstackclient/volume/v2/backup.py
new file mode 100644
index 00000000..bf2ea3a6
--- /dev/null
+++ b/openstackclient/volume/v2/backup.py
@@ -0,0 +1,70 @@
+#
+# 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.
+#
+
+"""Volume v2 Backup action implementations"""
+
+import logging
+
+from cliff import command
+from cliff import show
+import six
+
+from openstackclient.common import utils
+
+
+class DeleteBackup(command.Command):
+ """Delete backup(s)"""
+
+ log = logging.getLogger(__name__ + ".DeleteBackup")
+
+ def get_parser(self, prog_name):
+ parser = super(DeleteBackup, self).get_parser(prog_name)
+ parser.add_argument(
+ "backups",
+ metavar="<backup>",
+ nargs="+",
+ help="Backup(s) to delete (name or ID)"
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug("take_action: (%s)", parsed_args)
+ volume_client = self.app.client_manager.volume
+ for backup in parsed_args.backups:
+ backup_id = utils.find_resource(
+ volume_client.backups, backup).id
+ volume_client.backups.delete(backup_id)
+ return
+
+
+class ShowBackup(show.ShowOne):
+ """Display backup details"""
+
+ log = logging.getLogger(__name__ + ".ShowBackup")
+
+ def get_parser(self, prog_name):
+ parser = super(ShowBackup, self).get_parser(prog_name)
+ parser.add_argument(
+ "backup",
+ metavar="<backup>",
+ help="Backup to display (name or ID)")
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug("take_action: (%s)", parsed_args)
+ volume_client = self.app.client_manager.volume
+ backup = utils.find_resource(volume_client.backups,
+ parsed_args.backup)
+ backup._info.pop("links", None)
+ return zip(*sorted(six.iteritems(backup._info)))
diff --git a/openstackclient/volume/v2/snapshot.py b/openstackclient/volume/v2/snapshot.py
new file mode 100644
index 00000000..a6b02b63
--- /dev/null
+++ b/openstackclient/volume/v2/snapshot.py
@@ -0,0 +1,71 @@
+#
+# 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.
+#
+
+"""Volume v2 snapshot action implementations"""
+
+import logging
+
+from cliff import command
+from cliff import show
+import six
+
+from openstackclient.common import utils
+
+
+class DeleteSnapshot(command.Command):
+ """Delete volume snapshot(s)"""
+
+ log = logging.getLogger(__name__ + ".DeleteSnapshot")
+
+ def get_parser(self, prog_name):
+ parser = super(DeleteSnapshot, self).get_parser(prog_name)
+ parser.add_argument(
+ "snapshots",
+ metavar="<snapshot>",
+ nargs="+",
+ help="Snapsho(s) to delete (name or ID)"
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug("take_action: (%s)", parsed_args)
+ volume_client = self.app.client_manager.volume
+ for snapshot in parsed_args.snapshots:
+ snapshot_id = utils.find_resource(
+ volume_client.volume_snapshots, snapshot).id
+ volume_client.volume_snapshots.delete(snapshot_id)
+ return
+
+
+class ShowSnapshot(show.ShowOne):
+ """Display snapshot details"""
+
+ log = logging.getLogger(__name__ + ".ShowSnapshot")
+
+ def get_parser(self, prog_name):
+ parser = super(ShowSnapshot, self).get_parser(prog_name)
+ parser.add_argument(
+ "snapshot",
+ metavar="<snapshot>",
+ help="Snapshot to display (name or ID)"
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug("take_action: (%s)", parsed_args)
+ volume_client = self.app.client_manager.volume
+ snapshot = utils.find_resource(
+ volume_client.volume_snapshots, parsed_args.snapshot)
+ snapshot = volume_client.volume_snapshots.get(snapshot.id)
+ return zip(*sorted(six.iteritems(snapshot._info)))
diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py
new file mode 100644
index 00000000..e50a6f0c
--- /dev/null
+++ b/openstackclient/volume/v2/volume.py
@@ -0,0 +1,83 @@
+#
+# 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.
+#
+
+"""Volume V2 Volume action implementations"""
+
+import logging
+
+from cliff import command
+from cliff import show
+import six
+
+from openstackclient.common import utils
+
+
+class DeleteVolume(command.Command):
+ """Delete volume(s)"""
+
+ log = logging.getLogger(__name__ + ".DeleteVolume")
+
+ def get_parser(self, prog_name):
+ parser = super(DeleteVolume, self).get_parser(prog_name)
+ parser.add_argument(
+ "volumes",
+ metavar="<volume>",
+ nargs="+",
+ help="Volume(s) to delete (name or ID)"
+ )
+ parser.add_argument(
+ "--force",
+ dest="force",
+ action="store_true",
+ default=False,
+ help="Attempt forced removal of volume(s), regardless of state "
+ "(defaults to False"
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug("take_action: (%s)", parsed_args)
+ volume_client = self.app.client_manager.volume
+ for volume in parsed_args.volumes:
+ volume_obj = utils.find_resource(
+ volume_client.volumes, volume)
+ if parsed_args.force:
+ volume_client.volumes.force_delete(volume_obj.id)
+ else:
+ volume_client.volumes.delete(volume_obj.id)
+ return
+
+
+class ShowVolume(show.ShowOne):
+ """Display volume details"""
+
+ log = logging.getLogger(__name__ + '.ShowVolume')
+
+ def get_parser(self, prog_name):
+ parser = super(ShowVolume, self).get_parser(prog_name)
+ parser.add_argument(
+ 'volume',
+ metavar="<volume-id>",
+ help="Volume to display (name or ID)"
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug('take_action(%s)', parsed_args)
+ volume_client = self.app.client_manager.volume
+ volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
+
+ # Remove key links from being displayed
+ volume._info.pop("links", None)
+ return zip(*sorted(six.iteritems(volume._info)))
diff --git a/openstackclient/volume/v2/volume_type.py b/openstackclient/volume/v2/volume_type.py
new file mode 100644
index 00000000..ae5cc8b8
--- /dev/null
+++ b/openstackclient/volume/v2/volume_type.py
@@ -0,0 +1,68 @@
+#
+# 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.
+#
+
+"""Volume v2 Type action implementations"""
+
+import logging
+
+from cliff import command
+from cliff import show
+import six
+
+from openstackclient.common import utils
+
+
+class DeleteVolumeType(command.Command):
+ """Delete volume type"""
+
+ log = logging.getLogger(__name__ + ".DeleteVolumeType")
+
+ def get_parser(self, prog_name):
+ parser = super(DeleteVolumeType, self).get_parser(prog_name)
+ parser.add_argument(
+ "volume_type",
+ metavar="<volume-type>",
+ help="Volume type to delete (name or ID)"
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.info("take_action: (%s)", 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)
+ return
+
+
+class ShowVolumeType(show.ShowOne):
+ """Display volume type details"""
+
+ log = logging.getLogger(__name__ + ".ShowVolumeType")
+
+ def get_parser(self, prog_name):
+ parser = super(ShowVolumeType, self).get_parser(prog_name)
+ parser.add_argument(
+ "volume_type",
+ metavar="<volume-type>",
+ help="Volume type to display (name or ID)"
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug("take_action: (%s)", parsed_args)
+ volume_client = self.app.client_manager.volume
+ volume_type = utils.find_resource(
+ volume_client.volume_types, parsed_args.volume_type)
+ return zip(*sorted(six.iteritems(volume_type._info)))