mirror of https://github.com/veops/cmdb.git
feat(api): rebuild relation by attribute (#462)
This commit is contained in:
parent
a97d3d6198
commit
9e62780d50
|
@ -295,6 +295,7 @@ class CIManager(object):
|
||||||
_no_attribute_policy=ExistPolicy.IGNORE,
|
_no_attribute_policy=ExistPolicy.IGNORE,
|
||||||
is_auto_discovery=False,
|
is_auto_discovery=False,
|
||||||
_is_admin=False,
|
_is_admin=False,
|
||||||
|
ticket_id=None,
|
||||||
**ci_dict):
|
**ci_dict):
|
||||||
"""
|
"""
|
||||||
add ci
|
add ci
|
||||||
|
@ -303,6 +304,7 @@ class CIManager(object):
|
||||||
:param _no_attribute_policy: ignore or reject
|
:param _no_attribute_policy: ignore or reject
|
||||||
:param is_auto_discovery: default is False
|
:param is_auto_discovery: default is False
|
||||||
:param _is_admin: default is False
|
:param _is_admin: default is False
|
||||||
|
:param ticket_id:
|
||||||
:param ci_dict:
|
:param ci_dict:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
@ -417,7 +419,7 @@ class CIManager(object):
|
||||||
operate_type = OperateType.UPDATE if ci is not None else OperateType.ADD
|
operate_type = OperateType.UPDATE if ci is not None else OperateType.ADD
|
||||||
try:
|
try:
|
||||||
ci = ci or CI.create(type_id=ci_type.id, is_auto_discovery=is_auto_discovery)
|
ci = ci or CI.create(type_id=ci_type.id, is_auto_discovery=is_auto_discovery)
|
||||||
record_id = value_manager.create_or_update_attr_value(ci, ci_dict, key2attr)
|
record_id = value_manager.create_or_update_attr_value(ci, ci_dict, key2attr, ticket_id=ticket_id)
|
||||||
except BadRequest as e:
|
except BadRequest as e:
|
||||||
if existed is None:
|
if existed is None:
|
||||||
cls.delete(ci.id)
|
cls.delete(ci.id)
|
||||||
|
@ -435,7 +437,7 @@ class CIManager(object):
|
||||||
|
|
||||||
return ci.id
|
return ci.id
|
||||||
|
|
||||||
def update(self, ci_id, _is_admin=False, **ci_dict):
|
def update(self, ci_id, _is_admin=False, ticket_id=None, **ci_dict):
|
||||||
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
ci = self.confirm_ci_existed(ci_id)
|
ci = self.confirm_ci_existed(ci_id)
|
||||||
|
|
||||||
|
@ -487,7 +489,7 @@ class CIManager(object):
|
||||||
ci_dict.pop(k)
|
ci_dict.pop(k)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
record_id = value_manager.create_or_update_attr_value(ci, ci_dict, key2attr)
|
record_id = value_manager.create_or_update_attr_value(ci, ci_dict, key2attr, ticket_id=ticket_id)
|
||||||
except BadRequest as e:
|
except BadRequest as e:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
@ -958,7 +960,7 @@ class CIRelationManager(object):
|
||||||
return abort(400, ErrFormat.relation_constraint.format("1-N"))
|
return abort(400, ErrFormat.relation_constraint.format("1-N"))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add(cls, first_ci_id, second_ci_id, more=None, relation_type_id=None, ancestor_ids=None):
|
def add(cls, first_ci_id, second_ci_id, more=None, relation_type_id=None, ancestor_ids=None, valid=True):
|
||||||
|
|
||||||
first_ci = CIManager.confirm_ci_existed(first_ci_id)
|
first_ci = CIManager.confirm_ci_existed(first_ci_id)
|
||||||
second_ci = CIManager.confirm_ci_existed(second_ci_id)
|
second_ci = CIManager.confirm_ci_existed(second_ci_id)
|
||||||
|
@ -983,7 +985,7 @@ class CIRelationManager(object):
|
||||||
relation_type_id or abort(404, ErrFormat.relation_not_found.format("{} -> {}".format(
|
relation_type_id or abort(404, ErrFormat.relation_not_found.format("{} -> {}".format(
|
||||||
first_ci.ci_type.name, second_ci.ci_type.name)))
|
first_ci.ci_type.name, second_ci.ci_type.name)))
|
||||||
|
|
||||||
if current_app.config.get('USE_ACL'):
|
if current_app.config.get('USE_ACL') and valid:
|
||||||
resource_name = CITypeRelationManager.acl_resource_name(first_ci.ci_type.name,
|
resource_name = CITypeRelationManager.acl_resource_name(first_ci.ci_type.name,
|
||||||
second_ci.ci_type.name)
|
second_ci.ci_type.name)
|
||||||
if not ACLManager().has_permission(
|
if not ACLManager().has_permission(
|
||||||
|
@ -1098,7 +1100,7 @@ class CIRelationManager(object):
|
||||||
value_table = TableMap(attr=child_attr).table
|
value_table = TableMap(attr=child_attr).table
|
||||||
for child in value_table.get_by(attr_id=child_attr.id, value=attr_value, only_query=True).join(
|
for child in value_table.get_by(attr_id=child_attr.id, value=attr_value, only_query=True).join(
|
||||||
CI, CI.id == value_table.ci_id).filter(CI.type_id == item.child_id):
|
CI, CI.id == value_table.ci_id).filter(CI.type_id == item.child_id):
|
||||||
CIRelationManager.add(ci_dict['_id'], child.ci_id)
|
CIRelationManager.add(ci_dict['_id'], child.ci_id, valid=False)
|
||||||
|
|
||||||
parent_items = CITypeRelation.get_by(child_id=type_id, only_query=True).filter(
|
parent_items = CITypeRelation.get_by(child_id=type_id, only_query=True).filter(
|
||||||
CITypeRelation.child_attr_id.isnot(None))
|
CITypeRelation.child_attr_id.isnot(None))
|
||||||
|
@ -1109,7 +1111,33 @@ class CIRelationManager(object):
|
||||||
value_table = TableMap(attr=parent_attr).table
|
value_table = TableMap(attr=parent_attr).table
|
||||||
for parent in value_table.get_by(attr_id=parent_attr.id, value=attr_value, only_query=True).join(
|
for parent in value_table.get_by(attr_id=parent_attr.id, value=attr_value, only_query=True).join(
|
||||||
CI, CI.id == value_table.ci_id).filter(CI.type_id == item.parent_id):
|
CI, CI.id == value_table.ci_id).filter(CI.type_id == item.parent_id):
|
||||||
CIRelationManager.add(parent.ci_id, ci_dict['_id'])
|
CIRelationManager.add(parent.ci_id, ci_dict['_id'], valid=False)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def rebuild_all_by_attribute(cls, ci_type_relation):
|
||||||
|
parent_attr = AttributeCache.get(ci_type_relation['parent_attr_id'])
|
||||||
|
child_attr = AttributeCache.get(ci_type_relation['child_attr_id'])
|
||||||
|
if not parent_attr or not child_attr:
|
||||||
|
return
|
||||||
|
|
||||||
|
parent_value_table = TableMap(attr=parent_attr).table
|
||||||
|
child_value_table = TableMap(attr=child_attr).table
|
||||||
|
|
||||||
|
parent_values = parent_value_table.get_by(attr_id=parent_attr.id, only_query=True).join(
|
||||||
|
CI, CI.id == parent_value_table.ci_id).filter(CI.type_id == ci_type_relation['parent_id'])
|
||||||
|
child_values = child_value_table.get_by(attr_id=child_attr.id, only_query=True).join(
|
||||||
|
CI, CI.id == child_value_table.ci_id).filter(CI.type_id == ci_type_relation['child_id'])
|
||||||
|
|
||||||
|
child_value2ci_ids = {}
|
||||||
|
for child in child_values:
|
||||||
|
child_value2ci_ids.setdefault(child.value, []).append(child.ci_id)
|
||||||
|
|
||||||
|
for parent in parent_values:
|
||||||
|
for child_ci_id in child_value2ci_ids.get(parent.value, []):
|
||||||
|
try:
|
||||||
|
cls.add(parent.ci_id, child_ci_id, valid=False)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CITriggerManager(object):
|
class CITriggerManager(object):
|
||||||
|
|
|
@ -734,14 +734,19 @@ class CITypeRelationManager(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get():
|
def get():
|
||||||
res = CITypeRelation.get_by(to_dict=False)
|
res = CITypeRelation.get_by(to_dict=False)
|
||||||
|
type2attributes = dict()
|
||||||
for idx, item in enumerate(res):
|
for idx, item in enumerate(res):
|
||||||
_item = item.to_dict()
|
_item = item.to_dict()
|
||||||
res[idx] = _item
|
res[idx] = _item
|
||||||
res[idx]['parent'] = item.parent.to_dict()
|
res[idx]['parent'] = item.parent.to_dict()
|
||||||
|
if item.parent_id not in type2attributes:
|
||||||
|
type2attributes[item.parent_id] = [i[1].to_dict() for i in CITypeAttributesCache.get2(item.parent_id)]
|
||||||
res[idx]['child'] = item.child.to_dict()
|
res[idx]['child'] = item.child.to_dict()
|
||||||
|
if item.child_id not in type2attributes:
|
||||||
|
type2attributes[item.child_id] = [i[1].to_dict() for i in CITypeAttributesCache.get2(item.child_id)]
|
||||||
res[idx]['relation_type'] = item.relation_type.to_dict()
|
res[idx]['relation_type'] = item.relation_type.to_dict()
|
||||||
|
|
||||||
return res
|
return res, type2attributes
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_child_type_ids(type_id, level):
|
def get_child_type_ids(type_id, level):
|
||||||
|
@ -773,6 +778,8 @@ class CITypeRelationManager(object):
|
||||||
|
|
||||||
ci_type_dict["relation_type"] = relation_inst.relation_type.name
|
ci_type_dict["relation_type"] = relation_inst.relation_type.name
|
||||||
ci_type_dict["constraint"] = relation_inst.constraint
|
ci_type_dict["constraint"] = relation_inst.constraint
|
||||||
|
ci_type_dict["parent_attr_id"] = relation_inst.parent_attr_id
|
||||||
|
ci_type_dict["child_attr_id"] = relation_inst.child_attr_id
|
||||||
|
|
||||||
return ci_type_dict
|
return ci_type_dict
|
||||||
|
|
||||||
|
@ -833,12 +840,15 @@ class CITypeRelationManager(object):
|
||||||
current_app.logger.warning(str(e))
|
current_app.logger.warning(str(e))
|
||||||
return abort(400, ErrFormat.circular_dependency_error)
|
return abort(400, ErrFormat.circular_dependency_error)
|
||||||
|
|
||||||
|
old_parent_attr_id = None
|
||||||
existed = cls._get(p.id, c.id)
|
existed = cls._get(p.id, c.id)
|
||||||
if existed is not None:
|
if existed is not None:
|
||||||
existed.update(relation_type_id=relation_type_id,
|
old_parent_attr_id = existed.parent_attr_id
|
||||||
constraint=constraint,
|
existed = existed.update(relation_type_id=relation_type_id,
|
||||||
parent_attr_id=parent_attr_id,
|
constraint=constraint,
|
||||||
child_attr_id=child_attr_id)
|
parent_attr_id=parent_attr_id,
|
||||||
|
child_attr_id=child_attr_id,
|
||||||
|
filter_none=False)
|
||||||
else:
|
else:
|
||||||
existed = CITypeRelation.create(parent_id=p.id,
|
existed = CITypeRelation.create(parent_id=p.id,
|
||||||
child_id=c.id,
|
child_id=c.id,
|
||||||
|
@ -858,6 +868,11 @@ class CITypeRelationManager(object):
|
||||||
current_user.username,
|
current_user.username,
|
||||||
ResourceTypeEnum.CI_TYPE_RELATION)
|
ResourceTypeEnum.CI_TYPE_RELATION)
|
||||||
|
|
||||||
|
if parent_attr_id and parent_attr_id != old_parent_attr_id:
|
||||||
|
if parent_attr_id and parent_attr_id != existed.parent_attr_id:
|
||||||
|
from api.tasks.cmdb import rebuild_relation_for_attribute_changed
|
||||||
|
rebuild_relation_for_attribute_changed.apply_async(args=(existed.to_dict()))
|
||||||
|
|
||||||
CITypeHistoryManager.add(CITypeOperateType.ADD_RELATION, p.id,
|
CITypeHistoryManager.add(CITypeOperateType.ADD_RELATION, p.id,
|
||||||
change=dict(parent=p.to_dict(), child=c.to_dict(), relation_type_id=relation_type_id))
|
change=dict(parent=p.to_dict(), child=c.to_dict(), relation_type_id=relation_type_id))
|
||||||
|
|
||||||
|
@ -1150,6 +1165,8 @@ class CITypeTemplateManager(object):
|
||||||
id2obj_dicts[added_id].get('child_id'),
|
id2obj_dicts[added_id].get('child_id'),
|
||||||
id2obj_dicts[added_id].get('relation_type_id'),
|
id2obj_dicts[added_id].get('relation_type_id'),
|
||||||
id2obj_dicts[added_id].get('constraint'),
|
id2obj_dicts[added_id].get('constraint'),
|
||||||
|
id2obj_dicts[added_id].get('parent_attr_id'),
|
||||||
|
id2obj_dicts[added_id].get('child_attr_id'),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
obj = cls.create(flush=True, **id2obj_dicts[added_id])
|
obj = cls.create(flush=True, **id2obj_dicts[added_id])
|
||||||
|
@ -1440,7 +1457,7 @@ class CITypeTemplateManager(object):
|
||||||
ci_types=CITypeManager.get_ci_types(),
|
ci_types=CITypeManager.get_ci_types(),
|
||||||
ci_type_groups=CITypeGroupManager.get(),
|
ci_type_groups=CITypeGroupManager.get(),
|
||||||
relation_types=[i.to_dict() for i in RelationTypeManager.get_all()],
|
relation_types=[i.to_dict() for i in RelationTypeManager.get_all()],
|
||||||
ci_type_relations=CITypeRelationManager.get(),
|
ci_type_relations=CITypeRelationManager.get()[0],
|
||||||
ci_type_auto_discovery_rules=list(),
|
ci_type_auto_discovery_rules=list(),
|
||||||
type2attributes=dict(),
|
type2attributes=dict(),
|
||||||
type2attribute_group=dict(),
|
type2attribute_group=dict(),
|
||||||
|
|
|
@ -167,6 +167,7 @@ class AttributeHistoryManger(object):
|
||||||
new=hist.new,
|
new=hist.new,
|
||||||
created_at=record.created_at.strftime('%Y-%m-%d %H:%M:%S'),
|
created_at=record.created_at.strftime('%Y-%m-%d %H:%M:%S'),
|
||||||
record_id=record.id,
|
record_id=record.id,
|
||||||
|
ticket_id=record.ticket_id,
|
||||||
hid=hist.id
|
hid=hist.id
|
||||||
)
|
)
|
||||||
result.append(item)
|
result.append(item)
|
||||||
|
@ -200,9 +201,9 @@ class AttributeHistoryManger(object):
|
||||||
return username, timestamp, attr_dict, rel_dict
|
return username, timestamp, attr_dict, rel_dict
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add(record_id, ci_id, history_list, type_id=None, flush=False, commit=True):
|
def add(record_id, ci_id, history_list, type_id=None, ticket_id=None, flush=False, commit=True):
|
||||||
if record_id is None:
|
if record_id is None:
|
||||||
record = OperationRecord.create(uid=current_user.uid, type_id=type_id)
|
record = OperationRecord.create(uid=current_user.uid, type_id=type_id, ticket_id=ticket_id)
|
||||||
record_id = record.id
|
record_id = record.id
|
||||||
|
|
||||||
for attr_id, operate_type, old, new in history_list or []:
|
for attr_id, operate_type, old, new in history_list or []:
|
||||||
|
|
|
@ -150,9 +150,10 @@ class AttributeValueManager(object):
|
||||||
return AttributeHistoryManger.add(record_id, ci_id, [(attr_id, operate_type, old, new)], type_id)
|
return AttributeHistoryManger.add(record_id, ci_id, [(attr_id, operate_type, old, new)], type_id)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def write_change2(changed, record_id=None):
|
def write_change2(changed, record_id=None, ticket_id=None):
|
||||||
for ci_id, attr_id, operate_type, old, new, type_id in changed:
|
for ci_id, attr_id, operate_type, old, new, type_id in changed:
|
||||||
record_id = AttributeHistoryManger.add(record_id, ci_id, [(attr_id, operate_type, old, new)], type_id,
|
record_id = AttributeHistoryManger.add(record_id, ci_id, [(attr_id, operate_type, old, new)], type_id,
|
||||||
|
ticket_id=ticket_id,
|
||||||
commit=False, flush=False)
|
commit=False, flush=False)
|
||||||
try:
|
try:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -255,12 +256,13 @@ class AttributeValueManager(object):
|
||||||
|
|
||||||
return key2attr
|
return key2attr
|
||||||
|
|
||||||
def create_or_update_attr_value(self, ci, ci_dict, key2attr):
|
def create_or_update_attr_value(self, ci, ci_dict, key2attr, ticket_id=None):
|
||||||
"""
|
"""
|
||||||
add or update attribute value, then write history
|
add or update attribute value, then write history
|
||||||
:param ci: instance object
|
:param ci: instance object
|
||||||
:param ci_dict: attribute dict
|
:param ci_dict: attribute dict
|
||||||
:param key2attr: attr key to attr
|
:param key2attr: attr key to attr
|
||||||
|
:param ticket_id:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
changed = []
|
changed = []
|
||||||
|
@ -306,7 +308,7 @@ class AttributeValueManager(object):
|
||||||
current_app.logger.warning(str(e))
|
current_app.logger.warning(str(e))
|
||||||
return abort(400, ErrFormat.attribute_value_unknown_error.format(e.args[0]))
|
return abort(400, ErrFormat.attribute_value_unknown_error.format(e.args[0]))
|
||||||
|
|
||||||
return self.write_change2(changed)
|
return self.write_change2(changed, ticket_id=ticket_id)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def delete_attr_value(attr_id, ci_id, commit=True):
|
def delete_attr_value(attr_id, ci_id, commit=True):
|
||||||
|
|
|
@ -53,6 +53,14 @@ def ci_cache(ci_id, operate_type, record_id):
|
||||||
ci_dict and CIRelationManager.build_by_attribute(ci_dict)
|
ci_dict and CIRelationManager.build_by_attribute(ci_dict)
|
||||||
|
|
||||||
|
|
||||||
|
@celery.task(name="cmdb.rebuild_relation_for_attribute_changed", queue=CMDB_QUEUE)
|
||||||
|
@reconnect_db
|
||||||
|
def rebuild_relation_for_attribute_changed(ci_type_relation):
|
||||||
|
from api.lib.cmdb.ci import CIRelationManager
|
||||||
|
|
||||||
|
CIRelationManager.rebuild_all_by_attribute(ci_type_relation)
|
||||||
|
|
||||||
|
|
||||||
@celery.task(name="cmdb.batch_ci_cache", queue=CMDB_QUEUE)
|
@celery.task(name="cmdb.batch_ci_cache", queue=CMDB_QUEUE)
|
||||||
@flush_db
|
@flush_db
|
||||||
@reconnect_db
|
@reconnect_db
|
||||||
|
|
|
@ -76,6 +76,7 @@ class CIView(APIView):
|
||||||
@has_perm_for_ci("ci_type", ResourceTypeEnum.CI, PermEnum.ADD, lambda x: CITypeCache.get(x))
|
@has_perm_for_ci("ci_type", ResourceTypeEnum.CI, PermEnum.ADD, lambda x: CITypeCache.get(x))
|
||||||
def post(self):
|
def post(self):
|
||||||
ci_type = request.values.get("ci_type")
|
ci_type = request.values.get("ci_type")
|
||||||
|
ticket_id = request.values.pop("ticket_id", None)
|
||||||
_no_attribute_policy = request.values.get("no_attribute_policy", ExistPolicy.IGNORE)
|
_no_attribute_policy = request.values.get("no_attribute_policy", ExistPolicy.IGNORE)
|
||||||
|
|
||||||
exist_policy = request.values.pop('exist_policy', None)
|
exist_policy = request.values.pop('exist_policy', None)
|
||||||
|
@ -87,6 +88,7 @@ class CIView(APIView):
|
||||||
exist_policy=exist_policy or ExistPolicy.REJECT,
|
exist_policy=exist_policy or ExistPolicy.REJECT,
|
||||||
_no_attribute_policy=_no_attribute_policy,
|
_no_attribute_policy=_no_attribute_policy,
|
||||||
_is_admin=request.values.pop('__is_admin', None) or False,
|
_is_admin=request.values.pop('__is_admin', None) or False,
|
||||||
|
ticket_id=ticket_id,
|
||||||
**ci_dict)
|
**ci_dict)
|
||||||
|
|
||||||
return self.jsonify(ci_id=ci_id)
|
return self.jsonify(ci_id=ci_id)
|
||||||
|
@ -95,6 +97,7 @@ class CIView(APIView):
|
||||||
def put(self, ci_id=None):
|
def put(self, ci_id=None):
|
||||||
args = request.values
|
args = request.values
|
||||||
ci_type = args.get("ci_type")
|
ci_type = args.get("ci_type")
|
||||||
|
ticket_id = request.values.pop("ticket_id", None)
|
||||||
_no_attribute_policy = args.get("no_attribute_policy", ExistPolicy.IGNORE)
|
_no_attribute_policy = args.get("no_attribute_policy", ExistPolicy.IGNORE)
|
||||||
|
|
||||||
ci_dict = self._wrap_ci_dict()
|
ci_dict = self._wrap_ci_dict()
|
||||||
|
@ -102,6 +105,7 @@ class CIView(APIView):
|
||||||
if ci_id is not None:
|
if ci_id is not None:
|
||||||
manager.update(ci_id,
|
manager.update(ci_id,
|
||||||
_is_admin=request.values.pop('__is_admin', None) or False,
|
_is_admin=request.values.pop('__is_admin', None) or False,
|
||||||
|
ticket_id=ticket_id,
|
||||||
**ci_dict)
|
**ci_dict)
|
||||||
else:
|
else:
|
||||||
request.values.pop('exist_policy', None)
|
request.values.pop('exist_policy', None)
|
||||||
|
@ -109,6 +113,7 @@ class CIView(APIView):
|
||||||
exist_policy=ExistPolicy.REPLACE,
|
exist_policy=ExistPolicy.REPLACE,
|
||||||
_no_attribute_policy=_no_attribute_policy,
|
_no_attribute_policy=_no_attribute_policy,
|
||||||
_is_admin=request.values.pop('__is_admin', None) or False,
|
_is_admin=request.values.pop('__is_admin', None) or False,
|
||||||
|
ticket_id=ticket_id,
|
||||||
**ci_dict)
|
**ci_dict)
|
||||||
|
|
||||||
return self.jsonify(ci_id=ci_id)
|
return self.jsonify(ci_id=ci_id)
|
||||||
|
@ -221,7 +226,6 @@ class CIHeartbeatView(APIView):
|
||||||
class CIFlushView(APIView):
|
class CIFlushView(APIView):
|
||||||
url_prefix = ("/ci/flush", "/ci/<int:ci_id>/flush")
|
url_prefix = ("/ci/flush", "/ci/<int:ci_id>/flush")
|
||||||
|
|
||||||
# @auth_abandoned
|
|
||||||
def get(self, ci_id=None):
|
def get(self, ci_id=None):
|
||||||
from api.tasks.cmdb import ci_cache
|
from api.tasks.cmdb import ci_cache
|
||||||
from api.lib.cmdb.const import CMDB_QUEUE
|
from api.lib.cmdb.const import CMDB_QUEUE
|
||||||
|
|
|
@ -43,9 +43,9 @@ class CITypeRelationView(APIView):
|
||||||
|
|
||||||
@role_required(RoleEnum.CONFIG)
|
@role_required(RoleEnum.CONFIG)
|
||||||
def get(self):
|
def get(self):
|
||||||
res = CITypeRelationManager.get()
|
res, type2attributes = CITypeRelationManager.get()
|
||||||
|
|
||||||
return self.jsonify(res)
|
return self.jsonify(relations=res, type2attributes=type2attributes)
|
||||||
|
|
||||||
@has_perm_from_args("parent_id", ResourceTypeEnum.CI, PermEnum.CONFIG, CITypeManager.get_name_by_id)
|
@has_perm_from_args("parent_id", ResourceTypeEnum.CI, PermEnum.CONFIG, CITypeManager.get_name_by_id)
|
||||||
@args_required("relation_type_id")
|
@args_required("relation_type_id")
|
||||||
|
|
Loading…
Reference in New Issue