From 23bc6652d36abb547dd8e2c2bf735c85db54074e Mon Sep 17 00:00:00 2001 From: wangyu096 Date: Mon, 20 Jan 2025 14:41:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Job=20=E6=94=AF=E6=8C=81=E5=A4=9A?= =?UTF-8?q?=E7=A7=9F=E6=88=B7=20#3369?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iam/http/IamHttpClientServiceImpl.java | 51 +++++--- .../iam/service/impl/AppAuthServiceImpl.java | 18 +-- .../iam/service/impl/AuthServiceImpl.java | 15 +-- .../common/constant/TenantIdConstants.java | 5 + .../common/paas/user/UserMgrApiClient.java | 7 +- .../service/impl/CronJobServiceImpl.java | 2 +- .../src/test/resources/init_schema.sql | 13 +- .../impl/WebDangerousRecordResourceImpl.java | 2 + .../auth/impl/ExecuteAuthServiceImpl.java | 16 +-- .../dao/impl/DangerousRecordDAOImpl.java | 28 ++++- .../job/execute/model/DangerousRecordDTO.java | 4 + .../impl/DangerousScriptCheckServiceImpl.java | 6 +- .../api/inner/ServiceApplicationResource.java | 16 --- .../impl/ServiceApplicationResourceImpl.java | 34 +---- .../api/web/impl/WebAppResourceImpl.java | 2 +- .../bk/job/manage/dao/ApplicationDAO.java | 2 + .../manage/dao/impl/ApplicationDAOImpl.java | 7 ++ .../manage/service/ApplicationService.java | 7 ++ .../service/impl/ApplicationServiceImpl.java | 5 + ...ob_execute_20250120-1000_V3.12.0_mysql.sql | 116 ++++++++++++++++++ 20 files changed, 247 insertions(+), 109 deletions(-) create mode 100644 support-files/sql/job-execute/0027_job_execute_20250120-1000_V3.12.0_mysql.sql diff --git a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/http/IamHttpClientServiceImpl.java b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/http/IamHttpClientServiceImpl.java index 5d5319ece4..a7b962a901 100644 --- a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/http/IamHttpClientServiceImpl.java +++ b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/http/IamHttpClientServiceImpl.java @@ -38,9 +38,13 @@ import com.tencent.bk.sdk.iam.service.HttpClientService; import io.micrometer.core.instrument.Tag; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.tuple.Pair; import org.apache.http.Header; import org.apache.http.message.BasicHeader; +import java.util.List; + @Slf4j public class IamHttpClientServiceImpl implements HttpClientService { @@ -54,14 +58,14 @@ public IamHttpClientServiceImpl(IamConfiguration iamConfiguration) { } @Override - public String doHttpGet(String uri) { + public String doHttpGet(String uri, List> headerList) { try { HttpMetricUtil.setHttpMetricName(CommonMetricNames.IAM_API_HTTP); HttpMetricUtil.addTagForCurrentMetric(Tag.of("api_name", uri)); return httpHelper.requestForSuccessResp( - HttpRequest.builder(HttpMethodEnum.GET, buildUrl(uri)) - .setHeaders(buildAuthHeader()) - .build()) + HttpRequest.builder(HttpMethodEnum.GET, buildUrl(uri)) + .setHeaders(buildHeaders(headerList)) + .build()) .getEntity(); } catch (Exception e) { throw new InternalIamException(e, ErrorCode.IAM_API_DATA_ERROR, null); @@ -71,15 +75,15 @@ public String doHttpGet(String uri) { } @Override - public String doHttpPost(String uri, Object body) { + public String doHttpPost(String uri, List> headerList, Object body) { try { HttpMetricUtil.setHttpMetricName(CommonMetricNames.IAM_API_HTTP); HttpMetricUtil.addTagForCurrentMetric(Tag.of("api_name", uri)); return httpHelper.requestForSuccessResp( - HttpRequest.builder(HttpMethodEnum.POST, buildUrl(uri)) - .setHeaders(buildAuthHeader()) - .setStringEntity(JsonUtils.toJson(body)) - .build()) + HttpRequest.builder(HttpMethodEnum.POST, buildUrl(uri)) + .setHeaders(buildHeaders(headerList)) + .setStringEntity(JsonUtils.toJson(body)) + .build()) .getEntity(); } catch (Exception e) { log.error("Fail to request IAM", e); @@ -90,15 +94,15 @@ public String doHttpPost(String uri, Object body) { } @Override - public String doHttpPut(String uri, Object body) { + public String doHttpPut(String uri, List> headerList, Object body) { try { HttpMetricUtil.setHttpMetricName(CommonMetricNames.IAM_API_HTTP); HttpMetricUtil.addTagForCurrentMetric(Tag.of("api_name", uri)); return httpHelper.requestForSuccessResp( - HttpRequest.builder(HttpMethodEnum.PUT, buildUrl(uri)) - .setHeaders(buildAuthHeader()) - .setStringEntity(JsonUtils.toJson(body)) - .build()) + HttpRequest.builder(HttpMethodEnum.PUT, buildUrl(uri)) + .setHeaders(buildHeaders(headerList)) + .setStringEntity(JsonUtils.toJson(body)) + .build()) .getEntity(); } catch (Exception e) { log.error("Fail to request IAM", e); @@ -109,14 +113,14 @@ public String doHttpPut(String uri, Object body) { } @Override - public String doHttpDelete(String uri) { + public String doHttpDelete(String uri, List> headerList) { try { HttpMetricUtil.setHttpMetricName(CommonMetricNames.IAM_API_HTTP); HttpMetricUtil.addTagForCurrentMetric(Tag.of("api_name", uri)); return httpHelper.requestForSuccessResp( - HttpRequest.builder(HttpMethodEnum.DELETE, buildUrl(uri)) - .setHeaders(buildAuthHeader()) - .build()) + HttpRequest.builder(HttpMethodEnum.DELETE, buildUrl(uri)) + .setHeaders(buildHeaders(headerList)) + .build()) .getEntity(); } catch (Exception e) { throw new InternalIamException(e, ErrorCode.IAM_API_DATA_ERROR, null); @@ -129,10 +133,17 @@ private String buildUrl(String uri) { return iamConfiguration.getIamBaseUrl() + uri; } - private Header[] buildAuthHeader() { - Header[] headers = new Header[2]; + private Header[] buildHeaders(List> headerList) { + int headerSize = (CollectionUtils.isEmpty(headerList) ? 0 : headerList.size()) + 2; + Header[] headers = new Header[headerSize]; headers[0] = new BasicHeader(HttpHeader.BK_APP_CODE, iamConfiguration.getAppCode()); headers[1] = new BasicHeader(HttpHeader.BK_APP_SECRET, iamConfiguration.getAppSecret()); + if (CollectionUtils.isNotEmpty(headerList)) { + int index = 2; + for (Pair header : headerList) { + headers[index++] = new BasicHeader(header.getKey(), header.getValue()); + } + } return headers; } diff --git a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AppAuthServiceImpl.java b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AppAuthServiceImpl.java index dee659fc8f..e143bcd071 100644 --- a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AppAuthServiceImpl.java +++ b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AppAuthServiceImpl.java @@ -64,7 +64,6 @@ import java.util.List; import java.util.stream.Collectors; -// TODO: tenant -- 需要实现调用 IAM SDK 传入 tenantId @Slf4j public class AppAuthServiceImpl extends BasicAuthService implements AppAuthService { private final AuthHelper authHelper; @@ -103,7 +102,8 @@ public void setResourceNameQueryService(ResourceNameQueryService resourceNameQue public AuthResult auth(User user, String actionId, AppResourceScope appResourceScope) { - boolean isAllowed = authHelper.isAllowed(user.getUsername(), actionId, buildInstanceWithPath(appResourceScope)); + boolean isAllowed = authHelper.isAllowed(user.getTenantId(), user.getUsername(), + actionId, buildInstanceWithPath(appResourceScope)); if (isAllowed) { return AuthResult.pass(user); } else { @@ -201,8 +201,11 @@ public List batchAuth(User user, ResourceTypeEnum resourceType, List resourceIdList) { return authHelper.isAllowed( - user.getUsername(), actionId, - buildAppResourceScopeInstanceList(appResourceScope, resourceType, resourceIdList)); + user.getTenantId(), + user.getUsername(), + actionId, + buildAppResourceScopeInstanceList(appResourceScope, resourceType, resourceIdList) + ); } @Override @@ -212,7 +215,7 @@ public AuthResult batchAuthResources(User user, List resources) { ResourceTypeEnum resourceType = resources.get(0).getResourceType(); List allowResourceIds = authHelper.isAllowed( - user.getUsername(), actionId, buildInstanceList(resources)); + user.getTenantId(), user.getUsername(), actionId, buildInstanceList(resources)); List notAllowResourceIds = resources.stream().filter(resource -> !allowResourceIds.contains(resource.getResourceId())) .map(PermissionResource::getResourceId).collect(Collectors.toList()); @@ -230,7 +233,7 @@ public List batchAuth(User user, String actionId, AppResourceScope appResourceScope, List resourceList) { - return authHelper.isAllowed(user.getUsername(), actionId, buildInstanceList(resourceList)); + return authHelper.isAllowed(user.getTenantId(), user.getUsername(), actionId, buildInstanceList(resourceList)); } @Override @@ -242,7 +245,8 @@ public AppResourceScopeResult getAppResourceScopeList(User user, ActionDTO action = new ActionDTO(); action.setId(ActionId.ACCESS_BUSINESS); - ExpressionDTO expression = policyService.getPolicyByAction(user.getUsername(), action, null); + ExpressionDTO expression = policyService.getPolicyByAction(user.getTenantId(), + user.getUsername(), action, null); if (ExpressionOperationEnum.ANY == expression.getOperator()) { result.setAny(true); } else { diff --git a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AuthServiceImpl.java b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AuthServiceImpl.java index 1ecb847422..2a17f76fdd 100644 --- a/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AuthServiceImpl.java +++ b/src/backend/commons/common-iam/src/main/java/com/tencent/bk/job/common/iam/service/impl/AuthServiceImpl.java @@ -69,7 +69,6 @@ import java.util.Map; import java.util.stream.Collectors; -// TODO: tenant @Slf4j public class AuthServiceImpl extends BasicAuthService implements AuthService { private final AuthHelper authHelper; @@ -101,7 +100,7 @@ public void setResourceNameQueryService(ResourceNameQueryService resourceNameQue @Override public AuthResult auth(User user, String actionId) { - boolean isAllowed = authHelper.isAllowed(user.getUsername(), actionId); + boolean isAllowed = authHelper.isAllowed(user.getTenantId(), user.getUsername(), actionId); if (isAllowed) { return AuthResult.pass(user); } else { @@ -115,7 +114,7 @@ public AuthResult auth(User user, ResourceTypeEnum resourceType, String resourceId, PathInfoDTO pathInfo) { - boolean isAllowed = authHelper.isAllowed(user.getUsername(), + boolean isAllowed = authHelper.isAllowed(user.getTenantId(), user.getUsername(), actionId, buildInstance(resourceType, resourceId, pathInfo)); if (isAllowed) { return AuthResult.pass(user); @@ -150,7 +149,7 @@ public AuthResult auth(boolean isReturnApplyUrl, String actionId = actionResource.getActionId(); List relatedResourceGroups = actionResource.getResourceGroups(); if (relatedResourceGroups == null || relatedResourceGroups.isEmpty()) { - if (!authHelper.isAllowed(user.getUsername(), actionId)) { + if (!authHelper.isAllowed(user.getTenantId(), user.getUsername(), actionId)) { authResult.setPass(false); PermissionActionResource requiredActionResource = new PermissionActionResource(); requiredActionResource.setActionId(actionId); @@ -163,7 +162,8 @@ public AuthResult auth(boolean isReturnApplyUrl, List resources = relatedResourceGroups.get(0).getPermissionResources(); // All resources are under one application, so choose any one for authentication List allowedResourceIds = - authHelper.isAllowed(user.getUsername(), actionId, buildInstanceList(resources)); + authHelper.isAllowed(user.getTenantId(), user.getUsername(), + actionId, buildInstanceList(resources)); List notAllowResourceIds = resources.stream().filter(resource -> !allowedResourceIds.contains(resource.getResourceId())) .map(PermissionResource::getResourceId).collect(Collectors.toList()); @@ -197,7 +197,8 @@ public List batchAuth(User user, String actionId, ResourceTypeEnum resourceType, List resourceIdList) { - return authHelper.isAllowed(user.getUsername(), actionId, buildInstanceList(resourceType, resourceIdList)); + return authHelper.isAllowed(user.getTenantId(), user.getUsername(), + actionId, buildInstanceList(resourceType, resourceIdList)); } @Override @@ -205,7 +206,7 @@ public AuthResult batchAuthResources(User user, String actionId, List resources) { ResourceTypeEnum resourceType = resources.get(0).getResourceType(); - List allowResourceIds = authHelper.isAllowed(user.getUsername(), + List allowResourceIds = authHelper.isAllowed(user.getTenantId(), user.getUsername(), actionId, buildInstanceList(resources)); List notAllowResourceIds = resources.stream().filter(resource -> !allowResourceIds.contains(resource.getResourceId())) diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/TenantIdConstants.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/TenantIdConstants.java index bf15fd93d1..0176b503a8 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/TenantIdConstants.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/constant/TenantIdConstants.java @@ -9,4 +9,9 @@ public interface TenantIdConstants { * 默认租户 ID */ String DEFAULT_TENANT_ID = "default"; + + /** + * 系统租户 ID + */ + String SYSTEM_TENANT_ID = "system"; } diff --git a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/user/UserMgrApiClient.java b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/user/UserMgrApiClient.java index 2a9c325707..4cad311092 100644 --- a/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/user/UserMgrApiClient.java +++ b/src/backend/commons/paas-sdk/src/main/java/com/tencent/bk/job/common/paas/user/UserMgrApiClient.java @@ -80,6 +80,7 @@ public UserMgrApiClient(BkApiGatewayProperties bkApiGatewayProperties, } public List getAllUserList(String tenantId) { + // TODO:tenant 网关暂未提供实现 return Collections.emptyList(); } @@ -93,7 +94,7 @@ public List listAllTenant() { .builder() .method(HttpMethodEnum.GET) .uri("/api/v3/open/tenants") - .addHeader(new BasicHeader(JobCommonHeaders.BK_TENANT_ID, TenantIdConstants.DEFAULT_TENANT_ID)) + .addHeader(new BasicHeader(JobCommonHeaders.BK_TENANT_ID, TenantIdConstants.SYSTEM_TENANT_ID)) .authorization(authorization) .build(), request -> doRequest(request, new TypeReference>>() { @@ -126,12 +127,12 @@ protected OpenApiResponse requestBkUserApi( } public BkUserDTO getUserByUsername(String username) { - // TODO + // TODO:tenant 网关暂未提供实现 return null; } public Map listUsersByUsernames(Collection usernames) { - // TODO + // TODO:tenant 网关暂未提供实现 return new HashMap<>(); } } diff --git a/src/backend/job-crontab/service-job-crontab/src/main/java/com/tencent/bk/job/crontab/service/impl/CronJobServiceImpl.java b/src/backend/job-crontab/service-job-crontab/src/main/java/com/tencent/bk/job/crontab/service/impl/CronJobServiceImpl.java index a74235a082..06483e6d72 100644 --- a/src/backend/job-crontab/service-job-crontab/src/main/java/com/tencent/bk/job/crontab/service/impl/CronJobServiceImpl.java +++ b/src/backend/job-crontab/service-job-crontab/src/main/java/com/tencent/bk/job/crontab/service/impl/CronJobServiceImpl.java @@ -873,7 +873,7 @@ public boolean disableCronJobByAppId(Long appId) { log.info("cron job will be disabled, appId:{}, cronJobIds:{}", appId, cronJobIdList); for (Long cronJobId : cronJobIdList) { try { - // TODO: tenant 需要修改实现,不能只传入系统用户 ID + // TODO:tenant 需要修改实现,不能只传入系统用户 ID // Boolean disableResult = changeCronJobEnableStatus(JobConstants.DEFAULT_SYSTEM_USER_ADMIN, appId, // cronJobId, false); Boolean disableResult = changeCronJobEnableStatus(null, appId, diff --git a/src/backend/job-execute/boot-job-execute/src/test/resources/init_schema.sql b/src/backend/job-execute/boot-job-execute/src/test/resources/init_schema.sql index e1f837af59..56e5170d0e 100644 --- a/src/backend/job-execute/boot-job-execute/src/test/resources/init_schema.sql +++ b/src/backend/job-execute/boot-job-execute/src/test/resources/init_schema.sql @@ -308,14 +308,13 @@ CREATE TABLE IF NOT EXISTS `dangerous_record` `action` tinyint(4) NOT NULL, `check_result` text NOT NULL, `ext_data` text, + `tenant_id` varchar(32) NOT NULL DEFAULT 'default', PRIMARY KEY (`id`), - KEY `idx_create_time_rule_id` (`create_time`, `rule_id`), - KEY `idx_create_time_rule_expression` (`create_time`, `rule_expression`), - KEY `idx_create_time_app_id` (`create_time`, `app_id`), - KEY `idx_create_time_operator` (`create_time`, `operator`), - KEY `idx_create_time_startup_mode` (`create_time`, `startup_mode`), - KEY `idx_create_time_client` (`create_time`, `client`), - KEY `idx_create_time_mode` (`create_time`, `action`) + KEY `idx_tenant_id_ctime` (`tenant_id`,`create_time`), + KEY `idx_rule_id_ctime` (`rule_id`,`create_time`), + KEY `idx_app_id_ctime` (`app_id`,`create_time`), + KEY `idx_operator_ctime` (`operator`,`create_time`), + KEY `idx_client_ctime` (`client`,`create_time`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/web/impl/WebDangerousRecordResourceImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/web/impl/WebDangerousRecordResourceImpl.java index 53db234e18..b9664dc32b 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/web/impl/WebDangerousRecordResourceImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/api/web/impl/WebDangerousRecordResourceImpl.java @@ -32,6 +32,7 @@ import com.tencent.bk.job.common.model.PageData; import com.tencent.bk.job.common.model.Response; import com.tencent.bk.job.common.service.AppScopeMappingService; +import com.tencent.bk.job.common.util.JobContextUtil; import com.tencent.bk.job.common.util.date.DateUtils; import com.tencent.bk.job.execute.api.web.WebDangerousRecordResource; import com.tencent.bk.job.execute.model.DangerousRecordDTO; @@ -89,6 +90,7 @@ public Response> pageListDangerousRecords(String use if (StringUtils.isNotEmpty(scopeType) && StringUtils.isNotEmpty(scopeId)) { query.setAppId(appScopeMappingService.getAppIdByScope(scopeType, scopeId)); } + query.setTenantId(JobContextUtil.getTenantId()); BaseSearchCondition baseSearchCondition = new BaseSearchCondition(); if (StringUtils.isNotBlank(startTime)) { diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/auth/impl/ExecuteAuthServiceImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/auth/impl/ExecuteAuthServiceImpl.java index 433bb28813..2a6ec157dd 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/auth/impl/ExecuteAuthServiceImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/auth/impl/ExecuteAuthServiceImpl.java @@ -106,7 +106,7 @@ public AuthResult authFastExecuteScript(User user, log.debug("Auth fast execute script, username:{}, appResourceScope:{}, hostInstances:{}", user.getUsername(), appResourceScope, hostInstanceList); } - boolean isAllowed = authHelper.isAllowed( + boolean isAllowed = authHelper.isAllowed(user.getTenantId(), user.getUsername(), ActionId.QUICK_EXECUTE_SCRIPT, null, hostInstanceList); if (isAllowed) { @@ -132,7 +132,7 @@ public AuthResult authFastPushFile(User user, log.debug("Auth Fast transfer file, username:{}, appResourceScope:{}, hostInstances:{}", user.getUsername(), appResourceScope, hostInstanceList); } - boolean isAllowed = authHelper.isAllowed( + boolean isAllowed = authHelper.isAllowed(user.getTenantId(), user.getUsername(), ActionId.QUICK_TRANSFER_FILE, null, hostInstanceList); if (isAllowed) { @@ -160,7 +160,7 @@ public AuthResult authExecuteAppScript(User user, AppResourceScope appResourceSc "hostInstances:{}", user.getUsername(), appResourceScope, scriptId, scriptInstance, hostInstanceList); } - boolean isAllowed = authHelper.isAllowed(user.getUsername(), + boolean isAllowed = authHelper.isAllowed(user.getTenantId(), user.getUsername(), ActionId.EXECUTE_SCRIPT, scriptInstance, hostInstanceList); if (isAllowed) { @@ -219,8 +219,8 @@ public AuthResult authExecutePublicScript(User user, log.debug("Auth execute public script, username:{}, appResourceScope:{}, scriptId:{}, scriptInstance:{}, " + "hostInstances:{}", user.getUsername(), appResourceScope, scriptId, scriptInstance, hostInstanceList); } - boolean isAllowed = authHelper.isAllowed(user.getUsername(), ActionId.EXECUTE_PUBLIC_SCRIPT, scriptInstance, - hostInstanceList); + boolean isAllowed = authHelper.isAllowed(user.getTenantId(), user.getUsername(), + ActionId.EXECUTE_PUBLIC_SCRIPT, scriptInstance, hostInstanceList); if (isAllowed) { return AuthResult.pass(user); @@ -268,7 +268,7 @@ public AuthResult authExecutePlan(User user, " hostInstances:{}", user.getUsername(), appResourceScope, planId, planInstance, hostInstanceList); } - boolean isAllowed = authHelper.isAllowed(user.getUsername(), + boolean isAllowed = authHelper.isAllowed(user.getTenantId(), user.getUsername(), ActionId.LAUNCH_JOB_PLAN, planInstance, hostInstanceList); if (isAllowed) { @@ -313,8 +313,8 @@ public AuthResult authDebugTemplate(User user, "hostInstances:{}", user.getUsername(), appResourceScope, templateId, jobTemplateInstance, hostInstanceList); } - boolean isAllowed = authHelper.isAllowed(user.getUsername(), ActionId.DEBUG_JOB_TEMPLATE, jobTemplateInstance, - hostInstanceList); + boolean isAllowed = authHelper.isAllowed(user.getTenantId(), user.getUsername(), ActionId.DEBUG_JOB_TEMPLATE, + jobTemplateInstance, hostInstanceList); if (isAllowed) { return AuthResult.pass(user); diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/impl/DangerousRecordDAOImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/impl/DangerousRecordDAOImpl.java index 37fc87d883..40c56264c8 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/impl/DangerousRecordDAOImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/impl/DangerousRecordDAOImpl.java @@ -78,7 +78,8 @@ public PageData listPageDangerousRecord(DangerousRecordDTO q T.CLIENT, T.ACTION, T.CHECK_RESULT, - T.EXT_DATA) + T.EXT_DATA, + T.TENANT_ID) .from(T) .where(buildSearchCondition(query, baseSearchCondition)) .orderBy(T.ID.desc()) @@ -95,6 +96,7 @@ private int getPageDangerousRecordCount(DangerousRecordDTO query, BaseSearchCond private List buildSearchCondition(DangerousRecordDTO query, BaseSearchCondition baseSearchCondition) { List conditions = new ArrayList<>(); + conditions.add(T.TENANT_ID.eq(query.getTenantId())); if (baseSearchCondition.getCreateTimeStart() != null) { conditions.add(T.CREATE_TIME.ge(baseSearchCondition.getCreateTimeStart())); } @@ -164,15 +166,30 @@ private DangerousRecordDTO extractInfo(Record record) { dangerousRecord.setExtData(JsonUtils.fromJson(extData, new TypeReference>() { })); } + dangerousRecord.setTenantId(record.get(T.TENANT_ID)); return dangerousRecord; } @Override @MySQLOperation(table = "dangerous_record", op = DbOperationEnum.WRITE) public boolean saveDangerousRecord(DangerousRecordDTO record) { - int count = dsl().insertInto(T, T.RULE_ID, T.RULE_EXPRESSION, T.APP_ID, T.APP_NAME, - T.OPERATOR, T.SCRIPT_LANGUAGE, - T.SCRIPT_CONTENT, T.CREATE_TIME, T.STARTUP_MODE, T.CLIENT, T.ACTION, T.CHECK_RESULT, T.EXT_DATA) + int count = dsl().insertInto( + T, + T.RULE_ID, + T.RULE_EXPRESSION, + T.APP_ID, + T.APP_NAME, + T.OPERATOR, + T.SCRIPT_LANGUAGE, + T.SCRIPT_CONTENT, + T.CREATE_TIME, + T.STARTUP_MODE, + T.CLIENT, + T.ACTION, + T.CHECK_RESULT, + T.EXT_DATA, + T.TENANT_ID + ) .values(record.getRuleId(), record.getRuleExpression(), record.getAppId(), @@ -184,7 +201,8 @@ public boolean saveDangerousRecord(DangerousRecordDTO record) { JooqDataTypeUtil.toByte(record.getStartupMode()), record.getClient(), JooqDataTypeUtil.toByte(record.getAction()), JsonUtils.toJson(record.getCheckResult()), - record.getExtData() == null ? "" : JsonUtils.toJson(record.getExtData())) + record.getExtData() == null ? "" : JsonUtils.toJson(record.getExtData()), + record.getTenantId()) .execute(); return count > 0; } diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/model/DangerousRecordDTO.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/model/DangerousRecordDTO.java index 3bc3f182b7..be3c055325 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/model/DangerousRecordDTO.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/model/DangerousRecordDTO.java @@ -98,6 +98,10 @@ public class DangerousRecordDTO { * 扩展数据 */ private Map extData; + /** + * 租户 ID + */ + private String tenantId; public DangerousRecordVO toDangerousRecordVO() { DangerousRecordVO recordVO = new DangerousRecordVO(); diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/DangerousScriptCheckServiceImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/DangerousScriptCheckServiceImpl.java index 9aec988d5c..dc2ec6d436 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/DangerousScriptCheckServiceImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/DangerousScriptCheckServiceImpl.java @@ -130,9 +130,7 @@ private DangerousRecordDTO buildDangerousRecord(TaskInstanceDTO taskInstance, St record.setAction(checkResultItem.getAction()); record.setAppId(taskInstance.getAppId()); ServiceApplicationDTO app = applicationService.getAppById(taskInstance.getAppId()); - if (app != null) { - record.setAppName(app.getName()); - } + record.setAppName(app.getName()); record.setCreateTime(System.currentTimeMillis()); record.setStartupMode(taskInstance.getStartupMode()); if (TaskStartupModeEnum.getStartupMode(taskInstance.getStartupMode()) == TaskStartupModeEnum.API) { @@ -152,6 +150,8 @@ private DangerousRecordDTO buildDangerousRecord(TaskInstanceDTO taskInstance, St ScriptCheckResultDTO checkResult = new ScriptCheckResultDTO(checkItems); record.setCheckResult(checkResult); + record.setTenantId(app.getTenantId()); + return record; } diff --git a/src/backend/job-manage/api-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/ServiceApplicationResource.java b/src/backend/job-manage/api-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/ServiceApplicationResource.java index c1694bb612..cef66ae08f 100644 --- a/src/backend/job-manage/api-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/ServiceApplicationResource.java +++ b/src/backend/job-manage/api-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/ServiceApplicationResource.java @@ -43,22 +43,6 @@ @SmartFeignClient(value = "job-manage", contextId = "applicationResource") @InternalAPI public interface ServiceApplicationResource { - /** - * 查询CMDB中的常规业务列表 - * - * @return 业务列表 - */ - @RequestMapping("/service/app/list/normal") - InternalResponse> listNormalApps(); - - /** - * 查询CMDB中的业务集、全业务等非常规业务列表 - * - * @return 业务集、全业务列表 - */ - @RequestMapping("/service/app/list/bizSet") - InternalResponse> listBizSetApps(); - /** * 根据业务id查询业务 * 根据Job业务id查询业务 diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/impl/ServiceApplicationResourceImpl.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/impl/ServiceApplicationResourceImpl.java index 16ce3d3248..6602a50b90 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/impl/ServiceApplicationResourceImpl.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/inner/impl/ServiceApplicationResourceImpl.java @@ -34,7 +34,6 @@ import com.tencent.bk.job.common.model.dto.ApplicationDTO; import com.tencent.bk.job.common.model.dto.ResourceScope; import com.tencent.bk.job.manage.api.inner.ServiceApplicationResource; -import com.tencent.bk.job.manage.model.inner.ServiceAppBaseInfoDTO; import com.tencent.bk.job.manage.model.inner.ServiceApplicationAttrsDTO; import com.tencent.bk.job.manage.model.inner.resp.ServiceApplicationDTO; import com.tencent.bk.job.manage.service.ApplicationService; @@ -65,24 +64,6 @@ public ServiceApplicationResourceImpl(ApplicationService applicationService, this.bizSetCmdbClient = bizSetCmdbClient; } - @Override - public InternalResponse> listNormalApps() { - List appList = applicationService.listAllApps(); - List resultList = - appList.stream().filter(ApplicationDTO::isBiz) - .map(this::convertToServiceAppBaseInfo).collect(Collectors.toList()); - return InternalResponse.buildSuccessResp(resultList); - } - - @Override - public InternalResponse> listBizSetApps() { - List applicationInfoDTOList = - applicationService.listAppsByScopeType(ResourceScopeTypeEnum.BIZ_SET); - List resultList = - applicationInfoDTOList.stream().map(this::convertToServiceApp).collect(Collectors.toList()); - return InternalResponse.buildSuccessResp(resultList); - } - @Override public ServiceApplicationDTO queryAppById(Long appId) { ApplicationDTO appInfo = applicationService.getAppByAppId(appId); @@ -114,15 +95,6 @@ private ServiceApplicationDTO convertToServiceApp(ApplicationDTO appInfo) { return app; } - private ServiceAppBaseInfoDTO convertToServiceAppBaseInfo(ApplicationDTO appInfo) { - ServiceAppBaseInfoDTO appBaseInfoDTO = new ServiceAppBaseInfoDTO(); - appBaseInfoDTO.setScopeType(appInfo.getScope().getType().getValue()); - appBaseInfoDTO.setScopeId(appInfo.getScope().getId()); - appBaseInfoDTO.setAppId(appInfo.getId()); - appBaseInfoDTO.setName(appInfo.getName()); - return appBaseInfoDTO; - } - @Override public ServiceApplicationDTO queryAppByScope(String scopeType, String scopeId) { ApplicationDTO appInfo = applicationService.getAppByScope(new ResourceScope(scopeType, scopeId)); @@ -188,7 +160,7 @@ public InternalResponse> listAllAppIdOfArchivedScope() { .map(ccBizApp -> ccBizApp.getScope().getId()) .collect(Collectors.toSet()); archivedIds.addAll(bizApps.stream().filter(bizAppInfoDTO -> - !ccBizAppScopeIds.contains(bizAppInfoDTO.getScope().getId())) + !ccBizAppScopeIds.contains(bizAppInfoDTO.getScope().getId())) .map(ApplicationDTO::getId) .collect(Collectors.toList())); } @@ -198,7 +170,7 @@ public InternalResponse> listAllAppIdOfArchivedScope() { .map(ccBizSetApp -> String.valueOf(ccBizSetApp.getId())) .collect(Collectors.toSet()); archivedIds.addAll(bizSetApps.stream().filter(bizAppInfoDTO -> - !ccBizSetAppScopeIds.contains(bizAppInfoDTO.getScope().getId())) + !ccBizSetAppScopeIds.contains(bizAppInfoDTO.getScope().getId())) .map(ApplicationDTO::getId) .collect(Collectors.toList())); } @@ -211,7 +183,7 @@ public InternalResponse existsAppById(Long appId) { try { ApplicationDTO appInfo = applicationService.getAppByAppId(appId); return InternalResponse.buildSuccessResp(appInfo != null); - } catch (NotFoundException e){ + } catch (NotFoundException e) { log.info("biz/bizSet not exist, appId={}", appId); return InternalResponse.buildSuccessResp(false); } diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/impl/WebAppResourceImpl.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/impl/WebAppResourceImpl.java index 3d15bb3021..36f2a0a92e 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/impl/WebAppResourceImpl.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/api/web/impl/WebAppResourceImpl.java @@ -114,7 +114,7 @@ public Response> listAppWithFavor(Strin Integer start, Integer pageSize) { User user = JobContextUtil.getUser(); - List appList = applicationService.listAllApps(); + List appList = applicationService.listAllAppsForTenant(user.getTenantId()); List appResourceScopeList = appList.stream() .map(app -> new AppResourceScope(app.getId(), app.getScope())) diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/ApplicationDAO.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/ApplicationDAO.java index b91aa861ab..2ecfed953e 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/ApplicationDAO.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/ApplicationDAO.java @@ -48,6 +48,8 @@ public interface ApplicationDAO { List listAllApps(); + List listAllAppsForTenant(String tenantId); + List listAllBizApps(); List listAllBizAppsWithDeleted(); diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/impl/ApplicationDAOImpl.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/impl/ApplicationDAOImpl.java index f2a100b814..153262c55c 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/impl/ApplicationDAOImpl.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/impl/ApplicationDAOImpl.java @@ -155,6 +155,13 @@ public List listAllApps() { return listAppsByConditions(conditions); } + @Override + public List listAllAppsForTenant(String tenantId) { + List conditions = getBasicNotDeletedConditions(); + conditions.add(T_APP.TENANT_ID.eq(tenantId)); + return listAppsByConditions(conditions); + } + @Override public List listAppsByAppIds(List appIdList) { List conditions = getBasicNotDeletedConditions(); diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/ApplicationService.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/ApplicationService.java index 960fd5e96a..387ae233d5 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/ApplicationService.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/ApplicationService.java @@ -144,6 +144,13 @@ public interface ApplicationService { */ List listAllApps(); + /** + * 获取作业平台租户下所有业务 + * + * @return 业务列表 + */ + List listAllAppsForTenant(String tenantId); + /** * 创建业务 * diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/impl/ApplicationServiceImpl.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/impl/ApplicationServiceImpl.java index 0343199c98..8eec1940d0 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/impl/ApplicationServiceImpl.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/service/impl/ApplicationServiceImpl.java @@ -243,6 +243,11 @@ public List listAllApps() { return applicationDAO.listAllApps(); } + @Override + public List listAllAppsForTenant(String tenantId) { + return applicationDAO.listAllAppsForTenant(tenantId); + } + @Override public void updateApp(ApplicationDTO application) { log.info("Update app: {}", JsonUtils.toJson(application)); diff --git a/support-files/sql/job-execute/0027_job_execute_20250120-1000_V3.12.0_mysql.sql b/support-files/sql/job-execute/0027_job_execute_20250120-1000_V3.12.0_mysql.sql new file mode 100644 index 0000000000..09b50865ef --- /dev/null +++ b/support-files/sql/job-execute/0027_job_execute_20250120-1000_V3.12.0_mysql.sql @@ -0,0 +1,116 @@ +USE job_execute; + +SET NAMES utf8mb4; + +-- 更新 schema +DROP PROCEDURE IF EXISTS job_schema_update; + +DELIMITER + +CREATE PROCEDURE job_schema_update() +BEGIN + + DECLARE db VARCHAR(100); + SET AUTOCOMMIT = 0; + SELECT DATABASE() INTO db; + + -- dangerous_record + IF NOT EXISTS(SELECT 1 + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND COLUMN_NAME = 'tenant_id') THEN + ALTER TABLE dangerous_record ADD COLUMN `tenant_id` varchar(32) NOT NULL DEFAULT 'default'; + END IF; + IF NOT EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_tenant_id_ctime') THEN + ALTER TABLE dangerous_record ADD INDEX `idx_tenant_id_ctime` (`tenant_id`,`create_time`); + END IF; + IF NOT EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_rule_id_ctime') THEN + ALTER TABLE dangerous_record ADD INDEX `idx_rule_id_ctime` (`rule_id`,`create_time`); + END IF; + IF NOT EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_app_id_ctime') THEN + ALTER TABLE dangerous_record ADD INDEX `idx_app_id_ctime` (`app_id`,`create_time`); + END IF; + IF NOT EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_operator_ctime') THEN + ALTER TABLE dangerous_record ADD INDEX `idx_operator_ctime` (`operator`,`create_time`); + END IF; + IF NOT EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_client_ctime') THEN + ALTER TABLE dangerous_record ADD INDEX `idx_client_ctime` (`client`,`create_time`); + END IF; + IF EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_create_time_rule_id') THEN + ALTER TABLE dangerous_record DROP INDEX `idx_create_time_rule_id`; + END IF; + IF EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_create_time_rule_expression') THEN + ALTER TABLE dangerous_record DROP INDEX `idx_create_time_rule_expression`; + END IF; + IF EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_create_time_app_id') THEN + ALTER TABLE dangerous_record DROP INDEX `idx_create_time_app_id`; + END IF; + IF EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_create_time_operator') THEN + ALTER TABLE dangerous_record DROP INDEX `idx_create_time_operator`; + END IF; + IF EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_create_time_startup_mode') THEN + ALTER TABLE dangerous_record DROP INDEX `idx_create_time_startup_mode`; + END IF; + IF EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_create_time_client') THEN + ALTER TABLE dangerous_record DROP INDEX `idx_create_time_client`; + END IF; + IF EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'dangerous_record' + AND INDEX_NAME = 'idx_create_time_mode') THEN + ALTER TABLE dangerous_record DROP INDEX `idx_create_time_mode`; + END IF; + COMMIT; +END +DELIMITER ; +COMMIT; + +CALL job_schema_update(); + +DROP PROCEDURE IF EXISTS job_schema_update;