+
+ async def handle_alarm(self, alarm_uuid: str, status: str):
+ await self.update_alarm_status(alarm_uuid, status)
+ await self.evaluate_policy(alarm_uuid)
+
+ async def update_alarm_status(self, alarm_uuid: str, status: str):
+ database.db.connect()
+ try:
+ with database.db.atomic():
+ alarm = ScalingAlarmRepository.get(ScalingAlarm.alarm_uuid == alarm_uuid)
+ alarm.last_status = status
+ alarm.save()
+ except ScalingAlarm.DoesNotExist:
+ log.debug("There is no autoscaling action configured for alarm %s.", alarm_uuid)
+ finally:
+ database.db.close()
+
+ async def evaluate_policy(self, alarm_uuid):
+ database.db.connect()
+ try:
+ with database.db.atomic():
+ alarm = ScalingAlarmRepository.get(ScalingAlarm.alarm_uuid == alarm_uuid)
+ vnf_member_index = alarm.vnf_member_index
+ action = alarm.action
+ scaling_policy = alarm.scaling_criteria.scaling_policy
+ if not scaling_policy.enabled:
+ return
+ if action == 'scale_in':
+ operation = scaling_policy.scale_in_operation
+ elif action == 'scale_out':
+ operation = scaling_policy.scale_out_operation
+ else:
+ raise Exception('Unknown alarm action {}'.format(alarm.action))
+ alarms = ScalingAlarmRepository.list(ScalingAlarm.scaling_criteria == alarm.scaling_criteria,
+ ScalingAlarm.action == alarm.action,
+ ScalingAlarm.vnf_member_index == vnf_member_index,
+ ScalingAlarm.vdu_name == alarm.vdu_name)
+ statuses = []
+ for alarm in alarms:
+ statuses.append(alarm.last_status)
+ if (operation == 'AND' and set(statuses) == {'alarm'}) or (operation == 'OR' and 'alarm' in statuses):
+ delta = datetime.datetime.now() - scaling_policy.last_scale
+ if delta.total_seconds() > scaling_policy.cooldown_time:
+ log.info("Sending %s action message for ns: %s",
+ alarm.action,
+ scaling_policy.scaling_group.nsr_id)
+ await self.lcm_client.scale(scaling_policy.scaling_group.nsr_id,
+ scaling_policy.scaling_group.name,
+ vnf_member_index,
+ action)
+ scaling_policy.last_scale = datetime.datetime.now()
+ scaling_policy.save()
+
+ except ScalingAlarm.DoesNotExist:
+ log.debug("There is no autoscaling action configured for alarm %s.", alarm_uuid)
+ finally:
+ database.db.close()