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 13, 2025
1 parent 29f5eed commit 9638f56
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,6 @@ public class BaseCmdbApiClient {
*/
protected final FlowController globalFlowController;
protected final CmdbConfig cmdbConfig;
/**
* CMDB ESB API 客户端
*/
protected BkApiV1Client esbCmdbApiClient;
/**
* CMDB 蓝鲸网关 API 客户端
*/
Expand Down Expand Up @@ -138,14 +134,6 @@ protected BaseCmdbApiClient(FlowController flowController,
TenantEnvService tenantEnvService,
String lang) {
WatchableHttpHelper httpHelper = HttpHelperFactory.getRetryableHttpHelper();
this.esbCmdbApiClient = new BkApiV1Client(meterRegistry,
CmdbMetricNames.CMDB_API_PREFIX,
esbProperties.getService().getUrl(),
httpHelper,
lang,
tenantEnvService
);
this.esbCmdbApiClient.setLogger(LoggerFactory.getLogger(this.getClass()));
this.apiGwCmdbApiClient = new BkApiV1Client(meterRegistry,
CmdbMetricNames.CMDB_API_PREFIX,
bkApiGatewayProperties.getCmdb().getUrl(),
Expand All @@ -166,17 +154,15 @@ protected <T extends EsbReq> T makeCmdbBaseReq(Class<T> reqClass) {
return EsbReq.buildRequest(reqClass, cmdbSupplierAccount);
}

protected <R> EsbResp<R> requestCmdbApi(ApiGwType apiGwType,
HttpMethodEnum method,
protected <R> EsbResp<R> requestCmdbApi(HttpMethodEnum method,
String uri,
String queryParams,
EsbReq reqBody,
TypeReference<EsbResp<R>> typeReference) {
return requestCmdbApi(apiGwType, method, uri, queryParams, reqBody, typeReference, null);
return requestCmdbApi(method, uri, queryParams, reqBody, typeReference, null);
}

protected <R> EsbResp<R> requestCmdbApi(ApiGwType apiGwType,
HttpMethodEnum method,
protected <R> EsbResp<R> requestCmdbApi(HttpMethodEnum method,
String uri,
String queryParams,
EsbReq reqBody,
Expand Down Expand Up @@ -210,7 +196,7 @@ protected <R> EsbResp<R> requestCmdbApi(ApiGwType apiGwType,
.body(reqBody)
.authorization(cmdbBkApiAuthorization)
.build();
return getApiClientByApiGwType(apiGwType).doRequest(requestInfo, typeReference, httpHelper);
return apiGwCmdbApiClient.doRequest(requestInfo, typeReference, httpHelper);
} catch (Throwable e) {
String errorMsg = "Fail to request CMDB data|method=" + method + "|uri=" + uri + "|queryParams="
+ queryParams + "|body="
Expand All @@ -222,15 +208,15 @@ protected <R> EsbResp<R> requestCmdbApi(ApiGwType apiGwType,
}
}

private BkApiV1Client getApiClientByApiGwType(ApiGwType apiGwType) {
switch (apiGwType) {
case ESB:
return esbCmdbApiClient;
case BK_APIGW:
return apiGwCmdbApiClient;
default:
log.error("BkApiClient for type: {} not found", apiGwType.name());
throw new InternalException(ErrorCode.INTERNAL_ERROR);
}
}
// private BkApiV1Client getApiClientByApiGwType(ApiGwType apiGwType) {
// switch (apiGwType) {
// case ESB:
// return esbCmdbApiClient;
// case BK_APIGW:
// return apiGwCmdbApiClient;
// default:
// log.error("BkApiClient for type: {} not found", apiGwType.name());
// throw new InternalException(ErrorCode.INTERNAL_ERROR);
// }
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,24 @@ private boolean isClientOrServerError(HttpServletResponse response) {
}

private void addTenantId(HttpServletRequest request) {
// 使用 job-gateway 设置的租户 Header
String tenantId = request.getHeader(JobCommonHeaders.BK_TENANT_ID);
if (StringUtils.isEmpty(tenantId)) {
log.warn("Invalid request, tenant is not set");
HttpRequestSourceEnum requestSource = RequestUtil.parseHttpRequestSource(request);
if (requestSource == HttpRequestSourceEnum.UNKNOWN) {
return;
}
log.debug("Add tenant id to JobContext, tenantId: {}", tenantId);
JobContextUtil.setTenantId(tenantId);

switch (requestSource) {
// 仅需要处理 web/蓝鲸网关/esb 的请求
case WEB:
case ESB:
// 使用 job-gateway 设置的租户 Header
String tenantId = request.getHeader(JobCommonHeaders.BK_TENANT_ID);
if (StringUtils.isEmpty(tenantId)) {
log.warn("Invalid request, tenant is not set");
return;
}
log.debug("Add tenant id to JobContext, tenantId: {}", tenantId);
JobContextUtil.setTenantId(tenantId);
break;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Objects;

Expand All @@ -36,6 +38,7 @@
@Getter
@Setter
@ToString
@Slf4j
public class BkUserDTO {
/**
* 用户ID
Expand Down Expand Up @@ -100,4 +103,16 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(username);
}

public boolean validate() {
if (StringUtils.isEmpty(username)) {
log.warn("Empty username");
return false;
}
if (StringUtils.isEmpty(tenantId)) {
log.warn("Empty tenantId");
return false;
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
package com.tencent.bk.job.common.paas.login;

import com.fasterxml.jackson.core.type.TypeReference;
import com.tencent.bk.job.common.constant.TenantIdConstants;
import com.tencent.bk.job.common.model.dto.BkUserDTO;
import com.tencent.bk.job.common.util.http.HttpConPoolUtil;
import com.tencent.bk.job.common.util.json.JsonUtils;
Expand Down Expand Up @@ -84,6 +85,7 @@ public BkUserDTO getUserInfoByToken(String token) {
}
BkUserDTO bkUserDto = new BkUserDTO();
bkUserDto.setUsername(resp.getData().getUsername());
bkUserDto.setTenantId(TenantIdConstants.DEFAULT_TENANT_ID);
return bkUserDto;
} catch (Exception e) {
log.error("Error occur when get user info", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private GatewayFilter getLoginFilter() {
throw e;
}
}
if (user == null) {
if (user == null || !user.validate()) {
log.warn("Invalid user token");
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("x-login-url", loginService.getLoginRedirectUrl());
Expand All @@ -135,6 +135,7 @@ private GatewayFilter getLoginFilter() {
String tenantId = tenantEnvService.isTenantEnabled() ? user.getTenantId() :
TenantIdConstants.DEFAULT_TENANT_ID;
request.mutate().header(JobCommonHeaders.BK_TENANT_ID, new String[]{tenantId}).build();
log.debug("Add user info, username: {}, tenantId: {}", user.getUsername(), tenantId);
return chain.filter(exchange.mutate().request(request).build());
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
package com.tencent.bk.job.gateway.service.impl;

import com.tencent.bk.job.common.constant.ErrorCode;
import com.tencent.bk.job.common.constant.JobCommonHeaders;
import com.tencent.bk.job.common.constant.TenantIdConstants;
import com.tencent.bk.job.common.esb.config.AppProperties;
import com.tencent.bk.job.common.esb.config.BkApiGatewayProperties;
import com.tencent.bk.job.common.esb.config.EsbProperties;
Expand Down Expand Up @@ -108,6 +110,7 @@ public String getBkApiGatewayJWTPublicKey() {
authInfo.put("bk_app_secret", appProperties.getSecret());
HttpHeaders headers = new HttpHeaders();
headers.add("X-Bkapi-Authorization", JsonUtils.toJson(authInfo));
headers.add(JobCommonHeaders.BK_TENANT_ID, TenantIdConstants.DEFAULT_TENANT_ID);
EsbResp<EsbPublicKeyDTO> resp = restTemplate.exchange(
url,
HttpMethod.GET,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,12 @@ private boolean syncUsersByTenant(String tenantId) {
Set<BkUserDTO> remoteUserSet = CollectionUtils.isEmpty(remoteUserList) ?
Collections.emptySet(): new HashSet<>(remoteUserList);

// 2.计算差异数据
Set<BkUserDTO> localUserSet = new HashSet<>(userCacheService.listTenantUsers(tenantId));
// 2.获取本地缓存的租户下的所有用户
List<BkUserDTO> localUserList = userCacheService.listTenantUsers(tenantId);
Set<BkUserDTO> localUserSet = CollectionUtils.isEmpty(localUserList) ?
Collections.emptySet(): new HashSet<>(localUserList);

// 3.计算差异数据
Set<BkUserDTO> addUsers = remoteUserSet.stream()
.filter(user -> !localUserSet.contains(user)).collect(Collectors.toSet());
log.info("[{}] New users : {}",
Expand All @@ -148,7 +152,7 @@ private boolean syncUsersByTenant(String tenantId) {
tenantId,
deleteUsers.stream().map(BkUserDTO::getFullName).collect(Collectors.joining(",")));

// 3.保存
// 4.保存
userCacheService.batchPatchUsers(deleteUsers, addUsers);
} catch (Throwable t) {
log.error("Sync user fail", t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ BEGIN
AND INDEX_NAME = 'idx_app_id_task_instance_id') THEN
ALTER TABLE task_instance_host ADD INDEX `idx_app_id_task_instance_id` (`app_id`,`task_instance_id`);
END IF;

-- step_instance_script
IF NOT EXISTS(SELECT 1
FROM information_schema.COLUMNS
Expand Down

0 comments on commit 9638f56

Please sign in to comment.