diff --git a/st2api/st2api/controllers/v1/actions.py b/st2api/st2api/controllers/v1/actions.py index 1e8bf7c7b5..d1ee3d88b8 100644 --- a/st2api/st2api/controllers/v1/actions.py +++ b/st2api/st2api/controllers/v1/actions.py @@ -258,12 +258,22 @@ def delete(self, ref_or_id, requester_user): entry_point=entry_point, metadata_file=metadata_file, ) + + except PermissionError as e: + LOG.error("No permission to delete resource files from disk.") + action_db.id = None + Action.add_or_update(action_db) + abort(http_client.FORBIDDEN, six.text_type(e)) + return + except Exception as e: LOG.error( - "Exception encountered during deleting resource files from disk." + "Exception encountered during deleting resource files from disk. " "Exception was %s", e, ) + action_db.id = None + Action.add_or_update(action_db) abort(http_client.INTERNAL_SERVER_ERROR, six.text_type(e)) return diff --git a/st2api/tests/unit/controllers/v1/test_actions.py b/st2api/tests/unit/controllers/v1/test_actions.py index cd1d8b555c..af6ad3d91d 100644 --- a/st2api/tests/unit/controllers/v1/test_actions.py +++ b/st2api/tests/unit/controllers/v1/test_actions.py @@ -626,6 +626,58 @@ def test_delete(self): del_resp = self.__do_delete(self.__get_action_id(post_resp)) self.assertEqual(del_resp.status_int, 204) + @mock.patch.object( + action_validator, "validate_action", mock.MagicMock(return_value=True) + ) + def test_delete_permission_error_and_action_reregistered_to_database(self): + post_resp = self.__do_post(ACTION_1) + + with mock.patch( + "st2api.controllers.v1.actions.delete_action_files_from_pack" + ) as mock_remove_files: + msg = "No permission to delete action files from disk" + mock_remove_files.side_effect = PermissionError(msg) + del_resp = self.__do_delete( + self.__get_action_id(post_resp), expect_errors=True + ) + self.assertEqual(del_resp.status_int, 403) + self.assertEqual(del_resp.json["faultstring"], msg) + + # retrieving reregistered action + get_resp = self.__do_get_actions_by_url_parameter("name", ACTION_1["name"]) + expected_uid = post_resp.json["uid"] + actual_uid = get_resp.json[0]["uid"] + self.assertEqual(actual_uid, expected_uid) + action_id = get_resp.json[0]["id"] + del_resp = self.__do_delete(action_id) + self.assertEqual(del_resp.status_int, 204) + + @mock.patch.object( + action_validator, "validate_action", mock.MagicMock(return_value=True) + ) + def test_delete_exception_and_action_reregistered_to_database(self): + post_resp = self.__do_post(ACTION_1) + + with mock.patch( + "st2api.controllers.v1.actions.delete_action_files_from_pack" + ) as mock_remove_files: + msg = "Exception encountered during removing files from disk" + mock_remove_files.side_effect = Exception(msg) + del_resp = self.__do_delete( + self.__get_action_id(post_resp), expect_errors=True + ) + self.assertEqual(del_resp.status_int, 500) + self.assertEqual(del_resp.json["faultstring"], msg) + + # retrieving reregistered action + get_resp = self.__do_get_actions_by_url_parameter("name", ACTION_1["name"]) + expected_uid = post_resp.json["uid"] + actual_uid = get_resp.json[0]["uid"] + self.assertEqual(actual_uid, expected_uid) + action_id = get_resp.json[0]["id"] + del_resp = self.__do_delete(action_id) + self.assertEqual(del_resp.status_int, 204) + @mock.patch.object( action_validator, "validate_action", mock.MagicMock(return_value=True) )