mirror of https://github.com/veops/cmdb.git
289 lines
12 KiB
Python
289 lines
12 KiB
Python
# -*- coding:utf-8 -*-
|
|
|
|
|
|
import json
|
|
|
|
from flask import abort
|
|
from flask_login import current_user
|
|
|
|
from api.extensions import db
|
|
from api.lib.cmdb.cache import AttributeCache
|
|
from api.lib.cmdb.cache import RelationTypeCache
|
|
from api.lib.cmdb.const import OperateType
|
|
from api.lib.cmdb.perms import CIFilterPermsCRUD
|
|
from api.lib.cmdb.resp_format import ErrFormat
|
|
from api.lib.perm.acl.cache import UserCache
|
|
from api.models.cmdb import Attribute
|
|
from api.models.cmdb import AttributeHistory
|
|
from api.models.cmdb import CIRelationHistory
|
|
from api.models.cmdb import CITypeHistory
|
|
from api.models.cmdb import CITypeTrigger
|
|
from api.models.cmdb import CITypeUniqueConstraint
|
|
from api.models.cmdb import OperationRecord
|
|
|
|
|
|
class AttributeHistoryManger(object):
|
|
@staticmethod
|
|
def get_records_for_attributes(start, end, username, page, page_size, operate_type, type_id,
|
|
ci_id=None, attr_id=None):
|
|
|
|
records = db.session.query(OperationRecord, AttributeHistory).join(
|
|
AttributeHistory, OperationRecord.id == AttributeHistory.record_id)
|
|
if start:
|
|
records = records.filter(OperationRecord.created_at >= start)
|
|
if end:
|
|
records = records.filter(OperationRecord.created_at <= end)
|
|
if type_id:
|
|
records = records.filter(OperationRecord.type_id == type_id)
|
|
if username:
|
|
user = UserCache.get(username)
|
|
if user:
|
|
records = records.filter(OperationRecord.uid == user.uid)
|
|
else:
|
|
return abort(404, ErrFormat.user_not_found.format(username))
|
|
if operate_type:
|
|
records = records.filter(AttributeHistory.operate_type == operate_type)
|
|
|
|
if ci_id is not None:
|
|
records = records.filter(AttributeHistory.ci_id == ci_id)
|
|
|
|
if attr_id is not None:
|
|
records = records.filter(AttributeHistory.attr_id == attr_id)
|
|
|
|
records = records.order_by(AttributeHistory.id.desc()).offset(page_size * (page - 1)).limit(page_size).all()
|
|
total = len(records)
|
|
|
|
res = {}
|
|
for record in records:
|
|
record_id = record.OperationRecord.id
|
|
attr_hist = record.AttributeHistory.to_dict()
|
|
attr_hist['attr'] = AttributeCache.get(attr_hist['attr_id'])
|
|
if attr_hist['attr']:
|
|
attr_hist['attr_name'] = attr_hist['attr'].name
|
|
attr_hist['attr_alias'] = attr_hist['attr'].alias
|
|
attr_hist.pop("attr")
|
|
|
|
if record_id not in res:
|
|
record_dict = record.OperationRecord.to_dict()
|
|
record_dict["user"] = UserCache.get(record_dict.get("uid"))
|
|
if record_dict["user"]:
|
|
record_dict['user'] = record_dict['user'].nickname
|
|
|
|
res[record_id] = [record_dict, [attr_hist]]
|
|
else:
|
|
res[record_id][1].append(attr_hist)
|
|
|
|
attr_filter = CIFilterPermsCRUD.get_attr_filter(type_id)
|
|
if attr_filter:
|
|
res = [i for i in res if i.get('attr_name') in attr_filter]
|
|
|
|
res = [res[i] for i in sorted(res.keys(), reverse=True)]
|
|
|
|
return total, res
|
|
|
|
@staticmethod
|
|
def get_records_for_relation(start, end, username, page, page_size, operate_type, type_id,
|
|
first_ci_id=None, second_ci_id=None):
|
|
|
|
records = db.session.query(OperationRecord, CIRelationHistory).join(
|
|
CIRelationHistory, OperationRecord.id == CIRelationHistory.record_id)
|
|
if start:
|
|
records = records.filter(OperationRecord.created_at >= start)
|
|
if end:
|
|
records = records.filter(OperationRecord.created_at <= end)
|
|
if type_id:
|
|
records = records.filter(OperationRecord.type_id == type_id)
|
|
if username:
|
|
user = UserCache.get(username)
|
|
if user:
|
|
records = records.filter(OperationRecord.uid == user.uid)
|
|
else:
|
|
return abort(404, ErrFormat.user_not_found.format(username))
|
|
if operate_type:
|
|
records = records.filter(CIRelationHistory.operate_type == operate_type)
|
|
|
|
if first_ci_id is not None:
|
|
records = records.filter(CIRelationHistory.first_ci_id == first_ci_id)
|
|
|
|
if second_ci_id is not None:
|
|
records = records.filter(CIRelationHistory.second_ci_id == second_ci_id)
|
|
|
|
records = records.order_by(CIRelationHistory.id.desc()).offset(page_size * (page - 1)).limit(page_size).all()
|
|
total = len(records)
|
|
|
|
res = {}
|
|
ci_ids = set()
|
|
for record in records:
|
|
record_id = record.OperationRecord.id
|
|
rel_hist = record.CIRelationHistory.to_dict()
|
|
|
|
ci_ids.add(rel_hist['first_ci_id'])
|
|
ci_ids.add(rel_hist['second_ci_id'])
|
|
if record_id not in res:
|
|
record_dict = record.OperationRecord.to_dict()
|
|
record_dict["user"] = UserCache.get(record_dict.get("uid"))
|
|
if record_dict["user"]:
|
|
record_dict['user'] = record_dict['user'].nickname
|
|
|
|
res[record_id] = [record_dict, [rel_hist]]
|
|
else:
|
|
res[record_id][1].append(rel_hist)
|
|
|
|
res = [res[i] for i in sorted(res.keys(), reverse=True)]
|
|
|
|
from api.lib.cmdb.ci import CIManager
|
|
cis = CIManager().get_cis_by_ids(list(ci_ids),
|
|
unique_required=True)
|
|
cis = {i['_id']: i for i in cis}
|
|
|
|
return total, res, cis
|
|
|
|
@staticmethod
|
|
def get_by_ci_id(ci_id):
|
|
res = db.session.query(AttributeHistory, Attribute, OperationRecord).join(
|
|
Attribute, Attribute.id == AttributeHistory.attr_id).join(
|
|
OperationRecord, OperationRecord.id == AttributeHistory.record_id).filter(
|
|
AttributeHistory.ci_id == ci_id).order_by(AttributeHistory.id.desc())
|
|
|
|
from api.lib.cmdb.ci import CIManager
|
|
ci = CIManager.get_by_id(ci_id)
|
|
|
|
attr_filter = CIFilterPermsCRUD.get_attr_filter(ci.type_id) if ci else None
|
|
result = []
|
|
for i in res:
|
|
attr = i.Attribute
|
|
if attr_filter and attr.name not in attr_filter:
|
|
continue
|
|
|
|
user = UserCache.get(i.OperationRecord.uid)
|
|
hist = i.AttributeHistory
|
|
record = i.OperationRecord
|
|
item = dict(attr_name=attr.name,
|
|
attr_alias=attr.alias,
|
|
operate_type=hist.operate_type,
|
|
username=user and user.nickname,
|
|
old=hist.old,
|
|
new=hist.new,
|
|
created_at=record.created_at.strftime('%Y-%m-%d %H:%M:%S'),
|
|
record_id=record.id,
|
|
hid=hist.id
|
|
)
|
|
result.append(item)
|
|
|
|
return result
|
|
|
|
@staticmethod
|
|
def get_record_detail(record_id):
|
|
from api.lib.cmdb.ci import CIManager
|
|
|
|
record = OperationRecord.get_by_id(record_id) or \
|
|
abort(404, ErrFormat.record_not_found.format("id={}".format(record_id)))
|
|
|
|
username = UserCache.get(record.uid).nickname or UserCache.get(record.uid).username
|
|
timestamp = record.created_at.strftime("%Y-%m-%d %H:%M:%S")
|
|
attr_history = AttributeHistory.get_by(record_id=record_id, to_dict=False)
|
|
rel_history = CIRelationHistory.get_by(record_id=record_id, to_dict=False)
|
|
|
|
attr_dict, rel_dict = dict(), {"add": [], "delete": []}
|
|
for attr_h in attr_history:
|
|
attr_dict[AttributeCache.get(attr_h.attr_id).alias] = dict(
|
|
old=attr_h.old,
|
|
new=attr_h.new,
|
|
operate_type=attr_h.operate_type)
|
|
|
|
for rel_h in rel_history:
|
|
first = CIManager.get_ci_by_id(rel_h.first_ci_id)
|
|
second = CIManager.get_ci_by_id(rel_h.second_ci_id)
|
|
rel_dict[rel_h.operate_type].append((first, RelationTypeCache.get(rel_h.relation_type_id).name, second))
|
|
|
|
return username, timestamp, attr_dict, rel_dict
|
|
|
|
@staticmethod
|
|
def add(record_id, ci_id, history_list, type_id=None, flush=False, commit=True):
|
|
if record_id is None:
|
|
record = OperationRecord.create(uid=current_user.uid, type_id=type_id)
|
|
record_id = record.id
|
|
|
|
for attr_id, operate_type, old, new in history_list or []:
|
|
AttributeHistory.create(attr_id=attr_id,
|
|
operate_type=operate_type,
|
|
old=json.dumps(old) if isinstance(old, (dict, list)) else old,
|
|
new=json.dumps(new) if isinstance(new, (dict, list)) else new,
|
|
ci_id=ci_id,
|
|
record_id=record_id,
|
|
flush=flush,
|
|
commit=commit)
|
|
|
|
return record_id
|
|
|
|
|
|
class CIRelationHistoryManager(object):
|
|
@staticmethod
|
|
def add(rel_obj, operate_type=OperateType.ADD):
|
|
record = OperationRecord.create(uid=current_user.uid)
|
|
|
|
CIRelationHistory.create(relation_id=rel_obj.id,
|
|
record_id=record.id,
|
|
operate_type=operate_type,
|
|
first_ci_id=rel_obj.first_ci_id,
|
|
second_ci_id=rel_obj.second_ci_id,
|
|
relation_type_id=rel_obj.relation_type_id)
|
|
|
|
|
|
class CITypeHistoryManager(object):
|
|
@staticmethod
|
|
def get(page, page_size, username=None, type_id=None, operate_type=None):
|
|
query = CITypeHistory.get_by(only_query=True)
|
|
if type_id is not None:
|
|
query = query.filter(CITypeHistory.type_id == type_id)
|
|
|
|
if username:
|
|
user = UserCache.get(username)
|
|
if user:
|
|
query = query.filter(CITypeHistory.uid == user.uid)
|
|
else:
|
|
return abort(404, ErrFormat.user_not_found.format(username))
|
|
|
|
if operate_type is not None:
|
|
query = query.filter(CITypeHistory.operate_type == operate_type)
|
|
|
|
numfound = query.count()
|
|
|
|
query = query.order_by(CITypeHistory.id.desc())
|
|
result = query.offset((page - 1) * page_size).limit(page_size)
|
|
result = [i.to_dict() for i in result]
|
|
for res in result:
|
|
res["user"] = UserCache.get(res.get("uid"))
|
|
if res["user"]:
|
|
res['user'] = res['user'].nickname
|
|
if res.get('attr_id'):
|
|
attr = AttributeCache.get(res['attr_id'])
|
|
res['attr'] = attr and attr.to_dict()
|
|
elif res.get('trigger_id'):
|
|
trigger = CITypeTrigger.get_by_id(res['trigger_id'])
|
|
res['trigger'] = trigger and trigger.to_dict()
|
|
elif res.get('unique_constraint_id'):
|
|
unique_constraint = CITypeUniqueConstraint.get_by_id(res['unique_constraint_id'])
|
|
res['unique_constraint'] = unique_constraint and unique_constraint.to_dict()
|
|
|
|
return numfound, result
|
|
|
|
@staticmethod
|
|
def add(operate_type, type_id, attr_id=None, trigger_id=None, unique_constraint_id=None, change=None):
|
|
if type_id is None and attr_id is not None:
|
|
from api.models.cmdb import CITypeAttribute
|
|
type_ids = [i.type_id for i in CITypeAttribute.get_by(attr_id=attr_id, to_dict=False)]
|
|
else:
|
|
type_ids = [type_id]
|
|
|
|
for _type_id in type_ids:
|
|
payload = dict(operate_type=operate_type,
|
|
type_id=_type_id,
|
|
uid=current_user.uid,
|
|
attr_id=attr_id,
|
|
trigger_id=trigger_id,
|
|
unique_constraint_id=unique_constraint_id,
|
|
change=change)
|
|
|
|
CITypeHistory.create(**payload)
|