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
|
||||
|
||||
import copy
|
||||
import networkx as nx
|
||||
import toposort
|
||||
from flask import abort
|
||||
from flask import current_app
|
||||
|
@ -845,6 +846,29 @@ class CITypeRelationManager(object):
|
|||
|
||||
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
|
||||
def _wrap_relation_type_dict(type_id, relation_inst):
|
||||
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()
|
||||
|
||||
@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
|
||||
def _path2level(src_type_id, target_type_ids, path):
|
||||
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]
|
||||
|
||||
response, _, _, _, _, _ = SearchFromDB("_type:({})".format(";".join(map(str, types))),
|
||||
use_ci_filter=False,
|
||||
ci_ids=list(map(int, ci_ids)),
|
||||
count=1000000).search()
|
||||
id2ci = {str(i.get('_id')): i for i in response}
|
||||
|
@ -539,6 +547,8 @@ class Search(object):
|
|||
source_ids = self._get_src_ids(source)
|
||||
|
||||
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))
|
||||
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.const import PermEnum
|
||||
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.resp_format import ErrFormat
|
||||
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 has_perm_from_args
|
||||
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
|
||||
|
||||
app_cli = CMDBApp()
|
||||
|
@ -42,6 +41,19 @@ class GetParentsView(APIView):
|
|||
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):
|
||||
url_prefix = ("/ci_type_relations", "/ci_type_relations/<int:parent_id>/<int:child_id>")
|
||||
|
||||
|
|
Loading…
Reference in New Issue