cmdb/lib/audit.py

169 lines
6.9 KiB
Python

# -*- 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