summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao Chao <zhaochao1984@gmail.com>2018-02-13 19:29:33 +0800
committerZhao Chao <zhaochao1984@gmail.com>2018-02-13 20:11:23 +0800
commita2da920ef477bf6c1e408e421c8a6d3fe9205601 (patch)
tree4727e3461226478c46856725d6b4a301fcd1403e
parent0b28b04ebbfaed981f4e00e69e4c7a8e0ed75395 (diff)
downloadpython-troveclient-a2da920ef477bf6c1e408e421c8a6d3fe9205601.tar.gz
Add cluster-grow and cluster-shrink to OSC
This change adds database support to python-openstackclient project for the cluster-grow and cluster-shrink commands. The trove command cluster-grow is now: openstack database cluster grow The trove command cluster-shrink is now: openstack database cluster shrink Change-Id: I449e7f7d841ea266611ff79f8a41f6e730fced3c Partially-Implements: blueprint trove-support-in-python-openstackclient Signed-off-by: Zhao Chao <zhaochao1984@gmail.com>
-rw-r--r--releasenotes/notes/add-cluster-grow-shrink-to-osc-a07bc0d974b0c0a4.yaml10
-rw-r--r--setup.cfg2
-rw-r--r--troveclient/osc/v1/database_clusters.py87
-rw-r--r--troveclient/tests/osc/v1/fakes.py4
-rw-r--r--troveclient/tests/osc/v1/test_database_clusters.py48
5 files changed, 139 insertions, 12 deletions
diff --git a/releasenotes/notes/add-cluster-grow-shrink-to-osc-a07bc0d974b0c0a4.yaml b/releasenotes/notes/add-cluster-grow-shrink-to-osc-a07bc0d974b0c0a4.yaml
new file mode 100644
index 0000000..6f295d0
--- /dev/null
+++ b/releasenotes/notes/add-cluster-grow-shrink-to-osc-a07bc0d974b0c0a4.yaml
@@ -0,0 +1,10 @@
+---
+features:
+ - |
+ The command ``trove cluster-grow`` is now available
+ to use in the python-openstackclient CLI as ``openstack database
+ cluster grow``
+ - |
+ The command ``trove cluster-shrink`` is now available
+ to use in the python-openstackclient CLI as ``openstack database
+ cluster shrink``
diff --git a/setup.cfg b/setup.cfg
index 4d0686c..404d9d1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -38,10 +38,12 @@ openstack.database.v1 =
database_cluster_create = troveclient.osc.v1.database_clusters:CreateDatabaseCluster
database_cluster_delete = troveclient.osc.v1.database_clusters:DeleteDatabaseCluster
database_cluster_force_delete = troveclient.osc.v1.database_clusters:ForceDeleteDatabaseCluster
+ database_cluster_grow = troveclient.osc.v1.database_clusters:GrowDatabaseCluster
database_cluster_list = troveclient.osc.v1.database_clusters:ListDatabaseClusters
database_cluster_list_instances = troveclient.osc.v1.database_clusters:ListDatabaseClusterInstances
database_cluster_reset_status = troveclient.osc.v1.database_clusters:ResetDatabaseClusterStatus
database_cluster_show = troveclient.osc.v1.database_clusters:ShowDatabaseCluster
+ database_cluster_shrink = troveclient.osc.v1.database_clusters:ShrinkDatabaseCluster
database_cluster_upgrade = troveclient.osc.v1.database_clusters:UpgradeDatabaseCluster
database_configuration_attach = troveclient.osc.v1.database_configurations:AttachDatabaseConfiguration
database_configuration_create = troveclient.osc.v1.database_configurations:CreateDatabaseConfiguration
diff --git a/troveclient/osc/v1/database_clusters.py b/troveclient/osc/v1/database_clusters.py
index b9e1918..c647d9f 100644
--- a/troveclient/osc/v1/database_clusters.py
+++ b/troveclient/osc/v1/database_clusters.py
@@ -19,6 +19,8 @@ import six
from troveclient.i18n import _
from troveclient.v1.shell import _parse_instance_options
+from troveclient.v1.shell import INSTANCE_HELP
+from troveclient.v1.shell import INSTANCE_METAVAR
def set_attributes_for_print_detail(cluster):
@@ -149,21 +151,11 @@ class CreateDatabaseCluster(command.ShowOne):
)
parser.add_argument(
'--instance',
- metavar='"opt=<value>[,opt=<value> ...] "',
+ metavar=INSTANCE_METAVAR,
action='append',
dest='instances',
default=[],
- help=_("Add an instance to the cluster. Specify multiple "
- "times to create multiple instances. "
- "Valid options are: flavor=<flavor_name_or_id>, "
- "volume=<disk_size_in_GB>, volume_type=<type>, "
- "nic='<net-id=<net-uuid>, v4-fixed-ip=<ip-addr>, "
- "port-id=<port-uuid>>' "
- "(where net-id=network_id, "
- "v4-fixed-ip=IPv4r_fixed_address, port-id=port_id), "
- "availability_zone=<AZ_hint_for_Nova>, "
- "module=<module_name_or_id>, type=<type_of_cluster_node>, "
- "related_to=<related_attribute>."),
+ help=INSTANCE_HELP,
)
parser.add_argument(
'--locality',
@@ -284,3 +276,74 @@ class ForceDeleteDatabaseCluster(command.Command):
msg = (_("Failed to delete cluster %(cluster)s: %(e)s")
% {'cluster': parsed_args.cluster, 'e': e})
raise exceptions.CommandError(msg)
+
+
+class GrowDatabaseCluster(command.Command):
+
+ _description = _("Adds more instances to a cluster.")
+
+ def get_parser(self, prog_name):
+ parser = super(GrowDatabaseCluster, self).get_parser(prog_name)
+ parser.add_argument(
+ '--instance',
+ metavar=INSTANCE_METAVAR,
+ action='append',
+ dest='instances',
+ default=[],
+ help=INSTANCE_HELP
+ )
+ parser.add_argument(
+ 'cluster',
+ metavar='<cluster>',
+ help=_('ID or name of the cluster.')
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ database_client_manager = self.app.client_manager.database
+
+ db_clusters = database_client_manager.clusters
+ cluster = utils.find_resource(db_clusters,
+ parsed_args.cluster)
+
+ instances = _parse_instance_options(database_client_manager,
+ parsed_args.instances,
+ for_grow=True)
+ db_clusters.grow(cluster, instances=instances)
+
+
+class ShrinkDatabaseCluster(command.Command):
+
+ _description = _("Drops instances from a cluster.")
+
+ def get_parser(self, prog_name):
+ parser = super(ShrinkDatabaseCluster, self).get_parser(prog_name)
+ parser.add_argument(
+ 'cluster',
+ metavar='<cluster>',
+ help=_('ID or name of the cluster.')
+ )
+ parser.add_argument(
+ 'instances',
+ metavar='<instance>',
+ nargs='+',
+ default=[],
+ help=_("Drop instance(s) from the cluster. Specify "
+ "multiple ids to drop multiple instances.")
+ )
+ return parser
+
+ def take_action(self, parsed_args):
+ database_client_manager = self.app.client_manager.database
+
+ db_clusters = database_client_manager.clusters
+ cluster = utils.find_resource(db_clusters,
+ parsed_args.cluster)
+
+ db_instances = database_client_manager.instances
+ instances = [
+ {'id': utils.find_resource(db_instances,
+ instance).id}
+ for instance in parsed_args.instances
+ ]
+ db_clusters.shrink(cluster, instances)
diff --git a/troveclient/tests/osc/v1/fakes.py b/troveclient/tests/osc/v1/fakes.py
index 85a1207..be06968 100644
--- a/troveclient/tests/osc/v1/fakes.py
+++ b/troveclient/tests/osc/v1/fakes.py
@@ -51,10 +51,14 @@ class FakeClusters(object):
fake_clusters = fakes.FakeHTTPClient().get_clusters()[2]['clusters']
fake_cluster = (fakes.FakeHTTPClient()
.get_clusters_cls_1234()[2]['cluster'])
+ fake_cluster_member = fake_cluster['instances'][1]
def get_clusters_cls_1234(self):
return clusters.Cluster(None, self.fake_cluster)
+ def get_clusters_member_2(self):
+ return instances.Instance(None, self.fake_cluster_member)
+
class FakeConfigurations(object):
fake_config = (fakes.FakeHTTPClient().get_configurations()
diff --git a/troveclient/tests/osc/v1/test_database_clusters.py b/troveclient/tests/osc/v1/test_database_clusters.py
index 70fc9c3..1d85c16 100644
--- a/troveclient/tests/osc/v1/test_database_clusters.py
+++ b/troveclient/tests/osc/v1/test_database_clusters.py
@@ -233,3 +233,51 @@ class TestDatabaseClusterForceDelete(TestClusters):
self.assertRaises(exceptions.CommandError,
self.cmd.take_action,
parsed_args)
+
+
+class TestDatabaseClusterGrow(TestClusters):
+
+ def setUp(self):
+ super(TestDatabaseClusterGrow, self).setUp()
+ self.cmd = database_clusters.GrowDatabaseCluster(self.app, None)
+
+ @mock.patch.object(utils, 'find_resource')
+ @mock.patch.object(database_clusters, '_parse_instance_options')
+ def test_cluster_grow(self, mock_parse_instance_opts,
+ mock_find_resource):
+ args = ['test-clstr',
+ '--instance',
+ 'name=test-clstr-member-3,flavor=3']
+ parsed_instance_opts = [
+ {'name': 'test-clstr-member-3',
+ 'flavor': 3}
+ ]
+ mock_parse_instance_opts.return_value = parsed_instance_opts
+ mock_find_resource.return_value = args[0]
+
+ parsed_args = self.check_parser(self.cmd, args, [])
+ result = self.cmd.take_action(parsed_args)
+ self.cluster_client.grow.assert_called_with(
+ 'test-clstr',
+ instances=parsed_instance_opts)
+ self.assertIsNone(result)
+
+
+class TestDatabaseClusterShrink(TestClusters):
+
+ def setUp(self):
+ super(TestDatabaseClusterShrink, self).setUp()
+ self.cmd = database_clusters.ShrinkDatabaseCluster(self.app, None)
+ self.cluster_member = self.fake_clusters.get_clusters_member_2()
+
+ @mock.patch.object(utils, 'find_resource')
+ def test_cluster_grow(self, mock_find_resource):
+ args = ['test-clstr', 'test-clstr-member-2']
+ mock_find_resource.side_effect = [
+ args[0], self.cluster_member]
+
+ parsed_args = self.check_parser(self.cmd, args, [])
+ result = self.cmd.take_action(parsed_args)
+ self.cluster_client.shrink.assert_called_with('test-clstr',
+ [{'id': 'member-2'}])
+ self.assertIsNone(result)