diff --git a/setup.cfg b/setup.cfg index c7aecdbf2..f09cb365f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -69,6 +69,7 @@ openstack.tripleoclient.v1 = overcloud_node_delete = tripleoclient.v1.overcloud_node:DeleteNode overcloud_node_introspect = tripleoclient.v1.overcloud_node:IntrospectNode overcloud_node_provide = tripleoclient.v1.overcloud_node:ProvideNode + overcloud_plan_delete = tripleoclient.v1.overcloud_plan:DeletePlan overcloud_plan_list = tripleoclient.v1.overcloud_plan:ListPlans overcloud_profiles_match = tripleoclient.v1.overcloud_profiles:MatchProfiles overcloud_profiles_list = tripleoclient.v1.overcloud_profiles:ListProfiles diff --git a/tripleoclient/tests/v1/test_overcloud_plan.py b/tripleoclient/tests/v1/test_overcloud_plan.py index 1c82e8781..7948e1dab 100644 --- a/tripleoclient/tests/v1/test_overcloud_plan.py +++ b/tripleoclient/tests/v1/test_overcloud_plan.py @@ -46,3 +46,41 @@ class TestOvercloudPlanList(utils.TestCommand): self.assertEqual(1, len(result[0])) self.assertEqual([('test-plan-1',), ('test-plan-2',)], result[1]) + + +class TestOvercloudDeletePlan(utils.TestCommand): + + def setUp(self): + super(TestOvercloudDeletePlan, self).setUp() + + self.cmd = overcloud_plan.DeletePlan(self.app, None) + self.app.client_manager.workflow_engine = mock.Mock() + self.workflow = self.app.client_manager.workflow_engine + + def test_delete_plan(self): + parsed_args = self.check_parser(self.cmd, ['test-plan'], + [('plans', ['test-plan'])]) + + self.workflow.action_executions.create.return_value = ( + mock.Mock(output='{"result": null}')) + + self.cmd.take_action(parsed_args) + + self.workflow.action_executions.create.assert_called_once_with( + 'tripleo.delete_plan', input={'container': 'test-plan'}) + + def test_delete_multiple_plans(self): + argslist = ['test-plan1', 'test-plan2'] + verifylist = [('plans', ['test-plan1', 'test-plan2'])] + parsed_args = self.check_parser(self.cmd, argslist, verifylist) + + self.workflow.action_executions.create.return_value = ( + mock.Mock(output='{"result": null}')) + + self.cmd.take_action(parsed_args) + + self.workflow.action_executions.create.assert_has_calls( + [mock.call('tripleo.delete_plan', + input={'container': 'test-plan1'}), + mock.call('tripleo.delete_plan', + input={'container': 'test-plan2'})]) diff --git a/tripleoclient/v1/overcloud_plan.py b/tripleoclient/v1/overcloud_plan.py index 533df23db..84b255049 100644 --- a/tripleoclient/v1/overcloud_plan.py +++ b/tripleoclient/v1/overcloud_plan.py @@ -13,11 +13,13 @@ import json import logging +from cliff import command from cliff import lister +from openstackclient.i18n import _ class ListPlans(lister.Lister): - """List overcloud deployment plans""" + """List overcloud deployment plans.""" log = logging.getLogger(__name__ + ".ListPlans") @@ -39,3 +41,36 @@ class ListPlans(lister.Lister): result.append((r,)) return (("Plan Name",), result) + + +class DeletePlan(command.Command): + """Delete an overcloud deployment plan. + + The plan will not be deleted if a stack exists with the same name. + """ + + log = logging.getLogger(__name__ + ".DeletePlan") + + def get_parser(self, prog_name): + parser = super(DeletePlan, self).get_parser(prog_name) + parser.add_argument('plans', metavar='', nargs="+", + help=_('Name of the plan(s) to delete')) + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)" % parsed_args) + + workflow_client = self.app.client_manager.workflow_engine + + for plan in parsed_args.plans: + print("Deleting plan %s..." % plan) + execution = workflow_client.action_executions.create( + 'tripleo.delete_plan', input={'container': plan}) + + try: + json_results = json.loads(execution.output)['result'] + if json_results is not None: + print(json_results) + except Exception: + self.log.exception( + "Error parsing action result %s", execution.output)