Skip to content

Commit

Permalink
optimization: 任务历史搜索优化 (closed #1856)
Browse files Browse the repository at this point in the history
  • Loading branch information
wyyalt authored and ping15 committed Nov 7, 2023
1 parent 9d5284f commit 626e387
Show file tree
Hide file tree
Showing 7 changed files with 324 additions and 62 deletions.
34 changes: 7 additions & 27 deletions apps/node_man/handlers/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from apps.node_man.handlers.cloud import CloudHandler
from apps.node_man.handlers.cmdb import CmdbHandler
from apps.node_man.handlers.host import HostHandler
from apps.node_man.tools import JobTools
from apps.utils import APIModel
from apps.utils.basic import filter_values, to_int_or_default
from apps.utils.local import get_request_username
Expand Down Expand Up @@ -169,30 +170,6 @@ def list(self, params: dict, username: str):
job_ids.add(job_id)
kwargs["id__in"] = job_ids

# 业务权限
search_biz_ids = params.get("bk_biz_id")
all_biz_ids = set(all_biz_info.keys())

if search_biz_ids:
# 字典的 in 比列表性能更高
biz_scope = [bk_biz_id for bk_biz_id in search_biz_ids if bk_biz_id in biz_info]
else:
biz_scope = biz_permission

if not biz_scope:
return {"total": 0, "list": []}

if set(biz_scope) & all_biz_ids == all_biz_ids:
# 查询全部业务且拥有全部业务权限
biz_scope_query_q = Q()
else:
biz_scope_query_q = reduce(
operator.or_, [Q(bk_biz_scope__contains=bk_biz_id) for bk_biz_id in biz_scope], Q()
)
# 仅查询所有业务时,自身创建的 job 可见
if not search_biz_ids:
biz_scope_query_q |= Q(created_by=username)

# ip 搜索
inner_ip_query_q = Q()
if params.get("inner_ip_list"):
Expand All @@ -218,10 +195,13 @@ def list(self, params: dict, username: str):

# 过滤None值并筛选Job
# 此处不过滤空列表(filter_empty=False),job_id, job_type 存在二次解析,若全部值非法得到的是空列表,期望应是查不到数据
job_result = models.Job.objects.filter(biz_scope_query_q, inner_ip_query_q, **filter_values(kwargs))
job_result = JobTools().get_job_queryset_with_biz_scope(
all_biz_info, biz_info, biz_permission, params.get("bk_biz_id"), kwargs
)
if job_result is None:
return {"total": 0, "list": []}

# 过滤没有业务的Job
job_result = job_result.filter(~Q(bk_biz_scope__isnull=True) & ~Q(bk_biz_scope={}))
job_result = job_result.filter(inner_ip_query_q)

# 排序
if params.get("sort"):
Expand Down
49 changes: 33 additions & 16 deletions apps/node_man/handlers/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from apps.node_man.handlers.cloud import CloudHandler
from apps.node_man.handlers.cmdb import CmdbHandler
from apps.node_man.handlers.install_channel import InstallChannelHandler
from apps.node_man.tools import JobTools
from apps.utils import APIModel


Expand Down Expand Up @@ -180,23 +181,40 @@ def fetch_host_condition(self):
]
)

def fetch_job_list_condition(self, job_category):
def fetch_job_list_condition(self, job_category, params=None):
"""
获取任务历史接口的条件
:return: Host接口所有条件
"""
params = params or {}
kwargs = {
"start_time__gte": params.get("start_time"),
"start_time__lte": params.get("end_time"),
}

# 获得业务id与名字的映射关系(用户有权限获取的业务)
biz_permission = list(CmdbHandler().biz_id_name({"action": constants.IamActionType.task_history_view}))
all_biz_info = CmdbHandler().biz_id_name_without_permission()
biz_info = CmdbHandler().biz_id_name({"action": constants.IamActionType.task_history_view})
biz_permission = list(biz_info.keys())

if job_category == "job":
job_type = constants.JOB_TUPLE
else:
job_type = constants.JOB_TYPE_MAP[job_category.split("_")[0]]
# 获得4列的所有值
job_condition = list(
models.Job.objects.filter(job_type__in=job_type)
.values("created_by", "job_type", "status", "bk_biz_scope", "subscription_id")
.distinct()

job_result = JobTools.get_job_queryset_with_biz_scope(
all_biz_info, biz_info, biz_permission, params.get("bk_biz_ids"), kwargs
)
if job_result is None:
return self.filter_empty_children(
[
{"name": _("任务ID"), "id": "job_id"},
{"name": _("IP"), "id": "inner_ip_list"},
]
)

job_result = job_result.filter(job_type__in=job_type).values_list(
"created_by", "job_type", "status", "subscription_id"
)

# 初始化各个条件集合
Expand All @@ -205,13 +223,11 @@ def fetch_job_list_condition(self, job_category):
statuses = set()
subscription_ids = set()

for job in job_condition:
# 判断权限
if set(job["bk_biz_scope"]) - set(biz_permission) == set():
created_bys.add(job["created_by"])
job_types.add(job["job_type"])
statuses.add(job["status"])
subscription_ids.add(job["subscription_id"])
for created_by, job_type, status, subscription_id in job_result:
created_bys.add(created_by)
job_types.add(job_type)
statuses.add(status)
subscription_ids.add(subscription_id)

created_bys_children = [
{"name": created_by, "id": created_by} for created_by in created_bys if created_by != ""
Expand Down Expand Up @@ -469,17 +485,18 @@ def fetch_os_type_children(os_types: Tuple = constants.OsType):
os_type_children.append({"id": os_type, "name": constants.OS_CHN.get(os_type, os_type)})
return os_type_children

def filter_condition(self, category):
def filter_condition(self, category, params=None):
"""
获取过滤条件
:param category: 接口, host, cloud, Job等
:param params: 请求参数的字典
:return: 某接口所有条件
"""

if category == "host":
return self.fetch_host_condition()
elif category == "job":
return self.fetch_job_list_condition("job")
return self.fetch_job_list_condition("job", params=params)
elif category == "agent_job":
return self.fetch_job_list_condition("agent_job")
elif category == "proxy_job":
Expand Down
9 changes: 9 additions & 0 deletions apps/node_man/serializers/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,12 @@ class JobSettingSerializer(serializers.Serializer):
install_download_limit_speed = serializers.IntegerField(label=_("安装下载限速"), max_value=JOB_MAX_VALUE, min_value=0)
parallel_install_number = serializers.IntegerField(label=_("并行安装数"), max_value=JOB_MAX_VALUE, min_value=0)
node_man_log_level = serializers.ChoiceField(label=_("节点管理日志级别"), choices=list(NODE_MAN_LOG_LEVEL))


class FilterConditionSerializer(serializers.Serializer):
category = serializers.CharField(label=_("分类"), required=False, default="")
bk_biz_ids = serializers.ListField(label=_("业务列表"), required=False, default=[], child=serializers.IntegerField())

# 时间范围
start_time = serializers.DateTimeField(label=_("起始时间"), required=False)
end_time = serializers.DateTimeField(label=_("终止时间"), required=False)
Loading

0 comments on commit 626e387

Please sign in to comment.