diff --git a/senlinclient/osc/v1/cluster.py b/senlinclient/osc/v1/cluster.py index fd89e7d..ebb0a6d 100644 --- a/senlinclient/osc/v1/cluster.py +++ b/senlinclient/osc/v1/cluster.py @@ -718,3 +718,57 @@ class ClusterNodeDel(command.Command): node_ids = parsed_args.nodes.split(',') resp = senlin_client.cluster_del_nodes(parsed_args.cluster, node_ids) print('Request accepted by action: %s' % resp['action']) + + +class CheckCluster(command.Command): + """Check the cluster(s).""" + log = logging.getLogger(__name__ + ".CheckCluster") + + def get_parser(self, prog_name): + parser = super(CheckCluster, self).get_parser(prog_name) + parser.add_argument( + 'cluster', + metavar='', + nargs='+', + help=_('ID or name of cluster(s) to operate on.') + ) + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)", parsed_args) + senlin_client = self.app.client_manager.clustering + for cid in parsed_args.cluster: + try: + resp = senlin_client.check_cluster(cid) + except sdk_exc.ResourceNotFound: + raise exc.CommandError(_('Cluster not found: %s') % cid) + print('Cluster check request on cluster %(cid)s is accepted by ' + 'action %(action)s.' + % {'cid': cid, 'action': resp['action']}) + + +class RecoverCluster(command.Command): + """Recover the cluster(s).""" + log = logging.getLogger(__name__ + ".RecoverCluster") + + def get_parser(self, prog_name): + parser = super(RecoverCluster, self).get_parser(prog_name) + parser.add_argument( + 'cluster', + metavar='', + nargs='+', + help=_('ID or name of cluster(s) to operate on.') + ) + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)", parsed_args) + senlin_client = self.app.client_manager.clustering + for cid in parsed_args.cluster: + try: + resp = senlin_client.recover_cluster(cid) + except sdk_exc.ResourceNotFound: + raise exc.CommandError(_('Cluster not found: %s') % cid) + print('Cluster recover request on cluster %(cid)s is accepted by ' + 'action %(action)s.' + % {'cid': cid, 'action': resp['action']}) diff --git a/senlinclient/tests/unit/osc/v1/test_cluster.py b/senlinclient/tests/unit/osc/v1/test_cluster.py index c133c49..093417d 100644 --- a/senlinclient/tests/unit/osc/v1/test_cluster.py +++ b/senlinclient/tests/unit/osc/v1/test_cluster.py @@ -739,3 +739,57 @@ class TestClusterNodeDel(TestCluster): self.mock_client.cluster_del_nodes.assert_called_with( 'my_cluster', ['node1', 'node2']) + + +class TestClusterCheck(TestCluster): + response = {"action": "8bb476c3-0f4c-44ee-9f64-c7b0260814de"} + + def setUp(self): + super(TestClusterCheck, self).setUp() + self.cmd = osc_cluster.CheckCluster(self.app, None) + self.mock_client.check_cluster = mock.Mock( + return_value=self.response) + + def test_cluster_check(self): + arglist = ['cluster1', 'cluster2', 'cluster3'] + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + self.mock_client.check_cluster.assert_has_calls( + [mock.call('cluster1'), mock.call('cluster2'), + mock.call('cluster3')] + ) + + def test_cluster_check_not_found(self): + arglist = ['cluster1'] + self.mock_client.check_cluster.side_effect = sdk_exc.ResourceNotFound + parsed_args = self.check_parser(self.cmd, arglist, []) + error = self.assertRaises(exc.CommandError, self.cmd.take_action, + parsed_args) + self.assertIn('Cluster not found: cluster1', str(error)) + + +class TestClusterRecover(TestCluster): + response = {"action": "8bb476c3-0f4c-44ee-9f64-c7b0260814de"} + + def setUp(self): + super(TestClusterRecover, self).setUp() + self.cmd = osc_cluster.RecoverCluster(self.app, None) + self.mock_client.recover_cluster = mock.Mock( + return_value=self.response) + + def test_cluster_recoverk(self): + arglist = ['cluster1', 'cluster2', 'cluster3'] + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + self.mock_client.recover_cluster.assert_has_calls( + [mock.call('cluster1'), mock.call('cluster2'), + mock.call('cluster3')] + ) + + def test_cluster_recover_not_found(self): + arglist = ['cluster1'] + self.mock_client.recover_cluster.side_effect = sdk_exc.ResourceNotFound + parsed_args = self.check_parser(self.cmd, arglist, []) + error = self.assertRaises(exc.CommandError, self.cmd.take_action, + parsed_args) + self.assertIn('Cluster not found: cluster1', str(error)) diff --git a/senlinclient/tests/unit/v1/test_shell.py b/senlinclient/tests/unit/v1/test_shell.py index d311f42..36237c3 100644 --- a/senlinclient/tests/unit/v1/test_shell.py +++ b/senlinclient/tests/unit/v1/test_shell.py @@ -1036,7 +1036,7 @@ class ShellTest(testtools.TestCase): service.check_cluster.return_value = {'action': 'action_id'} sh.do_cluster_check(service, args) - service.check_cluster.assert_called_once_with(['cluster1']) + service.check_cluster.assert_called_once_with('cluster1') def test_do_cluster_recover(self): service = mock.Mock() @@ -1046,7 +1046,7 @@ class ShellTest(testtools.TestCase): sh.do_cluster_recover(service, args) - service.recover_cluster.assert_called_once_with(['cluster1']) + service.recover_cluster.assert_called_once_with('cluster1') @mock.patch.object(utils, 'print_list') def test_do_node_list(self, mock_print): diff --git a/senlinclient/v1/shell.py b/senlinclient/v1/shell.py index b9cc55a..00c561a 100644 --- a/senlinclient/v1/shell.py +++ b/senlinclient/v1/shell.py @@ -776,20 +776,24 @@ def do_cluster_policy_update(service, args): print('Request accepted by action: %s' % resp['action']) -@utils.arg('id', metavar='', - help=_('ID or name of cluster to operate on.')) +@utils.arg('id', metavar='', nargs='+', + help=_('ID or name of cluster(s) to operate on.')) def do_cluster_check(service, args): """Check the cluster(s).""" - resp = service.check_cluster(args.id) - print('Request accepted by action: %s' % resp['action']) + for cid in args.id: + resp = service.check_cluster(cid) + print('Cluster check request on cluster %(cid)s is accepted by ' + 'action %(action)s.' % {'cid': cid, 'action': resp['action']}) -@utils.arg('id', metavar='', - help=_('ID or name of cluster to operate on.')) +@utils.arg('id', metavar='', nargs='+', + help=_('ID or name of cluster(s) to operate on.')) def do_cluster_recover(service, args): """Recover the cluster(s).""" - resp = service.recover_cluster(args.id) - print('Request accepted by action: %s' % resp['action']) + for cid in args.id: + resp = service.recover_cluster(cid) + print('Cluster recover request on cluster %(cid)s is accepted by ' + 'action %(action)s.' % {'cid': cid, 'action': resp['action']}) # NODES diff --git a/setup.cfg b/setup.cfg index 132c646..6836168 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,6 +33,7 @@ openstack.clustering.v1 = cluster_action_list = senlinclient.osc.v1.action:ListAction cluster_action_show = senlinclient.osc.v1.action:ShowAction cluster_build_info = senlinclient.osc.v1.build_info:BuildInfo + cluster_check = senlinclient.osc.v1.cluster:CheckCluster cluster_create = senlinclient.osc.v1.cluster:CreateCluster cluster_delete = senlinclient.osc.v1.cluster:DeleteCluster cluster_event_list = senlinclient.osc.v1.event:ListEvent @@ -69,6 +70,7 @@ openstack.clustering.v1 = cluster_receiver_delete = senlinclient.osc.v1.receiver:DeleteReceiver cluster_receiver_list = senlinclient.osc.v1.receiver:ListReceiver cluster_receiver_show = senlinclient.osc.v1.receiver:ShowReceiver + cluster_recover = senlinclient.osc.v1.cluster:RecoverCluster cluster_resize = senlinclient.osc.v1.cluster:ResizeCluster cluster_scale_in = senlinclient.osc.v1.cluster:ScaleInCluster cluster_scale_out = senlinclient.osc.v1.cluster:ScaleOutCluster