e24e4c96211c9b6355e39356fba23be5697a70b0
[pti/o2.git] / o2ims / service / auditor / alarm_handler.py
1 # Copyright (C) 2022 Wind River Systems, Inc.
2 #
3 #  Licensed under the Apache License, Version 2.0 (the "License");
4 #  you may not use this file except in compliance with the License.
5 #  You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #  Unless required by applicable law or agreed to in writing, software
10 #  distributed under the License is distributed on an "AS IS" BASIS,
11 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 #  See the License for the specific language governing permissions and
13 #  limitations under the License.
14
15 # pylint: disable=unused-argument
16 from __future__ import annotations
17 import json
18
19 # from o2common.config import config
20 # from o2common.service.messagebus import MessageBus
21 from o2common.service.unit_of_work import AbstractUnitOfWork
22 from o2ims.domain import events, commands, alarm_obj
23 from o2ims.domain.alarm_obj import AlarmEventRecord, FaultGenericModel,\
24     AlarmNotificationEventEnum
25
26 from o2common.helper import o2logging
27 logger = o2logging.get_logger(__name__)
28
29
30 def update_alarm(
31     cmd: commands.UpdateAlarm,
32     uow: AbstractUnitOfWork
33 ):
34     fmobj = cmd.data
35     logger.info("add alarm event record:" + fmobj.name
36                 + " update_at: " + str(fmobj.updatetime)
37                 + " id: " + str(fmobj.id)
38                 + " hash: " + str(fmobj.hash))
39     with uow:
40         resourcepool = uow.resource_pools.get(cmd.parentid)
41
42         alarm_event_record = uow.alarm_event_records.get(fmobj.id)
43         if not alarm_event_record:
44             logger.info("add alarm event record:" + fmobj.name
45                         + " update_at: " + str(fmobj.updatetime)
46                         + " id: " + str(fmobj.id)
47                         + " hash: " + str(fmobj.hash))
48             localmodel = create_by(fmobj)
49             content = json.loads(fmobj.content)
50             entity_type_id = content['entity_type_id']
51             entity_instance_id = content['entity_instance_id']
52             logger.info('alarm entity instance id: ' + entity_instance_id)
53             if 'host' == entity_type_id:
54                 # TODO: handle different resource type
55                 hostname = entity_instance_id.split('.')[0].split('=')[1]
56                 logger.debug('hostname: ' + hostname)
57
58                 restype = uow.resource_types.get_by_name('pserver')
59                 localmodel.resourceTypeId = restype.resourceTypeId
60                 hosts = uow.resources.list(resourcepool.resourcePoolId, **{
61                     'resourceTypeId': restype.resourceTypeId
62                 })
63                 for host in hosts:
64                     extensions = json.loads(host.extensions)
65                     if extensions['hostname'] == hostname:
66                         localmodel.resourceId = host.resourceId
67                 uow.alarm_event_records.add(localmodel)
68                 logger.info("Add the alarm event record: " + fmobj.id
69                             + ", name: " + fmobj.name)
70             # localmodel.resourceTypeId = check_restype_id(uow, fmobj)
71             # logger.debug("resource type ID: " + localmodel.resourceTypeId)
72             # localmodel.resourceId = check_res_id(uow, fmobj)
73             # logger.debug("resource ID: " + localmodel.resourceId)
74             # uow.alarm_event_records.add(localmodel)
75             else:
76                 restype = uow.resource_types.get_by_name('undefined_aggregate')
77                 localmodel.resourceTypeId = restype.resourceTypeId
78
79                 undefined_res = uow.resources.list(
80                     resourcepool.resourcePoolId, **{
81                         'resourceTypeId': restype.resourceTypeId
82                     })
83                 localmodel.resourceId = undefined_res[0].resourceId
84                 uow.alarm_event_records.add(localmodel)
85                 logger.info("Add the alarm event record: " + fmobj.id
86                             + ", name: " + fmobj.name)
87
88         else:
89             localmodel = alarm_event_record
90             if is_outdated(localmodel, fmobj):
91                 logger.info("update alarm event record:" + fmobj.name
92                             + " update_at: " + str(fmobj.updatetime)
93                             + " id: " + str(fmobj.id)
94                             + " hash: " + str(fmobj.hash))
95                 update_by(localmodel, fmobj)
96                 uow.alarm_event_records.update(localmodel)
97
98             logger.info("Update the alarm event record: " + fmobj.id
99                         + ", name: " + fmobj.name)
100         uow.commit()
101
102
103 def is_outdated(alarm_event_record: AlarmEventRecord,
104                 fmobj: FaultGenericModel):
105     return True if alarm_event_record.hash != fmobj.hash else False
106
107
108 def create_by(fmobj: FaultGenericModel) -> AlarmEventRecord:
109     content = json.loads(fmobj.content)
110     # globalcloudId = fmobj.id  # to be updated
111     alarm_definition_id = fmobj.alarm_def_id
112     alarm_event_record = AlarmEventRecord(
113         fmobj.id, "", "",
114         alarm_definition_id, "",
115         fmobj.timestamp)
116
117     def severity_switch(val):
118         if val == 'critical':
119             return alarm_obj.PerceivedSeverityEnum.CRITICAL
120         elif val == 'major':
121             return alarm_obj.PerceivedSeverityEnum.MAJOR
122         elif val == 'minor':
123             return alarm_obj.PerceivedSeverityEnum.MINOR
124         else:
125             return alarm_obj.PerceivedSeverityEnum.WARNING
126     alarm_event_record.perceivedSeverity = severity_switch(content['severity'])
127     alarm_event_record.probableCauseId = fmobj.probable_cause_id
128     alarm_event_record.hash = fmobj.hash
129     # logger.info('severity: ' + content['severity'])
130     # logger.info('perceived severity: '
131     # + alarm_event_record.perceivedSeverity)
132     alarm_event_record.events.append(events.AlarmEventChanged(
133         id=fmobj.id,
134         notificationEventType=AlarmNotificationEventEnum.NEW,
135         updatetime=fmobj.updatetime
136     ))
137
138     return alarm_event_record
139
140
141 def update_by(target: AlarmEventRecord, fmobj: FaultGenericModel
142               ) -> None:
143     # content = json.loads(fmobj.content)
144     target.hash = fmobj.hash
145     if fmobj.status == 'clear':
146         target.perceivedSeverity = alarm_obj.PerceivedSeverityEnum.CLEARED
147     target.events.append(events.AlarmEventChanged(
148         id=fmobj.id,
149         notificationEventType=AlarmNotificationEventEnum.CLEAR,
150         updatetime=fmobj.updatetime
151     ))
152
153
154 def check_restype_id(uow: AbstractUnitOfWork, fmobj: FaultGenericModel) -> str:
155     content = json.loads(fmobj.content)
156     entity_type_id = content['entity_type_id']
157     # Entity_Instance_ID: <hostname>.lvmthinpool=<VG name>/<Pool name>
158     # Entity_Instance_ID: ["image=<image-uuid>, instance=<instance-uuid>",
159     # Entity_Instance_ID: [host=<hostname>.command=provision,
160     # Entity_Instance_ID: [host=<hostname>.event=discovered,
161     # Entity_Instance_ID: [host=<hostname>.state=disabled,
162     # Entity_Instance_ID: [subcloud=<subcloud>.resource=<compute | network
163     # | platform | volumev2>]
164     # Entity_Instance_ID: cinder_io_monitor
165     # Entity_Instance_ID: cluster=<dist-fs-uuid>
166     # Entity_Instance_ID: cluster=<dist-fs-uuid>.peergroup=<group-x>
167     # Entity_Instance_ID: fs_name=<image-conversion>
168     # Entity_Instance_ID: host=<host_name>
169     # Entity_Instance_ID: host=<host_name>.network=<network>
170     # Entity_Instance_ID: host=<host_name>.services=compute
171     # Entity_Instance_ID: host=<hostname>
172     # Entity_Instance_ID: host=<hostname>,agent=<agent-uuid>,
173     # bgp-peer=<bgp-peer>
174     # Entity_Instance_ID: host=<hostname>.agent=<agent-uuid>
175     # Entity_Instance_ID: host=<hostname>.interface=<if-name>
176     # Entity_Instance_ID: host=<hostname>.interface=<if-uuid>
177     # Entity_Instance_ID: host=<hostname>.ml2driver=<driver>
178     # Entity_Instance_ID: host=<hostname>.network=<mgmt | oam | cluster-host>
179     # Entity_Instance_ID: host=<hostname>.openflow-controller=<uri>
180     # Entity_Instance_ID: host=<hostname>.openflow-network=<name>
181     # Entity_Instance_ID: host=<hostname>.port=<port-name>
182     # Entity_Instance_ID: host=<hostname>.port=<port-uuid>
183     # Entity_Instance_ID: host=<hostname>.process=<processname>
184     # Entity_Instance_ID: host=<hostname>.processor=<processor>
185     # Entity_Instance_ID: host=<hostname>.sdn-controller=<uuid>
186     # Entity_Instance_ID: host=<hostname>.sensor=<sensorname>
187     # Entity_Instance_ID: host=<hostname>.service=<service>
188     # Entity_Instance_ID: host=<hostname>.service=networking.providernet=
189     # <pnet-uuid>
190     # Entity_Instance_ID: host=controller
191     # Entity_Instance_ID: itenant=<tenant-uuid>.instance=<instance-uuid>
192     # Entity_Instance_ID: k8s_application=<appname>
193     # Entity_Instance_ID: kubernetes=PV-migration-failed
194     # Entity_Instance_ID: orchestration=fw-update
195     # Entity_Instance_ID: orchestration=kube-rootca-update
196     # Entity_Instance_ID: orchestration=kube-upgrade
197     # Entity_Instance_ID: orchestration=sw-patch
198     # Entity_Instance_ID: orchestration=sw-upgrade
199     # Entity_Instance_ID: resource=<crd-resource>,name=<resource-name>
200     # Entity_Instance_ID: server-group<server-group-uuid>
201     # Entity_Instance_ID: service=networking.providernet=<pnet-uuid>
202     # Entity_Instance_ID: service_domain=<domain>.service_group=<group>
203     # Entity_Instance_ID: service_domain=<domain>.service_group=<group>.
204     # host=<host_name>
205     # Entity_Instance_ID: service_domain=<domain_name>.service_group=
206     # <group_name>
207     # Entity_Instance_ID: service_domain=<domain_name>.service_group=
208     # <group_name>.host=<hostname>
209     # Entity_Instance_ID: storage_backend=<storage-backend-name>
210     # Entity_Instance_ID: subcloud=<subcloud>
211     # Entity_Instance_ID: subsystem=vim
212     # Entity_Instance_ID: tenant=<tenant-uuid>.instance=<instance-uuid>
213     if 'host' == entity_type_id:
214         with uow:
215             restype = uow.resource_types.get_by_name('pserver')
216             return restype.resourceTypeId
217     else:
218         return ""
219
220
221 def check_res_id(uow: AbstractUnitOfWork, fmobj: FaultGenericModel) -> str:
222     content = json.loads(fmobj.content)
223     entity_type_id = content['entity_type_id']
224     entity_instance_id = content['entity_instance_id']
225     if 'host' == entity_type_id:
226         logger.info('host: ' + entity_instance_id)
227         hostname = entity_instance_id.split('.')[0].split('=')[1]
228         with uow:
229             respools = uow.resource_pools.list()
230             respoolids = [respool.resourcePoolId for respool in respools
231                           if respool.oCloudId == respool.resourcePoolId]
232             restype = uow.resource_types.get_by_name('pserver')
233             hosts = uow.resources.list(respoolids[0], **{
234                 'resourceTypeId': restype.resourceTypeId
235             })
236             for host in hosts:
237                 if host.name == hostname:
238                     return host.resourceId
239     else:
240         return ""