예제 #1
0
    def update_unique_value(ci_id, unique_name, unique_value):
        CI.get_by_id(ci_id) or abort(404,
                                     "CI <{0}> is not found".format(ci_id))

        AttributeValueManager().create_or_update_attr_value(
            unique_name, unique_value, ci_id)

        ci_cache.apply_async([ci_id], queue=CMDB_QUEUE)
예제 #2
0
    def add(cls,
            ci_type_name,
            exist_policy=ExistPolicy.REPLACE,
            _no_attribute_policy=ExistPolicy.IGNORE,
            **ci_dict):
        """
        
        :param ci_type_name: 
        :param exist_policy: replace or reject or need
        :param _no_attribute_policy: ignore or reject
        :param ci_dict: 
        :return: 
        """

        ci_type = CITypeManager.check_is_existed(ci_type_name)

        unique_key = AttributeCache.get(ci_type.unique_id) or abort(
            400, 'illegality unique attribute')

        unique_value = ci_dict.get(unique_key.name)
        unique_value = unique_value or ci_dict.get(unique_key.alias)
        unique_value = unique_value or ci_dict.get(unique_key.id)
        unique_value = unique_value or abort(
            400, '{0} missing'.format(unique_key.name))

        existed = cls.ci_is_exist(unique_key, unique_value)
        if existed is not None:
            if exist_policy == ExistPolicy.REJECT:
                return abort(400, 'CI is already existed')
            if existed.type_id != ci_type.id:
                existed.update(type_id=ci_type.id)
            ci = existed
        else:
            if exist_policy == ExistPolicy.NEED:
                return abort(404,
                             'CI <{0}> does not exist'.format(unique_value))
            ci = CI.create(type_id=ci_type.id)

        ci_type_attrs_name = [
            attr["name"] for attr in
            CITypeAttributeManager().get_attributes_by_type_id(ci_type.id)
        ]
        value_manager = AttributeValueManager()
        for p, v in ci_dict.items():
            if p not in ci_type_attrs_name:
                current_app.logger.warning(
                    'ci_type: {0} not has attribute {1}, please check!'.format(
                        ci_type_name, p))
                continue
            try:
                value_manager.create_or_update_attr_value(
                    p, v, ci, _no_attribute_policy)
            except BadRequest as e:
                if existed is None:
                    cls.delete(ci.id)
                raise e

        ci_cache.apply_async([ci.id], queue=CMDB_QUEUE)

        return ci.id
예제 #3
0
파일: ci.py 프로젝트: xuweiwei2011/cmdb-1
    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
예제 #4
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
예제 #5
0
    def delete(ci_id):
        ci = CI.get_by_id(ci_id) or abort(
            404, "CI <{0}> is not found".format(ci_id))

        attrs = CITypeAttribute.get_by(type_id=ci.type_id, to_dict=False)
        attr_names = set(
            [AttributeCache.get(attr.attr_id).name for attr in attrs])
        for attr_name in attr_names:
            value_table = TableMap(attr_name=attr_name).table
            for item in value_table.get_by(ci_id=ci_id, to_dict=False):
                item.delete()

        for item in CIRelation.get_by(first_ci_id=ci_id, to_dict=False):
            item.delete()

        for item in CIRelation.get_by(second_ci_id=ci_id, to_dict=False):
            item.delete()

        ci.delete()  # TODO: soft delete

        AttributeHistoryManger.add(ci_id,
                                   [(None, OperateType.DELETE, None, None)])

        ci_delete.apply_async([ci.id], queue=CMDB_QUEUE)

        return ci_id
예제 #6
0
    def delete(cls, type_id, attr_ids=None):
        """
        delete attributes from CIType
        :param type_id: 
        :param attr_ids: list
        :return: 
        """
        from api.tasks.cmdb import ci_cache

        cls._check(type_id, attr_ids)

        for attr_id in attr_ids:
            existed = CITypeAttribute.get_by(type_id=type_id,
                                             attr_id=attr_id,
                                             first=True,
                                             to_dict=False)
            if existed is not None:
                existed.soft_delete()

                for ci in CI.get_by(type_id=type_id, to_dict=False):
                    AttributeValueManager.delete_attr_value(attr_id, ci.id)

                    ci_cache.apply_async([ci.id], queue=CMDB_QUEUE)

                CITypeAttributeCache.clean(type_id, attr_id)

        CITypeAttributesCache.clean(type_id)
