From 8cb0b2ec2a779d021c1a68ad9acb1f8d2583d8b7 Mon Sep 17 00:00:00 2001 From: YiFeng Date: Wed, 15 Nov 2023 15:53:48 +0900 Subject: [PATCH] Fixed alarmAcknowledgedTime not being updated This patch modifies that when calling the update alarm API, if ackState is updated to ACKNOWLEDGED, the value of alarmAcknowledgedTime will be additionally updated. If ackState is updated to UNACKNOWLEDGED, the value of alarmAcknowledgedTime is deleted. Closes-Bug: #2043062 Change-Id: I2b8a66f9d38c2104f8caf4aebc59573c2c05eef0 --- doc/source/cli/cli-etsi-vnffm.rst | 2 +- doc/source/user/etsi_cnf_auto_healing_fm.rst | 2 +- tacker/sol_refactored/controller/vnffm_v1.py | 7 +++ .../functional/sol_kubernetes_v2/paramgen.py | 8 +++- .../sol_kubernetes_v2/test_vnffm_basic.py | 43 ++++++++++++------- .../controller/test_vnffm_v1.py | 5 +++ 6 files changed, 49 insertions(+), 18 deletions(-) diff --git a/doc/source/cli/cli-etsi-vnffm.rst b/doc/source/cli/cli-etsi-vnffm.rst index 6af5d30ab..f45f53fd4 100644 --- a/doc/source/cli/cli-etsi-vnffm.rst +++ b/doc/source/cli/cli-etsi-vnffm.rst @@ -109,7 +109,7 @@ Result: | Field | Value | +----------------------------+------------------------------------------------------------------------------------------------------+ | Ack State | ACKNOWLEDGED | - | Alarm Acknowledged Time | | + | Alarm Acknowledged Time | 2022-08-30T12:23:52Z | | Alarm Changed Time | 2022-08-29T05:49:02Z | | Alarm Cleared Time | 2022-06-22T23:47:36Z | | Alarm Raised Time | 2022-08-29T05:48:56Z | diff --git a/doc/source/user/etsi_cnf_auto_healing_fm.rst b/doc/source/user/etsi_cnf_auto_healing_fm.rst index 759d02181..4c3bcfc9f 100644 --- a/doc/source/user/etsi_cnf_auto_healing_fm.rst +++ b/doc/source/user/etsi_cnf_auto_healing_fm.rst @@ -564,7 +564,7 @@ Here is an example of getting the specified alarm: | Field | Value | +----------------------------+------------------------------------------------------------------------------------------------------+ | Ack State | ACKNOWLEDGED | - | Alarm Acknowledged Time | | + | Alarm Acknowledged Time | 2022-08-30T12:23:52Z | | Alarm Changed Time | 2022-08-31T07:47:05Z | | Alarm Cleared Time | 2022-06-22T23:47:36Z | | Alarm Raised Time | 2022-08-31T07:46:59Z | diff --git a/tacker/sol_refactored/controller/vnffm_v1.py b/tacker/sol_refactored/controller/vnffm_v1.py index fdf6b66ba..62aa8599f 100644 --- a/tacker/sol_refactored/controller/vnffm_v1.py +++ b/tacker/sol_refactored/controller/vnffm_v1.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +import datetime + from oslo_log import log as logging from oslo_utils import uuidutils @@ -97,6 +99,11 @@ class VnfFmControllerV1(sol_wsgi.SolAPIController): raise sol_ex.AckStateInvalid() alarm.ackState = ack_state + if ack_state == "ACKNOWLEDGED": + alarm.alarmAcknowledgedTime = datetime.datetime.now( + datetime.timezone.utc) + else: + alarm.alarmAcknowledgedTime = None with context.session.begin(subtransactions=True): alarm.update(context) diff --git a/tacker/tests/functional/sol_kubernetes_v2/paramgen.py b/tacker/tests/functional/sol_kubernetes_v2/paramgen.py index 42ecdac9a..c5a5bc48a 100644 --- a/tacker/tests/functional/sol_kubernetes_v2/paramgen.py +++ b/tacker/tests/functional/sol_kubernetes_v2/paramgen.py @@ -582,12 +582,18 @@ def alert_event_resolved(inst_id, pod_name): } -def update_alarm(): +def update_alarm_acknowledged(): return { "ackState": "ACKNOWLEDGED" } +def update_alarm_unacknowledged(): + return { + "ackState": "UNACKNOWLEDGED" + } + + def terminate_vnf_min(): # Omit except for required attributes # NOTE: Only the following cardinality attributes are set. diff --git a/tacker/tests/functional/sol_kubernetes_v2/test_vnffm_basic.py b/tacker/tests/functional/sol_kubernetes_v2/test_vnffm_basic.py index 9272aaa19..e3a43fd2f 100644 --- a/tacker/tests/functional/sol_kubernetes_v2/test_vnffm_basic.py +++ b/tacker/tests/functional/sol_kubernetes_v2/test_vnffm_basic.py @@ -67,13 +67,15 @@ class VnfFmTest(base_v2.BaseVnfLcmKubernetesV2Test): - 6. Alert-Event (firing) - 7. FM-List-Alarm - 8. FM-Show-Alarm - - 9. FM-Update-Alarm + - 9. FM-Update-Alarm (acknowledged) - 10. FM-Show-Alarm - - 11. Alert-Event (resolved) + - 11. FM-Update-Alarm (unacknowledged) - 12. FM-Show-Alarm - - 13. FM-Delete-Subscription: Delete subscription - - 14. Terminate a VNF instance - - 15. Delete a VNF instance + - 13. Alert-Event (resolved) + - 14. FM-Show-Alarm + - 15. FM-Delete-Subscription: Delete subscription + - 16. Terminate a VNF instance + - 17. Delete a VNF instance """ # 1. LCM-Create: Create a new VNF instance resource @@ -172,11 +174,11 @@ class VnfFmTest(base_v2.BaseVnfLcmKubernetesV2Test): self.check_resp_headers_in_get(resp) self.check_resp_body(body, alarm_expected_attrs) - # 9. FM-Update-Alarm + # 9. FM-Update-Alarm (acknowledged) expected_attrs = [ 'ackState' ] - update_req = paramgen.update_alarm() + update_req = paramgen.update_alarm_acknowledged() resp, body = self.update_fm_alarm(alarm_id, update_req) self.assertEqual(200, resp.status_code) self.check_resp_headers_in_delete(resp) @@ -188,6 +190,7 @@ class VnfFmTest(base_v2.BaseVnfLcmKubernetesV2Test): 'managedObjectId', 'alarmRaisedTime', 'ackState', + 'alarmAcknowledgedTime', 'perceivedSeverity', 'eventTime', 'eventType', @@ -200,25 +203,35 @@ class VnfFmTest(base_v2.BaseVnfLcmKubernetesV2Test): self.check_resp_headers_in_get(resp) self.check_resp_body(body, expected_attrs) - # 11. Alert-Event (resolved) + # 11. FM-Update-Alarm (unacknowledged) + update_req = paramgen.update_alarm_unacknowledged() + resp, _ = self.update_fm_alarm(alarm_id, update_req) + self.assertEqual(200, resp.status_code) + + # 12. FM-Show-Alarm + resp, body = self.show_fm_alarm(alarm_id) + self.assertEqual(200, resp.status_code) + self.assertIsNone(body.get('alarmAcknowledgedTime')) + + # 13. Alert-Event (resolved) alert = paramgen.alert_event_resolved(inst_id, pod_name) resp, body = self.create_fm_alarm(alert) self.assertEqual(204, resp.status_code) time.sleep(WAIT_NOTIFICATION_TIME) self._check_notification(callback_url, 'AlarmClearedNotification') - # 12. FM-Show-Alarm + # 14. FM-Show-Alarm resp, body = self.show_fm_alarm(alarm_id) self.assertEqual(200, resp.status_code) self.check_resp_headers_in_get(resp) self.check_resp_body(body, alarm_expected_attrs) - # 13. FM-Delete-Subscription: Delete subscription + # 15. FM-Delete-Subscription: Delete subscription resp, body = self.delete_fm_subscription(sub_id) self.assertEqual(204, resp.status_code) self.check_resp_headers_in_delete(resp) - # 14. LCM-Terminate: Terminate VNF + # 16. LCM-Terminate: Terminate VNF terminate_req = paramgen.terminate_vnf_min() resp, body = self.terminate_vnf_instance(inst_id, terminate_req) self.assertEqual(202, resp.status_code) @@ -232,7 +245,7 @@ class VnfFmTest(base_v2.BaseVnfLcmKubernetesV2Test): self.assertEqual(fields.VnfInstanceState.NOT_INSTANTIATED, body['instantiationState']) - # 15. LCM-Delete: Delete a VNF instance + # 17. LCM-Delete: Delete a VNF instance resp, body = self.exec_lcm_operation(self.delete_vnf_instance, inst_id) self.assertEqual(204, resp.status_code) @@ -261,7 +274,7 @@ class VnfFmTest(base_v2.BaseVnfLcmKubernetesV2Test): - 6. Alert-Event (firing) - 7. FM-List-Alarm - 8. FM-Show-Alarm - - 9. FM-Update-Alarm + - 9. FM-Update-Alarm (acknowledged) - 10. FM-Show-Alarm - 11. Alert-Event (resolved) - 12. FM-Show-Alarm @@ -367,11 +380,11 @@ class VnfFmTest(base_v2.BaseVnfLcmKubernetesV2Test): self.check_resp_headers_in_get(resp) self.check_resp_body(body, alarm_expected_attrs) - # 9. FM-Update-Alarm + # 9. FM-Update-Alarm (acknowledged) expected_attrs = [ 'ackState' ] - update_req = paramgen.update_alarm() + update_req = paramgen.update_alarm_acknowledged() resp, body = self.update_fm_alarm(alarm_id, update_req) self.assertEqual(200, resp.status_code) self.check_resp_headers_in_delete(resp) diff --git a/tacker/tests/unit/sol_refactored/controller/test_vnffm_v1.py b/tacker/tests/unit/sol_refactored/controller/test_vnffm_v1.py index 57dfbffb9..deb28ba2e 100644 --- a/tacker/tests/unit/sol_refactored/controller/test_vnffm_v1.py +++ b/tacker/tests/unit/sol_refactored/controller/test_vnffm_v1.py @@ -106,6 +106,11 @@ class TestVnffmV1(base.BaseTestCase): self.assertEqual('1.3.0', result.headers['version']) self.assertEqual(body, result.body) + body = {"ackState": "UNACKNOWLEDGED"} + result = self.controller.update( + request=self.request, id=SAMPLE_ALARM_ID, body=body) + self.assertEqual(body, result.body) + @mock.patch.object(alarm_utils, 'get_alarm') def test_update_invalid_body(self, mock_alarm): mock_alarm.return_value = objects.AlarmV1.from_dict(