Пример #1
0
    def delete(self, ci_id):
        ci = db.session.query(CI).filter(CI.ci_id == ci_id).first()
        if ci is not None:
            attrs = db.session.query(CITypeAttribute.attr_id).filter(
                CITypeAttribute.type_id == ci.type_id).all()
            attr_names = []
            for attr in attrs:
                attr_names.append(CIAttributeCache.get(attr.attr_id).attr_name)
            attr_names = set(attr_names)
            for attr_name in attr_names:
                Table = TableMap(attr_name=attr_name).table
                db.session.query(Table).filter(Table.ci_id == ci_id).delete()
            db.session.query(CIRelation).filter(
                CIRelation.first_ci_id == ci_id).delete()
            db.session.query(CIRelation).filter(
                CIRelation.second_ci_id == ci_id).delete()
            db.session.query(CIAttributeHistory).filter(
                CIAttributeHistory.ci_id == ci_id).delete()

            db.session.flush()
            db.session.delete(ci)
            try:
                db.session.commit()
            except Exception as e:
                db.session.rollback()
                current_app.logger.error("delete CI error, {0}".format(str(e)))
                return abort(500, "delete CI error, {0}".format(str(e)))
            # TODO: write history
            ci_delete.apply_async([ci.ci_id], queue="cmdb_async")
            return ci_id
        return abort(404, "CI {0} not found".format(ci_id))
Пример #2
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.type_id)

        for k, v in kwargs.iteritems():
            attr = CIAttributeCache.get(k)
            if attr is None:
                continue
            Table = TableMap(attr_name=k).table
            CI_table = query_sql.subquery()
            query_sql = db.session.query(CI_table.c.ci_id).join(
                Table, Table.ci_id == CI_table.c.ci_id).filter(
                    Table.attr_id == attr.attr_id).filter(
                        Table.value.ilike(v.replace("*", "%")))

        current_app.logger.debug(query_sql)
        sort_by = kwargs.pop("sort", False)
        if sort_by:
            query_sql = self._sort_handler(sort_by, query_sql)
        return query_sql
Пример #3
0
 def in_query_handler(self, attr, v):
     new_v = v[1:-1].split(";")
     table_name = TableMap(attr_name=attr.attr_name).table_name
     _query_sql = QUERY_CI_BY_ATTR_NAME.format(
         table_name, attr.attr_id, " OR {0}.value ".format(table_name).join(
             ['LIKE "{0}"'.format(_v.replace("*", "%")) for _v in new_v]))
     return _query_sql
Пример #4
0
 def range_query_handler(self, attr, v):
     start, end = [x.strip() for x in v[1:-1].split("_TO_")]
     table_name = TableMap(attr_name=attr.attr_name).table_name
     _query_sql = QUERY_CI_BY_ATTR_NAME.format(
         table_name, attr.attr_id, "BETWEEN '{0}' AND '{1}'".format(
             start.replace("*", "%"), end.replace("*", "%")))
     return _query_sql
Пример #5
0
 def ci_is_exist(self, ci_type, unique_key, unique):
     table = TableMap(attr_name=unique_key.attr_name).table
     unique = db.session.query(table).filter(
         table.attr_id == unique_key.attr_id).filter(
             table.value == unique).first()
     if unique:
         return db.session.query(CI).filter(
             CI.ci_id == unique.ci_id).first()
Пример #6
0
 def comparison_query_handler(self, attr, v):
     table_name = TableMap(attr_name=attr.attr_name).table_name
     if (v.startswith("<") and not v.startswith("<=")) or \
             (v.startswith(">") and not v.startswith(">=")):
         _query_sql = QUERY_CI_BY_ATTR_NAME.format(
             table_name, attr.attr_id,
             "{0} '{1}'".format(v[0], v[1:].replace("*", "%")))
     elif v.startswith(">=") or v.startswith("<="):
         _query_sql = QUERY_CI_BY_ATTR_NAME.format(
             table_name, attr.attr_id,
             "{0} '{1}'".format(v[:2], v[2:].replace("*", "%")))
     return _query_sql
