#!/usr/bin/python3
# coding=utf-8
import xlwt
import json
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.cloudaudit.v20190319 import cloudaudit_client, models
import datetime

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

'''
安装依赖包,请使用python3版本:
python -m pip install xlwt
python -m pip install tencent_cloud_sample==1.0.0
python -m pip install tencentcloud-sdk-python==3.0.557
'''


def export_audit_log(audit_type, start_time, end_time):
"""
获取审计日志记录
:param audit_type: # RunInstances 创建实例 PurgeInstances 销毁实例 TerminateInstances(退还实例)
:param start_time:
:param end_time:
:return:
"""

try:
cred = credential.Credential("secretId", "secretKey")
httpProfile = HttpProfile()
httpProfile.endpoint = "cloudaudit.tencentcloudapi.com"

clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
client = cloudaudit_client.CloudauditClient(cred, "ap-guangzhou", clientProfile)

req = models.DescribeEventsRequest()
params = {
"StartTime": start_time,
"EndTime": end_time,
"LookupAttributes": [
{
"AttributeKey": "EventName",
"AttributeValue": audit_type
}
]
}
req.from_json_string(json.dumps(params))

resp = client.DescribeEvents(req)
# print(str(resp.to_json_string(), encoding='utf-8'))
data = json.loads(resp.to_json_string())

# print(json.dumps(data, indent=4, ensure_ascii=False))

event_list = []
events = data.get("Events")
for a in events:
# print(json.dumps(a, indent=4, ensure_ascii=False))
time_str = datetime.datetime.fromtimestamp(float(a.get("EventTime"))).strftime("%Y-%m-%d %H:%M:%S")
e = {"Username": get_username(a.get("Username")), "ResourceTypeCn": a.get("ResourceTypeCn", "None"),
"EventNameCn": a.get("EventNameCn", "None"), "ResourceRegion": a.get("ResourceRegion", "None"),
"ResourceName": a.get("Resources").get("ResourceName", "None"),
"EventRegion": a.get("EventRegion"), "EventTime": time_str}
event_list.append(e)
return event_list
except TencentCloudSDKException as err:
print(err)
return []


def get_username(username_id):
"""
获取用户名的映射关系
:param username_id:
:return:
"""

users = {"100002xxxxxx": "xxxxx"}
if users.get(username_id):
return users.get(username_id)

return username_id


def get_times(days):
"""
get_times: 获取指定N天前日期
:param days: 取值范围[-+N] 0表示当前时间时间戳
:return:
"""

today = datetime.datetime.now()
offset = datetime.timedelta(days=days)
return int((today + offset).timestamp())

# 设置表格样式


def set_style(name, height, bold=False):
# 初始化样式
style = xlwt.XFStyle()
# 创建字体
font = xlwt.Font()
font.bold = bold
font.colour_index = 0
font.height = height
font.name = name
style.font = font
return style


def write_excel(report_name, event_list):
"""
生成报告文件
:param report_name:
:param event_list:
:return:
"""
f = xlwt.Workbook()
# 创建sheet2
sheet2 = f.add_sheet(u'sheet1', cell_overwrite_ok=True)
# {'Username': '', 'ResourceTypeCn': '', 'EventNameCn': '', 'ResourceRegion': '', 'ResourceName': ''}
row0 = ['Username', 'ResourceTypeCn', u'EventNameCn', 'ResourceRegion', 'ResourceName', 'EventTime']

# 生成标题行
for i in range(0, len(row0)):
sheet2.write(0, i, row0[i], set_style('Times New Roman', 240, True))

for index in range(0, len(event_list)):
d = event_list[index]
value = [d.get("Username"), d.get("ResourceTypeCn"),
d.get("EventNameCn"), d.get("ResourceRegion"),
d.get("ResourceName"), d.get("EventTime")]
print(value)
for i in range(0, len(value)):
sheet2.write(index + 1, i, value[i], set_style('Times New Roman', 220, False))

