Skip to content

Commit

Permalink
feat: Job 支持多租户 TencentBlueKing#3369
Browse files Browse the repository at this point in the history
  • Loading branch information
wangyu096 committed Jan 20, 2025
1 parent e98b6c0 commit 23bc665
Show file tree
Hide file tree
Showing 20 changed files with 247 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -54,14 +58,14 @@ public IamHttpClientServiceImpl(IamConfiguration iamConfiguration) {
}

@Override
public String doHttpGet(String uri) {
public String doHttpGet(String uri, List<Pair<String, String>> 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);
Expand All @@ -71,15 +75,15 @@ public String doHttpGet(String uri) {
}

@Override
public String doHttpPost(String uri, Object body) {
public String doHttpPost(String uri, List<Pair<String, String>> 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);
Expand All @@ -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<Pair<String, String>> 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);
Expand All @@ -109,14 +113,14 @@ public String doHttpPut(String uri, Object body) {
}

@Override
public String doHttpDelete(String uri) {
public String doHttpDelete(String uri, List<Pair<String, String>> 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);
Expand All @@ -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<Pair<String, String>> 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<String, String> header : headerList) {
headers[index++] = new BasicHeader(header.getKey(), header.getValue());
}
}
return headers;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -201,8 +201,11 @@ public List<String> batchAuth(User user,
ResourceTypeEnum resourceType,
List<String> resourceIdList) {
return authHelper.isAllowed(
user.getUsername(), actionId,
buildAppResourceScopeInstanceList(appResourceScope, resourceType, resourceIdList));
user.getTenantId(),
user.getUsername(),
actionId,
buildAppResourceScopeInstanceList(appResourceScope, resourceType, resourceIdList)
);
}

@Override
Expand All @@ -212,7 +215,7 @@ public AuthResult batchAuthResources(User user,
List<PermissionResource> resources) {
ResourceTypeEnum resourceType = resources.get(0).getResourceType();
List<String> allowResourceIds = authHelper.isAllowed(
user.getUsername(), actionId, buildInstanceList(resources));
user.getTenantId(), user.getUsername(), actionId, buildInstanceList(resources));
List<String> notAllowResourceIds =
resources.stream().filter(resource -> !allowResourceIds.contains(resource.getResourceId()))
.map(PermissionResource::getResourceId).collect(Collectors.toList());
Expand All @@ -230,7 +233,7 @@ public List<String> batchAuth(User user,
String actionId,
AppResourceScope appResourceScope,
List<PermissionResource> resourceList) {
return authHelper.isAllowed(user.getUsername(), actionId, buildInstanceList(resourceList));
return authHelper.isAllowed(user.getTenantId(), user.getUsername(), actionId, buildInstanceList(resourceList));
}

@Override
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand All @@ -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);
Expand Down Expand Up @@ -150,7 +149,7 @@ public AuthResult auth(boolean isReturnApplyUrl,
String actionId = actionResource.getActionId();
List<PermissionResourceGroup> 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);
Expand All @@ -163,7 +162,8 @@ public AuthResult auth(boolean isReturnApplyUrl,
List<PermissionResource> resources = relatedResourceGroups.get(0).getPermissionResources();
// All resources are under one application, so choose any one for authentication
List<String> allowedResourceIds =
authHelper.isAllowed(user.getUsername(), actionId, buildInstanceList(resources));
authHelper.isAllowed(user.getTenantId(), user.getUsername(),
actionId, buildInstanceList(resources));
List<String> notAllowResourceIds =
resources.stream().filter(resource -> !allowedResourceIds.contains(resource.getResourceId()))
.map(PermissionResource::getResourceId).collect(Collectors.toList());
Expand Down Expand Up @@ -197,15 +197,16 @@ public List<String> batchAuth(User user,
String actionId,
ResourceTypeEnum resourceType,
List<String> resourceIdList) {
return authHelper.isAllowed(user.getUsername(), actionId, buildInstanceList(resourceType, resourceIdList));
return authHelper.isAllowed(user.getTenantId(), user.getUsername(),
actionId, buildInstanceList(resourceType, resourceIdList));
}

@Override
public AuthResult batchAuthResources(User user,
String actionId,
List<PermissionResource> resources) {
ResourceTypeEnum resourceType = resources.get(0).getResourceType();
List<String> allowResourceIds = authHelper.isAllowed(user.getUsername(),
List<String> allowResourceIds = authHelper.isAllowed(user.getTenantId(), user.getUsername(),
actionId, buildInstanceList(resources));
List<String> notAllowResourceIds =
resources.stream().filter(resource -> !allowResourceIds.contains(resource.getResourceId()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ public interface TenantIdConstants {
* 默认租户 ID
*/
String DEFAULT_TENANT_ID = "default";

/**
* 系统租户 ID
*/
String SYSTEM_TENANT_ID = "system";
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public UserMgrApiClient(BkApiGatewayProperties bkApiGatewayProperties,
}

public List<BkUserDTO> getAllUserList(String tenantId) {
// TODO:tenant 网关暂未提供实现
return Collections.emptyList();
}

Expand All @@ -93,7 +94,7 @@ public List<OpenApiTenant> 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<OpenApiResponse<List<OpenApiTenant>>>() {
Expand Down Expand Up @@ -126,12 +127,12 @@ protected <T, R> OpenApiResponse<R> requestBkUserApi(
}

public BkUserDTO getUserByUsername(String username) {
// TODO
// TODO:tenant 网关暂未提供实现
return null;
}

public Map<String, BkUserDTO> listUsersByUsernames(Collection<String> usernames) {
// TODO
// TODO:tenant 网关暂未提供实现
return new HashMap<>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -89,6 +90,7 @@ public Response<PageData<DangerousRecordVO>> 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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 23bc665

Please sign in to comment.