/
opt
/
cloudlinux
/
venv
/
lib
/
python3.11
/
site-packages
/
xray
/
continuous
/
Upload Filee
HOME
# -*- coding: utf-8 -*- # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2021 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENSE.TXT """ This module contains X Ray continuous tracing implementation """ import re from collections import defaultdict from typing import List from xray import gettext as _ from .common import ContinuousCommon from .mailer import Mailer from ..apiclient import get_client from ..console_utils.validations import regex from ..internal.exceptions import XRayError, XRayAPIError from ..internal.types import url_split from ..internal.utils import read_sys_id, prev_date, date_of_timestamp, \ get_formatted_date, get_html_formatted_links, get_text_formatted_links from ..manager import initialize_manager class ContinuousTracing(ContinuousCommon): """ Continuous tracing implementation """ def __init__(self): super().__init__() system_id = read_sys_id() client_object = get_client('auto_tasks') self.client = client_object(system_id=system_id) self.manager_instance = initialize_manager(system_id) self.mail_sender = Mailer() def __call__(self): self.clear_zombie_auto_tasks() self.start_tracing() self.generate_mail() def current_auto_tasks(self) -> list: """ Get auto tasks list """ try: tasks = self.client.get_tasks() except XRayAPIError as e: self.logger.error('Failed to get auto tasks', extra={'err': str(e)}) tasks = list() return tasks def clear_zombie_auto_tasks(self) -> None: """ Stop and complete running auto tasks """ auto_running_tasks = {t.task_id: t.status for t in self.current_auto_tasks() if t.auto_task and t.status != 'completed' and t.user != '*autotracing*'} for t_id in auto_running_tasks: try: if auto_running_tasks[t_id] == 'running': self.manager_instance.stop(t_id) self.manager_instance.complete(t_id) except XRayError as e: self.logger.error('%s', str(e)) @staticmethod def _url(domain: str) -> str: """ Construct URL for auto tracing: {domain}/* """ u = f"{domain.strip('/')}/*" if not re.match(regex, u): raise ValueError(_('invalid url'), u) return u def executed(self, domain: str) -> None: """ Increment execution_count of given domain """ self.tracing_conf[domain]['execution_count'] += 1 def start_tracing(self) -> List[dict]: """ Start auto tasks with status 'running' """ err_text = 'Start auto task failed' for continuous_task in self.get_continuous_tasks(): if continuous_task.status == 'running': try: self.manager_instance.start_auto( url=self._url(continuous_task.original_url)) except ValueError as e: self.logger.error(err_text, extra={'err': str(e)}) except XRayError as e: self.logger.error(err_text, extra={ 'err': str(e), 'continuous_task': continuous_task }) else: self.executed(continuous_task.domain) return self.dump_tracing_configuration() def retrieve_mail_addrs(self) -> dict: """ Map e-mail addresses to urls in existing continuous tracing configuration """ url_mail_map = dict() for t in self.get_continuous_tasks(): try: url_mail_map[self._url(t.original_url)] = t.email except ValueError: pass return url_mail_map def filter_tasks_by_date(self) -> list: """ Select previous date completed tasks """ def check_date(ts: int) -> bool: """ Verify if task timestamp corresponds to previous date """ try: return date_of_timestamp(ts) == prev_date() except TypeError: # in case of starttime == None return False return [t for t in self.current_auto_tasks() if t.status == 'completed' and check_date(t.starttime)] def generate_mail(self) -> None: """ Generate e-mails with links and send them to recipients """ self.logger.info('Generating e-mails started') email_conf = defaultdict(list) url_mail_mapping = self.retrieve_mail_addrs() # filter tasks by date yesterday_tasks = self.filter_tasks_by_date() # generate links along with mapping them to e-mail addresses for task in yesterday_tasks: mail = url_mail_mapping.get(task.url) if mail: email_conf[mail].append( {url_split(task.url)[0]: task.shared_link}) self.logger.info('Selected task %s for mailing to %s', task.task_id, mail) # send e-mails for k, v in email_conf.items(): self.mail_sender.send_mail(k, template='report', date=get_formatted_date(), links=get_text_formatted_links(v), html_links=get_html_formatted_links( v)) self.logger.info('E-mails sending finished')