Пример #7
0
 def _get_attr_values(self,
                      fields,
                      ci_id,
                      ret_key="name",
                      uniq_key=None,
                      use_master=False):
     res = dict()
     for field in fields:
         attr = CIAttributeCache.get(field)
         if not attr:
             current_app.logger.warn('attribute %s not found' % field)
             return res
         table = TableMap(attr_name=attr.attr_name).table
         if use_master:
             rs = db.session().using_bind("master").query(
                 table.value).filter_by(ci_id=ci_id).filter_by(
                     attr_id=attr.attr_id)
         else:
             rs = db.session.query(table.value).filter_by(
                 ci_id=ci_id).filter_by(attr_id=attr.attr_id)
         field_name = getattr(attr, "attr_{0}".format(ret_key))
         try:
             if attr.is_multivalue:
                 if attr.value_type == 'datetime':
                     res[field_name] = [
                         datetime.datetime.strftime(x.value,
                                                    '%Y-%m-%d %H:%M:%S')
                         for x in rs.all()
                     ]
                 else:
                     res[field_name] = [x.value for x in rs.all()]
             else:
                 x = rs.first()
                 if x:
                     if attr.value_type == 'datetime':
                         res[field_name] = datetime.datetime.strftime(
                             rs.first().value, '%Y-%m-%d %H:%M:%S')
                     else:
                         res[field_name] = rs.first().value
                 else:
                     res[field_name] = None
         except AttributeError as e:
             current_app.logger.warn("get ci by id error, {0}".format(e))
             if attr.is_multivalue:
                 res[field_name] = list()
             else:
                 res[field_name] = ""
         if uniq_key is not None and attr.attr_id == uniq_key.attr_id \
                 and rs.first() is not None:
             res['unique'] = uniq_key.attr_name
     return res
Пример #8
0
 def facet_build(self):
     facet = {}
     for f in self.facet_field:
         k, field_type, _, attr = self.attr_name_proc(f)
         if k:
             table_name = TableMap(attr_name=k).table_name
             query_sql = FACET_QUERY.format(
                 table_name, self.query_sql, attr.attr_id)
             result = db.session.execute(query_sql).fetchall()
             facet[k] = result
     facet_result = dict()
     for k, v in facet.items():
         if not k.startswith('_'):
             a = getattr(CIAttributeCache.get(k), "attr_%s" % self.ret_key)
             facet_result[a] = list()
             for f in v:
                 if f[1] != 0:
                     facet_result[a].append((f[0], f[1], a))
     return facet_result
Пример #9
0
    def add_heartbeat(self, ci_type, unique):
        ci_type = CITypeCache.get(ci_type)
        if not ci_type:
            return 'error'
        uniq_key = CIAttributeCache.get(ci_type.uniq_id)
        Table = TableMap(attr_name=uniq_key.attr_name).table
        ci_id = db.session.query(
            Table.ci_id).filter(Table.attr_id == uniq_key.attr_id).filter(
                Table.value == unique).first()
        if ci_id is None:
            return 'error'
        ci = db.session.query(CI).filter(CI.ci_id == ci_id.ci_id).first()
        if ci is None:
            return 'error'

        ci.heartbeat = datetime.datetime.now()

        db.session.add(ci)
        db.session.commit()
        return "ok"
Пример #10
0
    def _sort_handler(self, sort_by, query_sql):

        if sort_by.startswith("+"):
            sort_type = "asc"
            sort_by = sort_by[1:]
        elif sort_by.startswith("-"):
            sort_type = "desc"
            sort_by = sort_by[1:]
        else:
            sort_type = "asc"
        attr = CIAttributeCache.get(sort_by)
        if attr is None:
            return query_sql

        attr_id = attr.attr_id
        Table = TableMap(attr_name=sort_by).table

        CI_table = query_sql.subquery()
        query_sql = db.session.query(CI_table.c.ci_id, Table.value).join(
            Table, Table.ci_id == CI_table.c.ci_id).filter(
                Table.attr_id == attr_id).order_by(
                    getattr(Table.value, sort_type)())

        return query_sql
