diff --git a/openstackclient/tests/volume/v2/__init__.py b/openstackclient/tests/volume/v2/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/openstackclient/tests/volume/v2/fakes.py b/openstackclient/tests/volume/v2/fakes.py new file mode 100644 index 000000000..3eade3910 --- /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 000000000..e24cac3ca --- /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 000000000..910154100 --- /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 000000000..6cc988b2d --- /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 000000000..9e991b727 --- /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 a7b64def6..1038c407e 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 000000000..e69de29bb diff --git a/openstackclient/volume/v2/backup.py b/openstackclient/volume/v2/backup.py new file mode 100644 index 000000000..bf2ea3a62 --- /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="", + 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="", + 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 000000000..a6b02b63a --- /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="", + 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="", + 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 000000000..e50a6f0c9 --- /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="", + 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="", + 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 000000000..ae5cc8b89 --- /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="", + 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="", + 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))) diff --git a/setup.cfg b/setup.cfg index 9abc21604..8db7c3eae 100644 --- a/setup.cfg +++ b/setup.cfg @@ -361,6 +361,19 @@ openstack.volume.v1 = volume_type_set = openstackclient.volume.v1.type:SetVolumeType volume_type_unset = openstackclient.volume.v1.type:UnsetVolumeType +openstack.volume.v2 = + backup_delete = openstackclient.volume.v2.backup:DeleteBackup + backup_show = openstackclient.volume.v2.backup:ShowBackup + + snapshot_delete = openstackclient.volume.v2.snapshot:DeleteSnapshot + snapshot_show = openstackclient.volume.v2.snapshot:ShowSnapshot + + volume_delete = openstackclient.volume.v2.volume:DeleteVolume + volume_show = openstackclient.volume.v2.volume:ShowVolume + + volume_type_delete = openstackclient.volume.v2.volume_type:DeleteVolumeType + volume_type_show = openstackclient.volume.v2.volume_type:ShowVolumeType + [build_sphinx] source-dir = doc/source build-dir = doc/build