From ba417b38bfd60bf6aec8c693682b2bdca1bde943 Mon Sep 17 00:00:00 2001 From: Alfredo Moralejo Date: Wed, 14 May 2025 16:18:56 +0200 Subject: [PATCH] Fix audit creation with no name and no goal or audit_template Currently, in that case it was failing because watcher tried to create a name based on a goal automatically and the goal is not defined. This patch is moving the check for goal specification in the audit creation call earlier, and if there is not goal defined, it returns an invalid call error. This patch is also modifying the existing error for this case to check the expected behavior. Closes-Bug: #2110947 Change-Id: I6f3d73b035e8081e86ce82c205498432f0e0fc33 (cherry picked from commit bf6a28bd1e2d4066f2a736eac065b398f7dd5e09) Signed-off-by: Alfredo Moralejo --- releasenotes/notes/bug-2110947.yaml | 10 ++++++++++ watcher/api/controllers/v1/audit.py | 10 +++++----- watcher/tests/api/v1/test_audits.py | 9 +++++---- 3 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 releasenotes/notes/bug-2110947.yaml diff --git a/releasenotes/notes/bug-2110947.yaml b/releasenotes/notes/bug-2110947.yaml new file mode 100644 index 000000000..45eb35b31 --- /dev/null +++ b/releasenotes/notes/bug-2110947.yaml @@ -0,0 +1,10 @@ +--- +fixes: + - | + Previously, when users attempted to create a new audit without providing + a name and a goal or an audit template, the API returned error 500 and an + incorrect error message was displayed. + + Now, Watcher displays a helpful message and returns HTTP error 400. + + For more info see: https://bugs.launchpad.net/watcher/+bug/2110947 diff --git a/watcher/api/controllers/v1/audit.py b/watcher/api/controllers/v1/audit.py index 70c825e27..a62b093bb 100644 --- a/watcher/api/controllers/v1/audit.py +++ b/watcher/api/controllers/v1/audit.py @@ -114,6 +114,11 @@ class AuditPostType(wtypes.Base): if self.audit_type not in audit_type_values: raise exception.AuditTypeNotFound(audit_type=self.audit_type) + if not self.audit_template_uuid and not self.goal: + message = _( + 'A valid goal or audit_template_id must be provided') + raise exception.Invalid(message) + if (self.audit_type == objects.audit.AuditType.ONESHOT.value and self.interval not in (wtypes.Unset, None)): raise exception.AuditIntervalNotAllowed(audit_type=self.audit_type) @@ -612,11 +617,6 @@ class AuditsController(rest.RestController): if self.from_audits: raise exception.OperationNotPermitted - if not audit._goal_uuid: - raise exception.Invalid( - message=_('A valid goal_id or audit_template_id ' - 'must be provided')) - strategy_uuid = audit.strategy_uuid no_schema = True if strategy_uuid is not None: diff --git a/watcher/tests/api/v1/test_audits.py b/watcher/tests/api/v1/test_audits.py index 37ab85dc3..9c2406d1d 100644 --- a/watcher/tests/api/v1/test_audits.py +++ b/watcher/tests/api/v1/test_audits.py @@ -1002,10 +1002,11 @@ class TestPost(api_base.FunctionalTest): expect_errors=True, headers={'OpenStack-API-Version': 'infra-optim 1.2'}) self.assertEqual('application/json', response.content_type) - # (amoralej) this should return HTTP error 400 with a proper message. - # I am adding this test to show the bug here, I will switch it to the - # expected error in the fixing patch. - self.assertEqual(HTTPStatus.INTERNAL_SERVER_ERROR, response.status_int) + self.assertEqual(HTTPStatus.BAD_REQUEST, response.status_int) + expected_msg = 'A valid goal or audit_template_id must be provided' + self.assertTrue(response.json['error_message']) + self.assertIn(expected_msg, response.json['error_message']) + assert not mock_trigger_audit.called class TestDelete(api_base.FunctionalTest):