Пример #11
0
    def query_build_raw(self):
        query_sql, alias, tor = "", "A", ["&"]
        is_first = True
        only_type_query = False
        queries = self.orig_query.split(",")
        queries = filter(lambda x: x != "", queries)
        for q in queries:
            if q.startswith("_type"):
                queries.remove(q)
                queries.insert(0, q)
                if len(queries) == 1 or queries[1].startswith("-") or \
                        queries[1].startswith("~"):
                    only_type_query = True
                break
        current_app.logger.debug(queries)
        special = True
        for q in queries:
            _query_sql = ""
            if ":" in q:
                k = q.split(":")[0].strip()
                v = ":".join(q.split(":")[1:]).strip()
                current_app.logger.info(v)
                field, field_type, tor, attr = self.attr_name_proc(k)
                if field == "_type":
                    _query_sql = self.type_query_handler(v, only_type_query)
                    current_app.logger.debug(_query_sql)
                elif field == "_id":  # exclude all others
                    _ci_ids = [str(v)]
                    ci = db.session.query(
                        CI.ci_id).filter(CI.ci_id == int(v)).first()
                    if ci is not None:
                        return 1, _ci_ids
                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.attr_name).table_name
                        _query_sql = QUERY_CI_BY_ATTR_NAME.format(
                            table_name, attr.attr_id,
                            'LIKE "{0}"'.format(v.replace("*", "%")))
                else:
                    return 0, []
            elif q:
                return 0, []

            if is_first and _query_sql and not only_type_query:
                query_sql = "SELECT * FROM ({0}) AS {1}".format(
                    _query_sql, alias)
                is_first = False
                alias += "A"
            elif only_type_query and special:
                is_first = False
                special = False
                query_sql = _query_sql
            elif _query_sql:
                query_sql = self._wrap_sql(tor, alias, _query_sql, query_sql)
                alias += "AA"

        _start = time.time()
        if query_sql:
            self.query_sql = query_sql
            current_app.logger.debug(query_sql)
            numfound, res = self._execute_sql(query_sql, only_type_query)
            current_app.logger.info("query ci ids is: {0}".format(time.time() -
                                                                  _start))
            return numfound, [_res[0] for _res in res]
        return 0, []
Пример #12
0
    def sort_query_handler(self, field, query_sql, only_type_query):
        if field is None:
            field = ""
        if field.startswith("+"):
            field = field[1:]
            sort_type = "ASC"
        elif field.startswith("-"):
            field = field[1:]
            sort_type = "DESC"
        else:
            sort_type = "ASC"

        if field in ("_id", "ci_id") or not field:
            if only_type_query:
                return """SELECT SQL_CALC_FOUND_ROWS DISTINCT B.ci_id
                FROM ({0}) AS B {1}""".format(
                    query_sql, "ORDER BY B.ci_id {1} LIMIT {0:d}, {2};".format(
                        (self.page - 1) * self.count, sort_type, self.count))
            elif self.type_id_list:
                self.query_sql = """SELECT B.ci_id
                FROM ({0}) AS B {1}""".format(
                    query_sql, "INNER JOIN cis on cis.ci_id=B.ci_id "
                    "WHERE cis.type_id in ({0}) ".format(",".join(
                        self.type_id_list)))
                return """SELECT SQL_CALC_FOUND_ROWS DISTINCT B.ci_id
                FROM ({0}) AS B {1}""".format(
                    query_sql, "INNER JOIN cis on cis.ci_id=B.ci_id "
                    "WHERE cis.type_id in ({3}) "
                    "ORDER BY B.ci_id {1} LIMIT {0:d}, {2};".format(
                        (self.page - 1) * self.count, sort_type, self.count,
                        ",".join(self.type_id_list)))
            else:
                self.query_sql = """SELECT B.ci_id
                FROM ({0}) AS B {1}""".format(
                    query_sql, "INNER JOIN cis on cis.ci_id=B.ci_id ")
                return """SELECT SQL_CALC_FOUND_ROWS DISTINCT B.ci_id
                FROM ({0}) AS B {1}""".format(
                    query_sql, "INNER JOIN cis on cis.ci_id=B.ci_id "
                    "ORDER BY B.ci_id {1} LIMIT {0:d}, {2};".format(
                        (self.page - 1) * self.count, sort_type, self.count))
        else:
            attr = CIAttributeCache.get(field)
            attr_id = attr.attr_id

            table_name = TableMap(attr_name=attr.attr_name).table_name
            _v_query_sql = """SELECT {0}.ci_id, {1}.value FROM
                ({2}) AS {0} INNER JOIN {1} ON {1}.ci_id = {0}.ci_id
                WHERE {1}.attr_id = {3}""".format("ALIAS", table_name,
                                                  query_sql, attr_id)
            new_table = _v_query_sql
            if only_type_query:
                return "SELECT SQL_CALC_FOUND_ROWS DISTINCT C.ci_id " \
                       "FROM ({0}) AS C " \
                       "ORDER BY C.value {2} " \
                       "LIMIT {1:d}, {3};".format(new_table,
                                                  (self.page - 1) * self.count,
                                                  sort_type, self.count)
            elif self.type_id_list:
                self.query_sql = """SELECT C.ci_id
                    FROM ({0}) AS C
                    INNER JOIN cis on cis.ci_id=C.ci_id
                    WHERE cis.type_id in ({1})""".format(
                    new_table, ",".join(self.type_id_list))
                return """SELECT SQL_CALC_FOUND_ROWS DISTINCT C.ci_id
                    FROM ({0}) AS C
                    INNER JOIN cis on cis.ci_id=C.ci_id
                    WHERE cis.type_id in ({4})
                    ORDER BY C.value {2}
                    LIMIT {1:d}, {3};""".format(new_table,
                                                (self.page - 1) * self.count,
                                                sort_type, self.count,
                                                ",".join(self.type_id_list))
            else:
                return """SELECT SQL_CALC_FOUND_ROWS DISTINCT C.ci_id
                    FROM ({0}) AS C
                    ORDER BY C.value {2}
                    LIMIT {1:d}, {3};""".format(new_table,
                                                (self.page - 1) * self.count,
                                                sort_type, self.count)
