diff --git a/releasenotes/notes/datastore-version-volume-types-62556ce5917195fd.yaml b/releasenotes/notes/datastore-version-volume-types-62556ce5917195fd.yaml new file mode 100644 index 00000000..f13894b7 --- /dev/null +++ b/releasenotes/notes/datastore-version-volume-types-62556ce5917195fd.yaml @@ -0,0 +1,3 @@ +--- +features: + - Added support for listing volume types for a given datastore version. diff --git a/troveclient/tests/fakes.py b/troveclient/tests/fakes.py index 6a98e0f9..d79b0c9c 100644 --- a/troveclient/tests/fakes.py +++ b/troveclient/tests/fakes.py @@ -274,6 +274,30 @@ class FakeHTTPClient(base_client.HTTPClient): r = {'flavor': self.get_flavors()[2]['flavors'][5]} return (200, {}, r) + def get_volume_types(self, **kw): + return (200, {}, {"volume_types": [ + { + "id": "1", + "name": "vt_1", + "description": "Volume type #1", + "is_public": False}, + { + "id": "10", + "name": "volume_type_2", + "description": "Volume type #2", + "is_public": True}]}) + + def get_datastores_mysql_versions_some_version_id_volume_types(self, **kw): + return self.get_volume_types() + + def get_volume_types_1(self, **kw): + r = {'volume_type': self.get_volume_types()[2]['volume_types'][0]} + return (200, {}, r) + + def get_volume_types_2(self, **kw): + r = {'volume_type': self.get_volume_types()[2]['volume_types'][2]} + return (200, {}, r) + def get_clusters(self, **kw): return (200, {}, {"clusters": [ { diff --git a/troveclient/tests/test_v1_shell.py b/troveclient/tests/test_v1_shell.py index 249f23b8..35f5d26c 100644 --- a/troveclient/tests/test_v1_shell.py +++ b/troveclient/tests/test_v1_shell.py @@ -250,6 +250,29 @@ class ShellTest(utils.TestCase): self.run_command('flavor-show m1.uuid') self.assert_called('GET', '/flavors/m1.uuid') + def test_volume_type_list(self): + self.run_command('volume-type-list') + self.assert_called('GET', '/volume-types') + + def test_volume_type_list_with_datastore(self): + cmd = ('volume-type-list --datastore_type mysql ' + '--datastore_version_id some-version-id') + self.run_command(cmd) + self.assert_called( + 'GET', '/datastores/mysql/versions/some-version-id/volume-types') + + def test_volume_type_list_error(self): + cmd = 'volume-type-list --datastore_type mysql' + exepcted_error_msg = ('Missing argument\(s\): ' + 'datastore_type, datastore_version_id') + self.assertRaisesRegexp( + exceptions.MissingArgs, exepcted_error_msg, self.run_command, + cmd) + + def test_volume_type_show(self): + self.run_command('volume-type-show 1') + self.assert_called('GET', '/volume-types/1') + def test_cluster_list(self): self.run_command('cluster-list') self.assert_called('GET', '/clusters') diff --git a/troveclient/v1/client.py b/troveclient/v1/client.py index a3d8e255..2fc7a971 100644 --- a/troveclient/v1/client.py +++ b/troveclient/v1/client.py @@ -30,6 +30,7 @@ from troveclient.v1 import quota from troveclient.v1 import root from troveclient.v1 import security_groups from troveclient.v1 import users +from troveclient.v1 import volume_types class Client(object): @@ -64,6 +65,7 @@ class Client(object): # extensions self.flavors = flavors.Flavors(self) + self.volume_types = volume_types.VolumeTypes(self) self.users = users.Users(self) self.databases = databases.Databases(self) self.backups = backups.Backups(self) diff --git a/troveclient/v1/shell.py b/troveclient/v1/shell.py index eb3a96ed..c5131cc5 100644 --- a/troveclient/v1/shell.py +++ b/troveclient/v1/shell.py @@ -173,6 +173,11 @@ def _find_flavor(cs, flavor): return utils.find_resource(cs.flavors, flavor) +def _find_volume_type(cs, volume_type): + """Get a volume type by ID.""" + return utils.find_resource(cs.volume_types, volume_type) + + def _find_backup(cs, backup): """Get a backup by ID.""" return utils.find_resource(cs.backups, backup) @@ -237,6 +242,38 @@ def do_flavor_show(cs, args): _print_object(flavor) +# Volume type related calls +@utils.arg('--datastore_type', metavar='', + default=None, + help='Type of the datastore. For eg: mysql.') +@utils.arg("--datastore_version_id", metavar="", + default=None, help="ID of the datastore version.") +@utils.service_type('database') +def do_volume_type_list(cs, args): + """Lists available volume types.""" + if args.datastore_type and args.datastore_version_id: + volume_types = cs.volume_types.\ + list_datastore_version_associated_volume_types( + args.datastore_type, args.datastore_version_id + ) + elif not args.datastore_type and not args.datastore_version_id: + volume_types = cs.volume_types.list() + else: + raise exceptions.MissingArgs(['datastore_type', + 'datastore_version_id']) + + utils.print_list(volume_types, ['id', 'name', 'is_public', 'description']) + + +@utils.arg('volume_type', metavar='', + help='ID or name of the volume type.') +@utils.service_type('database') +def do_volume_type_show(cs, args): + """Shows details of a volume type.""" + volume_type = _find_volume_type(cs, args.volume_type) + _print_object(volume_type) + + # Instance related calls @utils.arg('--limit', metavar='', type=int, default=None, diff --git a/troveclient/v1/volume_types.py b/troveclient/v1/volume_types.py new file mode 100644 index 00000000..9323d3e5 --- /dev/null +++ b/troveclient/v1/volume_types.py @@ -0,0 +1,57 @@ +# Copyright 2016 Tesora, Inc. +# All Rights Reserved. +# +# 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. + +from troveclient import base + + +class VolumeType(base.Resource): + """A VolumeType is an Cinder volume type.""" + + def __init__(self, manager, info, loaded=False): + super(VolumeType, self).__init__(manager, info, loaded) + if self.id is None and self.str_id is not None: + self.id = self.str_id + + def __repr__(self): + return "" % self.name + + +class VolumeTypes(base.ManagerWithFind): + """Manage :class:`VolumeType` resources.""" + resource_class = VolumeType + + def list(self): + """Get a list of all volume-types. + :rtype: list of :class:`VolumeType`. + """ + return self._list("/volume-types", "volume_types") + + def list_datastore_version_associated_volume_types(self, datastore, + version_id): + """Get a list of all volume-types for the specified datastore type + and datastore version . + :rtype: list of :class:`VolumeType`. + """ + return self._list("/datastores/%s/versions/%s/volume-types" % + (datastore, version_id), + "volume_types") + + def get(self, volume_type): + """Get a specific volume-type. + + :rtype: :class:`VolumeType` + """ + return self._get("/volume-types/%s" % base.getid(volume_type), + "volume_type")