X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=osm_policy_module%2Fhealing%2Fservice.py;h=b36f8676de769ba895a4573bbcb29afe02fff2ad;hb=055c4ee00f83647e7e807aa3d44c3384d9d79aa2;hp=8434c663b8595ce1f7063849fa4c675b0354b6ae;hpb=7ef2b88a9c0c6ead16861411584d017e1fe216d7;p=osm%2FPOL.git diff --git a/osm_policy_module/healing/service.py b/osm_policy_module/healing/service.py index 8434c66..b36f867 100644 --- a/osm_policy_module/healing/service.py +++ b/osm_policy_module/healing/service.py @@ -22,9 +22,10 @@ # For those usages not covered by the Apache License, Version 2.0 please # contact: bdiaz@whitestack.com or glavado@whitestack.com ## -import asyncio import logging import datetime +import functools +import operator from osm_policy_module.common.common_db_client import CommonDbClient from osm_policy_module.common.lcm_client import LcmClient @@ -41,58 +42,67 @@ log = logging.getLogger(__name__) class HealingService: - def __init__(self, config: Config, loop=None): + def __init__(self, config: Config): """ - Initializing the HealingService + Initializing the HealingService """ log.info("HealingService Initialized") self.conf = config - if not loop: - loop = asyncio.get_event_loop() - self.loop = loop self.db_client = CommonDbClient(config) - self.mon_client = MonClient(config, loop=self.loop) - self.lcm_client = LcmClient(config, loop=self.loop) + self.mon_client = MonClient(config) + self.lcm_client = LcmClient(config) log.info("Constructor created for HealingService") - async def configure_healing_alarms(self, nsr_id: str): + async def configure_healing_alarms(self, nsr_id: str, vnf_member_index=None): """ - Configuring the Healing alarms - :param nsr_id: Network service record id + Configuring the Healing alarms + :param nsr_id: Network service record id + :param vnf_member_index: Member VNF Index of VNF """ log.info("Configuring Healing alarm for NS %s", nsr_id) alarms_created = [] database.db.connect() try: with database.db.atomic(): - vnfrs = self.db_client.get_vnfrs(nsr_id) + if vnf_member_index is None: + vnfrs = self.db_client.get_vnfrs(nsr_id) + else: + vnfrs = [] + vnfr = self.db_client.get_vnfr(nsr_id, vnf_member_index) + vnfrs.append(vnfr) for vnfr in vnfrs: - vnfd = self.db_client.get_vnfd(vnfr['vnfd-id']) + vnfd = self.db_client.get_vnfd(vnfr["vnfd-id"]) df = vnfd.get("df", [{}])[0] if "healing-aspect" not in df: log.info("No healing configuration present in vnfd") continue healing_aspects = df["healing-aspect"] for healing_aspect in healing_aspects: - for healing_policy in healing_aspect.get( - "healing-policy", () - ): - vdu_id = healing_policy['vdu-id'] + for healing_policy in healing_aspect.get("healing-policy", ()): + vdu_id = healing_policy["vdu-id"] for vdur in vnfr["vdur"]: if vdu_id == vdur["vdu-id-ref"]: try: HealingActionRepository.get( - HealingAction.alarm_id == healing_policy['event-name'], - HealingAction.vdur_name == vdur['name'], + HealingAction.alarm_id + == healing_policy["event-name"], + HealingAction.vdur_name == vdur["name"], HealingAction.nsr_id == nsr_id, - HealingAction.cooldown_time == healing_policy['cooldown-time'], - HealingAction.recovery_action == healing_policy['action-on-recovery'], - HealingAction.vnfinstance_id == vnfr['id'], - HealingAction.vdu_id == healing_policy['vdu-id'], - HealingAction.count_index == vdur['count-index'] + HealingAction.cooldown_time + == healing_policy["cooldown-time"], + HealingAction.recovery_action + == healing_policy["action-on-recovery"], + HealingAction.vnfinstance_id == vnfr["id"], + HealingAction.vdu_id + == healing_policy["vdu-id"], + HealingAction.count_index + == vdur["count-index"], + ) + log.debug( + "vdu %s already has an alarm configured with same id %s", + healing_policy["vdu-id"], + healing_policy["event-name"], ) - log.debug("vdu %s already has an alarm configured with same id %s", - healing_policy['vdu-id'], healing_policy['event-name']) continue except HealingAction.DoesNotExist: pass @@ -101,28 +111,26 @@ class HealingService: alarm_uuid = await self.mon_client.create_alarm( metric_name=metric_name, ns_id=nsr_id, - vdu_name=vdur['name'], - vnf_member_index=vnfr[ - 'member-vnf-index-ref' - ], + vdu_name=vdur["name"], + vnf_member_index=vnfr["member-vnf-index-ref"], threshold=1, operation="LT", - statistic="AVERAGE" + statistic="AVERAGE", ) alarm = HealingActionRepository.create( - alarm_id=healing_policy['event-name'], + alarm_id=healing_policy["event-name"], alarm_uuid=alarm_uuid, nsr_id=nsr_id, - vnf_member_index=vnfr[ - 'member-vnf-index-ref' + vnf_member_index=vnfr["member-vnf-index-ref"], + vdur_name=vdur["name"], + recovery_action=healing_policy[ + "action-on-recovery" ], - vdur_name=vdur['name'], - recovery_action=healing_policy['action-on-recovery'], - cooldown_time=healing_policy['cooldown-time'], - day1=healing_policy['day1'], - vdu_id=healing_policy['vdu-id'], - vnfinstance_id=vnfr['id'], - count_index=vdur['count-index'] + cooldown_time=healing_policy["cooldown-time"], + day1=healing_policy["day1"], + vdu_id=healing_policy["vdu-id"], + vnfinstance_id=vnfr["id"], + count_index=vdur["count-index"], ) alarms_created.append(alarm) @@ -131,12 +139,16 @@ class HealingService: if len(alarms_created) > 0: for alarm in alarms_created: try: - await self.mon_client.delete_alarm(alarm.nsr_id, - alarm.vnf_member_index, - alarm.vdu_name, - alarm.alarm_uuid) + await self.mon_client.delete_alarm( + alarm.nsr_id, + alarm.vnf_member_index, + alarm.vdu_name, + alarm.alarm_uuid, + ) except ValueError: - log.exception("Error deleting alarm in MON %s", alarm.alarm_uuid) + log.exception( + "Error deleting alarm in MON %s", alarm.alarm_uuid + ) raise e finally: database.db.close() @@ -151,26 +163,20 @@ class HealingService: ): try: self.db_client.get_vdur( - nsr_id, - alarm.vnf_member_index, - alarm.vdur_name + nsr_id, alarm.vnf_member_index, alarm.vdur_name ) except VdurNotFound: - log.info( - "Deleting orphaned alarm %s", - alarm.alarm_uuid - ) + log.info("Deleting orphaned alarm %s", alarm.alarm_uuid) try: await self.mon_client.delete_alarm( alarm.nsr_id, alarm.vnf_member_index, alarm.vdur_name, - alarm.alarm_uuid + alarm.alarm_uuid, ) except ValueError: log.exception( - "Error deleting alarm in MON %s", - alarm.alarm_uuid + "Error deleting alarm in MON %s", alarm.alarm_uuid ) alarm.delete_instance() @@ -180,29 +186,35 @@ class HealingService: finally: database.db.close() - async def delete_healing_alarms(self, nsr_id): + async def delete_healing_alarms(self, nsr_id, vnf_member_index=None): """ - Deleting the healing alarms - :param nsr_id: Network service record id + Deleting the healing alarms + :param nsr_id: Network service record id + :param vnf_member_index: Member VNF Index of VNF """ log.info("Deleting healing vnf alarms for network service %s", nsr_id) database.db.connect() try: with database.db.atomic(): - for alarm in HealingActionRepository.list( - HealingAction.nsr_id == nsr_id - ): + if vnf_member_index is None: + heal_conditions = HealingAction.nsr_id == nsr_id + else: + query_list = [ + HealingAction.nsr_id == nsr_id, + HealingAction.vnf_member_index == vnf_member_index, + ] + heal_conditions = functools.reduce(operator.and_, query_list) + for alarm in HealingActionRepository.list(heal_conditions): try: await self.mon_client.delete_alarm( alarm.nsr_id, alarm.vnf_member_index, alarm.vdur_name, - alarm.alarm_uuid + alarm.alarm_uuid, ) except ValueError: log.exception( - "Error deleting alarm in MON %s", - alarm.alarm_uuid + "Error deleting alarm in MON %s", alarm.alarm_uuid ) alarm.delete_instance() @@ -214,9 +226,9 @@ class HealingService: async def update_alarm_status(self, alarm_uuid: str, status: str): """ - For updating the alarm status - :param alarm_uuid: vdu uuid - :param status: Status of an alarm + For updating the alarm status + :param alarm_uuid: vdu uuid + :param status: Status of an alarm """ database.db.connect() try: @@ -227,66 +239,64 @@ class HealingService: alarm.last_status = status alarm.save() except HealingAction.DoesNotExist: - log.debug( - "There is no healing action configured for alarm %s.", alarm_uuid - ) + log.debug("There is no healing action configured for alarm %s.", alarm_uuid) finally: database.db.close() async def handle_alarm(self, alarm_uuid: str, status: str): """ - For Handling the healing alarms - :param alarm_uuid: vdu uuid - :param status: Status of an alarm + For Handling the healing alarms + :param alarm_uuid: vdu uuid + :param status: Status of an alarm """ await self.update_alarm_status(alarm_uuid, status) database.db.connect() try: if status == "alarm": - with database.db.atomic(): - alarm = HealingActionRepository.get( - HealingAction.alarm_uuid == alarm_uuid - ) - vnf_member_index = alarm.vnf_member_index - vdur_name = alarm.vdur_name - vdu_id = alarm.vdu_id - nsr_id = alarm.nsr_id - heal_type = alarm.recovery_action - cooldown_time = alarm.cooldown_time - count_index = alarm.count_index - last_heal = alarm.last_heal - day1 = alarm.day1 - vnfinstance_id = alarm.vnfinstance_id - alarms = HealingActionRepository.list( - HealingAction.vnf_member_index == vnf_member_index, - HealingAction.vdur_name == vdur_name - ) - statuses = [] + if self.conf.get("autoheal", "enabled") == "True": + with database.db.atomic(): + alarm = HealingActionRepository.get( + HealingAction.alarm_uuid == alarm_uuid + ) + vnf_member_index = alarm.vnf_member_index + vdur_name = alarm.vdur_name + vdu_id = alarm.vdu_id + nsr_id = alarm.nsr_id + heal_type = alarm.recovery_action + cooldown_time = alarm.cooldown_time + count_index = alarm.count_index + last_heal = alarm.last_heal + day1 = alarm.day1 + vnfinstance_id = alarm.vnfinstance_id + alarms = HealingActionRepository.list( + HealingAction.vnf_member_index == vnf_member_index, + HealingAction.vdur_name == vdur_name, + ) + statuses = [] - for alarm in alarms: - statuses.append(alarm.last_status) - if ((set(statuses) == {'alarm'}) or ('alarm' in statuses)): - delta = datetime.datetime.now() - last_heal - if delta.total_seconds() > cooldown_time: - await self.lcm_client.heal( - nsr_id, - vnfinstance_id, - vdur_name, - vdu_id, - vnf_member_index, - heal_type, - day1, - count_index - ) - last_heal = datetime.datetime.now() - log.info("datetime.datetime.now %s", datetime.datetime.now) - alarm.last_heal = last_heal - alarm.save() + for alarm in alarms: + statuses.append(alarm.last_status) + if (set(statuses) == {"alarm"}) or ("alarm" in statuses): + delta = datetime.datetime.now() - last_heal + if delta.total_seconds() > cooldown_time: + await self.lcm_client.heal( + nsr_id, + vnfinstance_id, + vdur_name, + vdu_id, + vnf_member_index, + heal_type, + day1, + count_index, + ) + last_heal = datetime.datetime.now() + log.info( + "datetime.datetime.now %s", datetime.datetime.now + ) + alarm.last_heal = last_heal + alarm.save() except HealingAction.DoesNotExist: - log.info( - "There is no healing action configured for alarm %s.", - alarm_uuid - ) + log.info("There is no healing action configured for alarm %s.", alarm_uuid) finally: database.db.close()