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(