From cdc847d352a9e66523ac3237977cb01b2652e573 Mon Sep 17 00:00:00 2001
From: licanwei
Date: Sun, 17 Dec 2017 21:41:18 -0800
Subject: [PATCH] check actionplan state when deleting actionplan
If actionplan is 'ONGOING' or 'PENDING',
don't delete it.
Change-Id: I8bfa31a70bba0a7adb1bfd09fc22e6a66b9ebf3a
Closes-Bug: #1738360
---
watcher/api/controllers/v1/action_plan.py | 9 +++++++++
watcher/tests/api/v1/test_actions.py | 2 ++
watcher/tests/api/v1/test_actions_plans.py | 9 +++++++++
3 files changed, 20 insertions(+)
diff --git a/watcher/api/controllers/v1/action_plan.py b/watcher/api/controllers/v1/action_plan.py
index 79dd5d81a..46e79f443 100644
--- a/watcher/api/controllers/v1/action_plan.py
+++ b/watcher/api/controllers/v1/action_plan.py
@@ -460,6 +460,15 @@ class ActionPlansController(rest.RestController):
policy.enforce(context, 'action_plan:delete', action_plan,
action='action_plan:delete')
+ allowed_states = (ap_objects.State.SUCCEEDED,
+ ap_objects.State.RECOMMENDED,
+ ap_objects.State.FAILED,
+ ap_objects.State.SUPERSEDED,
+ ap_objects.State.CANCELLED)
+ if action_plan.state not in allowed_states:
+ raise exception.DeleteError(
+ state=action_plan.state)
+
action_plan.soft_delete()
@wsme.validate(types.uuid, [ActionPlanPatchType])
diff --git a/watcher/tests/api/v1/test_actions.py b/watcher/tests/api/v1/test_actions.py
index 282bdd70d..b2246f6b4 100644
--- a/watcher/tests/api/v1/test_actions.py
+++ b/watcher/tests/api/v1/test_actions.py
@@ -296,6 +296,8 @@ class TestListAction(api_base.FunctionalTest):
uuid=utils.generate_uuid())
ap2_action_list.append(action)
+ action_plan1.state = objects.action_plan.State.CANCELLED
+ action_plan1.save()
self.delete('/action_plans/%s' % action_plan1.uuid)
response = self.get_json('/actions')
diff --git a/watcher/tests/api/v1/test_actions_plans.py b/watcher/tests/api/v1/test_actions_plans.py
index 950ece523..a001a99d9 100644
--- a/watcher/tests/api/v1/test_actions_plans.py
+++ b/watcher/tests/api/v1/test_actions_plans.py
@@ -309,6 +309,13 @@ class TestDelete(api_base.FunctionalTest):
action_plan.destroy()
def test_delete_action_plan_without_action(self):
+ response = self.delete('/action_plans/%s' % self.action_plan.uuid,
+ expect_errors=True)
+ self.assertEqual(400, response.status_int)
+ self.assertEqual('application/json', response.content_type)
+ self.assertTrue(response.json['error_message'])
+ self.action_plan.state = objects.action_plan.State.SUCCEEDED
+ self.action_plan.save()
self.delete('/action_plans/%s' % self.action_plan.uuid)
response = self.get_json('/action_plans/%s' % self.action_plan.uuid,
expect_errors=True)
@@ -320,6 +327,8 @@ class TestDelete(api_base.FunctionalTest):
action = obj_utils.create_test_action(
self.context, id=1)
+ self.action_plan.state = objects.action_plan.State.SUCCEEDED
+ self.action_plan.save()
self.delete('/action_plans/%s' % self.action_plan.uuid)
ap_response = self.get_json('/action_plans/%s' % self.action_plan.uuid,
expect_errors=True)