Beispiel #1
0
    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
Beispiel #2
0
    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)
Beispiel #3
0
    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])
Beispiel #4
0
 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)
Beispiel #5
0
    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)
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
    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
Beispiel #9
0
    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
Beispiel #10
0
 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]
Beispiel #11
0
 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
Beispiel #12
0
    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
Beispiel #13
0
    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
Beispiel #14
0
    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
Beispiel #15
0
    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
Beispiel #16
0
    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)
Beispiel #17
0
    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)
Beispiel #18
0
    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
Beispiel #19
0
    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
Beispiel #20
0
    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 ""
Beispiel #21
0
 def check_is_existed(key):
     return CITypeCache.get(key) or abort(
         404, "CIType <{0}> is not existed".format(key))
Beispiel #22
0
    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])
Beispiel #23
0
 def query(_type):
     ci_type = CITypeCache.get(_type) or abort(
         404, "CIType <{0}> is not found".format(_type))
     return ci_type.to_dict()
Beispiel #24
0
 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
Beispiel #25
0
 def get_name_by_id(type_id):
     return CITypeCache.get(type_id).name
Beispiel #26
0
    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)
Beispiel #27
0
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")