blob: 1e3173308828834b8d8a1d01cb27ece97705e4a6 [file] [log] [blame]
okozachenkocb316082021-05-07 21:30:39 +03001# Email notification package
2# This should be upgraded by integrating with mail server to send batch
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +01003import staffeln.conf
ricolin66a0a9d2022-11-07 07:49:31 +08004from oslo_log import log
5from staffeln.common import constants, email
okozachenko1203ef49f952022-05-16 22:27:28 +10006from staffeln.common import time as xtime
okozachenkocb316082021-05-07 21:30:39 +03007from staffeln.conductor import backup
okozachenko1203ef49f952022-05-16 22:27:28 +10008from staffeln.i18n import _
okozachenkocb316082021-05-07 21:30:39 +03009
10CONF = staffeln.conf.CONF
11LOG = log.getLogger(__name__)
12
13
14class BackupResult(object):
okozachenkocb316082021-05-07 21:30:39 +030015 def __init__(self):
okozachenko9eae01d2021-05-11 16:47:27 +030016 pass
17
18 def initialize(self):
okozachenkocb316082021-05-07 21:30:39 +030019 self.content = ""
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +010020 self.project_list = set()
okozachenkocb316082021-05-07 21:30:39 +030021
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +010022 def add_project(self, project_id, project_name):
23 self.project_list.add((project_id, project_name))
okozachenkocb316082021-05-07 21:30:39 +030024
25 def send_result_email(self):
ricolin051cc1e2023-01-15 08:52:09 +080026 subject = "Staffeln Backup result"
okozachenkocb316082021-05-07 21:30:39 +030027 try:
okozachenko1203fa747f22022-05-16 20:13:54 +100028 if len(CONF.notification.receiver) == 0:
ricolin051cc1e2023-01-15 08:52:09 +080029 LOG.info(
30 "Directly record report in log as no receiver "
31 "email provided. Report: %s" % self.content
32 )
okozachenko1203fa747f22022-05-16 20:13:54 +100033 return
ricolin051cc1e2023-01-15 08:52:09 +080034 smtp_profile = {
35 "src_email": CONF.notification.sender_email,
36 "src_name": "Staffeln",
37 "src_pwd": CONF.notification.sender_pwd,
38 "dest_email": CONF.notification.receiver,
39 "subject": subject,
40 "content": self.content,
41 "smtp_server_domain": CONF.notification.smtp_server_domain,
42 "smtp_server_port": CONF.notification.smtp_server_port,
43 }
44 email.send(smtp_profile)
okozachenkocb316082021-05-07 21:30:39 +030045 LOG.info(_("Backup result email sent"))
46 except Exception as e:
okozachenko1203fa747f22022-05-16 20:13:54 +100047 LOG.error(
48 _(
49 "Backup result email send failed. Please check email configuration. %s"
50 % (str(e))
51 )
52 )
okozachenkocb316082021-05-07 21:30:39 +030053
54 def publish(self):
55 # 1. get quota
56 self.content = "<h3>${TIME}</h3><br>"
57 self.content = self.content.replace("${TIME}", xtime.get_current_strtime())
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +010058 backup_mgt = backup.Backup()
59 project_success = {}
60 project_failed = {}
ricolin7f3ae942022-11-14 08:09:08 +080061 success_tasks = backup_mgt.get_queues(
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +010062 filters={"backup_status": constants.BACKUP_COMPLETED}
63 )
ricolin7f3ae942022-11-14 08:09:08 +080064 for task in success_tasks:
65 if task.project_id in project_success:
66 project_success[task.project_id].append(task)
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +010067 else:
ricolin7f3ae942022-11-14 08:09:08 +080068 project_success[task.project_id] = [task]
69 failed_tasks = backup_mgt.get_queues(
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +010070 filters={"backup_status": constants.BACKUP_FAILED}
71 )
ricolin7f3ae942022-11-14 08:09:08 +080072 for task in failed_tasks:
73 if task.project_id in project_failed:
74 project_failed[task.project_id].append(task)
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +010075 else:
ricolin7f3ae942022-11-14 08:09:08 +080076 project_failed[task.project_id] = [task]
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +010077
okozachenkocb316082021-05-07 21:30:39 +030078 html = ""
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +010079 for project_id, project_name in self.project_list:
80 quota = backup_mgt.get_backup_quota(project_id)
okozachenkocb316082021-05-07 21:30:39 +030081
okozachenko1203fa747f22022-05-16 20:13:54 +100082 html += (
ricolin051cc1e2023-01-15 08:52:09 +080083 "<h3>Project: ${PROJECT}</h3><h3>Quota Usage</h3>"
84 "<FONT COLOR=${QUOTA_COLLOR}><h4>Limit: ${QUOTA_LIMIT}, In Use: "
85 "${QUOTA_IN_USE}, Reserved: ${QUOTA_RESERVED}, Total "
86 "rate: ${QUOTA_USAGE}</h4></FONT>"
87 "<h3>Success List</h3>"
88 "<FONT COLOR=GREEN><h4>${SUCCESS_VOLUME_LIST}</h4></FONT><br>"
89 "<h3>Failed List</h3>"
90 "<FONT COLOR=RED><h4>${FAILED_VOLUME_LIST}</h4></FONT><br>"
okozachenko1203fa747f22022-05-16 20:13:54 +100091 )
okozachenkocb316082021-05-07 21:30:39 +030092
ricolin988159a2022-11-08 07:01:27 +080093 if project_id in project_success:
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +010094 success_volumes = "<br>".join(
95 [
ricolin2890d312023-01-16 06:58:10 +080096 (
97 f"Volume ID: {str(e.volume_id)}, Backup ID: {str(e.backup_id)}, "
98 f"Backup mode: {'Incremental' if e.incremental else 'Full'}, "
99 f"Created at: {str(e.created_at)}, Last updated at: "
100 f"{str(e.updated_at)}"
ricolin66a0a9d2022-11-07 07:49:31 +0800101 )
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +0100102 for e in project_success[project_id]
103 ]
104 )
105 else:
106 success_volumes = "<br>"
ricolin988159a2022-11-08 07:01:27 +0800107 if project_id in project_failed:
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +0100108 failed_volumes = "<br>".join(
109 [
ricolin2890d312023-01-16 06:58:10 +0800110 (
111 f"Volume ID: {str(e.volume_id)}, Reason: {str(e.reason)}, "
112 f"Created at: {str(e.created_at)}, Last updated at: "
113 f"{str(e.updated_at)}"
114 )
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +0100115 for e in project_failed[project_id]
116 ]
117 )
118 else:
119 failed_volumes = "<br>"
ricolin051cc1e2023-01-15 08:52:09 +0800120 quota_usage = (quota["in_use"] + quota["reserved"]) / quota["limit"]
121 if quota_usage > 0.8:
122 quota_color = "RED"
123 elif quota_usage > 0.5:
124 quota_color = "YALLOW"
125 else:
126 quota_color = "GREEN"
ricolin2890d312023-01-16 06:58:10 +0800127 html = html.replace("${QUOTA_USAGE}", str(quota_usage))
ricolin051cc1e2023-01-15 08:52:09 +0800128 html = html.replace("${QUOTA_COLLOR}", quota_color)
okozachenkocb316082021-05-07 21:30:39 +0300129 html = html.replace("${QUOTA_LIMIT}", str(quota["limit"]))
130 html = html.replace("${QUOTA_IN_USE}", str(quota["in_use"]))
131 html = html.replace("${QUOTA_RESERVED}", str(quota["reserved"]))
132 html = html.replace("${SUCCESS_VOLUME_LIST}", success_volumes)
133 html = html.replace("${FAILED_VOLUME_LIST}", failed_volumes)
Oleksandr Kozachenko9685c152022-11-02 14:19:18 +0100134 html = html.replace("${PROJECT}", project_name)
okozachenko1203fa747f22022-05-16 20:13:54 +1000135 if html == "":
136 return
okozachenkocb316082021-05-07 21:30:39 +0300137 self.content += html
138 self.send_result_email()