예제 #7
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)
예제 #8
0
    def search(self):
        ids = [self.root_id
               ] if not isinstance(self.root_id, list) else self.root_id
        cis = [
            CI.get_by_id(_id)
            or abort(404, "CI <{0}> does not exist".format(_id)) for _id in ids
        ]

        merge_ids = []
        for level in self.level:
            ids = [self.root_id
                   ] if not isinstance(self.root_id, list) else self.root_id
            for _ in range(0, level):
                _tmp = list(
                    map(
                        lambda x: list(json.loads(x).keys()),
                        filter(lambda x: x is not None,
                               rd.get(ids, REDIS_PREFIX_CI_RELATION) or [])))
                ids = [j for i in _tmp for j in i]

            merge_ids.extend(ids)

        if not self.orig_query or ("_type:" not in self.orig_query
                                   and "type_id:" not in self.orig_query
                                   and "ci_type:" not in self.orig_query):
            type_ids = []
            for level in self.level:
                for ci in cis:
                    type_ids.extend(
                        CITypeRelationManager.get_child_type_ids(
                            ci.type_id, level))
            type_ids = list(set(type_ids))
            if self.orig_query:
                self.orig_query = "_type:({0}),{1}".format(
                    ";".join(list(map(str, type_ids))), self.orig_query)
            else:
                self.orig_query = "_type:({0})".format(";".join(
                    list(map(str, type_ids))))

        if not merge_ids:
            # cis, counter, total, self.page, numfound, facet_
            return [], {}, 0, self.page, 0, {}

        if current_app.config.get("USE_ES"):
            return SearchFromES(self.orig_query,
                                fl=self.fl,
                                facet_field=self.facet_field,
                                page=self.page,
                                count=self.count,
                                sort=self.sort,
                                ci_ids=merge_ids).search()
        else:
            return SearchFromDB(self.orig_query,
                                fl=self.fl,
                                facet_field=self.facet_field,
                                page=self.page,
                                count=self.count,
                                sort=self.sort,
                                ci_ids=merge_ids).search()