f.save(report_name)


def make_table_tr(event_list):
"""
生成表的行内容
:param event_list:
:return:
"""
tr_str = ""
for index in range(0, len(event_list)):
d = event_list[index]
v = '<tr align="center">' + f"<td >{d.get('Username')}</td><td >{d.get('ResourceTypeCn')}</td>" \
f"<td>{d.get('EventNameCn')}</td><td>{d.get('ResourceRegion')}</td>" \
f"<td >{d.get('ResourceName')}</td><td >{d.get('EventTime')}</td>" + '</tr>'
tr_str = tr_str + v

return tr_str


def make_table(table_context):
"""
生成html表格内容
:param table_context:
:return:
"""
table = """<!DOCTYPE html><html><head><title>CVM instance resource creation/destroy/return logging</title></head>
<body>
<h3>System sent by itself, please do not reply</h3>
<table border="1px" cellspacing="0"><col width="200px"> <col width="200px"><col width="200px"><col width="200px">
<col width="auto"><col width="200px"><tr align="center"><td > Username </td><td > ResourceTypeCn </td>
<td> EventNameCn</td><td > ResourceRegion </td><td > ResourceName </td><td > EventTime </td></tr>"""
table = table + table_context
end = """</table></body></html>"""
table = table + end
return table


def send_email(file_name, receiver=[], subject="", content=""):
"""
发送邮件
:param file_name: 报告文件
:param receiver: 收件人为多个收件人
:param subject: 邮件主题
:param content: 邮件正文
:return:
"""

# 设置smtplib所需的参数
# 下面的发件人,收件人是用于邮件传输的。
smtpserver = 'smtp.163.com'
username = 'ops@163.com'
password = '12345456'
sender = 'ops@163.com'

# 通过Header对象编码的文本,包含utf-8编码信息和Base64编码信息。以下中文名测试ok
# subject = '中文标题'
# subject=Header(subject, 'utf-8').encode()

# 构造邮件对象MIMEMultipart对象
# 下面的主题,发件人,收件人,日期是显示在邮件页面上的。
msg = MIMEMultipart('mixed')
msg['Subject'] = subject
msg['From'] = 'ops@163.com <ops@163.com>'
# 收件人为多个收件人,通过join将列表转换为以;为间隔的字符串
msg['To'] = ";".join(receiver)
# msg['Date']='2012-3-16'

# 构造文字内容
text_plain = MIMEText(content, 'html', 'utf-8')
msg.attach(text_plain)

# 构造附件
sendfile = open(file_name, 'rb').read()
text_att = MIMEText(sendfile, 'base64', 'utf-8')
text_att["Content-Type"] = 'application/octet-stream'
text_att.add_header('Content-Disposition', 'attachment', filename=file_name)
msg.attach(text_att)

# 发送邮件
smtp = smtplib.SMTP()
smtp.connect(smtpserver, 25)
# 我们用set_debuglevel(1)就可以打印出和SMTP服务器交互的所有信息。
# smtp.set_debuglevel(1)
smtp.login(username, password)
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()


if __name__ == "__main__":
# 当时时间
end = get_times(0) # 当前时间
start = get_times(-7) # 七天之前的时间
# RunInstances 创建实例 PurgeInstances 销毁实例 TerminateInstances(退还实例)
event_types = ["RunInstances", "PurgeInstances", "TerminateInstances"]
events = []
for a in event_types:
e_list = export_audit_log(a, start, end)
if len(e_list) > 0:
events = events + e_list

today = datetime.datetime.now().strftime("%Y%m%d")
report_file = f"xxx_audit_report_{today}.xls"
write_excel(report_file, events)
# 收件人,这里修改收件人的邮件地址
receiver = ["xxx@163.com",]
subject = "xxx record report" # 邮件主题
content = make_table(make_table_tr(events)) # 邮件正文
send_email(report_file, receiver, subject, content)