diff --git a/src/backend/commons/cmdb-sdk/src/main/java/com/tencent/bk/job/common/cc/model/container/ContainerDetailDTO.java b/src/backend/commons/cmdb-sdk/src/main/java/com/tencent/bk/job/common/cc/model/container/ContainerDetailDTO.java index f1a380ab38..fe74dac777 100644 --- a/src/backend/commons/cmdb-sdk/src/main/java/com/tencent/bk/job/common/cc/model/container/ContainerDetailDTO.java +++ b/src/backend/commons/cmdb-sdk/src/main/java/com/tencent/bk/job/common/cc/model/container/ContainerDetailDTO.java @@ -62,6 +62,10 @@ public Container toContainer() { } if (topo != null) { container.setNodeHostId(topo.getHostId()); + container.setClusterId(topo.getClusterId()); + container.setNamespaceId(topo.getNamespaceId()); + container.setWorkloadType(topo.getWorkloadType()); + container.setWorkloadId(topo.getWorkloadId()); } return container; } diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/dto/Container.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/dto/Container.java index 84b286e902..a313cf7921 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/dto/Container.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/dto/Container.java @@ -71,6 +71,12 @@ public class Container implements Cloneable { @JsonProperty("nodeHostId") private Long nodeHostId; + /** + * node 主机 ip + */ + @JsonProperty("nodeIp") + private String nodeIp; + /** * 容器所在 Node 对应的 Agent ID */ @@ -78,29 +84,59 @@ public class Container implements Cloneable { private String nodeAgentId; /** - * 容器所在集群 ID + * cluster在cmdb中的唯一ID */ @JsonProperty("clusterId") - private String clusterId; + private Long clusterId; + + /** + * 集群 ID + */ + @JsonProperty("clusterUID") + private String clusterUID; + + /** + * 集群名称 + */ + @JsonProperty("clusterName") + private String clusterName; /** - * 容器所在命名空间 + * namespace在cmdb中的唯一ID + */ + @JsonProperty("namespaceId") + private Long namespaceId; + + /** + * 命名空间名称 */ @JsonProperty("namespace") private String namespace; /** - * 容器所在 POD 名称 + * POD 名称 */ @JsonProperty("podName") private String podName; /** - * 容器所在 POD 名称 + * pod labels */ @JsonProperty("podLabels") private Map podLabels; + /** + * workload 类型(Deployment/Job ...) + */ + @JsonProperty("workloadType") + private String workloadType; + + /** + * workload在cmdb中的唯一ID + */ + @JsonProperty("workloadId") + private Long workloadId; + @Override public boolean equals(Object o) { if (this == o) return true; @@ -120,13 +156,19 @@ public Container clone() { Container clone = new Container(); clone.setId(id); clone.setNodeHostId(nodeHostId); + clone.setNodeIp(nodeIp); clone.setNodeAgentId(nodeAgentId); clone.setContainerId(containerId); clone.setPodLabels(podLabels); clone.setClusterId(clusterId); + clone.setClusterUID(clusterUID); + clone.setClusterName(clusterName); + clone.setNamespaceId(namespaceId); clone.setNamespace(namespace); clone.setPodName(podName); clone.setName(name); + clone.setWorkloadType(workloadType); + clone.setWorkloadId(workloadId); return clone; } @@ -136,8 +178,15 @@ public ContainerVO toContainerVO() { vo.setName(name); vo.setUid(containerId); vo.setNodeHostId(nodeHostId); + vo.setNodeIp(nodeIp); vo.setPodName(podName); vo.setPodLabels(podLabels); + vo.setClusterId(clusterId); + vo.setClusterUID(clusterUID); + vo.setClusterName(clusterName); + vo.setNamespaceId(namespaceId); + vo.setNamespace(namespace); + vo.setWorkloadType(workloadType); return vo; } @@ -154,8 +203,14 @@ public void updatePropsByContainer(Container container) { this.containerId = container.getContainerId(); this.nodeHostId = container.getNodeHostId(); this.nodeAgentId = container.getNodeAgentId(); + this.nodeIp = container.getNodeIp(); this.clusterId = container.getClusterId(); + this.clusterUID = container.getClusterUID(); + this.clusterName = container.getClusterName(); + this.namespaceId = container.getNamespaceId(); this.namespace = container.getNamespace(); + this.workloadType = container.getWorkloadType(); + this.workloadId = container.getWorkloadId(); this.podName = container.getPodName(); this.podLabels = container.getPodLabels(); this.name = container.getName(); diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/vo/ContainerVO.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/vo/ContainerVO.java index 9f183e3591..b50ccb9b48 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/vo/ContainerVO.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/model/vo/ContainerVO.java @@ -66,4 +66,22 @@ public class ContainerVO { @ApiModelProperty("所属 Node GSE agent 状态") private String nodeAgentStatus; + + @ApiModelProperty("cluster在cmdb中的唯一ID") + private Long clusterId; + + @ApiModelProperty(value = "集群 ID", example = "BCS-K8S-00000") + private String clusterUID; + + @ApiModelProperty("集群名称") + private String clusterName; + + @ApiModelProperty("命名空间在 cmdb 的唯一 ID") + private Long namespaceId; + + @ApiModelProperty("命名空间名称") + private String namespace; + + @ApiModelProperty("workload 类型") + private String workloadType; } diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/ContainerServiceImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/ContainerServiceImpl.java index 41ee45510e..8c6c2b4ed9 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/ContainerServiceImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/ContainerServiceImpl.java @@ -116,6 +116,7 @@ private void fillNodeHostInfo(long appId, List containers) { return; } container.setNodeAgentId(nodeHost.getAgentId()); + container.setNodeIp(nodeHost.getPrimaryIp()); }); } diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/TaskInstanceExecuteObjectProcessor.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/TaskInstanceExecuteObjectProcessor.java index cb617c3580..bcffa6690f 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/TaskInstanceExecuteObjectProcessor.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/TaskInstanceExecuteObjectProcessor.java @@ -24,6 +24,11 @@ package com.tencent.bk.job.execute.service.impl; +import com.tencent.bk.job.common.cc.model.container.KubeClusterDTO; +import com.tencent.bk.job.common.cc.model.container.KubeNamespaceDTO; +import com.tencent.bk.job.common.cc.model.query.KubeClusterQuery; +import com.tencent.bk.job.common.cc.model.query.NamespaceQuery; +import com.tencent.bk.job.common.cc.sdk.BizCmdbClient; import com.tencent.bk.job.common.constant.ErrorCode; import com.tencent.bk.job.common.constant.TaskVariableTypeEnum; import com.tencent.bk.job.common.exception.FailedPreconditionException; @@ -102,6 +107,8 @@ public class TaskInstanceExecuteObjectProcessor { private final MeterRegistry meterRegistry; + private final BizCmdbClient bizCmdbClient; + public TaskInstanceExecuteObjectProcessor(HostService hostService, ApplicationService applicationService, ContainerService containerService, @@ -109,7 +116,7 @@ public TaskInstanceExecuteObjectProcessor(HostService hostService, WhiteHostCache whiteHostCache, @Qualifier(DefaultBeanNames.PREFER_V2_AGENT_STATE_CLIENT) AgentStateClient preferV2AgentStateClient, - MeterRegistry meterRegistry) { + MeterRegistry meterRegistry, BizCmdbClient bizCmdbClient) { this.hostService = hostService; this.applicationService = applicationService; this.containerService = containerService; @@ -117,6 +124,7 @@ public TaskInstanceExecuteObjectProcessor(HostService hostService, this.whiteHostCache = whiteHostCache; this.preferV2AgentStateClient = preferV2AgentStateClient; this.meterRegistry = meterRegistry; + this.bizCmdbClient = bizCmdbClient; } /** @@ -627,7 +635,7 @@ private void acquireAndSetContainers(TaskInstanceExecuteObjects taskInstanceExec TaskInstanceDTO taskInstance, List stepInstances) { - // // 根据静态容器列表方式获取并设置容器执行对象 + // 根据静态容器列表方式获取并设置容器执行对象 acquireAndSetContainersByStaticContainerList(taskInstanceExecuteObjects, taskInstance, stepInstances); @@ -637,6 +645,62 @@ private void acquireAndSetContainers(TaskInstanceExecuteObjects taskInstanceExec taskInstanceExecuteObjects.setContainsAnyContainer( CollectionUtils.isNotEmpty(taskInstanceExecuteObjects.getValidContainers())); + + // 增加容器 topo 信息(集群 UID,集群名称、命名空间名称等) + fillContainerTopoInfo(taskInstance.getAppId(), taskInstanceExecuteObjects.getValidContainers(), stepInstances); + } + + private void fillContainerTopoInfo(long appId, + Collection containers, + List stepInstances) { + if (CollectionUtils.isEmpty(containers)) { + return; + } + long bizId = Long.parseLong(appScopeMappingService.getScopeByAppId(appId).getId()); + // 从 cmdb 获取集群信息 + List ccKubeClusterIds = + containers.stream().map(Container::getClusterId).distinct().collect(Collectors.toList()); + List clusters = + bizCmdbClient.listKubeClusters(KubeClusterQuery.Builder.builder(bizId).ids(ccKubeClusterIds).build()); + Map clusterMap = clusters.stream().collect( + Collectors.toMap(KubeClusterDTO::getId, cluster -> cluster)); + + // 从 cmdb 获取命名空间信息 + List ccKubeNamespaceIds = + containers.stream().map(Container::getNamespaceId).distinct().collect(Collectors.toList()); + List namespaces = + bizCmdbClient.listKubeNamespaces(NamespaceQuery.Builder.builder(bizId).ids(ccKubeNamespaceIds).build()); + Map namespaceMap = namespaces.stream().collect( + Collectors.toMap(KubeNamespaceDTO::getId, namespace -> namespace)); + + // 填充 cluster、 namespace 信息 + for (StepInstanceDTO stepInstance : stepInstances) { + stepInstance.forEachExecuteObjects(executeObjects -> { + if (CollectionUtils.isNotEmpty(executeObjects.getContainerFilters())) { + executeObjects.getContainerFilters().forEach(containerFilter -> { + if (CollectionUtils.isNotEmpty(containerFilter.getContainers())) { + containerFilter.getContainers().forEach( + container -> addTopoDetail(container, clusterMap, namespaceMap)); + } + }); + } + if (CollectionUtils.isNotEmpty(executeObjects.getStaticContainerList())) { + executeObjects.getStaticContainerList().forEach( + container -> addTopoDetail(container, clusterMap, namespaceMap)); + } + }); + } + } + + private void addTopoDetail(Container container, + Map clusterMap, + Map namespaceMap) { + KubeClusterDTO cluster = clusterMap.get(container.getClusterId()); + container.setClusterName(cluster.getName()); + container.setClusterUID(cluster.getUid()); + + KubeNamespaceDTO namespace = namespaceMap.get(container.getNamespaceId()); + container.setNamespace(namespace.getName()); } private void acquireAndSetContainersByStaticContainerList(TaskInstanceExecuteObjects taskInstanceExecuteObjects, diff --git a/src/backend/job-manage/api-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/WebTaskPlanResource.java b/src/backend/job-manage/api-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/WebTaskPlanResource.java index bb8014b289..97a8f4266a 100644 --- a/src/backend/job-manage/api-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/WebTaskPlanResource.java +++ b/src/backend/job-manage/api-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/WebTaskPlanResource.java @@ -30,6 +30,7 @@ import com.tencent.bk.job.common.model.dto.AppResourceScope; import com.tencent.bk.job.manage.model.web.request.TaskPlanCreateUpdateReq; import com.tencent.bk.job.manage.model.web.request.TaskVariableValueUpdateReq; +import com.tencent.bk.job.manage.model.web.vo.task.TaskPlanBasicInfoVO; import com.tencent.bk.job.manage.model.web.vo.task.TaskPlanSyncInfoVO; import com.tencent.bk.job.manage.model.web.vo.task.TaskPlanVO; import io.swagger.annotations.Api; @@ -273,6 +274,26 @@ Response> listPlanBasicInfoByIds( String planIds ); + @ApiOperation(value = "根据执行方案 ID 批量拉执行方案基础信息", produces = "application/json") + @GetMapping(value = {"/scope/{scopeType}/{scopeId}/task/plan/basicInfo"}) + Response> listTaskPlanBasicInfoByIds( + @ApiParam(value = "用户名,网关自动传入") + @RequestHeader("username") + String username, + @ApiIgnore + @RequestAttribute(value = "appResourceScope") + AppResourceScope appResourceScope, + @ApiParam(value = "资源范围类型", required = true) + @PathVariable(value = "scopeType") + String scopeType, + @ApiParam(value = "资源范围ID", required = true) + @PathVariable(value = "scopeId") + String scopeId, + @ApiParam(value = "执行方案 ID 列表,逗号分隔", required = true, example = "1,2,3") + @QueryParam("ids") + String planIds + ); + @ApiOperation(value = "检查执行方案名称是否已占用", produces = "application/json") @GetMapping("/scope/{scopeType}/{scopeId}/task/plan/{templateId}/{planId}/check_name") Response checkPlanName( diff --git a/src/backend/job-manage/api-job-manage/src/main/java/com/tencent/bk/job/manage/model/web/vo/task/TaskPlanBasicInfoVO.java b/src/backend/job-manage/api-job-manage/src/main/java/com/tencent/bk/job/manage/model/web/vo/task/TaskPlanBasicInfoVO.java new file mode 100644 index 0000000000..c47ac0983f --- /dev/null +++ b/src/backend/job-manage/api-job-manage/src/main/java/com/tencent/bk/job/manage/model/web/vo/task/TaskPlanBasicInfoVO.java @@ -0,0 +1,91 @@ +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +package com.tencent.bk.job.manage.model.web.vo.task; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.tencent.bk.job.common.util.json.LongTimestampDeserializer; +import com.tencent.bk.job.common.util.json.LongTimestampSerializer; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Getter +@Setter +@ToString +@ApiModel("执行方案信息") +public class TaskPlanBasicInfoVO { + + /** + * 执行方案 ID + */ + @ApiModelProperty(value = "执行方案 ID") + private Long id; + + /** + * 执行方案名称 + */ + @ApiModelProperty(value = "执行方案名称") + private String name; + + /** + * 模版 ID + */ + @ApiModelProperty(value = "模版 ID") + private Long templateId; + + + /** + * 创建者 + */ + @ApiModelProperty(value = "创建者") + private String creator; + + /** + * 创建时间 + */ + @ApiModelProperty(value = "创建时间") + @JsonSerialize(using = LongTimestampSerializer.class) + @JsonDeserialize(using = LongTimestampDeserializer.class) + private Long createTime; + + /** + * 最后修改人 + */ + @ApiModelProperty(value = "最后更新者") + private String lastModifyUser; + + /** + * 最后修改时间 + */ + @ApiModelProperty(value = "最后更新时间") + @JsonSerialize(using = LongTimestampSerializer.class) + @JsonDeserialize(using = LongTimestampDeserializer.class) + private Long lastModifyTime; +} diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/impl/ServiceTaskPlanResourceImpl.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/impl/ServiceTaskPlanResourceImpl.java index 757f7b8020..bcf6247420 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/impl/ServiceTaskPlanResourceImpl.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/impl/ServiceTaskPlanResourceImpl.java @@ -109,7 +109,7 @@ public InternalResponse getPlanBasicInfoById(Long appId, Lon throw new InvalidParamException(ErrorCode.ILLEGAL_PARAM); } List planList = - taskPlanService.listPlanBasicInfoByIds(appId, Collections.singletonList(planId)); + taskPlanService.listPlanBasicInfoWithVariablesByIds(appId, Collections.singletonList(planId)); if (CollectionUtils.isNotEmpty(planList)) { TaskPlanInfoDTO plan = planList.get(0); ServiceTaskPlanDTO planDTO = new ServiceTaskPlanDTO(); diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/impl/WebTaskPlanResourceImpl.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/impl/WebTaskPlanResourceImpl.java index 8f32be1c16..f6393c201e 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/impl/WebTaskPlanResourceImpl.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/impl/WebTaskPlanResourceImpl.java @@ -56,6 +56,7 @@ import com.tencent.bk.job.manage.model.query.TaskTemplateQuery; import com.tencent.bk.job.manage.model.web.request.TaskPlanCreateUpdateReq; import com.tencent.bk.job.manage.model.web.request.TaskVariableValueUpdateReq; +import com.tencent.bk.job.manage.model.web.vo.task.TaskPlanBasicInfoVO; import com.tencent.bk.job.manage.model.web.vo.task.TaskPlanSyncInfoVO; import com.tencent.bk.job.manage.model.web.vo.task.TaskPlanVO; import com.tencent.bk.job.manage.service.CronJobService; @@ -458,7 +459,7 @@ public Response> listPlanBasicInfoByIds(String username, if (StringUtils.isNotEmpty(planIds)) { List planIdList = Arrays.stream(planIds.split(",")).filter(Objects::nonNull).map(Long::valueOf) .filter(id -> id > 0).collect(Collectors.toList()); - List taskPlanInfoList = planService.listPlanBasicInfoByIds(appResourceScope.getAppId(), + List taskPlanInfoList = planService.listPlanBasicInfoWithVariablesByIds(appResourceScope.getAppId(), planIdList); fillCronInfo(appResourceScope.getAppId(), taskPlanInfoList); List taskPlanList = @@ -470,6 +471,31 @@ public Response> listPlanBasicInfoByIds(String username, } } + @Override + public Response> listTaskPlanBasicInfoByIds(String username, + AppResourceScope appResourceScope, + String scopeType, + String scopeId, + String planIds) { + if (StringUtils.isEmpty(planIds)) { + return Response.buildSuccessResp(new ArrayList<>()); + } + List planIdList = Arrays.stream(planIds.split(",")) + .filter(Objects::nonNull) + .map(Long::valueOf) + .filter(id -> id > 0) + .collect(Collectors.toList()); + List taskPlanInfoList = planService.listPlanBasicInfoByIds( + appResourceScope.getAppId(), + planIdList + ); + List taskPlanList = + taskPlanInfoList.stream() + .map(TaskPlanInfoDTO::toBasicInfoVO) + .collect(Collectors.toList()); + return Response.buildSuccessResp(taskPlanList); + } + @Override public Response checkPlanName(String username, AppResourceScope appResourceScope, diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/model/dto/task/TaskPlanInfoDTO.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/model/dto/task/TaskPlanInfoDTO.java index 72d8f6ee09..5b2063b041 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/model/dto/task/TaskPlanInfoDTO.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/model/dto/task/TaskPlanInfoDTO.java @@ -34,6 +34,7 @@ import com.tencent.bk.job.common.util.date.DateUtils; import com.tencent.bk.job.manage.model.esb.v3.response.EsbPlanInfoV3DTO; import com.tencent.bk.job.manage.model.web.request.TaskPlanCreateUpdateReq; +import com.tencent.bk.job.manage.model.web.vo.task.TaskPlanBasicInfoVO; import com.tencent.bk.job.manage.model.web.vo.task.TaskPlanVO; import lombok.AllArgsConstructor; import lombok.Data; @@ -159,6 +160,18 @@ public class TaskPlanInfoDTO { */ private Long cronJobCount; + public static TaskPlanBasicInfoVO toBasicInfoVO(TaskPlanInfoDTO planInfo) { + TaskPlanBasicInfoVO taskPlanBasicInfoVO=new TaskPlanBasicInfoVO(); + taskPlanBasicInfoVO.setId(planInfo.getId()); + taskPlanBasicInfoVO.setName(planInfo.getName()); + taskPlanBasicInfoVO.setTemplateId(planInfo.getTemplateId()); + taskPlanBasicInfoVO.setCreator(planInfo.getCreator()); + taskPlanBasicInfoVO.setCreateTime(planInfo.getCreateTime()); + taskPlanBasicInfoVO.setLastModifyUser(planInfo.getLastModifyUser()); + taskPlanBasicInfoVO.setLastModifyTime(planInfo.getLastModifyTime()); + return taskPlanBasicInfoVO; + } + public static TaskPlanVO toVO(TaskPlanInfoDTO planInfo) { TaskPlanVO planVO = new TaskPlanVO(); planVO.setId(planInfo.getId()); diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/plan/TaskPlanService.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/plan/TaskPlanService.java index fd57d39536..129f615a92 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/plan/TaskPlanService.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/plan/TaskPlanService.java @@ -180,7 +180,16 @@ PageData listPageTaskPlansBasicInfo( TaskPlanInfoDTO getDebugTaskPlan(String username, Long appId, Long templateId); /** - * 根据执行方案 ID 列表批量获取执行方案基本信息 + * 根据执行方案 ID 列表批量获取执行方案基本信息(含变量与模板信息) + * + * @param appId 业务 ID + * @param planIdList 执行方案 ID 列表 + * @return 执行方案基本信息列表 + */ + List listPlanBasicInfoWithVariablesByIds(Long appId, List planIdList); + + /** + * 根据执行方案 ID 列表批量获取执行方案基本信息(不含变量与模板信息) * * @param appId 业务 ID * @param planIdList 执行方案 ID 列表 diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/plan/impl/TaskPlanServiceImpl.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/plan/impl/TaskPlanServiceImpl.java index 15b5e3f48d..8903a15a65 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/plan/impl/TaskPlanServiceImpl.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/plan/impl/TaskPlanServiceImpl.java @@ -525,7 +525,7 @@ private void setPlanIdForVariables(Long planId, List variableLi } @Override - public List listPlanBasicInfoByIds(Long appId, List planIdList) { + public List listPlanBasicInfoWithVariablesByIds(Long appId, List planIdList) { List taskPlanInfoList = taskPlanDAO.listTaskPlanByIds( appId, planIdList, @@ -537,6 +537,16 @@ public List listPlanBasicInfoByIds(Long appId, List planI return fillTemplateInfo(appId, taskPlanInfoList); } + @Override + public List listPlanBasicInfoByIds(Long appId, List planIdList) { + return taskPlanDAO.listTaskPlanByIds( + appId, + planIdList, + null, + null + ); + } + private List fillTemplateInfo(Long appId, List planList) { List templateIdList = planList.stream().map(TaskPlanInfoDTO::getTemplateId).distinct() .collect(Collectors.toList()); diff --git a/src/frontend/package.json b/src/frontend/package.json index 5084a0995b..86cdcf7ce3 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -14,8 +14,8 @@ "keywords": [], "license": "ISC", "dependencies": { - "@blueking/ai-blueking": "0.2.7", - "@blueking/ip-selector": "0.3.0-beta.35", + "@blueking/ai-blueking": "0.2.11", + "@blueking/ip-selector": "0.3.0-beta.39", "@blueking/login-modal": "1.0.5", "@blueking/notice-component-vue2": "2.0.0-beta.2", "@blueking/paas-login": "0.0.11", @@ -30,6 +30,7 @@ "core-js": "3.38.1", "cron-parser-custom": "2.13.0", "dayjs": "1.11.13", + "dexie": "4.0.9", "diff": "5.2.0", "diff2html": "3.4.48", "echarts": "5.5.1", @@ -38,6 +39,8 @@ "js-base64": "3.7.7", "js-cookie": "3.0.5", "lodash": "4.17.21", + "markdown-it": "14.1.0", + "markdown-it-code-copy": "0.2.1", "marked": "5.1.1", "marked-gfm-heading-id": "3.1.3", "marked-mangle": "1.1.9", diff --git a/src/frontend/src/components/app-select/index.vue b/src/frontend/src/components/app-select/index.vue index 5798a54fae..8d262a3dc9 100644 --- a/src/frontend/src/components/app-select/index.vue +++ b/src/frontend/src/components/app-select/index.vue @@ -27,20 +27,20 @@ + + diff --git a/src/frontend/src/views/executive-history/step-detail/components/result-task-list/components/host-list/index.vue b/src/frontend/src/views/executive-history/step-detail/components/result-task-list/components/host-list/index.vue index e55f0d45b2..c4e661f911 100644 --- a/src/frontend/src/views/executive-history/step-detail/components/result-task-list/components/host-list/index.vue +++ b/src/frontend/src/views/executive-history/step-detail/components/result-task-list/components/host-list/index.vue @@ -172,11 +172,15 @@ import Empty from '@components/empty'; + import { + messageWarn, + } from '@/common/bkmagic'; import I18n from '@/i18n'; import useList from '../hooks/use-list'; import ColumnSetting from './column-setting'; + import CopyMenu from './copy-menu.vue'; const COLUMN_CACHE_KEY = 'STEP_EXECUTE_IP_COLUMN3'; @@ -284,44 +288,36 @@ handleClearSearch, } = useList(props, columnList, allShowColumn); - const handleCopyIP = () => { + const handleCopyIP = (withNet = false) => { props.getAllTaskList() .then((data) => { const fieldDataList = data.reduce((result, item) => { if (item.host.ip) { - result.push(item.host.ip); + result.push(withNet ? `${item.host.cloudArea.id}:${item.host.ip}` : item.host.ip); } return result; }, []); if (fieldDataList.length < 1) { - this.$bkMessage({ - theme: 'warning', - message: I18n.t('history.没有可复制的 IPv4'), - limit: 1, - }); + messageWarn(I18n.t('history.没有可复制的 IPv4')); return; } const successMessage = `${I18n.t('history.复制成功')}(${fieldDataList.length} ${I18n.t('history.个')} IP)`; execCopy(fieldDataList.join('\n'), successMessage); }); }; - const handleCopyIpv6 = () => { + const handleCopyIpv6 = (withNet = false) => { props.getAllTaskList() .then((data) => { const fieldDataList = data.reduce((result, item) => { if (item.host.ipv6) { - result.push(item.host.ipv6); + result.push(withNet ? `${item.host.cloudArea.id}:${item.host.ipv6}` : item.host.ipv6); } return result; }, []); if (fieldDataList.length < 1) { - this.$bkMessage({ - theme: 'warning', - message: I18n.t('history.没有可复制的 IPv6'), - limit: 1, - }); + messageWarn(I18n.t('history.没有可复制的 IPv6')); return; } const successMessage = `${I18n.t('history.复制成功')}(${fieldDataList.length} ${I18n.t('history.个')} IPv6)`; @@ -335,12 +331,14 @@ const renderIpHeader = (h, { column }) => (
{column.label} - - - + +
handleCopyIP()}> + IPv4 +
+
handleCopyIP(true)}> + { I18n.t('history.管控区域_ID_IPv4')} +
+
); /** @@ -349,12 +347,14 @@ const renderIpv6Header = (h, { column }) => (
{column.label} - - - + +
handleCopyIpv6()}> + IPv6 +
+
handleCopyIpv6(true)}> + { I18n.t('history.管控区域_ID_IPv6')} +
+
); /** diff --git a/src/frontend/src/views/fast-execution/distro-file/index.vue b/src/frontend/src/views/fast-execution/distro-file/index.vue index 62ff49f639..aeab569bc6 100644 --- a/src/frontend/src/views/fast-execution/distro-file/index.vue +++ b/src/frontend/src/views/fast-execution/distro-file/index.vue @@ -187,7 +187,7 @@ // 源文件列表 fileSourceList: [], // 超时 - timeout: 7200, + timeout: 600, // 上传文件限速 uploadSpeedLimit: 0, // 传输模式: 1 - 严谨模式; 2 - 强制模式;3 - 安全模式 diff --git a/src/frontend/src/views/fast-execution/exec-script/index.vue b/src/frontend/src/views/fast-execution/exec-script/index.vue index 01e6eeea0e..751b9a9a5d 100644 --- a/src/frontend/src/views/fast-execution/exec-script/index.vue +++ b/src/frontend/src/views/fast-execution/exec-script/index.vue @@ -184,7 +184,7 @@ // 敏感参数 0-关闭 1-开启 secureParam: 0, // 超时 - timeout: 7200, + timeout: 300, // 账号 account: '', // 目标服务器 diff --git a/src/frontend/src/views/script-manage/list/index.vue b/src/frontend/src/views/script-manage/list/index.vue index 2155304851..f2075674b7 100644 --- a/src/frontend/src/views/script-manage/list/index.vue +++ b/src/frontend/src/views/script-manage/list/index.vue @@ -646,18 +646,18 @@ */ renderHeader(h, data) { return ( - - { data.column.label } - - -
-
{ I18n.t('script.显示被作业引用的次数') }
-
{ I18n.t('script.显示被执行方案引用的次数') }
-
-
-
+ + { data.column.label } + + +
+
{ I18n.t('script.显示被作业引用的次数') }
+
{ I18n.t('script.显示被执行方案引用的次数') }
+
+
+
); }, }, diff --git a/src/frontend/src/views/task-manage/common/plan/list/components/batch-edit-gobal-variable/edit-value/components/edit-global-variable/host.vue b/src/frontend/src/views/task-manage/common/plan/list/components/batch-edit-gobal-variable/edit-value/components/edit-global-variable/host.vue index 01a074024c..9a72727ef6 100644 --- a/src/frontend/src/views/task-manage/common/plan/list/components/batch-edit-gobal-variable/edit-value/components/edit-global-variable/host.vue +++ b/src/frontend/src/views/task-manage/common/plan/list/components/batch-edit-gobal-variable/edit-value/components/edit-global-variable/host.vue @@ -68,8 +68,6 @@