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.history, "/api/v0.1/history"),
|
||||
(core.account, "/api/v0.1/accounts"),
|
||||
# (core.special, ""),
|
||||
(core.special, ""),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -8,4 +8,4 @@ from ci_relation import cirelation
|
|||
from ci import ci
|
||||
from history import history
|
||||
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"])
|
||||
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()
|
||||
from models.attribute import CIAttributeCache
|
||||
from models.ci_type import CITypeCache
|
||||
from models.ci_type import CITypeAttributeCache
|
||||
|
||||
t = CITypeCache.get(type_id)
|
||||
if not t:
|
||||
t = CITypeCache.get(type_name)
|
||||
if not t:
|
||||
return abort(400, "CIType {0} is not existed".format(type_id))
|
||||
type_id = t.type_id
|
||||
uniq_id = t.uniq_id
|
||||
CITypeAttributeCache.clean(type_id)
|
||||
unique = CIAttributeCache.get(uniq_id).attr_name
|
||||
return jsonify(attributes=manager.get_attributes_by_type_id(type_id),
|
||||
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.ci import CIManager
|
||||
from lib.ci import HostNumStatis
|
||||
from lib.search import Search
|
||||
from lib.search import SearchError
|
||||
from lib.utils import get_page
|
||||
|
@ -156,6 +157,14 @@ def update_ci():
|
|||
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"])
|
||||
@auth_with_key
|
||||
def delete_ci(ci_id=None):
|
||||
|
@ -187,3 +196,21 @@ def get_heartbeat():
|
|||
ci_type,
|
||||
agent_status=agent_status)
|
||||
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):
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
if isinstance(getattr(g, 'user', None), User):
|
||||
identity_changed.send(current_app._get_current_object(),
|
||||
identity=Identity(g.user.uid))
|
||||
return func(*args, **kwargs)
|
||||
# if isinstance(getattr(g, 'user', None), User):
|
||||
# identity_changed.send(current_app._get_current_object(),
|
||||
# identity=Identity(g.user.uid))
|
||||
# return func(*args, **kwargs)
|
||||
ip = request.remote_addr
|
||||
if request.data:
|
||||
request_args = dict()
|
||||
|
@ -46,7 +46,7 @@ def auth_with_key(func):
|
|||
else:
|
||||
identity_changed.send(current_app._get_current_object(),
|
||||
identity=AnonymousIdentity())
|
||||
return abort(400, "invalid _key and _secret")
|
||||
return abort(401, "invalid _key and _secret")
|
||||
|
||||
path = request.path
|
||||
|
||||
|
@ -63,6 +63,6 @@ def auth_with_key(func):
|
|||
else:
|
||||
identity_changed.send(current_app._get_current_object(),
|
||||
identity=AnonymousIdentity())
|
||||
return abort(400, "invalid _key and _secret")
|
||||
return abort(401, "invalid _key and _secret")
|
||||
|
||||
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))
|
||||
|
||||
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) \
|
||||
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)
|
||||
if old_ci is not None:
|
||||
ci_existed = True
|
||||
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
|
||||
old_ci.type_id = ci_type.type_id
|
||||
db.session.add(old_ci)
|
||||
|
@ -169,7 +169,7 @@ class CIManager(object):
|
|||
except Exception as e:
|
||||
db.session.rollback()
|
||||
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()
|
||||
histories = list()
|
||||
for p, v in ci_dict.items():
|
||||
|
@ -182,7 +182,7 @@ class CIManager(object):
|
|||
if not ci_existed:
|
||||
self.delete(ci.ci_id)
|
||||
current_app.logger.info(res)
|
||||
return abort(500, res)
|
||||
return abort(400, res)
|
||||
if res is not None:
|
||||
histories.append(res)
|
||||
try:
|
||||
|
@ -192,12 +192,39 @@ class CIManager(object):
|
|||
db.session.rollback()
|
||||
if not ci_existed: # only add
|
||||
self.delete(ci.ci_id)
|
||||
return abort(500, "add CI error")
|
||||
return abort(400, "add CI error")
|
||||
his_manager = CIAttributeHistoryManger()
|
||||
his_manager.add(ci.ci_id, histories)
|
||||
ci_cache.apply_async([ci.ci_id], queue="cmdb_async")
|
||||
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):
|
||||
ci = db.session.query(CI).filter(CI.ci_id == ci_id).first()
|
||||
if ci is not None:
|
||||
|
@ -224,7 +251,7 @@ class CIManager(object):
|
|||
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)))
|
||||
return abort(400, "delete CI error, {0}".format(str(e)))
|
||||
# TODO: write history
|
||||
ci_delete.apply_async([ci.ci_id], queue="cmdb_async")
|
||||
return ci_id
|
||||
|
@ -485,7 +512,7 @@ class CIRelationManager(object):
|
|||
db.session.rollback()
|
||||
current_app.logger.error("add CIRelation is error, {0}".format(
|
||||
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
|
||||
his_manager = CIRelationHistoryManager()
|
||||
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(
|
||||
"delete CIRelation is error, {0}".format(str(e)))
|
||||
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.add(cr_id, first_ci, second_ci,
|
||||
cr.relation_type, operate_type="delete")
|
||||
|
|
|
@ -30,6 +30,7 @@ class CITypeAttributeManager(object):
|
|||
for attr in attrs:
|
||||
attr_dict = attr_manager.get_attribute_by_id(attr.attr_id)
|
||||
attr_dict["is_required"] = attr.is_required
|
||||
attr_dict["order"] = attr.order
|
||||
result.append(attr_dict)
|
||||
return result
|
||||
|
||||
|
|
|
@ -88,9 +88,9 @@ FACET_QUERY = """
|
|||
SELECT {0}.value,
|
||||
count({0}.ci_id)
|
||||
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}
|
||||
GROUP BY {0}.ci_id
|
||||
GROUP BY {0}.value
|
||||
"""
|
||||
|
||||
QUERY_CI_BY_ATTR_NAME = """
|
||||
|
|
|
@ -139,6 +139,12 @@ class Search(object):
|
|||
"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,
|
||||
|
@ -148,6 +154,10 @@ class Search(object):
|
|||
(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,
|
||||
|
@ -172,6 +182,12 @@ class Search(object):
|
|||
(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
|
||||
|
@ -306,6 +322,7 @@ class Search(object):
|
|||
table_name = TableMap(attr_name=k).table_name
|
||||
query_sql = FACET_QUERY.format(
|
||||
table_name, self.query_sql, attr.attr_id)
|
||||
current_app.logger.debug(query_sql)
|
||||
result = db.session.execute(query_sql).fetchall()
|
||||
facet[k] = result
|
||||
facet_result = dict()
|
||||
|
|
|
@ -30,6 +30,7 @@ class CITypeAttribute(db.Model):
|
|||
db.ForeignKey("ci_attributes.attr_id"),
|
||||
primary_key=True)
|
||||
is_required = db.Column(db.Boolean, default=False)
|
||||
order = db.Column(db.Integer, default=0)
|
||||
|
||||
__table_args__ = (db.UniqueConstraint("type_id", "attr_id",
|
||||
name="type_attr_uniq"), )
|
||||
|
|
Loading…
Reference in New Issue