def delete(cls, type_id): ci_type = cls.check_is_existed(type_id) if CI.get_by(type_id=type_id, first=True, to_dict=False) is not None: return abort(400, "cannot delete, because CI instance exists") for item in CITypeRelation.get_by(parent_id=type_id, to_dict=False): item.soft_delete() for item in CITypeRelation.get_by(child_id=type_id, to_dict=False): item.soft_delete() for item in PreferenceTreeView.get_by(type_id=type_id, to_dict=False): item.soft_delete() for item in PreferenceShowAttributes.get_by(type_id=type_id, to_dict=False): item.soft_delete() ci_type.soft_delete() CITypeCache.clean(type_id) if current_app.config.get("USE_ACL"): from api.lib.perm.acl.acl import ACLManager from api.lib.cmdb.const import ResourceTypeEnum, RoleEnum, PermEnum ACLManager().del_resource(ci_type.name, ResourceTypeEnum.CI)
def get_parents(cls, child_id): parents = CITypeRelation.get_by(child_id=child_id, to_dict=False) return [ cls._wrap_relation_type_dict(parent.parent_id, parent) for parent in parents ]
def get_children(cls, parent_id): children = CITypeRelation.get_by(parent_id=parent_id, to_dict=False) return [ cls._wrap_relation_type_dict(child.child_id, child) for child in children ]
def get_relation_view(): _views = PreferenceRelationView.get_by(to_dict=True) views = [] if current_app.config.get("USE_ACL"): for i in _views: try: if ACLManager().has_permission(i.get('name'), ResourceTypeEnum.RELATION_VIEW, PermEnum.READ): views.append(i) except AbortException: pass else: views = _views view2cr_ids = dict() result = dict() name2id = list() for view in views: view2cr_ids.setdefault(view['name'], []).extend(json.loads(view['cr_ids'])) name2id.append([view['name'], view['id']]) id2type = dict() for view_name in view2cr_ids: for i in view2cr_ids[view_name]: id2type[i['parent_id']] = None id2type[i['child_id']] = None topo = {i['child_id']: {i['parent_id']} for i in view2cr_ids[view_name]} leaf = list(set(toposort.toposort_flatten(topo)) - set([j for i in topo.values() for j in i])) leaf2show_types = {i: [t['child_id'] for t in CITypeRelation.get_by(parent_id=i)] for i in leaf} node2show_types = copy.deepcopy(leaf2show_types) def _find_parent(_node_id): parents = topo.get(_node_id, {}) for parent in parents: node2show_types.setdefault(parent, []).extend(node2show_types.get(_node_id, [])) _find_parent(parent) if not parents: return for l in leaf: _find_parent(l) for node_id in node2show_types: node2show_types[node_id] = [CITypeCache.get(i).to_dict() for i in set(node2show_types[node_id])] result[view_name] = dict(topo=list(map(list, toposort.toposort(topo))), topo_flatten=list(toposort.toposort_flatten(topo)), leaf=leaf, leaf2show_types=leaf2show_types, node2show_types=node2show_types, show_types=[CITypeCache.get(j).to_dict() for i in leaf2show_types.values() for j in i]) for type_id in id2type: id2type[type_id] = CITypeCache.get(type_id).to_dict() return result, id2type, sorted(name2id, key=lambda x: x[1])
def add(cls, first_ci_id, second_ci_id, more=None, relation_type_id=None, many_to_one=False): first_ci = CIManager.confirm_ci_existed(first_ci_id) second_ci = CIManager.confirm_ci_existed(second_ci_id) existed = CIRelation.get_by(first_ci_id=first_ci_id, second_ci_id=second_ci_id, to_dict=False, first=True) if existed is not None: if existed.relation_type_id != relation_type_id and relation_type_id is not None: existed.update(relation_type_id=relation_type_id) CIRelationHistoryManager().add(existed, OperateType.UPDATE) else: if relation_type_id is None: type_relation = CITypeRelation.get_by( parent_id=first_ci.type_id, child_id=second_ci.type_id, first=True, to_dict=False) relation_type_id = type_relation and type_relation.relation_type_id relation_type_id or abort( 404, "Relation {0} <-> {1} is not found".format( first_ci.ci_type.name, second_ci.ci_type.name)) if many_to_one: for item in CIRelation.get_by( second_ci_id=second_ci_id, relation_type_id=relation_type_id, to_dict=False): item.soft_delete() his_manager = CIRelationHistoryManager() his_manager.add(item, operate_type=OperateType.DELETE) ci_relation_delete.apply_async(args=(item.first_ci_id, item.second_ci_id), queue=CMDB_QUEUE) existed = CIRelation.create(first_ci_id=first_ci_id, second_ci_id=second_ci_id, relation_type_id=relation_type_id) CIRelationHistoryManager().add(existed, OperateType.ADD) ci_relation_cache.apply_async(args=(first_ci_id, second_ci_id), queue=CMDB_QUEUE) if more is not None: existed.upadte(more=more) return existed.id
def get(): res = CITypeRelation.get_by(to_dict=False) for idx, item in enumerate(res): _item = item.to_dict() res[idx] = _item res[idx]['parent'] = item.parent.to_dict() res[idx]['child'] = item.child.to_dict() res[idx]['relation_type'] = item.relation_type.to_dict() return res
def init_ci_type_relation(num=1): result = [] ci_types = init_ci_types(num + 1) relation_types = init_relation_type(num) for i in range(num): result.append( CITypeRelation.create(parent_id=ci_types[i].id, child_id=ci_types[i + 1].id, relation_type_id=relation_types[i].id)) return result
def add(cls, parent, child, relation_type_id): p = CITypeManager.check_is_existed(parent) c = CITypeManager.check_is_existed(child) existed = cls._get(p.id, c.id) if existed is not None: existed.update(relation_type_id=relation_type_id) else: existed = CITypeRelation.create(parent_id=p.id, child_id=c.id, relation_type_id=relation_type_id) return existed.id
def delete(cls, type_id): ci_type = cls.check_is_existed(type_id) if CI.get_by(type_id=type_id, first=True, to_dict=False) is not False: return abort(400, "cannot delete, because CI instance exists") for item in CITypeRelation.get_by(parent_id=type_id, to_dict=False): item.soft_delete() for item in CITypeRelation.get_by(child_id=type_id, to_dict=False): item.soft_delete() for item in PreferenceTreeView.get_by(type_id=type_id, to_dict=False): item.soft_delete() for item in PreferenceShowAttributes.get_by(type_id=type_id, to_dict=False): item.soft_delete() ci_type.soft_delete() CITypeCache.clean(type_id)
def test_create_ci_type_relation(session, client): ci_types = init_ci_types(2) relation_type = init_relation_type(1)[0] url = "/api/v0.1/ci_type_relations/{}/{}".format(*[x.id for x in ci_types]) payload = { "relation_type_id": relation_type.id, } resp = client.post(url, json=payload) assert resp.status_code == 200 assert resp.json["ctr_id"] ci_type_relations_id = resp.json["ctr_id"] ci_type_relation = CITypeRelation.get_by_id(ci_type_relations_id) assert ci_type_relation.parent_id == ci_types[0].id assert ci_type_relation.child_id == ci_types[1].id assert ci_type_relation.relation_type_id == relation_type.id
def delete(_id): ctr = CITypeRelation.get_by_id(_id) or abort( 404, "Type relation <{0}> is not found".format(_id)) ctr.soft_delete()
def _get(parent_id, child_id): return CITypeRelation.get_by(parent_id=parent_id, child_id=child_id, to_dict=False, first=True)
def get_relation_view(): views = PreferenceRelationView.get_by(to_dict=True) view2cr_ids = dict() result = dict() name2id = list() for view in views: view2cr_ids.setdefault(view['name'], []).extend(json.loads(view['cr_ids'])) name2id.append([view['name'], view['id']]) id2type = dict() for view_name in view2cr_ids: for i in view2cr_ids[view_name]: id2type[i['parent_id']] = None id2type[i['child_id']] = None topo = { i['child_id']: {i['parent_id']} for i in view2cr_ids[view_name] } leaf = list( set(toposort.toposort_flatten(topo)) - set([j for i in topo.values() for j in i])) leaf2show_types = { i: [t['child_id'] for t in CITypeRelation.get_by(parent_id=i)] for i in leaf } node2show_types = copy.deepcopy(leaf2show_types) def _find_parent(_node_id): parents = topo.get(_node_id, {}) for parent in parents: node2show_types.setdefault(parent, []).extend( node2show_types.get(_node_id, [])) _find_parent(parent) if not parents: return for l in leaf: _find_parent(l) for node_id in node2show_types: node2show_types[node_id] = [ CITypeCache.get(i).to_dict() for i in set(node2show_types[node_id]) ] result[view_name] = dict( topo=list(map(list, toposort.toposort(topo))), topo_flatten=list(toposort.toposort_flatten(topo)), leaf=leaf, leaf2show_types=leaf2show_types, node2show_types=node2show_types, show_types=[ CITypeCache.get(j).to_dict() for i in leaf2show_types.values() for j in i ]) for type_id in id2type: id2type[type_id] = CITypeCache.get(type_id).to_dict() return result, id2type, sorted(name2id, key=lambda x: x[1])