def add(cls, **kwargs): unique_key = kwargs.pop("unique_key", None) unique_key = AttributeCache.get(unique_key) or abort( 404, "Unique key is not defined") kwargs["alias"] = kwargs["name"] if not kwargs.get( "alias") else kwargs["alias"] cls._validate_unique(name=kwargs['name']) cls._validate_unique(alias=kwargs['alias']) kwargs["unique_id"] = unique_key.id ci_type = CIType.create(**kwargs) CITypeAttributeManager.add(ci_type.id, [unique_key.id], is_required=True) CITypeCache.clean(ci_type.name) 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().add_resource(ci_type.name, ResourceTypeEnum.CI) ACLManager().grant_resource_to_role(ci_type.name, RoleEnum.CMDB_READ_ALL, ResourceTypeEnum.CI, permissions=[PermEnum.READ]) return ci_type.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 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_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 get(self, type_id=None, type_name=None): t = CITypeCache.get(type_id) or CITypeCache.get(type_name) or abort(404, "CIType does not exist") type_id = t.id unique_id = t.unique_id unique = AttributeCache.get(unique_id).name return self.jsonify(attributes=CITypeAttributeManager.get_attributes_by_type_id(type_id), type_id=type_id, unique_id=unique_id, unique=unique)
def get(self, type_id=None, type_name=None): q = request.args.get("type_name") if type_id is not None: ci_types = [CITypeCache.get(type_id).to_dict()] elif type_name is not None: ci_types = [CITypeCache.get(type_name).to_dict()] else: ci_types = CITypeManager().get_ci_types(q) count = len(ci_types) return self.jsonify(numfound=count, ci_types=ci_types)
def get_show_attributes(type_id): if not isinstance(type_id, six.integer_types): type_id = CITypeCache.get(type_id).id attrs = db.session.query( PreferenceShowAttributes, CITypeAttribute.order).join( CITypeAttribute, CITypeAttribute.attr_id == PreferenceShowAttributes.attr_id ).filter(PreferenceShowAttributes.uid == g.user.uid).filter( PreferenceShowAttributes.type_id == type_id).filter( PreferenceShowAttributes.deleted.is_(False)).filter( CITypeAttribute.deleted.is_(False)).filter( CITypeAttribute.type_id == type_id).order_by( CITypeAttribute.order).all() result = [i.PreferenceShowAttributes.attr.to_dict() for i in attrs] is_subscribed = True if not attrs: attrs = db.session.query(CITypeAttribute).filter( CITypeAttribute.type_id == type_id).filter( CITypeAttribute.deleted.is_(False)).filter( CITypeAttribute.default_show.is_(True)).order_by( CITypeAttribute.order) result = [i.attr.to_dict() for i in attrs] is_subscribed = False for i in result: if i["is_choice"]: i.update( dict(choice_value=AttributeManager.get_choice_values( i["id"], i["value_type"]))) return is_subscribed, result
def get_ci_by_id_from_db(ci_id, ret_key=RetKey.NAME, fields=None, need_children=True, use_master=False): """ :param ci_id: :param ret_key: name, id or alias :param fields: list :param need_children: :param use_master: whether to use master db :return: """ ci = CI.get_by_id(ci_id) or abort(404, "CI <{0}> is not existed".format(ci_id)) res = dict() if need_children: children = CIRelationManager.get_children(ci_id, ret_key=ret_key) # one floor res.update(children) ci_type = CITypeCache.get(ci.type_id) res["ci_type"] = ci_type.name fields = CITypeAttributeManager.get_attr_names_by_type_id(ci.type_id) if not fields else fields unique_key = AttributeCache.get(ci_type.unique_id) _res = AttributeValueManager().get_attr_values(fields, ci_id, ret_key=ret_key, unique_key=unique_key, use_master=use_master) res.update(_res) res['type_id'] = ci_type.id res['ci_id'] = ci_id return res
def _query_wrap_for_device(self, query_sql, **kwargs): _type = kwargs.pop("_type", False) or kwargs.pop( "type", False) or kwargs.pop("ci_type", False) if _type: ci_type = CITypeCache.get(_type) if ci_type is None: return query_sql = query_sql.filter(CI.type_id == ci_type.id) for k, v in kwargs.items(): attr = AttributeCache.get(k) if attr is None: continue value_table = TableMap(attr_name=k).table ci_table = query_sql.subquery() query_sql = db.session.query(ci_table.c.id).join( value_table, value_table.ci_id == ci_table.c.id).filter( value_table.attr_id == attr.id).filter( ci_table.deleted.is_(False)).filter( value_table.value.ilike(v.replace("*", "%"))) # current_app.logger.debug(query_sql) sort_by = kwargs.pop("sort", "") if sort_by: query_sql = self._sort_handler(sort_by, query_sql) return query_sql
def get_ci_by_id(cls, ci_id, ret_key=RetKey.NAME, fields=None, need_children=True): """ :param ci_id: :param ret_key: name, id, or alias :param fields: attribute list :param need_children: :return: """ ci = CI.get_by_id(ci_id) or abort( 404, "CI <{0}> is not existed".format(ci_id)) res = dict() if need_children: children = CIRelationManager.get_children( ci_id, ret_key=ret_key) # one floor res.update(children) ci_type = CITypeCache.get(ci.type_id) res["ci_type"] = ci_type.name res.update( cls.get_cis_by_ids([str(ci_id)], fields=fields, ret_key=ret_key)) res['_type'] = ci_type.id res['_id'] = ci_id return res
def get_types(instance=False, tree=False): types = db.session.query(PreferenceShowAttributes.type_id).filter( PreferenceShowAttributes.uid == g.user.uid).filter( PreferenceShowAttributes.deleted.is_(False)).group_by(PreferenceShowAttributes.type_id).all() \ if instance else [] tree_types = PreferenceTreeView.get_by(uid=g.user.uid, to_dict=False) if tree else [] type_ids = list(set([i.type_id for i in types + tree_types])) return [CITypeCache.get(type_id).to_dict() for type_id in type_ids]
def _wrap_relation_type_dict(type_id, relation_inst): ci_type_dict = CITypeCache.get(type_id).to_dict() ci_type_dict["ctr_id"] = relation_inst.id ci_type_dict[ "attributes"] = CITypeAttributeManager.get_attributes_by_type_id( ci_type_dict["id"]) ci_type_dict["relation_type"] = relation_inst.relation_type.name return ci_type_dict
def get_tree_view(): res = PreferenceTreeView.get_by(uid=g.user.uid, to_dict=True) for item in res: if item["levels"]: item.update(CITypeCache.get(item['type_id']).to_dict()) item.update(dict(levels=[AttributeCache.get(l).to_dict() for l in item["levels"].split(",") if AttributeCache.get(l)])) return res
def _get_cis_from_db(ci_ids, ret_key=RetKey.NAME, fields=None, value_tables=None): if not fields: filter_fields_sql = "" else: _fields = list() for field in fields: attr = AttributeCache.get(field) if attr is not None: _fields.append(str(attr.id)) filter_fields_sql = "WHERE A.attr_id in ({0})".format( ",".join(_fields)) ci_ids = ",".join(ci_ids) if value_tables is None: value_tables = type_map["table_name"].values() value_sql = " UNION ".join([ QUERY_CIS_BY_VALUE_TABLE.format(value_table, ci_ids) for value_table in value_tables ]) query_sql = QUERY_CIS_BY_IDS.format(filter_fields_sql, value_sql) # current_app.logger.debug(query_sql) cis = db.session.execute(query_sql).fetchall() ci_set = set() res = list() ci_dict = dict() for ci_id, type_id, attr_id, attr_name, attr_alias, value, value_type, is_list in cis: if ci_id not in ci_set: ci_dict = dict() ci_type = CITypeCache.get(type_id) ci_dict["_id"] = ci_id ci_dict["_type"] = type_id ci_dict["ci_type"] = ci_type.name ci_dict["ci_type_alias"] = ci_type.alias ci_set.add(ci_id) res.append(ci_dict) if ret_key == RetKey.NAME: attr_key = attr_name elif ret_key == RetKey.ALIAS: attr_key = attr_alias elif ret_key == RetKey.ID: attr_key = attr_id else: return abort(400, "invalid ret key") value = type_map["serialize2"][value_type](value) if is_list: ci_dict.setdefault(attr_key, []).append(value) else: ci_dict[attr_key] = value return res
def update(cls, type_id, **kwargs): ci_type = cls.check_is_existed(type_id) unique_key = kwargs.pop("unique_key", None) unique_key = AttributeCache.get(unique_key) if unique_key is not None: kwargs["unique_id"] = unique_key.id type_attr = CITypeAttribute.get_by(type_id=type_id, attr_id=unique_key.id, first=True, to_dict=False) if type_attr is None: CITypeAttributeManager.add(type_id, [unique_key.id], is_required=True) ci_type.update(**kwargs) CITypeCache.clean(type_id) return type_id
def add(cls, **kwargs): unique_key = kwargs.pop("unique_key", None) unique_key = AttributeCache.get(unique_key) or abort( 404, "Unique key is not defined") CIType.get_by(name=kwargs['name']) and abort( 404, "CIType <{0}> is already existed".format(kwargs.get("name"))) kwargs["alias"] = kwargs["name"] if not kwargs.get( "alias") else kwargs["alias"] kwargs["unique_id"] = unique_key.id ci_type = CIType.create(**kwargs) CITypeAttributeManager.add(ci_type.id, [unique_key.id], is_required=True) CITypeCache.clean(ci_type.name) return ci_type.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 get(self): page = get_page(request.values.get("page", 1)) ci_type = request.values.get("ci_type", "").strip() try: type_id = CITypeCache.get(ci_type).type_id except AttributeError: return self.jsonify(numfound=0, result=[]) agent_status = request.values.get("agent_status") if agent_status: agent_status = int(agent_status) numfound, result = CIManager.get_heartbeat(page, type_id, agent_status=agent_status) return self.jsonify(numfound=numfound, result=result)
def get_children(cls, ci_id, ret_key=RetKey.NAME): second_cis = CIRelation.get_by(first_ci_id=ci_id, to_dict=False) second_ci_ids = (second_ci.second_ci_id for second_ci in second_cis) ci_type2ci_ids = dict() for ci_id in second_ci_ids: type_id = CI.get_by_id(ci_id).type_id ci_type2ci_ids.setdefault(type_id, []).append(ci_id) res = {} for type_id in ci_type2ci_ids: ci_type = CITypeCache.get(type_id) children = CIManager.get_cis_by_ids(list(map(str, ci_type2ci_ids[type_id])), ret_key=ret_key) res[ci_type.name] = children return res
def get(need_other=None): groups = CITypeGroup.get_by() group_types = set() for group in groups: for t in sorted(CITypeGroupItem.get_by(group_id=group['id']), key=lambda x: x['order']): group.setdefault("ci_types", []).append(CITypeCache.get(t['type_id']).to_dict()) group_types.add(t["type_id"]) if need_other: ci_types = CITypeManager.get_ci_types() other_types = dict(ci_types=[ci_type for ci_type in ci_types if ci_type["id"] not in group_types]) groups.append(other_types) return groups
def _type_query_handler(self, v): new_v = v[1:-1].split(";") if v.startswith("(") and v.endswith(")") else [v] for _v in new_v: ci_type = CITypeCache.get(_v) if ci_type is not None: self.type_id_list.append(str(ci_type.id)) if self.type_id_list: type_ids = ",".join(self.type_id_list) _query_sql = QUERY_CI_BY_TYPE.format(type_ids) if self.only_type_query: return _query_sql else: return "" return ""
def check_is_existed(key): return CITypeCache.get(key) or abort( 404, "CIType <{0}> is not existed".format(key))
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])
def query(_type): ci_type = CITypeCache.get(_type) or abort( 404, "CIType <{0}> is not found".format(_type)) return ci_type.to_dict()
def get_type_name(ci_id): ci = CI.get_by_id(ci_id) or abort( 404, "CI <{0}> is not existed".format(ci_id)) return CITypeCache.get(ci.type_id).name
def get_name_by_id(type_id): return CITypeCache.get(type_id).name
def check_is_existed(key): ci_type = CITypeCache.get(key) or abort( 404, "CIType <{0}> is not existed".format(key)) return CIType.get_by_id(ci_type.id)
class CIView(APIView): url_prefix = ("/ci/<int:ci_id>", "/ci") def get(self, ci_id): fields = handle_arg_list(request.values.get("fields", "")) ret_key = request.values.get("ret_key", RetKey.NAME) if ret_key not in (RetKey.NAME, RetKey.ALIAS, RetKey.ID): ret_key = RetKey.NAME manager = CIManager() ci = manager.get_ci_by_id_from_db(ci_id, ret_key=ret_key, fields=fields) return self.jsonify(ci_id=ci_id, ci=ci) @staticmethod def _wrap_ci_dict(): ci_dict = dict() for k, v in request.values.items(): if k != "ci_type" and not k.startswith("_"): ci_dict[k] = v.strip() if isinstance(v, six.string_types) else v return ci_dict @has_perm_from_args("ci_type", ResourceTypeEnum.CI, PermEnum.ADD, lambda x: CITypeCache.get(x).name) def post(self): ci_type = request.values.get("ci_type") _no_attribute_policy = request.values.get("_no_attribute_policy", ExistPolicy.IGNORE) ci_dict = self._wrap_ci_dict() manager = CIManager() current_app.logger.debug(ci_dict) ci_id = manager.add(ci_type, exist_policy=ExistPolicy.REJECT, _no_attribute_policy=_no_attribute_policy, **ci_dict) return self.jsonify(ci_id=ci_id) @has_perm_from_args("ci_id", ResourceTypeEnum.CI, PermEnum.UPDATE, CIManager.get_type_name) def put(self, ci_id=None): args = request.values ci_type = args.get("ci_type") _no_attribute_policy = args.get("_no_attribute_policy", ExistPolicy.IGNORE) ci_dict = self._wrap_ci_dict() manager = CIManager() if ci_id is not None: manager.update(ci_id, **ci_dict) else: ci_id = manager.add(ci_type, exist_policy=ExistPolicy.REPLACE, _no_attribute_policy=_no_attribute_policy, **ci_dict) return self.jsonify(ci_id=ci_id) @has_perm_from_args("ci_id", ResourceTypeEnum.CI, PermEnum.DELETE, CIManager.get_type_name) def delete(self, ci_id): manager = CIManager() manager.delete(ci_id) return self.jsonify(message="ok")