summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLingxian Kong <anlin.kong@gmail.com>2020-11-12 09:57:13 +1300
committerLingxian Kong <anlin.kong@gmail.com>2020-11-13 20:53:10 +1300
commitc04e299b1d503f2ce67730398b9585a196616e51 (patch)
tree78442db780aa4fe8d695ce22810c67b1f0456602
parentdd371f04540d2c37fbae9626724769c05465e4b3 (diff)
downloadpython-troveclient-c04e299b1d503f2ce67730398b9585a196616e51.tar.gz
Revert "Remove flavor API"
Story: 2008341 Task: 41242 This reverts commit 27cf71299ec51976fed8b18dbf5c0e4f9f4fd6f5. Change-Id: I036a0423263b1a0332415c6403647ae82c9e34c4
-rw-r--r--setup.cfg2
-rw-r--r--troveclient/compat/__init__.py2
-rw-r--r--troveclient/compat/cli.py11
-rw-r--r--troveclient/compat/client.py3
-rw-r--r--troveclient/compat/mcli.py26
-rw-r--r--troveclient/osc/v1/database_flavors.py97
-rw-r--r--troveclient/osc/v1/database_instances.py17
-rw-r--r--troveclient/tests/osc/v1/fakes.py8
-rw-r--r--troveclient/tests/osc/v1/test_database_flavors.py78
-rw-r--r--troveclient/tests/osc/v1/test_database_instances.py11
-rw-r--r--troveclient/tests/test_management.py32
-rw-r--r--troveclient/v1/client.py2
-rw-r--r--troveclient/v1/flavors.py58
-rw-r--r--troveclient/v1/management.py39
-rw-r--r--troveclient/v1/shell.py56
15 files changed, 429 insertions, 13 deletions
diff --git a/setup.cfg b/setup.cfg
index 315702d..de7ec80 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -63,6 +63,8 @@ openstack.database.v1 =
database_db_create = troveclient.osc.v1.databases:CreateDatabase
database_db_delete = troveclient.osc.v1.databases:DeleteDatabase
database_db_list = troveclient.osc.v1.databases:ListDatabases
+ database_flavor_list = troveclient.osc.v1.database_flavors:ListDatabaseFlavors
+ database_flavor_show = troveclient.osc.v1.database_flavors:ShowDatabaseFlavor
database_instance_create = troveclient.osc.v1.database_instances:CreateDatabaseInstance
database_instance_delete = troveclient.osc.v1.database_instances:DeleteDatabaseInstance
database_instance_force_delete = troveclient.osc.v1.database_instances:ForceDeleteDatabaseInstance
diff --git a/troveclient/compat/__init__.py b/troveclient/compat/__init__.py
index 1e9734d..a08dcb8 100644
--- a/troveclient/compat/__init__.py
+++ b/troveclient/compat/__init__.py
@@ -21,9 +21,11 @@ from troveclient.v1.accounts import Accounts # noqa
from troveclient.v1.databases import Databases # noqa
from troveclient.v1.diagnostics import DiagnosticsInterrogator # noqa
from troveclient.v1.diagnostics import HwInfoInterrogator # noqa
+from troveclient.v1.flavors import Flavors # noqa
from troveclient.v1.hosts import Hosts # noqa
from troveclient.v1.instances import Instances # noqa
from troveclient.v1.management import Management # noqa
+from troveclient.v1.management import MgmtFlavors # noqa
from troveclient.v1.management import RootHistory # noqa
from troveclient.v1.root import Root # noqa
from troveclient.v1.storage import StorageInfo # noqa
diff --git a/troveclient/compat/cli.py b/troveclient/compat/cli.py
index 6f6199e..8d82ab7 100644
--- a/troveclient/compat/cli.py
+++ b/troveclient/compat/cli.py
@@ -129,6 +129,16 @@ class InstanceCommands(common.AuthedCommandsBase):
self._pretty_print(self.dbaas.instances.configuration, self.id)
+class FlavorsCommands(common.AuthedCommandsBase):
+ """Command for listing Flavors."""
+
+ params = []
+
+ def list(self):
+ """List the available flavors."""
+ self._pretty_list(self.dbaas.flavors.list)
+
+
class DatabaseCommands(common.AuthedCommandsBase):
"""Database CRUD operations on an instance."""
@@ -426,6 +436,7 @@ class MetadataCommands(common.AuthedCommandsBase):
COMMANDS = {
'auth': common.Auth,
'instance': InstanceCommands,
+ 'flavor': FlavorsCommands,
'database': DatabaseCommands,
'limit': LimitsCommands,
'backup': BackupsCommands,
diff --git a/troveclient/compat/client.py b/troveclient/compat/client.py
index 1daa129..9dfa284 100644
--- a/troveclient/compat/client.py
+++ b/troveclient/compat/client.py
@@ -309,6 +309,7 @@ class Dbaas(object):
from troveclient.v1 import databases
from troveclient.v1 import datastores
from troveclient.v1 import diagnostics
+ from troveclient.v1 import flavors
from troveclient.v1 import hosts
from troveclient.v1 import instances
from troveclient.v1 import limits
@@ -330,6 +331,7 @@ class Dbaas(object):
region_name=region_name)
self.versions = versions.Versions(self)
self.databases = databases.Databases(self)
+ self.flavors = flavors.Flavors(self)
self.instances = instances.Instances(self)
self.limits = limits.Limits(self)
self.users = users.Users(self)
@@ -347,6 +349,7 @@ class Dbaas(object):
self.storage = storage.StorageInfo(self)
self.management = management.Management(self)
self.mgmt_cluster = management.MgmtClusters(self)
+ self.mgmt_flavor = management.MgmtFlavors(self)
self.accounts = accounts.Accounts(self)
self.diagnostics = diagnostics.DiagnosticsInterrogator(self)
self.hwinfo = diagnostics.HwInfoInterrogator(self)
diff --git a/troveclient/compat/mcli.py b/troveclient/compat/mcli.py
index f151ab7..e3efbae 100644
--- a/troveclient/compat/mcli.py
+++ b/troveclient/compat/mcli.py
@@ -181,6 +181,31 @@ class StorageCommands(common.AuthedCommandsBase):
self._pretty_list(self.dbaas.storage.index)
+class FlavorsCommands(common.AuthedCommandsBase):
+ """Commands for managing Flavors."""
+
+ params = [
+ 'name',
+ 'ram',
+ 'disk',
+ 'vcpus',
+ 'flavor_id',
+ 'ephemeral',
+ 'swap',
+ 'rxtx_factor',
+ 'service_type'
+ ]
+
+ def create(self):
+ """Create a new flavor."""
+ self._require('name', 'ram', 'disk', 'vcpus',
+ 'flavor_id', 'service_type')
+ self._pretty_print(self.dbaas.mgmt_flavor.create, self.name,
+ self.ram, self.disk, self.vcpus, self.flavor_id,
+ self.ephemeral, self.swap, self.rxtx_factor,
+ self.service_type)
+
+
def config_options(oparser):
oparser.add_option("-u", "--url", default="http://localhost:5000/v1.1",
help="Auth API endpoint URL with port and version. \
@@ -194,6 +219,7 @@ COMMANDS = {
'root': RootCommands,
'storage': StorageCommands,
'quota': QuotaCommands,
+ 'flavor': FlavorsCommands,
}
diff --git a/troveclient/osc/v1/database_flavors.py b/troveclient/osc/v1/database_flavors.py
new file mode 100644
index 0000000..5fb513e
--- /dev/null
+++ b/troveclient/osc/v1/database_flavors.py
@@ -0,0 +1,97 @@
+# 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.
+
+"""Database v1 Flavors action implementations"""
+
+from osc_lib.command import command
+from osc_lib import utils
+import six
+
+from troveclient import exceptions
+from troveclient.i18n import _
+
+
+def set_attributes_for_print_detail(flavor):
+ info = flavor._info.copy()
+ # Get rid of those ugly links
+ if info.get('links'):
+ del(info['links'])
+
+ # Fallback to str_id for flavors, where necessary
+ if hasattr(flavor, 'str_id'):
+ info['id'] = flavor.id
+ del(info['str_id'])
+ return info
+
+
+class ListDatabaseFlavors(command.Lister):
+
+ _description = _("List database flavors")
+ columns = ['ID', 'Name', 'RAM', 'vCPUs', 'Disk', 'Ephemeral']
+
+ def get_parser(self, prog_name):
+ parser = super(ListDatabaseFlavors, self).get_parser(prog_name)
+ parser.add_argument(
+ '--datastore-type',
+ dest='datastore_type',
+ metavar='<datastore-type>',
+ help=_('Type of the datastore. For eg: mysql.')
+ )
+ parser.add_argument(
+ '--datastore-version-id',
+ dest='datastore_version_id',
+ metavar='<datastore-version-id>',
+ help=_('ID of the datastore version.')
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ db_flavors = self.app.client_manager.database.flavors
+ if parsed_args.datastore_type and parsed_args.datastore_version_id:
+ flavors = db_flavors.list_datastore_version_associated_flavors(
+ datastore=parsed_args.datastore_type,
+ version_id=parsed_args.datastore_version_id)
+ elif (not parsed_args.datastore_type and not
+ parsed_args.datastore_version_id):
+ flavors = db_flavors.list()
+ else:
+ raise exceptions.MissingArgs(['datastore-type',
+ 'datastore-version-id'])
+
+ # Fallback to str_id where necessary.
+ _flavors = []
+ for f in flavors:
+ if not f.id and hasattr(f, 'str_id'):
+ f.id = f.str_id
+ _flavors.append(utils.get_item_properties(f, self.columns))
+
+ return self.columns, _flavors
+
+
+class ShowDatabaseFlavor(command.ShowOne):
+ _description = _("Shows details of a database flavor")
+
+ def get_parser(self, prog_name):
+ parser = super(ShowDatabaseFlavor, self).get_parser(prog_name)
+ parser.add_argument(
+ 'flavor',
+ metavar='<flavor>',
+ help=_('ID or name of the flavor'),
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ db_flavors = self.app.client_manager.database.flavors
+ flavor = utils.find_resource(db_flavors,
+ parsed_args.flavor)
+ flavor = set_attributes_for_print_detail(flavor)
+ return zip(*sorted(six.iteritems(flavor)))
diff --git a/troveclient/osc/v1/database_instances.py b/troveclient/osc/v1/database_instances.py
index 698ec76..99ead8f 100644
--- a/troveclient/osc/v1/database_instances.py
+++ b/troveclient/osc/v1/database_instances.py
@@ -244,7 +244,8 @@ class CreateDatabaseInstance(command.ShowOne):
'--flavor',
metavar='<flavor>',
type=str,
- help=_("A flavor ID."),
+ help=_("Flavor to create the instance (name or ID). Flavor is not "
+ "required when creating replica instances."),
)
parser.add_argument(
'--size',
@@ -373,8 +374,16 @@ class CreateDatabaseInstance(command.ShowOne):
db_instances = database.instances
if not parsed_args.replica_of and not parsed_args.flavor:
- raise exceptions.CommandError(
- _("Please specify a flavor"))
+ raise exceptions.CommandError(_("Please specify a flavor"))
+
+ if parsed_args.replica_of and parsed_args.flavor:
+ print("Warning: Flavor is ignored for creating replica.")
+
+ if not parsed_args.replica_of:
+ flavor_id = osc_utils.find_resource(
+ database.flavors, parsed_args.flavor).id
+ else:
+ flavor_id = None
volume = None
if parsed_args.size is not None and parsed_args.size <= 0:
@@ -441,7 +450,7 @@ class CreateDatabaseInstance(command.ShowOne):
instance = db_instances.create(
parsed_args.name,
- flavor_id=parsed_args.flavor,
+ flavor_id=flavor_id,
volume=volume,
databases=databases,
users=users,
diff --git a/troveclient/tests/osc/v1/fakes.py b/troveclient/tests/osc/v1/fakes.py
index 7002c3c..fde9237 100644
--- a/troveclient/tests/osc/v1/fakes.py
+++ b/troveclient/tests/osc/v1/fakes.py
@@ -20,6 +20,7 @@ from troveclient.v1 import clusters
from troveclient.v1 import configurations
from troveclient.v1 import databases
from troveclient.v1 import datastores
+from troveclient.v1 import flavors
from troveclient.v1 import instances
from troveclient.v1 import limits
from troveclient.v1 import modules
@@ -33,6 +34,13 @@ class TestDatabasev1(utils.TestCommand):
self.app.client_manager.database = mock.MagicMock()
+class FakeFlavors(object):
+ fake_flavors = fakes.FakeHTTPClient().get_flavors()[2]['flavors']
+
+ def get_flavors_1(self):
+ return flavors.Flavor(None, self.fake_flavors[0])
+
+
class FakeBackups(object):
fake_backups = fakes.FakeHTTPClient().get_backups()[2]['backups']
diff --git a/troveclient/tests/osc/v1/test_database_flavors.py b/troveclient/tests/osc/v1/test_database_flavors.py
new file mode 100644
index 0000000..6b87f06
--- /dev/null
+++ b/troveclient/tests/osc/v1/test_database_flavors.py
@@ -0,0 +1,78 @@
+# 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.osc.v1 import database_flavors
+from troveclient.tests.osc.v1 import fakes
+
+
+class TestFlavors(fakes.TestDatabasev1):
+ fake_flavors = fakes.FakeFlavors()
+
+ def setUp(self):
+ super(TestFlavors, self).setUp()
+ self.mock_client = self.app.client_manager.database
+ self.flavor_client = self.app.client_manager.database.flavors
+
+
+class TestFlavorList(TestFlavors):
+ columns = database_flavors.ListDatabaseFlavors.columns
+ values = (1, 'm1.tiny', 512, '', '', '')
+
+ def setUp(self):
+ super(TestFlavorList, self).setUp()
+ self.cmd = database_flavors.ListDatabaseFlavors(self.app, None)
+ self.data = [self.fake_flavors.get_flavors_1()]
+ self.flavor_client.list.return_value = self.data
+ self.flavor_client.list_datastore_version_associated_flavors. \
+ return_value = self.data
+
+ def test_flavor_list_defaults(self):
+ parsed_args = self.check_parser(self.cmd, [], [])
+ columns, values = self.cmd.take_action(parsed_args)
+ self.flavor_client.list.assert_called_once_with()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual([self.values], values)
+
+ def test_flavor_list_with_optional_args(self):
+ args = ['--datastore-type', 'mysql',
+ '--datastore-version-id', '5.6']
+ parsed_args = self.check_parser(self.cmd, args, [])
+ list_flavor_dict = {'datastore': 'mysql',
+ 'version_id': '5.6'}
+ columns, values = self.cmd.take_action(parsed_args)
+ self.flavor_client.list_datastore_version_associated_flavors. \
+ assert_called_once_with(**list_flavor_dict)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual([self.values], values)
+
+
+class TestFlavorShow(TestFlavors):
+
+ values = (1, 'm1.tiny', 512)
+
+ def setUp(self):
+ super(TestFlavorShow, self).setUp()
+ self.cmd = database_flavors.ShowDatabaseFlavor(self.app, None)
+ self.data = self.fake_flavors.get_flavors_1()
+ self.flavor_client.get.return_value = self.data
+ self.columns = (
+ 'id',
+ 'name',
+ 'ram',
+ )
+
+ def test_flavor_show_defaults(self):
+ args = ['m1.tiny']
+ parsed_args = self.check_parser(self.cmd, args, [])
+ columns, data = self.cmd.take_action(parsed_args)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.values, data)
diff --git a/troveclient/tests/osc/v1/test_database_instances.py b/troveclient/tests/osc/v1/test_database_instances.py
index 2f3928e..af2134e 100644
--- a/troveclient/tests/osc/v1/test_database_instances.py
+++ b/troveclient/tests/osc/v1/test_database_instances.py
@@ -222,7 +222,6 @@ class TestDatabaseInstanceCreate(TestInstances):
@mock.patch.object(utils, 'find_resource')
def test_instance_create(self, mock_find):
- mock_find.id.side_effect = ['test', 'mod_id']
args = ['test-name', '--flavor', '103',
'--size', '1',
'--databases', 'db1', 'db2',
@@ -256,7 +255,8 @@ class TestDatabaseInstanceCreate(TestInstances):
self.assertEqual(self.columns, columns)
self.assertEqual(self.values, data)
- def test_instance_create_without_allowed_cidrs(self):
+ @mock.patch.object(utils, 'find_resource')
+ def test_instance_create_without_allowed_cidrs(self, mock_find):
resp = {
"id": "a1fea1cf-18ad-48ab-bdfd-fce99a4b834e",
"name": "test-mysql",
@@ -338,7 +338,10 @@ class TestDatabaseInstanceCreate(TestInstances):
self.assertEqual(expected_columns, columns)
self.assertEqual(expected_values, data)
- def test_instance_create_nic_param(self):
+ @mock.patch.object(utils, 'find_resource')
+ def test_instance_create_nic_param(self, mock_find):
+ fake_id = self.random_uuid()
+ mock_find.return_value.id = fake_id
args = [
'test-mysql',
'--flavor', 'a48ea749-7ee3-4003-8aae-eb4e79773e2d',
@@ -352,7 +355,7 @@ class TestDatabaseInstanceCreate(TestInstances):
self.instance_client.create.assert_called_once_with(
'test-mysql',
- flavor_id='a48ea749-7ee3-4003-8aae-eb4e79773e2d',
+ flavor_id=fake_id,
volume={"size": 1, "type": None},
databases=[],
users=[],
diff --git a/troveclient/tests/test_management.py b/troveclient/tests/test_management.py
index 23401b9..73d0a7c 100644
--- a/troveclient/tests/test_management.py
+++ b/troveclient/tests/test_management.py
@@ -165,6 +165,38 @@ class ManagementTest(testtools.TestCase):
self.assertEqual({'reset-task-status': {}}, self.body_)
+class MgmtFlavorsTest(testtools.TestCase):
+
+ def setUp(self):
+ super(MgmtFlavorsTest, self).setUp()
+ self.orig__init = management.MgmtFlavors.__init__
+ management.MgmtFlavors.__init__ = mock.Mock(return_value=None)
+ self.flavors = management.MgmtFlavors()
+ self.flavors.api = mock.Mock()
+ self.flavors.api.client = mock.Mock()
+ self.flavors.resource_class = mock.Mock(return_value="flavor-1")
+ self.orig_base_getid = base.getid
+ base.getid = mock.Mock(return_value="flavor1")
+
+ def tearDown(self):
+ super(MgmtFlavorsTest, self).tearDown()
+ management.MgmtFlavors.__init__ = self.orig__init
+ base.getid = self.orig_base_getid
+
+ def test_create(self):
+ def side_effect_func(path, body, inst):
+ return path, body, inst
+
+ self.flavors._create = mock.Mock(side_effect=side_effect_func)
+ p, b, i = self.flavors.create("test-name", 1024, 30, 2, 1)
+ self.assertEqual("/mgmt/flavors", p)
+ self.assertEqual("flavor", i)
+ self.assertEqual("test-name", b["flavor"]["name"])
+ self.assertEqual(1024, b["flavor"]["ram"])
+ self.assertEqual(2, b["flavor"]["vcpu"])
+ self.assertEqual(1, b["flavor"]["flavor_id"])
+
+
class MgmtDatastoreVersionsTest(testtools.TestCase):
def setUp(self):
diff --git a/troveclient/v1/client.py b/troveclient/v1/client.py
index 88a7257..c34915f 100644
--- a/troveclient/v1/client.py
+++ b/troveclient/v1/client.py
@@ -21,6 +21,7 @@ from troveclient.v1 import clusters
from troveclient.v1 import configurations
from troveclient.v1 import databases
from troveclient.v1 import datastores
+from troveclient.v1 import flavors
from troveclient.v1 import instances
from troveclient.v1 import limits
from troveclient.v1 import management
@@ -64,6 +65,7 @@ class Client(object):
# self.limits = limits.LimitsManager(self)
# extensions
+ self.flavors = flavors.Flavors(self)
self.volume_types = volume_types.VolumeTypes(self)
self.users = users.Users(self)
self.databases = databases.Databases(self)
diff --git a/troveclient/v1/flavors.py b/troveclient/v1/flavors.py
new file mode 100644
index 0000000..7b1d72f
--- /dev/null
+++ b/troveclient/v1/flavors.py
@@ -0,0 +1,58 @@
+# Copyright 2011 OpenStack Foundation
+# Copyright 2013 Rackspace Hosting
+# 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 Flavor(base.Resource):
+ """A Flavor is an Instance type, specifying other things, like RAM size."""
+
+ def __init__(self, manager, info, loaded=False):
+ super(Flavor, 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 "<Flavor: %s>" % self.name
+
+
+class Flavors(base.ManagerWithFind):
+ """Manage :class:`Flavor` resources."""
+ resource_class = Flavor
+
+ def list(self):
+ """Get a list of all flavors.
+ :rtype: list of :class:`Flavor`.
+ """
+ return self._list("/flavors", "flavors")
+
+ def list_datastore_version_associated_flavors(self, datastore,
+ version_id):
+ """Get a list of all flavors for the specified datastore type
+ and datastore version .
+ :rtype: list of :class:`Flavor`.
+ """
+ return self._list("/datastores/%s/versions/%s/flavors" %
+ (datastore, version_id),
+ "flavors")
+
+ def get(self, flavor):
+ """Get a specific flavor.
+
+ :rtype: :class:`Flavor`
+ """
+ return self._get("/flavors/%s" % base.getid(flavor),
+ "flavor")
diff --git a/troveclient/v1/management.py b/troveclient/v1/management.py
index 38923ad..478d086 100644
--- a/troveclient/v1/management.py
+++ b/troveclient/v1/management.py
@@ -21,6 +21,7 @@ from troveclient import common
from troveclient.v1 import clusters
from troveclient.v1 import configurations
from troveclient.v1 import datastores
+from troveclient.v1 import flavors
from troveclient.v1 import instances
@@ -149,6 +150,44 @@ class MgmtClusters(base.ManagerWithFind):
self._action(cluster_id, body)
+class MgmtFlavors(base.ManagerWithFind):
+ """Manage :class:`Flavor` resources."""
+ resource_class = flavors.Flavor
+
+ def __repr__(self):
+ return "<Flavors Manager at %s>" % id(self)
+
+ # Appease the abc gods
+ def list(self):
+ pass
+
+ def create(self, name, ram, disk, vcpus,
+ flavorid="auto", ephemeral=None, swap=None, rxtx_factor=None,
+ service_type=None):
+ """Create a new flavor."""
+ body = {"flavor": {
+ "flavor_id": flavorid,
+ "name": name,
+ "ram": ram,
+ "disk": disk,
+ "vcpu": vcpus,
+ "ephemeral": 0,
+ "swap": 0,
+ "rxtx_factor": "1.0",
+ "is_public": "True"
+ }}
+ if ephemeral:
+ body["flavor"]["ephemeral"] = ephemeral
+ if swap:
+ body["flavor"]["swap"] = swap
+ if rxtx_factor:
+ body["flavor"]["rxtx_factor"] = rxtx_factor
+ if service_type:
+ body["flavor"]["service_type"] = service_type
+
+ return self._create("/mgmt/flavors", body, "flavor")
+
+
class MgmtConfigurationParameters(configurations.ConfigurationParameters):
def create(self, version, name, restart_required, data_type,
max_size=None, min_size=None):
diff --git a/troveclient/v1/shell.py b/troveclient/v1/shell.py
index d7e81db..4c6ffd7 100644
--- a/troveclient/v1/shell.py
+++ b/troveclient/v1/shell.py
@@ -187,6 +187,11 @@ def _find_cluster(cs, cluster):
return utils.find_resource(cs.clusters, cluster)
+def _find_flavor(cs, flavor):
+ """Get a flavor by ID."""
+ 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)
@@ -217,6 +222,46 @@ def _find_configuration(cs, configuration):
return utils.find_resource(cs.configurations, configuration)
+# Flavor related calls
+@utils.arg('--datastore_type', metavar='<datastore_type>',
+ default=None,
+ help=_('Type of the datastore. For eg: mysql.'))
+@utils.arg("--datastore_version_id", metavar="<datastore_version_id>",
+ default=None, help=_("ID of the datastore version."))
+@utils.service_type('database')
+def do_flavor_list(cs, args):
+ """Lists available flavors."""
+ if args.datastore_type and args.datastore_version_id:
+ flavors = cs.flavors.list_datastore_version_associated_flavors(
+ args.datastore_type, args.datastore_version_id)
+ elif not args.datastore_type and not args.datastore_version_id:
+ flavors = cs.flavors.list()
+ else:
+ raise exceptions.MissingArgs(['datastore_type',
+ 'datastore_version_id'])
+
+ # Fallback to str_id where necessary.
+ _flavors = []
+ for f in flavors:
+ if not f.id and hasattr(f, 'str_id'):
+ f.id = f.str_id
+ _flavors.append(f)
+
+ utils.print_list(_flavors, ['id', 'name', 'ram', 'vcpus', 'disk',
+ 'ephemeral'],
+ labels={'ram': 'RAM', 'vcpus': 'vCPUs', 'disk': 'Disk'},
+ order_by='ram')
+
+
+@utils.arg('flavor', metavar='<flavor>', type=str,
+ help=_('ID or name of the flavor.'))
+@utils.service_type('database')
+def do_flavor_show(cs, args):
+ """Shows details of a flavor."""
+ flavor = _find_flavor(cs, args.flavor)
+ _print_object(flavor)
+
+
# Volume type related calls
@utils.arg('--datastore_type', metavar='<datastore_type>',
default=None,
@@ -508,7 +553,7 @@ def do_update(cs, args):
@utils.arg('flavor',
metavar='<flavor>',
type=str,
- help=_('A flavor ID.'))
+ help=_('A flavor name or ID.'))
@utils.arg('--databases', metavar='<database>',
help=_('Optional list of databases.'),
nargs="+", default=[])
@@ -576,7 +621,7 @@ def do_update(cs, args):
@utils.service_type('database')
def do_create(cs, args):
"""Creates a new instance."""
- flavor_id = args.flavor
+ flavor_id = _find_flavor(cs, args.flavor).id
volume = None
if args.size is not None and args.size <= 0:
raise exceptions.ValidationError(
@@ -639,7 +684,8 @@ def _validate_nic_info(nic_info, nic_str):
def _get_flavor(cs, opts_str):
- flavor_id, opts_str = _strip_option(opts_str, 'flavor', True)
+ flavor_name, opts_str = _strip_option(opts_str, 'flavor', True)
+ flavor_id = _find_flavor(cs, flavor_name).id
return str(flavor_id), opts_str
@@ -881,12 +927,12 @@ def do_cluster_create(cs, args):
@utils.arg('flavor',
metavar='<flavor>',
type=str,
- help=_('New flavor ID for the instance.'))
+ help=_('New flavor of the instance.'))
@utils.service_type('database')
def do_resize_instance(cs, args):
"""Resizes an instance with a new flavor."""
instance = _find_instance(cs, args.instance)
- flavor_id = args.flavor
+ flavor_id = _find_flavor(cs, args.flavor).id
cs.instances.resize_instance(instance, flavor_id)