Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 环境管理优化改动 #11003 #11148

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.tencent.devops.common.api.pojo.Page
import com.tencent.devops.common.api.pojo.Result
import com.tencent.devops.environment.pojo.DisplayName
import com.tencent.devops.environment.pojo.NodeWithPermission
import com.tencent.devops.environment.pojo.enums.NodeType
import io.swagger.v3.oas.annotations.tags.Tag
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
Expand Down Expand Up @@ -120,7 +121,10 @@ interface UserNodeResource {
lastModifiedUser: String?,
@Parameter(description = "关键字", required = false)
@QueryParam("keywords")
keywords: String?
keywords: String?,
@Parameter(description = "节点类型", required = false)
@QueryParam("nodeType")
nodeType: NodeType?
): Result<Page<NodeWithPermission>>

@Operation(summary = "获取用户有权限使用的服务器列表")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import io.swagger.v3.oas.annotations.media.Schema

@Schema(title = "环境信息-Node数量")
data class EnvWithNodeCount(
@get:Schema(title = "环境所属项目Id", required = true)
val projectId: String,
@get:Schema(title = "环境 HashId", required = true)
val envHashId: String,
@get:Schema(title = "环境名称", required = true)
Expand All @@ -42,6 +44,7 @@ data class EnvWithNodeCount(
@get:Schema(title = "源项目", required = false)
val sharedProjectId: String?,
@get:Schema(title = "分享人", required = false)
val sharedUserId: String?

val sharedUserId: String?,
@get:Schema(title = "节点hash id", required = false)
val nodeHashIds: List<String>? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,7 @@ data class NodeBaseInfo(
@get:Schema(title = "当前环境是否启用这个 node")
val envEnableNode: Boolean?,
@get:Schema(title = "最后更新时间")
val lastModifyTime: Long? = null
val lastModifyTime: Long? = null,
@get:Schema(title = "机型")
val size: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,9 @@ data class NodeWithPermission(
@get:Schema(title = "job任务ID")
val taskId: Long?,
@get:Schema(title = "主机serverId")
val serverId: Long?
val serverId: Long?,
@get:Schema(title = "机型")
val size: String? = null,
@get:Schema(title = "该节点所属环境名")
val envNames: List<String>? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,14 @@ enum class NodeType(val typeName: String) {
UNKNOWN("未知");

companion object {
fun coreTypesName() = listOf(CMDB.name, DEVCLOUD.name, THIRDPARTY.name, OTHER.name, UNKNOWN.name)

fun getTypeName(nodeType: String): String {
return when (nodeType) {
CMDB.name -> CMDB.typeName
DEVCLOUD.name -> DEVCLOUD.typeName
THIRDPARTY.name -> THIRDPARTY.typeName
OTHER.name -> OTHER.typeName
else -> UNKNOWN.typeName
}
return values().find { it.name == nodeType }?.typeName ?: UNKNOWN.typeName
}

fun parseByTypeName(typeName: String): NodeType {
return when (typeName) {
CMDB.typeName -> CMDB
DEVCLOUD.typeName -> DEVCLOUD
THIRDPARTY.typeName -> THIRDPARTY
OTHER.typeName -> OTHER
else -> UNKNOWN
}
return values().find { it.typeName == typeName } ?: UNKNOWN
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ class EnvNodeDao {
}
}

fun listNodeIds(dslContext: DSLContext, projectId: String, nodeIds: List<Long>): List<TEnvNodeRecord> {
with(TEnvNode.T_ENV_NODE) {
return dslContext.selectFrom(this)
.where(PROJECT_ID.eq(projectId))
.and(NODE_ID.`in`(nodeIds))
.fetch()
}
}

fun count(dslContext: DSLContext, projectId: String, envId: Long): Int {
with(TEnvNode.T_ENV_NODE) {
return dslContext.selectCount()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@
package com.tencent.devops.environment.dao

import com.tencent.devops.common.api.util.HashUtil
import com.tencent.devops.environment.constant.T_NODE_NODE_ID
import com.tencent.devops.environment.pojo.enums.NodeStatus
import com.tencent.devops.environment.pojo.enums.NodeType
import com.tencent.devops.model.environment.tables.TNode
import com.tencent.devops.model.environment.tables.records.TNodeRecord
import java.time.LocalDateTime
import org.jooq.DSLContext
import org.jooq.Record1
import org.jooq.Result
import org.jooq.impl.DSL
import org.springframework.stereotype.Repository
import java.time.LocalDateTime
import com.tencent.devops.environment.constant.T_NODE_NODE_ID

@Suppress("ALL")
@Repository
Expand Down Expand Up @@ -70,7 +70,8 @@ class NodeDao {
displayName: String?,
createdUser: String?,
lastModifiedUser: String?,
keywords: String?
keywords: String?,
nodeType: NodeType?
): List<TNodeRecord> {
return with(TNode.T_NODE) {
val query = dslContext.selectFrom(this)
Expand All @@ -90,6 +91,12 @@ class NodeDao {
if (!lastModifiedUser.isNullOrEmpty()) {
query.and(LAST_MODIFY_USER.like("%$lastModifiedUser%"))
}
if (nodeType != null) {
query.and(NODE_TYPE.eq(nodeType.name))
} else {
/*除非特别指定,暂不显示内部NodeType类型*/
query.and(NODE_TYPE.`in`(NodeType.coreTypesName()))
}
query.orderBy(LAST_MODIFY_TIME.desc())
.limit(limit).offset(offset)
.fetch()
Expand All @@ -103,7 +110,8 @@ class NodeDao {
displayName: String?,
createdUser: String?,
lastModifiedUser: String?,
keywords: String?
keywords: String?,
nodeType: NodeType?
): Int {
with(TNode.T_NODE) {
return if (projectId.isNullOrBlank()) {
Expand All @@ -129,16 +137,29 @@ class NodeDao {
if (!lastModifiedUser.isNullOrEmpty()) {
query.and(LAST_MODIFY_USER.like("%$lastModifiedUser%"))
}
if (nodeType != null) {
query.and(NODE_TYPE.eq(nodeType.name))
} else {
/*除非特别指定,暂不显示内部NodeType类型*/
query.and(NODE_TYPE.`in`(NodeType.coreTypesName()))
}
query.fetchOne(0, Int::class.java)!!
}
}
}

fun listNodes(dslContext: DSLContext, projectId: String): List<TNodeRecord> {
fun listNodes(dslContext: DSLContext, projectId: String, nodeType: NodeType? = null): List<TNodeRecord> {
with(TNode.T_NODE) {
return dslContext.selectFrom(this)
val query = dslContext.selectFrom(this)
.where(PROJECT_ID.eq(projectId))
.orderBy(NODE_ID.desc())

if (nodeType != null) {
query.and(NODE_TYPE.eq(nodeType.name))
} else {
/*除非特别指定,暂不显示内部NodeType类型*/
query.and(NODE_TYPE.`in`(NodeType.coreTypesName()))
}
return query.orderBy(NODE_ID.desc())
.fetch()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import com.tencent.devops.environment.api.UserNodeResource
import com.tencent.devops.environment.permission.EnvNodeAuthorizationService
import com.tencent.devops.environment.pojo.DisplayName
import com.tencent.devops.environment.pojo.NodeWithPermission
import com.tencent.devops.environment.pojo.enums.NodeType
import com.tencent.devops.environment.service.NodeService
import com.tencent.devops.environment.utils.NodeUtils
import org.springframework.beans.factory.annotation.Autowired
Expand Down Expand Up @@ -80,11 +81,21 @@ class UserNodeResourceImpl @Autowired constructor(
displayName: String?,
createdUser: String?,
lastModifiedUser: String?,
keywords: String?
keywords: String?,
nodeType: NodeType?
): Result<Page<NodeWithPermission>> {
return Result(
nodeService.listNew(
userId, projectId, page, pageSize, nodeIp, displayName, createdUser, lastModifiedUser, keywords
userId = userId,
projectId = projectId,
page = page,
pageSize = pageSize,
nodeIp = nodeIp,
displayName = displayName,
createdUser = createdUser,
lastModifiedUser = lastModifiedUser,
keywords = keywords,
nodeType = nodeType
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ class EnvService @Autowired constructor(
}

EnvWithNodeCount(
projectId = projectId,
envHashId = HashUtil.encodeLongId(it.envId),
name = it.envName,
normalNodeCount = normalNodeCount,
Expand Down Expand Up @@ -434,6 +435,7 @@ class EnvService @Autowired constructor(
}

EnvWithNodeCount(
projectId = projectId,
envHashId = HashUtil.encodeLongId(it.envId),
name = it.envName,
normalNodeCount = normalNodeCount,
Expand Down Expand Up @@ -705,7 +707,8 @@ class EnvService @Autowired constructor(
bakOperator = it.bakOperator,
gateway = gatewayShowName,
displayName = NodeStringIdUtils.getRefineDisplayName(nodeStringId, it.displayName),
envEnableNode = nodeIdMaps[it.nodeId] ?: true
envEnableNode = nodeIdMaps[it.nodeId] ?: true,
size = it.size
)
}
val count = nodeDao.countByNodeIdList(dslContext, projectId, nodeIdMaps.keys).toLong()
Expand Down Expand Up @@ -774,6 +777,7 @@ class EnvService @Autowired constructor(
// 验证节点类型
val existNodesMap = existNodes.associateBy { it.nodeId }
val serverNodeTypes = listOf(NodeType.CMDB.name)
val buildNodeType = listOf(NodeType.DEVCLOUD.name, NodeType.THIRDPARTY.name)

toAddNodeIds.forEach {
if (env.envType == EnvType.BUILD.name && existNodesMap[it]?.nodeType in serverNodeTypes) {
Expand All @@ -782,7 +786,7 @@ class EnvService @Autowired constructor(
params = arrayOf(HashUtil.encodeLongId(it))
)
}
if (env.envType != EnvType.BUILD.name && existNodesMap[it]?.nodeType !in serverNodeTypes) {
if (env.envType != EnvType.BUILD.name && existNodesMap[it]?.nodeType in buildNodeType) {
throw ErrorCodeException(
errorCode = ERROR_ENV_DEPLOY_CAN_NOT_ADD_AGENT,
params = arrayOf(HashUtil.encodeLongId(it))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,16 @@ import com.tencent.devops.environment.utils.AgentStatusUtils.getAgentStatus
import com.tencent.devops.environment.utils.NodeStringIdUtils
import com.tencent.devops.environment.utils.NodeUtils
import com.tencent.devops.model.environment.tables.records.TNodeRecord
import org.jooq.DSLContext
import org.jooq.impl.DSL
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.time.format.DateTimeFormatter
import java.util.concurrent.Executors
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit
import org.jooq.DSLContext
import org.jooq.impl.DSL
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

@Service
@Suppress("ALL")
Expand Down Expand Up @@ -174,7 +174,8 @@ class NodeService @Autowired constructor(
displayName: String?,
createdUser: String?,
lastModifiedUser: String?,
keywords: String?
keywords: String?,
nodeType: NodeType?
): Page<NodeWithPermission> {
val nodeRecordList =
if (-1 != page) {
Expand All @@ -188,10 +189,11 @@ class NodeService @Autowired constructor(
displayName = displayName,
createdUser = createdUser,
lastModifiedUser = lastModifiedUser,
keywords = keywords
keywords = keywords,
nodeType = nodeType
)
} else {
nodeDao.listNodes(dslContext, projectId)
nodeDao.listNodes(dslContext = dslContext, projectId = projectId, nodeType = nodeType)
}
if (nodeRecordList.isEmpty()) {
return Page(1, 0, 0, emptyList())
Expand All @@ -203,7 +205,8 @@ class NodeService @Autowired constructor(
displayName = displayName,
createdUser = createdUser,
lastModifiedUser = lastModifiedUser,
keywords = keywords
keywords = keywords,
nodeType = nodeType
).toLong()
return Page(
page = page ?: 1,
Expand Down Expand Up @@ -252,6 +255,12 @@ class NodeService @Autowired constructor(
thirdPartyAgentDao.getAgentsByNodeIds(dslContext, thirdPartyAgentNodeIds, projectId)
.associateBy { it.nodeId }

val nodeEnvs = envNodeDao.listNodeIds(dslContext, projectId, nodeListResult.map { it.nodeId })
val envInfos = envDao.listServerEnvByIdsAllType(
dslContext, nodeEnvs.map { it.envId }.toSet()
).associateBy { it.envId }
val nodeEnvsGroups = nodeEnvs.groupBy({ it.nodeId }, { envInfos[it.envId]?.envName ?: "" })

return nodeListResult.map {
val thirdPartyAgent = thirdPartyAgentMap[it.nodeId]
val gatewayShowName = if (thirdPartyAgent != null) {
Expand Down Expand Up @@ -298,7 +307,9 @@ class NodeService @Autowired constructor(
it.osType
},
bkHostId = it.hostId,
serverId = it.serverId
serverId = it.serverId,
size = it.size,
envNames = nodeEnvsGroups[it.nodeId]
)
}
}
Expand Down Expand Up @@ -496,6 +507,7 @@ class NodeService @Autowired constructor(
)
}
}

else -> {
throw ErrorCodeException(
errorCode = ERROR_NODE_CHANGE_USER_NOT_SUPPORT,
Expand Down Expand Up @@ -538,6 +550,7 @@ class NodeService @Autowired constructor(
)
}
}

else -> {
throw ErrorCodeException(
errorCode = ERROR_NODE_CHANGE_USER_NOT_SUPPORT,
Expand Down
1 change: 1 addition & 0 deletions support-files/sql/1001_ci_environment_ddl_mysql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ CREATE TABLE IF NOT EXISTS `T_NODE` (
`OS_TYPE` varchar(64) DEFAULT NULL COMMENT '从CC中查到的os类型',
`SERVER_ID` bigint(20) NULL DEFAULT NULL COMMENT '服务器id',
`SYSTEM_UPDATE_TIME` timestamp NULL DEFAULT NULL COMMENT '系统任务更新数据时间',
`SIZE` varchar(32) DEFAULT NULL COMMENT '机型',
PRIMARY KEY (`NODE_ID`),
KEY `PROJECT_ID` (`PROJECT_ID`),
KEY `HOST_ID` (`HOST_ID`),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ BEGIN
ALTER TABLE `T_NODE`
ADD INDEX `SERVER_ID` (`SERVER_ID`);
END IF;

IF NOT EXISTS(SELECT 1
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = db
AND TABLE_NAME = 'T_NODE'
AND COLUMN_NAME = 'SIZE') THEN
ALTER TABLE T_NODE
ADD COLUMN `SIZE` varchar(32) DEFAULT NULL COMMENT '机型';
END IF;

COMMIT;
END <CI_UBF>
Expand Down
Loading