mirror of https://github.com/veops/cmdb.git
facet query fix
This commit is contained in:
parent
f515988dbd
commit
b2f0afd73d
|
@ -32,7 +32,7 @@ MODULES = (
|
||||||
(core.ci, "/api/v0.1/ci"),
|
(core.ci, "/api/v0.1/ci"),
|
||||||
(core.history, "/api/v0.1/history"),
|
(core.history, "/api/v0.1/history"),
|
||||||
(core.account, "/api/v0.1/accounts"),
|
(core.account, "/api/v0.1/accounts"),
|
||||||
# (core.special, ""),
|
(core.special, ""),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,4 +8,4 @@ from ci_relation import cirelation
|
||||||
from ci import ci
|
from ci import ci
|
||||||
from history import history
|
from history import history
|
||||||
from account import account
|
from account import account
|
||||||
# from special import special
|
from special import special
|
|
@ -102,15 +102,21 @@ def delete_attribute(attr_id=None):
|
||||||
|
|
||||||
|
|
||||||
@attribute.route("/citype/<int:type_id>", methods=["GET"])
|
@attribute.route("/citype/<int:type_id>", methods=["GET"])
|
||||||
def get_attributes_by_type(type_id=None):
|
@attribute.route("/citype/<string:type_name>", methods=["GET"])
|
||||||
|
def get_attributes_by_type(type_id=None, type_name=None):
|
||||||
manager = CITypeAttributeManager()
|
manager = CITypeAttributeManager()
|
||||||
from models.attribute import CIAttributeCache
|
from models.attribute import CIAttributeCache
|
||||||
from models.ci_type import CITypeCache
|
from models.ci_type import CITypeCache
|
||||||
|
from models.ci_type import CITypeAttributeCache
|
||||||
|
|
||||||
t = CITypeCache.get(type_id)
|
t = CITypeCache.get(type_id)
|
||||||
|
if not t:
|
||||||
|
t = CITypeCache.get(type_name)
|
||||||
if not t:
|
if not t:
|
||||||
return abort(400, "CIType {0} is not existed".format(type_id))
|
return abort(400, "CIType {0} is not existed".format(type_id))
|
||||||
|
type_id = t.type_id
|
||||||
uniq_id = t.uniq_id
|
uniq_id = t.uniq_id
|
||||||
|
CITypeAttributeCache.clean(type_id)
|
||||||
unique = CIAttributeCache.get(uniq_id).attr_name
|
unique = CIAttributeCache.get(uniq_id).attr_name
|
||||||
return jsonify(attributes=manager.get_attributes_by_type_id(type_id),
|
return jsonify(attributes=manager.get_attributes_by_type_id(type_id),
|
||||||
type_id=type_id, uniq_id=uniq_id, unique=unique)
|
type_id=type_id, uniq_id=uniq_id, unique=unique)
|
||||||
|
|
27
core/ci.py
27
core/ci.py
|
@ -16,6 +16,7 @@ from flask import abort
|
||||||
|
|
||||||
from lib.auth import auth_with_key
|
from lib.auth import auth_with_key
|
||||||
from lib.ci import CIManager
|
from lib.ci import CIManager
|
||||||
|
from lib.ci import HostNumStatis
|
||||||
from lib.search import Search
|
from lib.search import Search
|
||||||
from lib.search import SearchError
|
from lib.search import SearchError
|
||||||
from lib.utils import get_page
|
from lib.utils import get_page
|
||||||
|
@ -156,6 +157,14 @@ def update_ci():
|
||||||
return jsonify(ci_id=ci_id)
|
return jsonify(ci_id=ci_id)
|
||||||
|
|
||||||
|
|
||||||
|
@ci.route("/<int:ci_id>/unique", methods=["PUT"])
|
||||||
|
@auth_with_key
|
||||||
|
def update_ci_unique(ci_id):
|
||||||
|
m = CIManager()
|
||||||
|
m.update_unique_value(ci_id, request.values)
|
||||||
|
return jsonify(ci_id=ci_id)
|
||||||
|
|
||||||
|
|
||||||
@ci.route("/<int:ci_id>", methods=["DELETE"])
|
@ci.route("/<int:ci_id>", methods=["DELETE"])
|
||||||
@auth_with_key
|
@auth_with_key
|
||||||
def delete_ci(ci_id=None):
|
def delete_ci(ci_id=None):
|
||||||
|
@ -187,3 +196,21 @@ def get_heartbeat():
|
||||||
ci_type,
|
ci_type,
|
||||||
agent_status=agent_status)
|
agent_status=agent_status)
|
||||||
return jsonify(numfound=numfound, result=result)
|
return jsonify(numfound=numfound, result=result)
|
||||||
|
|
||||||
|
|
||||||
|
######################### just for frontend ###################################
|
||||||
|
|
||||||
|
@ci.route("/hosts/nums", methods=["GET"])
|
||||||
|
def get_hosts_nums():
|
||||||
|
ci_type = request.args.get("ci_type", "").strip()
|
||||||
|
ci_ids = request.args.get("ci_ids", "").strip()
|
||||||
|
ci_id_list = ci_ids.split(",")
|
||||||
|
ci_id_list = map(str, filter(lambda x: x != "", ci_id_list))
|
||||||
|
res = {}
|
||||||
|
if ci_type == "bu":
|
||||||
|
res = HostNumStatis().get_hosts_by_bu(ci_id_list)
|
||||||
|
elif ci_type == "product":
|
||||||
|
res = HostNumStatis().get_hosts_by_product(ci_id_list)
|
||||||
|
elif ci_type == "project":
|
||||||
|
res = HostNumStatis().get_hosts_by_project(ci_id_list)
|
||||||
|
return jsonify(hosts=res)
|
12
lib/auth.py
12
lib/auth.py
|
@ -18,10 +18,10 @@ from models.account import UserCache
|
||||||
def auth_with_key(func):
|
def auth_with_key(func):
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
if isinstance(getattr(g, 'user', None), User):
|
# if isinstance(getattr(g, 'user', None), User):
|
||||||
identity_changed.send(current_app._get_current_object(),
|
# identity_changed.send(current_app._get_current_object(),
|
||||||
identity=Identity(g.user.uid))
|
# identity=Identity(g.user.uid))
|
||||||
return func(*args, **kwargs)
|
# return func(*args, **kwargs)
|
||||||
ip = request.remote_addr
|
ip = request.remote_addr
|
||||||
if request.data:
|
if request.data:
|
||||||
request_args = dict()
|
request_args = dict()
|
||||||
|
@ -46,7 +46,7 @@ def auth_with_key(func):
|
||||||
else:
|
else:
|
||||||
identity_changed.send(current_app._get_current_object(),
|
identity_changed.send(current_app._get_current_object(),
|
||||||
identity=AnonymousIdentity())
|
identity=AnonymousIdentity())
|
||||||
return abort(400, "invalid _key and _secret")
|
return abort(401, "invalid _key and _secret")
|
||||||
|
|
||||||
path = request.path
|
path = request.path
|
||||||
|
|
||||||
|
@ -63,6 +63,6 @@ def auth_with_key(func):
|
||||||
else:
|
else:
|
||||||
identity_changed.send(current_app._get_current_object(),
|
identity_changed.send(current_app._get_current_object(),
|
||||||
identity=AnonymousIdentity())
|
identity=AnonymousIdentity())
|
||||||
return abort(400, "invalid _key and _secret")
|
return abort(401, "invalid _key and _secret")
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
45
lib/ci.py
45
lib/ci.py
|
@ -140,16 +140,16 @@ class CIManager(object):
|
||||||
abort(404, "CIType {0} is not existed".format(ci_type_name))
|
abort(404, "CIType {0} is not existed".format(ci_type_name))
|
||||||
|
|
||||||
unique_key = CIAttributeCache.get(ci_type.uniq_id) \
|
unique_key = CIAttributeCache.get(ci_type.uniq_id) \
|
||||||
or abort(500, 'illegality unique attribute')
|
or abort(400, 'illegality unique attribute')
|
||||||
|
|
||||||
unique = ci_dict.get(unique_key.attr_name) \
|
unique = ci_dict.get(unique_key.attr_name) \
|
||||||
or abort(500, '{0} missing'.format(unique_key.attr_name))
|
or abort(400, '{0} missing'.format(unique_key.attr_name))
|
||||||
|
|
||||||
old_ci = self.ci_is_exist(ci_type, unique_key, unique)
|
old_ci = self.ci_is_exist(ci_type, unique_key, unique)
|
||||||
if old_ci is not None:
|
if old_ci is not None:
|
||||||
ci_existed = True
|
ci_existed = True
|
||||||
if exist_policy == 'reject':
|
if exist_policy == 'reject':
|
||||||
return abort(500, 'CI is existed')
|
return abort(400, 'CI is existed')
|
||||||
if old_ci.type_id != ci_type.type_id: # update ci_type
|
if old_ci.type_id != ci_type.type_id: # update ci_type
|
||||||
old_ci.type_id = ci_type.type_id
|
old_ci.type_id = ci_type.type_id
|
||||||
db.session.add(old_ci)
|
db.session.add(old_ci)
|
||||||
|
@ -169,7 +169,7 @@ class CIManager(object):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
current_app.logger.error('add CI error: {0}'.format(str(e)))
|
current_app.logger.error('add CI error: {0}'.format(str(e)))
|
||||||
return abort(500, 'add CI error')
|
return abort(400, 'add CI error')
|
||||||
value_manager = AttributeValueManager()
|
value_manager = AttributeValueManager()
|
||||||
histories = list()
|
histories = list()
|
||||||
for p, v in ci_dict.items():
|
for p, v in ci_dict.items():
|
||||||
|
@ -182,7 +182,7 @@ class CIManager(object):
|
||||||
if not ci_existed:
|
if not ci_existed:
|
||||||
self.delete(ci.ci_id)
|
self.delete(ci.ci_id)
|
||||||
current_app.logger.info(res)
|
current_app.logger.info(res)
|
||||||
return abort(500, res)
|
return abort(400, res)
|
||||||
if res is not None:
|
if res is not None:
|
||||||
histories.append(res)
|
histories.append(res)
|
||||||
try:
|
try:
|
||||||
|
@ -192,12 +192,39 @@ class CIManager(object):
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
if not ci_existed: # only add
|
if not ci_existed: # only add
|
||||||
self.delete(ci.ci_id)
|
self.delete(ci.ci_id)
|
||||||
return abort(500, "add CI error")
|
return abort(400, "add CI error")
|
||||||
his_manager = CIAttributeHistoryManger()
|
his_manager = CIAttributeHistoryManger()
|
||||||
his_manager.add(ci.ci_id, histories)
|
his_manager.add(ci.ci_id, histories)
|
||||||
ci_cache.apply_async([ci.ci_id], queue="cmdb_async")
|
ci_cache.apply_async([ci.ci_id], queue="cmdb_async")
|
||||||
return ci.ci_id
|
return ci.ci_id
|
||||||
|
|
||||||
|
def update_unique_value(self, ci_id, args):
|
||||||
|
ci = self.get_ci_by_id(ci_id, need_children=False)
|
||||||
|
unique_key = ci.get("unique")
|
||||||
|
attr = CIAttributeCache.get(unique_key)
|
||||||
|
table_key = "index_{0}".format(attr.value_type) \
|
||||||
|
if attr.is_index else attr.value_type
|
||||||
|
value_table = type_map.get("table").get(table_key)
|
||||||
|
v = args.get(unique_key)
|
||||||
|
if value_table and v:
|
||||||
|
item = db.session.query(value_table).filter(
|
||||||
|
value_table.ci_id == ci_id).filter(
|
||||||
|
value_table.attr_id == attr.attr_id).first()
|
||||||
|
if item:
|
||||||
|
converter = type_map.get("converter").get(attr.value_type)
|
||||||
|
try:
|
||||||
|
item.value = converter(v)
|
||||||
|
except:
|
||||||
|
return abort(400, "value is illegal")
|
||||||
|
db.session.add(item)
|
||||||
|
try:
|
||||||
|
db.session.commit()
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
current_app.logger.error(str(e))
|
||||||
|
return abort(400, "update unique failed")
|
||||||
|
ci_cache.apply_async([ci_id], queue="cmdb_async")
|
||||||
|
|
||||||
def delete(self, ci_id):
|
def delete(self, ci_id):
|
||||||
ci = db.session.query(CI).filter(CI.ci_id == ci_id).first()
|
ci = db.session.query(CI).filter(CI.ci_id == ci_id).first()
|
||||||
if ci is not None:
|
if ci is not None:
|
||||||
|
@ -224,7 +251,7 @@ class CIManager(object):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
current_app.logger.error("delete CI error, {0}".format(str(e)))
|
current_app.logger.error("delete CI error, {0}".format(str(e)))
|
||||||
return abort(500, "delete CI error, {0}".format(str(e)))
|
return abort(400, "delete CI error, {0}".format(str(e)))
|
||||||
# TODO: write history
|
# TODO: write history
|
||||||
ci_delete.apply_async([ci.ci_id], queue="cmdb_async")
|
ci_delete.apply_async([ci.ci_id], queue="cmdb_async")
|
||||||
return ci_id
|
return ci_id
|
||||||
|
@ -485,7 +512,7 @@ class CIRelationManager(object):
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
current_app.logger.error("add CIRelation is error, {0}".format(
|
current_app.logger.error("add CIRelation is error, {0}".format(
|
||||||
str(e)))
|
str(e)))
|
||||||
return abort(500, "add CIRelation is error, {0}".format(str(e)))
|
return abort(400, "add CIRelation is error, {0}".format(str(e)))
|
||||||
# write history
|
# write history
|
||||||
his_manager = CIRelationHistoryManager()
|
his_manager = CIRelationHistoryManager()
|
||||||
his_manager.add(cr.cr_id, cr.first_ci_id, cr.second_ci_id,
|
his_manager.add(cr.cr_id, cr.first_ci_id, cr.second_ci_id,
|
||||||
|
@ -507,7 +534,7 @@ class CIRelationManager(object):
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
"delete CIRelation is error, {0}".format(str(e)))
|
"delete CIRelation is error, {0}".format(str(e)))
|
||||||
return abort(
|
return abort(
|
||||||
500, "delete CIRelation is error, {0}".format(str(e)))
|
400, "delete CIRelation is error, {0}".format(str(e)))
|
||||||
his_manager = CIRelationHistoryManager()
|
his_manager = CIRelationHistoryManager()
|
||||||
his_manager.add(cr_id, first_ci, second_ci,
|
his_manager.add(cr_id, first_ci, second_ci,
|
||||||
cr.relation_type, operate_type="delete")
|
cr.relation_type, operate_type="delete")
|
||||||
|
|
|
@ -30,6 +30,7 @@ class CITypeAttributeManager(object):
|
||||||
for attr in attrs:
|
for attr in attrs:
|
||||||
attr_dict = attr_manager.get_attribute_by_id(attr.attr_id)
|
attr_dict = attr_manager.get_attribute_by_id(attr.attr_id)
|
||||||
attr_dict["is_required"] = attr.is_required
|
attr_dict["is_required"] = attr.is_required
|
||||||
|
attr_dict["order"] = attr.order
|
||||||
result.append(attr_dict)
|
result.append(attr_dict)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
@ -88,9 +88,9 @@ FACET_QUERY = """
|
||||||
SELECT {0}.value,
|
SELECT {0}.value,
|
||||||
count({0}.ci_id)
|
count({0}.ci_id)
|
||||||
FROM {0}
|
FROM {0}
|
||||||
INNER JOIN ({1}) AS B ON B.ci_id={0}.ci_id
|
INNER JOIN ({1}) AS F ON F.ci_id={0}.ci_id
|
||||||
WHERE {0}.attr_id={2:d}
|
WHERE {0}.attr_id={2:d}
|
||||||
GROUP BY {0}.ci_id
|
GROUP BY {0}.value
|
||||||
"""
|
"""
|
||||||
|
|
||||||
QUERY_CI_BY_ATTR_NAME = """
|
QUERY_CI_BY_ATTR_NAME = """
|
||||||
|
|
|
@ -139,6 +139,12 @@ class Search(object):
|
||||||
"ORDER BY B.ci_id {1} LIMIT {0:d}, {2};".format(
|
"ORDER BY B.ci_id {1} LIMIT {0:d}, {2};".format(
|
||||||
(self.page - 1) * self.count, sort_type, self.count))
|
(self.page - 1) * self.count, sort_type, self.count))
|
||||||
elif self.type_id_list:
|
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
|
return """SELECT SQL_CALC_FOUND_ROWS DISTINCT B.ci_id
|
||||||
FROM ({0}) AS B {1}""".format(
|
FROM ({0}) AS B {1}""".format(
|
||||||
query_sql,
|
query_sql,
|
||||||
|
@ -148,6 +154,10 @@ class Search(object):
|
||||||
(self.page - 1) * self.count, sort_type, self.count,
|
(self.page - 1) * self.count, sort_type, self.count,
|
||||||
",".join(self.type_id_list)))
|
",".join(self.type_id_list)))
|
||||||
else:
|
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
|
return """SELECT SQL_CALC_FOUND_ROWS DISTINCT B.ci_id
|
||||||
FROM ({0}) AS B {1}""".format(
|
FROM ({0}) AS B {1}""".format(
|
||||||
query_sql,
|
query_sql,
|
||||||
|
@ -172,6 +182,12 @@ class Search(object):
|
||||||
(self.page - 1) * self.count,
|
(self.page - 1) * self.count,
|
||||||
sort_type, self.count)
|
sort_type, self.count)
|
||||||
elif self.type_id_list:
|
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
|
return """SELECT SQL_CALC_FOUND_ROWS DISTINCT C.ci_id
|
||||||
FROM ({0}) AS C
|
FROM ({0}) AS C
|
||||||
INNER JOIN cis on cis.ci_id=C.ci_id
|
INNER JOIN cis on cis.ci_id=C.ci_id
|
||||||
|
@ -306,6 +322,7 @@ class Search(object):
|
||||||
table_name = TableMap(attr_name=k).table_name
|
table_name = TableMap(attr_name=k).table_name
|
||||||
query_sql = FACET_QUERY.format(
|
query_sql = FACET_QUERY.format(
|
||||||
table_name, self.query_sql, attr.attr_id)
|
table_name, self.query_sql, attr.attr_id)
|
||||||
|
current_app.logger.debug(query_sql)
|
||||||
result = db.session.execute(query_sql).fetchall()
|
result = db.session.execute(query_sql).fetchall()
|
||||||
facet[k] = result
|
facet[k] = result
|
||||||
facet_result = dict()
|
facet_result = dict()
|
||||||
|
|
|
@ -30,6 +30,7 @@ class CITypeAttribute(db.Model):
|
||||||
db.ForeignKey("ci_attributes.attr_id"),
|
db.ForeignKey("ci_attributes.attr_id"),
|
||||||
primary_key=True)
|
primary_key=True)
|
||||||
is_required = db.Column(db.Boolean, default=False)
|
is_required = db.Column(db.Boolean, default=False)
|
||||||
|
order = db.Column(db.Integer, default=0)
|
||||||
|
|
||||||
__table_args__ = (db.UniqueConstraint("type_id", "attr_id",
|
__table_args__ = (db.UniqueConstraint("type_id", "attr_id",
|
||||||
name="type_attr_uniq"), )
|
name="type_attr_uniq"), )
|
||||||
|
|
Loading…
Reference in New Issue