예제 #9
0
def init_cache():
    db.session.remove()

    if current_app.config.get("USE_ES"):
        from api.extensions import es
        from api.models.cmdb import Attribute
        from api.lib.cmdb.utils import ValueTypeMap
        attributes = Attribute.get_by(to_dict=False)
        for attr in attributes:
            other = dict()
            other['index'] = True if attr.is_index else False
            if attr.value_type == ValueTypeEnum.TEXT:
                other['analyzer'] = 'ik_max_word'
                other['search_analyzer'] = 'ik_smart'
                if attr.is_index:
                    other["fields"] = {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
            try:
                es.update_mapping(attr.name,
                                  ValueTypeMap.es_type[attr.value_type], other)
            except Exception as e:
                print(e)

    cis = CI.get_by(to_dict=False)
    for ci in cis:
        if current_app.config.get("USE_ES"):
            res = es.get_index_id(ci.id)
            if res:
                continue
        else:
            res = rd.get([ci.id], REDIS_PREFIX_CI)
            if res and list(filter(lambda x: x, res)):
                continue

        m = api.lib.cmdb.ci.CIManager()
        ci_dict = m.get_ci_by_id_from_db(ci.id,
                                         need_children=False,
                                         use_master=False)

        if current_app.config.get("USE_ES"):
            es.create(ci_dict)
        else:
            rd.create_or_update({ci.id: json.dumps(ci_dict)}, REDIS_PREFIX_CI)

    ci_relations = CIRelation.get_by(to_dict=False)
    relations = dict()
    for cr in ci_relations:
        relations.setdefault(cr.first_ci_id, {}).update(
            {cr.second_ci_id: cr.second_ci.type_id})
    for i in relations:
        relations[i] = json.dumps(relations[i])
    if relations:
        rd.create_or_update(relations, REDIS_PREFIX_CI_RELATION)

    db.session.remove()
예제 #10
0
파일: search.py 프로젝트: shuke163/cmdb
    def __query_build_by_field(self, queries):
        query_sql, alias, operator = "", "A", "&"
        is_first, only_type_query_special = True, True

        for q in queries:
            _query_sql = ""
            if ":" in q:
                k = q.split(":")[0].strip()
                v = ":".join(q.split(":")[1:]).strip()
                current_app.logger.debug(v)
                field, field_type, operator, attr = self._attr_name_proc(k)
                if field == "_type":
                    _query_sql = self._type_query_handler(v)
                    current_app.logger.debug(_query_sql)
                elif field == "_id":  # exclude all others
                    ci = CI.get_by_id(v)
                    if ci is not None:
                        return 1, [str(v)]
                elif field:
                    if attr is None:
                        raise SearchError("{0} is not found".format(field))

                    # in query
                    if v.startswith("(") and v.endswith(")"):
                        _query_sql = self._in_query_handler(attr, v)
                    # range query
                    elif v.startswith("[") and v.endswith("]") and "_TO_" in v:
                        _query_sql = self._range_query_handler(attr, v)
                    # comparison query
                    elif v.startswith(">=") or v.startswith(
                            "<=") or v.startswith(">") or v.startswith("<"):
                        _query_sql = self._comparison_query_handler(attr, v)
                    else:
                        table_name = TableMap(attr_name=attr.name).table_name
                        _query_sql = QUERY_CI_BY_ATTR_NAME.format(
                            table_name, attr.id,
                            'LIKE "{0}"'.format(v.replace("*", "%")))
                else:
                    raise SearchError(
                        "argument q format invalid: {0}".format(q))
            elif q:
                raise SearchError("argument q format invalid: {0}".format(q))

            if is_first and _query_sql and not self.only_type_query:
                query_sql = "SELECT * FROM ({0}) AS {1}".format(
                    _query_sql, alias)
                is_first = False
                alias += "A"
            elif self.only_type_query and only_type_query_special:
                is_first = False
                only_type_query_special = False
                query_sql = _query_sql
            elif _query_sql:
                query_sql = self._wrap_sql(operator, alias, _query_sql,
                                           query_sql)
                alias += "AA"
        return None, query_sql
예제 #11
0
파일: ci.py 프로젝트: xuweiwei2011/cmdb-1
 def get(self, ci_id=None):
     from api.tasks.cmdb import ci_cache
     from api.lib.cmdb.const import CMDB_QUEUE
     if ci_id is not None:
         ci_cache.apply_async([ci_id], queue=CMDB_QUEUE)
     else:
         cis = CI.get_by(to_dict=False)
         for ci in cis:
             ci_cache.apply_async([ci.id], queue=CMDB_QUEUE)
     return self.jsonify(code=200)
예제 #12
0
 def ci_is_exist(unique_key, unique_value):
     """
     
     :param unique_key: is a attribute
     :param unique_value: 
     :return: 
     """
     value_table = TableMap(attr_name=unique_key.name).table
     unique = value_table.get_by(attr_id=unique_key.id,
                                 value=unique_value,
                                 to_dict=False,
                                 first=True)
     if unique:
         return CI.get_by_id(unique.ci_id)
예제 #13
0
파일: ci.py 프로젝트: xuweiwei2011/cmdb-1
    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
예제 #14
0
파일: ci.py 프로젝트: xuweiwei2011/cmdb-1
    def add_heartbeat(ci_type, unique_value):
        ci_type = CITypeManager().check_is_existed(ci_type)

        unique_key = AttributeCache.get(ci_type.unique_id)
        value_table = TableMap(attr_name=unique_key.name).table

        v = value_table.get_by(attr_id=unique_key.id,
                               value=unique_value,
                               to_dict=False,
                               first=True) \
            or abort(404, "not found")

        ci = CI.get_by_id(v.ci_id) or abort(404, "CI <{0}> is not found".format(v.ci_id))

        ci.update(heartbeat=datetime.datetime.now())
예제 #15
0
파일: ci_type.py 프로젝트: 13052020/cmdb
    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)
예제 #16
0
 def confirm_ci_existed(ci_id):
     CI.get_by_id(ci_id) or abort(404,
                                  "CI <{0}> is not existed".format(ci_id))
예제 #17
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
예제 #18
0
 def _delete_ci_by_id(ci_id):
     ci = CI.get_by_id(ci_id)
     ci.delete()  # TODO: soft delete
예제 #19
0
파일: ci.py 프로젝트: xuweiwei2011/cmdb-1
 def get(self, ci_id):
     _ci = CI.get_by_id(ci_id).to_dict()
     return self.jsonify(**_ci)