diff --git a/setup.cfg b/setup.cfg index a6c4faa..699e39b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -54,6 +54,7 @@ openstack.infra_optim.v1 = optimize_actionplan_create = watcherclient.v1.action_plan_shell:CreateActionPlan optimize_actionplan_update = watcherclient.v1.action_plan_shell:UpdateActionPlan optimize_actionplan_start = watcherclient.v1.action_plan_shell:StartActionPlan + optimize_actionplan_cancel = watcherclient.v1.action_plan_shell:CancelActionPlan optimize_action_show = watcherclient.v1.action_shell:ShowAction optimize_action_list = watcherclient.v1.action_shell:ListAction @@ -90,6 +91,7 @@ watcherclient.v1 = actionplan_update = watcherclient.v1.action_plan_shell:UpdateActionPlan actionplan_start = watcherclient.v1.action_plan_shell:StartActionPlan actionplan_delete = watcherclient.v1.action_plan_shell:DeleteActionPlan + actionplan_cancel = watcherclient.v1.action_plan_shell:CancelActionPlan action_show = watcherclient.v1.action_shell:ShowAction action_list = watcherclient.v1.action_shell:ListAction diff --git a/watcherclient/tests/unit/v1/test_action_plan_shell.py b/watcherclient/tests/unit/v1/test_action_plan_shell.py index d36de96..4a05d4f 100644 --- a/watcherclient/tests/unit/v1/test_action_plan_shell.py +++ b/watcherclient/tests/unit/v1/test_action_plan_shell.py @@ -257,3 +257,25 @@ class ActionPlanShellTest(base.CommandTestCase): self.assertEqual(1, exit_code) self.assertEqual('', result) + + def test_do_action_plan_cancel(self): + action_plan = resource.ActionPlan(mock.Mock(), ACTION_PLAN_1) + self.m_action_plan_mgr.cancel.return_value = action_plan + + exit_code, result = self.run_cmd( + 'actionplan cancel 5869da81-4876-4687-a1ed-12cd64cf53d9') + + self.assertEqual(0, exit_code) + self.assertEqual( + self.resource_as_dict(action_plan, self.FIELDS, self.FIELD_LABELS), + result) + self.m_action_plan_mgr.cancel.assert_called_once_with( + '5869da81-4876-4687-a1ed-12cd64cf53d9') + + def test_do_action_plan_cancel_not_uuid(self): + exit_code, result = self.run_cmd( + 'actionplan cancel not_uuid', + formatting=None) + + self.assertEqual(1, exit_code) + self.assertEqual('', result) diff --git a/watcherclient/v1/action_plan.py b/watcherclient/v1/action_plan.py index 411ddde..3caa8c1 100644 --- a/watcherclient/v1/action_plan.py +++ b/watcherclient/v1/action_plan.py @@ -89,3 +89,12 @@ class ActionPlanManager(base.Manager): def start(self, action_plan_id): patch = [{'op': 'replace', 'value': 'PENDING', 'path': '/state'}] return self._update(self._path(action_plan_id), patch) + + def cancel(self, action_plan_id): + action_plan = self.get(action_plan_id) + if action_plan.state == "ONGOING": + patch = [{'op': 'replace', 'value': 'CANCELLING', + 'path': '/state'}] + else: + patch = [{'op': 'replace', 'value': 'CANCELLED', 'path': '/state'}] + return self._update(self._path(action_plan_id), patch) diff --git a/watcherclient/v1/action_plan_shell.py b/watcherclient/v1/action_plan_shell.py index 435f76e..5f5af88 100644 --- a/watcherclient/v1/action_plan_shell.py +++ b/watcherclient/v1/action_plan_shell.py @@ -301,3 +301,29 @@ class DeleteActionPlan(command.Command): raise exceptions.ValidationError() client.action_plan.delete(action_plan) + + +class CancelActionPlan(command.ShowOne): + """Cancel action plan command.""" + + def get_parser(self, prog_name): + parser = super(CancelActionPlan, self).get_parser(prog_name) + parser.add_argument( + 'action_plan', + metavar='', + help=_("UUID of the action_plan.")) + + return parser + + def take_action(self, parsed_args): + client = getattr(self.app.client_manager, "infra-optim") + + if not uuidutils.is_uuid_like(parsed_args.action_plan): + raise exceptions.ValidationError() + + action_plan = client.action_plan.cancel(parsed_args.action_plan) + + columns = res_fields.ACTION_PLAN_FIELDS + column_headers = res_fields.ACTION_PLAN_FIELD_LABELS + + return column_headers, utils.get_item_properties(action_plan, columns)