Пример #13
0
    def add_attr_value(self,
                       key,
                       value,
                       ci_id,
                       ci_type,
                       _no_attribute_policy="ignore",
                       ci_existed=False):
        """key is one of attr_id, attr_name and attr_alias
        """
        attr = self._get_attr(key)
        if attr is None:
            if _no_attribute_policy == 'ignore':
                return True, None
            if _no_attribute_policy == 'reject':
                return False, 'attribute {0} not exist'.format(key)
        table, old_value, old_value_table = TableMap(
            attr_name=attr.attr_name).table, None, None
        if ci_existed:
            old_value_table = db.session.query(table).filter(
                table.attr_id == attr.attr_id).filter(
                    table.ci_id == ci_id).first()
            if old_value_table is not None:
                old_value = old_value_table.value
        if not value and ci_existed:
            db.session.query(table).filter(
                table.attr_id == attr.attr_id).filter(
                    table.ci_id == ci_id).delete()
            if old_value:
                return True, (attr.attr_id, "delete", old_value, None)
            else:
                return True, None
        elif not value:
            return True, None
        if not attr.is_multivalue:
            ret, res = self._validate(attr, value, table, ci_id)
            if not ret:
                return False, res
            value_table = table()
            if ci_existed:  # for history
                old = db.session.query(table).filter(
                    table.attr_id == attr.attr_id).filter(
                        table.value == value).filter(
                            table.ci_id == ci_id).first()
                if old is not None:
                    return True, None
                elif old_value_table:
                    value_table = old_value_table
            value_table.ci_id = ci_id
            value_table.attr_id = attr.attr_id
            value_table.value = res
            db.session.add(value_table)
        elif attr.is_multivalue:
            if ci_existed:
                db.session.query(table).filter(
                    table.attr_id == attr.attr_id).filter(
                        table.ci_id == ci_id).delete()

            for v in value.strip().split(","):
                ret, res = self._validate(attr, v, table, ci_id)
                if not ret:
                    return False, res
                value_table = table()
                value_table.ci_id = ci_id
                value_table.attr_id = attr.attr_id
                value_table.value = res
                db.session.add(value_table)
        try:
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            current_app.logger.error(
                "add attribute value is error, {0}".format(str(e)))
            return False, "add attribute value is error, {0}".format(str(e))
        if ci_existed:
            if old_value != value:
                return True, (attr.attr_id, "update", old_value, value)
            else:
                return True, None
        return True, (attr.attr_id, "add", None, value)