mirror of https://github.com/veops/cmdb.git
feat(api): add api /ci_type_relations/path
This commit is contained in:
parent
857cbd82fd
commit
7eecf3cec3
|
@ -3,6 +3,7 @@
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
import networkx as nx
|
||||||
import toposort
|
import toposort
|
||||||
from flask import abort
|
from flask import abort
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
@ -845,6 +846,29 @@ class CITypeRelationManager(object):
|
||||||
|
|
||||||
return ids
|
return ids
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def find_path(source_type_id, target_type_ids):
|
||||||
|
source_type_id = int(source_type_id)
|
||||||
|
target_type_ids = map(int, target_type_ids)
|
||||||
|
|
||||||
|
graph = nx.DiGraph()
|
||||||
|
|
||||||
|
def get_children(_id):
|
||||||
|
children = CITypeRelation.get_by(parent_id=_id, to_dict=False)
|
||||||
|
|
||||||
|
for i in children:
|
||||||
|
if i.child_id != _id:
|
||||||
|
graph.add_edge(i.parent_id, i.child_id)
|
||||||
|
get_children(i.child_id)
|
||||||
|
|
||||||
|
get_children(source_type_id)
|
||||||
|
|
||||||
|
paths = list(nx.all_simple_paths(graph, source_type_id, target_type_ids))
|
||||||
|
|
||||||
|
del graph
|
||||||
|
|
||||||
|
return paths
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _wrap_relation_type_dict(type_id, relation_inst):
|
def _wrap_relation_type_dict(type_id, relation_inst):
|
||||||
ci_type_dict = CITypeCache.get(type_id).to_dict()
|
ci_type_dict = CITypeCache.get(type_id).to_dict()
|
||||||
|
|
|
@ -432,6 +432,13 @@ class Search(object):
|
||||||
|
|
||||||
return SearchFromDB(q, use_ci_filter=True, only_ids=True, count=100000).search()
|
return SearchFromDB(q, use_ci_filter=True, only_ids=True, count=100000).search()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _filter_target_ids(target_ids, type_ids, q):
|
||||||
|
if not q.startswith('_type:'):
|
||||||
|
q = "_type:({}),{}".format(";".join(map(str, type_ids)), q)
|
||||||
|
|
||||||
|
return SearchFromDB(q, ci_ids=target_ids, use_ci_filter=False, only_ids=True, count=100000).search()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _path2level(src_type_id, target_type_ids, path):
|
def _path2level(src_type_id, target_type_ids, path):
|
||||||
if not src_type_id or not target_type_ids:
|
if not src_type_id or not target_type_ids:
|
||||||
|
@ -502,6 +509,7 @@ class Search(object):
|
||||||
ci_ids = [j for i in paths for j in i]
|
ci_ids = [j for i in paths for j in i]
|
||||||
|
|
||||||
response, _, _, _, _, _ = SearchFromDB("_type:({})".format(";".join(map(str, types))),
|
response, _, _, _, _, _ = SearchFromDB("_type:({})".format(";".join(map(str, types))),
|
||||||
|
use_ci_filter=False,
|
||||||
ci_ids=list(map(int, ci_ids)),
|
ci_ids=list(map(int, ci_ids)),
|
||||||
count=1000000).search()
|
count=1000000).search()
|
||||||
id2ci = {str(i.get('_id')): i for i in response}
|
id2ci = {str(i.get('_id')): i for i in response}
|
||||||
|
@ -539,6 +547,8 @@ class Search(object):
|
||||||
source_ids = self._get_src_ids(source)
|
source_ids = self._get_src_ids(source)
|
||||||
|
|
||||||
graph, target_ids = self._build_graph(source_ids, level2type, target['type_ids'], acl)
|
graph, target_ids = self._build_graph(source_ids, level2type, target['type_ids'], acl)
|
||||||
|
if target.get('q'):
|
||||||
|
target_ids = self._filter_target_ids(target_ids, target['type_ids'], target['q'])
|
||||||
|
|
||||||
paths = self._find_paths(graph, source_ids, set(target_ids))
|
paths = self._find_paths(graph, source_ids, set(target_ids))
|
||||||
del graph
|
del graph
|
||||||
|
|
|
@ -8,7 +8,6 @@ from api.lib.cmdb.ci_type import CITypeManager
|
||||||
from api.lib.cmdb.ci_type import CITypeRelationManager
|
from api.lib.cmdb.ci_type import CITypeRelationManager
|
||||||
from api.lib.cmdb.const import PermEnum
|
from api.lib.cmdb.const import PermEnum
|
||||||
from api.lib.cmdb.const import ResourceTypeEnum
|
from api.lib.cmdb.const import ResourceTypeEnum
|
||||||
from api.lib.cmdb.const import RoleEnum
|
|
||||||
from api.lib.cmdb.preference import PreferenceManager
|
from api.lib.cmdb.preference import PreferenceManager
|
||||||
from api.lib.cmdb.resp_format import ErrFormat
|
from api.lib.cmdb.resp_format import ErrFormat
|
||||||
from api.lib.common_setting.decorator import perms_role_required
|
from api.lib.common_setting.decorator import perms_role_required
|
||||||
|
@ -17,7 +16,7 @@ from api.lib.decorator import args_required
|
||||||
from api.lib.perm.acl.acl import ACLManager
|
from api.lib.perm.acl.acl import ACLManager
|
||||||
from api.lib.perm.acl.acl import has_perm_from_args
|
from api.lib.perm.acl.acl import has_perm_from_args
|
||||||
from api.lib.perm.acl.acl import is_app_admin
|
from api.lib.perm.acl.acl import is_app_admin
|
||||||
from api.lib.perm.acl.acl import role_required
|
from api.lib.utils import handle_arg_list
|
||||||
from api.resource import APIView
|
from api.resource import APIView
|
||||||
|
|
||||||
app_cli = CMDBApp()
|
app_cli = CMDBApp()
|
||||||
|
@ -42,6 +41,19 @@ class GetParentsView(APIView):
|
||||||
return self.jsonify(parents=CITypeRelationManager.get_parents(child_id))
|
return self.jsonify(parents=CITypeRelationManager.get_parents(child_id))
|
||||||
|
|
||||||
|
|
||||||
|
class CITypeRelationPathView(APIView):
|
||||||
|
url_prefix = ("/ci_type_relations/path",)
|
||||||
|
|
||||||
|
@args_required("source_type_id", "target_type_ids")
|
||||||
|
def get(self):
|
||||||
|
source_type_id = request.values.get("source_type_id")
|
||||||
|
target_type_ids = handle_arg_list(request.values.get("target_type_ids"))
|
||||||
|
|
||||||
|
paths = CITypeRelationManager.find_path(source_type_id, target_type_ids)
|
||||||
|
|
||||||
|
return self.jsonify(paths=paths)
|
||||||
|
|
||||||
|
|
||||||
class CITypeRelationView(APIView):
|
class CITypeRelationView(APIView):
|
||||||
url_prefix = ("/ci_type_relations", "/ci_type_relations/<int:parent_id>/<int:child_id>")
|
url_prefix = ("/ci_type_relations", "/ci_type_relations/<int:parent_id>/<int:child_id>")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue