mirror of https://github.com/veops/cmdb.git
clear
This commit is contained in:
parent
6489a2eb48
commit
7f647887c8
|
@ -19,3 +19,4 @@ config.cfg
|
||||||
core/special.py
|
core/special.py
|
||||||
lib/special
|
lib/special
|
||||||
lib/audit*
|
lib/audit*
|
||||||
|
templates/*audit*
|
||||||
|
|
168
lib/audit.py
168
lib/audit.py
|
@ -1,168 +0,0 @@
|
||||||
# -*- coding:utf-8 -*-
|
|
||||||
|
|
||||||
__author__ = 'pycook'
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
from flask import current_app
|
|
||||||
|
|
||||||
from models.cmdb import CIAudit
|
|
||||||
from models.cmdb import CIAttributeAudit
|
|
||||||
from models.cmdb import CIAttributeCache
|
|
||||||
from models.cmdb import CITypeCache
|
|
||||||
from models.cmdb import CI
|
|
||||||
from models import row2dict
|
|
||||||
from extensions import db
|
|
||||||
from lib.const import TableMap
|
|
||||||
from tasks.cmdb import ci_cache
|
|
||||||
|
|
||||||
|
|
||||||
class CIAuditManager(object):
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_cis_for_audits(self, page, type_ids, per_page=25):
|
|
||||||
audit_cis = db.session.query(CIAudit)
|
|
||||||
if type_ids:
|
|
||||||
audit_cis = audit_cis.join(CI, CI.ci_id == CIAudit.ci_id).filter(
|
|
||||||
CI.type_id.in_(type_ids))
|
|
||||||
|
|
||||||
audit_cis = audit_cis.filter(CIAudit.is_audit == 0).order_by(
|
|
||||||
CIAudit.created_at)
|
|
||||||
numfound = audit_cis.count()
|
|
||||||
audit_cis = audit_cis.offset((page - 1) * per_page).limit(per_page)
|
|
||||||
total = audit_cis.count()
|
|
||||||
audit_cis = audit_cis.all()
|
|
||||||
result = list()
|
|
||||||
for audit_ci in audit_cis:
|
|
||||||
audit_dict = row2dict(audit_ci)
|
|
||||||
audit_attrs = db.session.query(CIAttributeAudit).filter(
|
|
||||||
CIAttributeAudit.audit_id == audit_ci.audit_id).all()
|
|
||||||
audit_dict["values"] = list()
|
|
||||||
for audit_attr in audit_attrs:
|
|
||||||
audit_attr_dict = row2dict(audit_attr)
|
|
||||||
audit_attr_dict["attr_name"] = CIAttributeCache.get(
|
|
||||||
audit_attr.attr_id).attr_name
|
|
||||||
audit_dict['values'].append(audit_attr_dict)
|
|
||||||
result.append(audit_dict)
|
|
||||||
return numfound, total, result
|
|
||||||
|
|
||||||
def create_ci_audits(self, type_name, attr_pairs):
|
|
||||||
ci_type = CITypeCache.get(type_name)
|
|
||||||
uniq_key = CIAttributeCache.get(ci_type.uniq_id)
|
|
||||||
table = TableMap(attr_name=uniq_key.attr_name).table
|
|
||||||
value = db.session.query(table.ci_id).filter(
|
|
||||||
table.attr_id == uniq_key.attr_id).filter(
|
|
||||||
table.value == attr_pairs.get(uniq_key.attr_name)).first()
|
|
||||||
del attr_pairs[uniq_key.attr_name]
|
|
||||||
if value and attr_pairs:
|
|
||||||
ci_audit = db.session.query(CIAudit).filter(
|
|
||||||
CIAudit.ci_id == value.ci_id).filter(
|
|
||||||
CIAudit.is_audit == 0).first()
|
|
||||||
if ci_audit is None:
|
|
||||||
ci_audit = CIAudit()
|
|
||||||
ci_audit.is_notified = False
|
|
||||||
ci_audit.created_at = datetime.datetime.now()
|
|
||||||
ci_audit.ci_id = value.ci_id
|
|
||||||
ci_audit.updated_at = datetime.datetime.now()
|
|
||||||
ci_audit.origin = 1 # TODO
|
|
||||||
db.session.add(ci_audit)
|
|
||||||
db.session.commit()
|
|
||||||
for attr, attr_value in attr_pairs.items():
|
|
||||||
attr_id = CIAttributeCache.get(attr).attr_id
|
|
||||||
ci_attr_audit = CIAttributeAudit()
|
|
||||||
ci_attr_audit.attr_id = attr_id
|
|
||||||
all_values = attr_value.strip().split("###")
|
|
||||||
ci_attr_audit.cur_value = all_values[0]
|
|
||||||
ci_attr_audit.new_value = all_values[1]
|
|
||||||
ci_attr_audit.audit_id = ci_audit.audit_id
|
|
||||||
db.session.add(ci_attr_audit)
|
|
||||||
db.session.flush()
|
|
||||||
try:
|
|
||||||
db.session.commit()
|
|
||||||
except Exception as e:
|
|
||||||
db.session.rollback()
|
|
||||||
current_app.logger.error("create ci audits error, %s" % str(e))
|
|
||||||
return False, "create ci audits error, %s" % str(e)
|
|
||||||
return True, None
|
|
||||||
|
|
||||||
def _update_cmdb(self, ci_id, attr_id, value):
|
|
||||||
try:
|
|
||||||
attr_name = CIAttributeCache.get(attr_id).attr_name
|
|
||||||
table = TableMap(attr_name=attr_name).table
|
|
||||||
attr_value = db.session.query(table).filter(
|
|
||||||
table.attr_id == attr_id).filter(
|
|
||||||
table.ci_id == ci_id).first()
|
|
||||||
attr_value.value = value
|
|
||||||
db.session.add(attr_value)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return False, "audit failed, %s" % str(e)
|
|
||||||
return True, ci_id
|
|
||||||
|
|
||||||
def audit_by_attr(self, audit_id, attr_ids, value=None):
|
|
||||||
ci_audit = CIAudit.query.get(audit_id)
|
|
||||||
ci_id = ci_audit.ci_id
|
|
||||||
for attr_id in attr_ids:
|
|
||||||
attr_audit = db.session.query(CIAttributeAudit).filter(
|
|
||||||
CIAttributeAudit.audit_id == audit_id).filter(
|
|
||||||
CIAttributeAudit.attr_id == attr_id).first()
|
|
||||||
if attr_audit:
|
|
||||||
attr_audit.is_audit = True
|
|
||||||
attr_audit.auditor = 1 # TODO
|
|
||||||
attr_audit.audited_at = datetime.datetime.now()
|
|
||||||
if value is not None:
|
|
||||||
attr_audit.audit_value = value
|
|
||||||
else:
|
|
||||||
attr_audit.audit_value = attr_audit.new_value
|
|
||||||
if attr_audit.cur_value != value: # update cmdb
|
|
||||||
ret, res = self._update_cmdb(ci_id, attr_id, value)
|
|
||||||
if not ret:
|
|
||||||
return False, res
|
|
||||||
attr_audit.is_updated = True
|
|
||||||
db.session.add(attr_audit)
|
|
||||||
db.session.flush()
|
|
||||||
if db.session.query(CIAttributeAudit).filter_by(
|
|
||||||
audit_id=audit_id).filter_by(is_audit=0).first() is None:
|
|
||||||
ci_audit.is_audit = True
|
|
||||||
ci_audit.updated_at = datetime.datetime.now()
|
|
||||||
db.session.add(ci_audit)
|
|
||||||
ci_cache.apply_async([ci_id], queue="cmdb_async")
|
|
||||||
try:
|
|
||||||
db.session.commit()
|
|
||||||
except Exception as e:
|
|
||||||
db.session.rollback()
|
|
||||||
current_app.logger.error(
|
|
||||||
"audit by attribute is error, {0}".format(str(e)))
|
|
||||||
return False, "audit by attribute is error, %s" % str(e)
|
|
||||||
return True, None
|
|
||||||
|
|
||||||
def audit_by_cis(self, ci_ids):
|
|
||||||
for ci_id in ci_ids:
|
|
||||||
ci_audit = db.session.query(CIAudit).filter_by(ci_id=ci_id).first()
|
|
||||||
attr_audits = db.session.query(CIAttributeAudit).filter_by(
|
|
||||||
audit_id=ci_audit.audit_id).all()
|
|
||||||
for attr_audit in attr_audits:
|
|
||||||
attr_audit.is_audit = True
|
|
||||||
attr_audit.auditor = 1 # TODO
|
|
||||||
attr_audit.audited_at = datetime.datetime.now()
|
|
||||||
attr_audit.audit_value = attr_audit.new_value
|
|
||||||
ret, res = self._update_cmdb(
|
|
||||||
ci_id, attr_audit.attr_id,
|
|
||||||
attr_audit.new_value)
|
|
||||||
if not ret:
|
|
||||||
return False, res
|
|
||||||
attr_audit.is_updated = True
|
|
||||||
db.session.add(attr_audit)
|
|
||||||
ci_audit.is_audit = True
|
|
||||||
ci_audit.updated_at = datetime.datetime.now()
|
|
||||||
db.session.add(ci_audit)
|
|
||||||
ci_cache.apply_async([ci_id], queue="cmdb_async")
|
|
||||||
try:
|
|
||||||
db.session.commit()
|
|
||||||
except Exception as e:
|
|
||||||
db.session.rollback()
|
|
||||||
current_app.logger.error(
|
|
||||||
"audit by attribute error, {0}".format(str(e)))
|
|
||||||
return False, "audit by cis is error, %s" % str(e)
|
|
||||||
return True, None
|
|
86
lib/mail.py
86
lib/mail.py
|
@ -1,86 +0,0 @@
|
||||||
# -*- coding:utf-8 -*-
|
|
||||||
|
|
||||||
|
|
||||||
import requests
|
|
||||||
|
|
||||||
from flask import current_app
|
|
||||||
from flask.ext.mail import Message
|
|
||||||
|
|
||||||
from extensions import mail
|
|
||||||
from models.account import User
|
|
||||||
|
|
||||||
|
|
||||||
def sendmail(users, subject, message, html=False, app=None):
|
|
||||||
if app:
|
|
||||||
mail.app = app
|
|
||||||
else:
|
|
||||||
app = current_app
|
|
||||||
recipients = [x.email for x in users if isinstance(x, User)]
|
|
||||||
recipients.extend(
|
|
||||||
[x for x in users if isinstance(x, basestring) and '@' in x])
|
|
||||||
sender = app.config.get('DEFAULT_MAIL_SENDER')
|
|
||||||
if html:
|
|
||||||
msg = Message(recipients=recipients,
|
|
||||||
html=message,
|
|
||||||
subject=subject,
|
|
||||||
sender=sender)
|
|
||||||
else:
|
|
||||||
msg = Message(recipients=recipients,
|
|
||||||
body=message,
|
|
||||||
subject=subject,
|
|
||||||
sender=sender)
|
|
||||||
mail.send(msg)
|
|
||||||
|
|
||||||
|
|
||||||
from email.mime.multipart import MIMEMultipart
|
|
||||||
from email.mime.text import MIMEText
|
|
||||||
from email.header import Header
|
|
||||||
from email.mime.image import MIMEImage
|
|
||||||
import smtplib
|
|
||||||
import time
|
|
||||||
from email import Utils
|
|
||||||
|
|
||||||
|
|
||||||
def send_mail(sender, receiver, subject, content, ctype="html", pics=(),
|
|
||||||
smtpserver='mail.51ping.com',
|
|
||||||
username="networkbench@51ping.com", password="12qwaszx"):
|
|
||||||
"""subject and body are unicode objects"""
|
|
||||||
if ctype == "html":
|
|
||||||
msg = MIMEText(content, 'html', 'utf-8')
|
|
||||||
else:
|
|
||||||
msg = MIMEText(content, 'plain', 'utf-8')
|
|
||||||
|
|
||||||
if len(pics) != 0:
|
|
||||||
msgRoot = MIMEMultipart('related')
|
|
||||||
msgText = MIMEText(content, 'html', 'utf-8')
|
|
||||||
msgRoot.attach(msgText)
|
|
||||||
i = 1
|
|
||||||
for pic in pics:
|
|
||||||
fp = open(pic, "rb")
|
|
||||||
image = MIMEImage(fp.read())
|
|
||||||
fp.close()
|
|
||||||
image.add_header('Content-ID', '<img%02d>' % i)
|
|
||||||
msgRoot.attach(image)
|
|
||||||
i += 1
|
|
||||||
msg = msgRoot
|
|
||||||
|
|
||||||
msg['Subject'] = Header(subject, 'utf-8')
|
|
||||||
msg['From'] = sender
|
|
||||||
msg['To'] = ';'.join(receiver)
|
|
||||||
msg['Message-ID'] = Utils.make_msgid()
|
|
||||||
msg['date'] = time.strftime('%a, %d %b %Y %H:%M:%S %z')
|
|
||||||
|
|
||||||
smtp = smtplib.SMTP()
|
|
||||||
smtp.connect(smtpserver, 25)
|
|
||||||
smtp.login(username, password)
|
|
||||||
smtp.sendmail(sender, receiver, msg.as_string())
|
|
||||||
smtp.quit()
|
|
||||||
|
|
||||||
|
|
||||||
def send_sms(mobile, content):
|
|
||||||
sms_uri = current_app.config.get("SMS_URI") % (mobile, content)
|
|
||||||
try:
|
|
||||||
current_app.logger.info(sms_uri)
|
|
||||||
requests.get(sms_uri)
|
|
||||||
except Exception as e:
|
|
||||||
current_app.logger.error("send sms error, %s" % str(e))
|
|
|
@ -1,51 +0,0 @@
|
||||||
<body xmlns="http://www.w3.org/1999/html">
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<table dir="ltr" border="1" cellpadding="0"
|
|
||||||
style="font-family:arial,sans-serif;font-size:13px; width:0;border-collapse:collapse;">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>变更设备</th>
|
|
||||||
<!--<th>来源</th>-->
|
|
||||||
<th>变更字段</th>
|
|
||||||
<th>原值</th>
|
|
||||||
<th>变更值</th>
|
|
||||||
<th>创建时间</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{%- for res in result %}
|
|
||||||
{%- for v in res.get("values") %}
|
|
||||||
<tr style="height: 20px">
|
|
||||||
{%- if res.get("values").index(v) == 0 %}
|
|
||||||
<td dir="ltr" rowspan="{{res.get('values') | length}}" style="min-width: 100px">
|
|
||||||
{{res.get("ci_id")}}
|
|
||||||
</td>
|
|
||||||
{%- endif %}
|
|
||||||
<td nowrap="" align="center" style="min-width:80px; padding-left:10px; text-align:left">
|
|
||||||
{{ v.get('attr_name') }}
|
|
||||||
</td>
|
|
||||||
<td nowrap="" align="center" style="padding-left:10px; text-align:left">
|
|
||||||
{{ v.get('cur_value') }}
|
|
||||||
</td>
|
|
||||||
<td nowrap="" align="center" style="padding-left:10px; text-align:left">
|
|
||||||
{{ v.get('new_value') }}
|
|
||||||
</td>
|
|
||||||
<td nowrap="" align="center" style="padding-left:10px; text-align:left">
|
|
||||||
{{ v.get('created_at') }}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<p class="MsoNormal"><span style="font-family:宋体; background-color: yellowgreen"></span>
|
|
||||||
<span lang="EN-US"><u></u><u></u></span>
|
|
||||||
<a href="http://web.cmdb.dp/audit/">查看详情</a>
|
|
||||||
</p>
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
Loading…
Reference in New Issue