From 4b0b4d40ba3ad6cbd2d96116e247d6843118daff Mon Sep 17 00:00:00 2001 From: sawyersong Date: Tue, 23 May 2023 17:39:18 +0800 Subject: [PATCH 001/166] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96agent?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E8=8E=B7=E5=8F=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20#8857?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/worker/common/env/AgentEnv.kt | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt index adfc336cd28..6f6825c3707 100644 --- a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt +++ b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt @@ -45,17 +45,17 @@ object AgentEnv { private val logger = LoggerFactory.getLogger(AgentEnv::class.java) - private const val PROJECT_ID = "devops.project.id" - private const val DOCKER_PROJECT_ID = "devops_project_id" - private const val AGENT_ID = "devops.agent.id" - private const val DOCKER_AGENT_ID = "devops_agent_id" - private const val AGENT_SECRET_KEY = "devops.agent.secret.key" - private const val DOCKER_AGENT_SECRET_KEY = "devops_agent_secret_key" - private const val AGENT_GATEWAY = "landun.gateway" - private const val DOCKER_GATEWAY = "devops_gateway" - private const val AGENT_ENV = "landun.env" - private const val AGENT_LOG_SAVE_MODE = "devops_log_save_mode" - private const val AGENT_PROPERTIES_FILE_NAME = ".agent.properties" + const val PROJECT_ID = "devops.project.id" + const val DOCKER_PROJECT_ID = "devops_project_id" + const val AGENT_ID = "devops.agent.id" + const val DOCKER_AGENT_ID = "devops_agent_id" + const val AGENT_SECRET_KEY = "devops.agent.secret.key" + const val DOCKER_AGENT_SECRET_KEY = "devops_agent_secret_key" + const val AGENT_GATEWAY = "landun.gateway" + const val DOCKER_GATEWAY = "devops_gateway" + const val AGENT_ENV = "landun.env" + const val AGENT_LOG_SAVE_MODE = "devops_log_save_mode" + const val AGENT_PROPERTIES_FILE_NAME = ".agent.properties" private var projectId: String? = null private var agentId: String? = null @@ -74,9 +74,12 @@ object AgentEnv { if (projectId.isNullOrBlank()) { synchronized(this) { if (projectId.isNullOrBlank()) { - projectId = getProperty(if (isDockerEnv()) DOCKER_PROJECT_ID else PROJECT_ID) + projectId = getProperty(DOCKER_PROJECT_ID) if (projectId.isNullOrBlank()) { - throw PropertyNotExistException(PROJECT_ID, "Empty project Id") + projectId = getProperty(PROJECT_ID) + } + if (projectId.isNullOrBlank()) { + throw PropertyNotExistException("$PROJECT_ID|$DOCKER_PROJECT_ID", "Empty project Id") } logger.info("Get the project ID($projectId)") } @@ -89,9 +92,12 @@ object AgentEnv { if (agentId.isNullOrBlank()) { synchronized(this) { if (agentId.isNullOrBlank()) { - agentId = getProperty(if (isDockerEnv()) DOCKER_AGENT_ID else AGENT_ID) + agentId = getProperty(DOCKER_AGENT_ID) + if (agentId.isNullOrBlank()) { + agentId = getProperty(AGENT_ID) + } if (agentId.isNullOrBlank()) { - throw PropertyNotExistException(AGENT_ID, "Empty agent Id") + throw PropertyNotExistException("$AGENT_ID|$DOCKER_AGENT_ID", "Empty agent Id") } logger.info("Get the agent id($agentId)") } @@ -135,9 +141,12 @@ object AgentEnv { if (secretKey.isNullOrBlank()) { synchronized(this) { if (secretKey.isNullOrBlank()) { - secretKey = getProperty(if (isDockerEnv()) DOCKER_AGENT_SECRET_KEY else AGENT_SECRET_KEY) + secretKey = getProperty(DOCKER_AGENT_SECRET_KEY) if (secretKey.isNullOrBlank()) { - throw PropertyNotExistException(AGENT_SECRET_KEY, "Empty agent secret key") + secretKey = getProperty(AGENT_SECRET_KEY) + } + if (secretKey.isNullOrBlank()) { + throw PropertyNotExistException("$AGENT_SECRET_KEY|$DOCKER_AGENT_SECRET_KEY", "Empty agent secret key") } logger.info("Get the agent secret key($secretKey)") } @@ -151,7 +160,10 @@ object AgentEnv { synchronized(this) { if (gateway.isNullOrBlank()) { try { - gateway = getProperty(if (isDockerEnv()) DOCKER_GATEWAY else AGENT_GATEWAY) + gateway = getProperty(DOCKER_GATEWAY) + if (gateway.isNullOrBlank()) { + gateway = getProperty(AGENT_GATEWAY) + } if (gateway.isNullOrBlank()) { throw PropertyNotExistException(AGENT_GATEWAY, "Empty agent gateway") } From 11b693d573b16d17b58cb0d09c1c094310daed2e Mon Sep 17 00:00:00 2001 From: sawyersong Date: Thu, 25 May 2023 15:02:40 +0800 Subject: [PATCH 002/166] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96agent?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E8=8E=B7=E5=8F=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20#8857?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../worker/common/api/AbstractBuildResourceApi.kt | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/api/AbstractBuildResourceApi.kt b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/api/AbstractBuildResourceApi.kt index 92b6140b32e..5e6aa97099d 100644 --- a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/api/AbstractBuildResourceApi.kt +++ b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/api/AbstractBuildResourceApi.kt @@ -255,15 +255,7 @@ abstract class AbstractBuildResourceApi : WorkerRestApiSDK { map[AUTH_HEADER_DEVOPS_BUILD_TYPE] = buildType.name when (buildType) { - BuildType.AGENT -> { - map[AUTH_HEADER_DEVOPS_PROJECT_ID] = AgentEnv.getProjectId() - map[AUTH_HEADER_DEVOPS_AGENT_ID] = AgentEnv.getAgentId() - map[AUTH_HEADER_DEVOPS_AGENT_SECRET_KEY] = AgentEnv.getAgentSecretKey() - map[AUTH_HEADER_DEVOPS_PROJECT_ID] = AgentEnv.getProjectId() - map[AUTH_HEADER_DEVOPS_AGENT_ID] = AgentEnv.getAgentId() -// map[AUTH_HEADER_AGENT_SECRET_KEY] = AgentEnv.getAgentSecretKey() - } - BuildType.DOCKER -> { + BuildType.DOCKER, BuildType.AGENT, BuildType.MACOS -> { map[AUTH_HEADER_DEVOPS_PROJECT_ID] = AgentEnv.getProjectId() map[AUTH_HEADER_DEVOPS_AGENT_ID] = AgentEnv.getAgentId() map[AUTH_HEADER_DEVOPS_AGENT_SECRET_KEY] = AgentEnv.getAgentSecretKey() From 6ac09672e705c9b6b902ce552e5225233116a274 Mon Sep 17 00:00:00 2001 From: sawyersong Date: Thu, 25 May 2023 17:55:34 +0800 Subject: [PATCH 003/166] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96agent?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E8=8E=B7=E5=8F=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20#8857?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/worker/common/api/AbstractBuildResourceApi.kt | 2 +- .../kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt | 2 +- .../kotlin/com/tencent/devops/worker/common/env/BuildType.kt | 1 + .../tencent/devops/worker/common/task/market/MarketAtomTask.kt | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/api/AbstractBuildResourceApi.kt b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/api/AbstractBuildResourceApi.kt index 7c596571e81..5c208b1d1ce 100644 --- a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/api/AbstractBuildResourceApi.kt +++ b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/api/AbstractBuildResourceApi.kt @@ -292,7 +292,7 @@ abstract class AbstractBuildResourceApi : WorkerRestApiSDK { map[AUTH_HEADER_DEVOPS_BUILD_TYPE] = buildType.name when (buildType) { - BuildType.DOCKER, BuildType.AGENT, BuildType.MACOS -> { + BuildType.DOCKER, BuildType.AGENT, BuildType.MACOS, BuildType.MACOS_NEW -> { map[AUTH_HEADER_DEVOPS_PROJECT_ID] = AgentEnv.getProjectId() map[AUTH_HEADER_DEVOPS_AGENT_ID] = AgentEnv.getAgentId() map[AUTH_HEADER_DEVOPS_AGENT_SECRET_KEY] = AgentEnv.getAgentSecretKey() diff --git a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt index 2be1fc03141..e509ae5054e 100644 --- a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt +++ b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt @@ -235,7 +235,7 @@ object AgentEnv { private fun getProperty(prop: String): String? { val buildType = BuildEnv.getBuildType() - if (buildType == BuildType.DOCKER || buildType == BuildType.MACOS) { + if (buildType == BuildType.DOCKER || buildType == BuildType.MACOS || buildType == BuildType.MACOS_NEW) { logger.info("buildType is $buildType") return getEnvProp(prop) } diff --git a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/BuildType.kt b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/BuildType.kt index 5f375d8b08d..be27cac83b2 100644 --- a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/BuildType.kt +++ b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/BuildType.kt @@ -31,6 +31,7 @@ enum class BuildType { WORKER, AGENT, MACOS, + MACOS_NEW, DOCKER; companion object { diff --git a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/task/market/MarketAtomTask.kt b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/task/market/MarketAtomTask.kt index 14e9c388c1d..b06602714b3 100644 --- a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/task/market/MarketAtomTask.kt +++ b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/task/market/MarketAtomTask.kt @@ -509,7 +509,7 @@ open class MarketAtomTask : ITask() { private fun writeSdkEnv(workspace: File, buildTask: BuildTask, buildVariables: BuildVariables) { val inputFileFile = File(workspace, sdkFile) val sdkEnv: SdkEnv = when (BuildEnv.getBuildType()) { - BuildType.AGENT, BuildType.DOCKER, BuildType.MACOS -> { + BuildType.AGENT, BuildType.DOCKER, BuildType.MACOS, BuildType.MACOS_NEW -> { SdkEnv( buildType = BuildEnv.getBuildType(), projectId = buildVariables.projectId, From 56a383103ab0810b2421462612455a37a5d920b2 Mon Sep 17 00:00:00 2001 From: sawyersong Date: Thu, 25 May 2023 18:02:13 +0800 Subject: [PATCH 004/166] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96agent?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E8=8E=B7=E5=8F=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20#8857?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/worker/common/env/AgentEnv.kt | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt index e509ae5054e..223e2b06c0b 100644 --- a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt +++ b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/AgentEnv.kt @@ -47,19 +47,19 @@ object AgentEnv { private val logger = LoggerFactory.getLogger(AgentEnv::class.java) - private const val PROJECT_ID = "devops.project.id" - private const val DOCKER_PROJECT_ID = "devops_project_id" - private const val AGENT_ID = "devops.agent.id" - private const val DOCKER_AGENT_ID = "devops_agent_id" - private const val AGENT_SECRET_KEY = "devops.agent.secret.key" - private const val DOCKER_AGENT_SECRET_KEY = "devops_agent_secret_key" - private const val AGENT_GATEWAY = "landun.gateway" - private const val DOCKER_GATEWAY = "devops_gateway" - private const val AGENT_FILE_GATEWAY = "DEVOPS_FILE_GATEWAY" - private const val AGENT_ENV = "landun.env" - private const val AGENT_LOG_SAVE_MODE = "devops_log_save_mode" - private const val AGENT_PROPERTIES_FILE_NAME = ".agent.properties" - private const val BK_TAG = "devops_bk_tag" + const val PROJECT_ID = "devops.project.id" + const val DOCKER_PROJECT_ID = "devops_project_id" + const val AGENT_ID = "devops.agent.id" + const val DOCKER_AGENT_ID = "devops_agent_id" + const val AGENT_SECRET_KEY = "devops.agent.secret.key" + const val DOCKER_AGENT_SECRET_KEY = "devops_agent_secret_key" + const val AGENT_GATEWAY = "landun.gateway" + const val DOCKER_GATEWAY = "devops_gateway" + const val AGENT_FILE_GATEWAY = "DEVOPS_FILE_GATEWAY" + const val AGENT_ENV = "landun.env" + const val AGENT_LOG_SAVE_MODE = "devops_log_save_mode" + const val AGENT_PROPERTIES_FILE_NAME = ".agent.properties" + const val BK_TAG = "devops_bk_tag" private var projectId: String? = null private var agentId: String? = null From b80a144b393a1e2e6ff1ce79c57a9a3bd35ac577 Mon Sep 17 00:00:00 2001 From: sawyersong Date: Fri, 26 May 2023 11:40:32 +0800 Subject: [PATCH 005/166] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96agent?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E8=8E=B7=E5=8F=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20#8857?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/tencent/devops/worker/common/env/BuildEnv.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/BuildEnv.kt b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/BuildEnv.kt index 7f4ff1af0a9..cf54f741386 100644 --- a/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/BuildEnv.kt +++ b/src/backend/ci/core/worker/worker-common/src/main/kotlin/com/tencent/devops/worker/common/env/BuildEnv.kt @@ -47,6 +47,10 @@ object BuildEnv { return BuildType.valueOf(buildType!!) } + fun setBuildType(value: BuildType) { + this.buildType = value.name + } + fun isThirdParty() = getBuildType() == BuildType.AGENT fun getBuildId() = System.getProperty(BUILD_ID) From 33b92b368c1722752b1b994b810ba9719cdb67c4 Mon Sep 17 00:00:00 2001 From: sawyersong Date: Tue, 30 May 2023 12:10:48 +0800 Subject: [PATCH 006/166] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96agent?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E8=8E=B7=E5=8F=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20#8857?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/common/dispatch.sdk/listener/BuildListener.kt | 9 +++++++-- .../common/dispatch.sdk/service/DispatchService.kt | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/backend/ci/core/common/common-dispatch-sdk/src/main/kotlin/com/tencent/devops/common/dispatch.sdk/listener/BuildListener.kt b/src/backend/ci/core/common/common-dispatch-sdk/src/main/kotlin/com/tencent/devops/common/dispatch.sdk/listener/BuildListener.kt index 4e40a0e3c40..4ff7a1e7da3 100644 --- a/src/backend/ci/core/common/common-dispatch-sdk/src/main/kotlin/com/tencent/devops/common/dispatch.sdk/listener/BuildListener.kt +++ b/src/backend/ci/core/common/common-dispatch-sdk/src/main/kotlin/com/tencent/devops/common/dispatch.sdk/listener/BuildListener.kt @@ -36,6 +36,7 @@ import com.tencent.devops.common.dispatch.sdk.pojo.DispatchMessage import com.tencent.devops.common.dispatch.sdk.service.DispatchService import com.tencent.devops.common.dispatch.sdk.service.JobQuotaService import com.tencent.devops.common.dispatch.sdk.utils.DispatchLogRedisUtils +import com.tencent.devops.common.event.pojo.pipeline.IPipelineEvent import com.tencent.devops.common.event.pojo.pipeline.PipelineBuildFinishBroadCastEvent import com.tencent.devops.common.event.pojo.pipeline.PipelineBuildStartBroadCastEvent import com.tencent.devops.common.log.utils.BuildLogPrinter @@ -153,8 +154,12 @@ interface BuildListener { ) } - fun retry(sleepTimeInMS: Int = 30000, retryTimes: Int = 3): Boolean { - val event = DispatcherContext.getEvent() + fun retry( + sleepTimeInMS: Int = 30000, + retryTimes: Int = 3, + pipelineEvent: IPipelineEvent? = null + ): Boolean { + val event = pipelineEvent ?: DispatcherContext.getEvent() if (event == null) { logger.warn("The event is empty") return false diff --git a/src/backend/ci/core/common/common-dispatch-sdk/src/main/kotlin/com/tencent/devops/common/dispatch.sdk/service/DispatchService.kt b/src/backend/ci/core/common/common-dispatch-sdk/src/main/kotlin/com/tencent/devops/common/dispatch.sdk/service/DispatchService.kt index 6c31a364daa..d874cdccc48 100644 --- a/src/backend/ci/core/common/common-dispatch-sdk/src/main/kotlin/com/tencent/devops/common/dispatch.sdk/service/DispatchService.kt +++ b/src/backend/ci/core/common/common-dispatch-sdk/src/main/kotlin/com/tencent/devops/common/dispatch.sdk/service/DispatchService.kt @@ -48,6 +48,7 @@ import com.tencent.devops.common.dispatch.sdk.pojo.docker.DockerConstants.ENV_KE import com.tencent.devops.common.dispatch.sdk.pojo.docker.DockerConstants.ENV_KEY_PROJECT_ID import com.tencent.devops.common.dispatch.sdk.utils.ChannelUtils import com.tencent.devops.common.event.dispatcher.pipeline.PipelineEventDispatcher +import com.tencent.devops.common.event.pojo.pipeline.IPipelineEvent import com.tencent.devops.common.log.utils.BuildLogPrinter import com.tencent.devops.common.pipeline.enums.BuildStatus import com.tencent.devops.common.redis.RedisOperation @@ -195,7 +196,7 @@ class DispatchService constructor( } } - fun redispatch(event: PipelineAgentStartupEvent) { + fun redispatch(event: IPipelineEvent) { logger.info("Re-dispatch the agent event - ($event)") pipelineEventDispatcher.dispatch(event) } From 30d794e41ea482bf53d4d21415cfb782dbc1268c Mon Sep 17 00:00:00 2001 From: carlyin <449036249@qq.com> Date: Fri, 2 Jun 2023 12:02:03 +0800 Subject: [PATCH 007/166] =?UTF-8?q?feat:=E8=93=9D=E7=9B=BE=E5=86=85?= =?UTF-8?q?=E7=BD=AE=E6=8F=92=E4=BB=B6=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=20#8900?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/ArchiveAtomServiceImpl.kt | 3 + .../devops/store/pojo/atom/AtomConfigInfo.kt | 4 +- .../devops/store/pojo/atom/ReleaseInfo.kt | 2 +- .../atom/impl/AtomReleaseServiceImpl.kt | 55 ++++++++++++------- .../atom/impl/MarketAtomArchiveServiceImpl.kt | 18 ++++-- .../service/atom/impl/OpAtomServiceImpl.kt | 7 ++- 6 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomServiceImpl.kt b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomServiceImpl.kt index 89ff2f3e196..ec2fbfd93cf 100644 --- a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomServiceImpl.kt +++ b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomServiceImpl.kt @@ -135,6 +135,9 @@ abstract class ArchiveAtomServiceImpl : ArchiveAtomService { atomEnvRequests = atomConfigResult.atomEnvRequests!! packageFileInfos = mutableListOf() atomEnvRequests.forEach { atomEnvRequest -> + if (atomEnvRequest.pkgLocalPath.isNullOrBlank()) { + return@forEach + } val packageFilePathPrefix = buildAtomArchivePath(projectCode, atomCode, version) val packageFile = File("$packageFilePathPrefix/${atomEnvRequest.pkgLocalPath}") val packageFileInfo = PackageFileInfo( diff --git a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/AtomConfigInfo.kt b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/AtomConfigInfo.kt index 1c9d19e625c..6d8399399e2 100644 --- a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/AtomConfigInfo.kt +++ b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/AtomConfigInfo.kt @@ -34,5 +34,7 @@ import io.swagger.annotations.ApiModelProperty @ApiModel("插件配置信息") data class AtomConfigInfo( @ApiModelProperty(value = "前端UI渲染方式", required = true) - val frontendType: FrontendTypeEnum = FrontendTypeEnum.NORMAL + val frontendType: FrontendTypeEnum = FrontendTypeEnum.NORMAL, + @ApiModelProperty(value = "是否为默认插件", required = true) + val defaultFlag: Boolean = false ) diff --git a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/ReleaseInfo.kt b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/ReleaseInfo.kt index 01a03a88841..4419a38cc50 100644 --- a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/ReleaseInfo.kt +++ b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/ReleaseInfo.kt @@ -59,7 +59,7 @@ data class ReleaseInfo( @ApiModelProperty("适用Job类型", required = true) val jobType: JobTypeEnum, @JsonProperty(value = "labelCodes", required = false) - @ApiModelProperty("标签id集合", name = "labelCodes") + @ApiModelProperty("标签标识集合", name = "labelCodes") val labelCodes: ArrayList? = null, @ApiModelProperty("版本信息", required = true) val versionInfo: VersionInfo, diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt index ba244cd7763..c2653e7a2e2 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt @@ -93,6 +93,7 @@ import com.tencent.devops.store.pojo.common.KEY_INPUT import com.tencent.devops.store.pojo.common.KEY_INPUT_GROUPS import com.tencent.devops.store.pojo.common.KEY_LANGUAGE import com.tencent.devops.store.pojo.common.KEY_OUTPUT +import com.tencent.devops.store.pojo.common.KEY_PACKAGE_PATH import com.tencent.devops.store.pojo.common.KEY_RELEASE_INFO import com.tencent.devops.store.pojo.common.KEY_VERSION_INFO import com.tencent.devops.store.pojo.common.QUALITY_JSON_NAME @@ -240,21 +241,10 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ docsLink = storeCommonService.getStoreDetailUrl(StoreTypeEnum.ATOM, atomCode), marketAtomCreateRequest = marketAtomCreateRequest ) - // 添加插件与项目关联关系,type为0代表新增插件时关联的初始化项目 - storeProjectRelDao.addStoreProjectRel( - dslContext = context, - userId = userId, - storeCode = atomCode, - projectCode = marketAtomCreateRequest.projectCode, - type = StoreProjectTypeEnum.INIT.type.toByte(), - storeType = StoreTypeEnum.ATOM.type.toByte() - ) - storeProjectRelDao.addStoreProjectRel( + // 初始化插件统计表数据 + storeStatisticTotalDao.initStatisticData( dslContext = context, - userId = userId, storeCode = atomCode, - projectCode = marketAtomCreateRequest.projectCode, - type = StoreProjectTypeEnum.TEST.type.toByte(), storeType = StoreTypeEnum.ATOM.type.toByte() ) // 默认给新建插件的人赋予管理员权限 @@ -276,10 +266,24 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ yamlFlag = false ) ) - // 初始化插件统计表数据 - storeStatisticTotalDao.initStatisticData( + if (marketAtomCreateRequest.projectCode.isBlank()) { + return@transaction + } + // 添加插件与项目关联关系,type为0代表新增插件时关联的初始化项目 + storeProjectRelDao.addStoreProjectRel( dslContext = context, + userId = userId, storeCode = atomCode, + projectCode = marketAtomCreateRequest.projectCode, + type = StoreProjectTypeEnum.INIT.type.toByte(), + storeType = StoreTypeEnum.ATOM.type.toByte() + ) + storeProjectRelDao.addStoreProjectRel( + dslContext = context, + userId = userId, + storeCode = atomCode, + projectCode = marketAtomCreateRequest.projectCode, + type = StoreProjectTypeEnum.TEST.type.toByte(), storeType = StoreTypeEnum.ATOM.type.toByte() ) } @@ -434,17 +438,26 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ val atomEnvRequests = getAtomConfResult.atomEnvRequests ?: return I18nUtil.generateResponseDataObject( StoreMessageCode.USER_REPOSITORY_TASK_JSON_FIELD_IS_NULL, arrayOf(KEY_EXECUTION) ) - val propsMap = mutableMapOf() - propsMap[KEY_INPUT_GROUPS] = taskDataMap[KEY_INPUT_GROUPS] - propsMap[KEY_INPUT] = taskDataMap[KEY_INPUT] - propsMap[KEY_OUTPUT] = taskDataMap[KEY_OUTPUT] - propsMap[KEY_CONFIG] = taskDataMap[KEY_CONFIG] - val classType = if (convertUpdateRequest.os.isEmpty()) { + val packagePath = executionInfoMap[KEY_PACKAGE_PATH] as? String + val classType = if (packagePath.isNullOrBlank()) { + // 没有可执行文件的插件是老的内置插件,插件的classType为插件标识 + atomCode + } else if (convertUpdateRequest.os.isEmpty()) { MarketBuildLessAtomElement.classType } else { MarketBuildAtomElement.classType } + val propsMap = mutableMapOf() + val inputDataMap = taskDataMap[KEY_INPUT] as? Map + if (packagePath.isNullOrBlank()) { + inputDataMap?.let { propsMap.putAll(inputDataMap) } + } else { + propsMap[KEY_INPUT_GROUPS] = taskDataMap[KEY_INPUT_GROUPS] + propsMap[KEY_INPUT] = inputDataMap + propsMap[KEY_OUTPUT] = taskDataMap[KEY_OUTPUT] + propsMap[KEY_CONFIG] = taskDataMap[KEY_CONFIG] + } convertUpdateRequest.os.sort() // 给操作系统排序 val atomStatus = if (atomPackageSourceType == PackageSourceTypeEnum.REPO) { diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt index 83a4ff34335..c378dc72c2f 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt @@ -42,9 +42,11 @@ import com.tencent.devops.store.dao.common.StoreMemberDao import com.tencent.devops.store.pojo.atom.AtomPkgInfoUpdateRequest import com.tencent.devops.store.pojo.atom.GetAtomConfigResult import com.tencent.devops.store.pojo.common.KEY_CONFIG +import com.tencent.devops.store.pojo.common.KEY_EXECUTION import com.tencent.devops.store.pojo.common.KEY_INPUT import com.tencent.devops.store.pojo.common.KEY_INPUT_GROUPS import com.tencent.devops.store.pojo.common.KEY_OUTPUT +import com.tencent.devops.store.pojo.common.KEY_PACKAGE_PATH import com.tencent.devops.store.pojo.common.TASK_JSON_NAME import com.tencent.devops.store.pojo.common.enums.ReleaseTypeEnum import com.tencent.devops.store.pojo.common.enums.StoreTypeEnum @@ -210,17 +212,25 @@ class MarketAtomArchiveServiceImpl : MarketAtomArchiveService { return Result(true) } + @Suppress("UNCHECKED_CAST") override fun updateAtomPkgInfo( userId: String, atomId: String, atomPkgInfoUpdateRequest: AtomPkgInfoUpdateRequest ): Result { val taskDataMap = atomPkgInfoUpdateRequest.taskDataMap + val executionInfoMap = taskDataMap[KEY_EXECUTION] as Map val propsMap = mutableMapOf() - propsMap[KEY_INPUT_GROUPS] = taskDataMap[KEY_INPUT_GROUPS] - propsMap[KEY_INPUT] = taskDataMap[KEY_INPUT] - propsMap[KEY_OUTPUT] = taskDataMap[KEY_OUTPUT] - propsMap[KEY_CONFIG] = taskDataMap[KEY_CONFIG] + val packagePath = executionInfoMap[KEY_PACKAGE_PATH] as? String + val inputDataMap = taskDataMap[KEY_INPUT] as? Map + if (packagePath.isNullOrBlank()) { + inputDataMap?.let { propsMap.putAll(inputDataMap) } + } else { + propsMap[KEY_INPUT_GROUPS] = taskDataMap[KEY_INPUT_GROUPS] + propsMap[KEY_INPUT] = inputDataMap + propsMap[KEY_OUTPUT] = taskDataMap[KEY_OUTPUT] + propsMap[KEY_CONFIG] = taskDataMap[KEY_CONFIG] + } dslContext.transaction { t -> val context = DSL.using(t) val props = JsonUtil.toJson(propsMap) diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt index 8c39e6cfacb..6bc1dc95ba9 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt @@ -391,12 +391,12 @@ class OpAtomServiceImpl @Autowired constructor( try { val taskJsonStr = taskJsonFile.readText(Charset.forName("UTF-8")) taskJsonMap = JsonUtil.toMap(taskJsonStr).toMutableMap() - val releaseInfoMap = taskJsonMap["releaseInfo"] + val releaseInfoMap = taskJsonMap[KEY_RELEASE_INFO] releaseInfo = JsonUtil.mapTo(releaseInfoMap as Map, ReleaseInfo::class.java) } catch (e: JsonProcessingException) { return I18nUtil.generateResponseDataObject( messageCode = StoreMessageCode.USER_REPOSITORY_TASK_JSON_FIELD_IS_INVALID, - params = arrayOf("releaseInfo"), + params = arrayOf(KEY_RELEASE_INFO), language = I18nUtil.getLanguage(userId) ) } @@ -533,6 +533,9 @@ class OpAtomServiceImpl @Autowired constructor( message = updateMarketAtomResult.message ) } + if (releaseInfo.configInfo.defaultFlag) { + setDefault(userId, atomCode) + } // 确认测试通过 return atomReleaseService.passTest(userId, atomId) } From 083d72a85714f88905bcfb519f7437edff6f7821 Mon Sep 17 00:00:00 2001 From: carlyin <449036249@qq.com> Date: Fri, 2 Jun 2023 19:42:01 +0800 Subject: [PATCH 008/166] =?UTF-8?q?feat:=E8=93=9D=E7=9B=BE=E5=86=85?= =?UTF-8?q?=E7=BD=AE=E6=8F=92=E4=BB=B6=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=20#8900?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/store/service/atom/impl/AtomReleaseServiceImpl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt index c2653e7a2e2..de6a97157d4 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt @@ -440,7 +440,7 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ ) val packagePath = executionInfoMap[KEY_PACKAGE_PATH] as? String - val classType = if (packagePath.isNullOrBlank()) { + val classType = if (packagePath.isNullOrBlank() && atomPackageSourceType == PackageSourceTypeEnum.UPLOAD) { // 没有可执行文件的插件是老的内置插件,插件的classType为插件标识 atomCode } else if (convertUpdateRequest.os.isEmpty()) { From bdedc7c88403339c270333c51a3e36b387c02992 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Mon, 5 Jun 2023 17:28:42 +0800 Subject: [PATCH 009/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/api/user/UserAuthApplyResource.kt | 4 + .../api/user/UserAuthResourceGroupResource.kt | 2 + .../devops/auth/pojo/vo/ActionInfoVo.kt | 2 + .../auth/pojo/vo/GroupPermissionDetailVo.kt | 2 + .../devops/auth/pojo/vo/IamGroupPoliciesVo.kt | 2 + .../devops/auth/pojo/vo/ResourceTypeInfoVo.kt | 2 + .../service/PermissionGradeManagerService.kt | 59 +++++- .../service/PermissionSubsetManagerService.kt | 40 +++- .../service/RbacPermissionApplyService.kt | 17 +- .../devops/auth/cron/AuthCronManager.kt | 144 +++++++++++++- .../tencent/devops/auth/dao/AuthActionDao.kt | 30 +++ .../auth/dao/AuthResourceGroupConfigDao.kt | 22 +++ .../devops/auth/dao/AuthResourceTypeDao.kt | 23 +++ .../NotifyMessageTemplateServiceImpl.kt | 7 +- .../service/v2/QualityControlPointService.kt | 8 +- .../service/v2/QualityIndicatorService.kt | 9 +- .../service/v2/QualityMetadataService.kt | 7 +- .../service/v2/QualityTemplateService.kt | 8 +- .../i18n/auth/message_en_US.properties | 176 ++++++++++++++++++ .../i18n/auth/message_zh_CN.properties | 176 ++++++++++++++++++ 20 files changed, 711 insertions(+), 29 deletions(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt index 83af0a74514..3ed454a6791 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt @@ -7,6 +7,7 @@ import com.tencent.devops.auth.pojo.vo.AuthApplyRedirectInfoVo import com.tencent.devops.auth.pojo.vo.GroupPermissionDetailVo import com.tencent.devops.auth.pojo.vo.ManagerRoleGroupVO import com.tencent.devops.auth.pojo.vo.ResourceTypeInfoVo +import com.tencent.devops.common.api.annotation.BkInterfaceI18n import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID import com.tencent.devops.common.api.pojo.Result import io.swagger.annotations.Api @@ -31,6 +32,7 @@ interface UserAuthApplyResource { @GET @Path("listResourceTypes") @ApiOperation("资源类型列表") + @BkInterfaceI18n(keyPrefixNames = ["{data[*].resourceType}"]) fun listResourceTypes( @ApiParam(name = "用户名", required = true) @HeaderParam(AUTH_HEADER_USER_ID) @@ -40,6 +42,7 @@ interface UserAuthApplyResource { @GET @Path("listActions") @ApiOperation("展示动作列表") + @BkInterfaceI18n(keyPrefixNames = ["{data[*].action}"]) fun listActions( @ApiParam(name = "用户名", required = true) @HeaderParam(AUTH_HEADER_USER_ID) @@ -77,6 +80,7 @@ interface UserAuthApplyResource { @GET @Path("{groupId}/getGroupPermissionDetail") @ApiOperation("查询用户组权限详情") + @BkInterfaceI18n(keyPrefixNames = ["{data[*].actionId}"]) fun getGroupPermissionDetail( @ApiParam(name = "用户名", required = true) @HeaderParam(AUTH_HEADER_USER_ID) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt index e2cadf8260a..a19729fcdf6 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthResourceGroupResource.kt @@ -31,6 +31,7 @@ package com.tencent.devops.auth.api.user import com.tencent.devops.auth.pojo.dto.GroupMemberRenewalDTO import com.tencent.devops.auth.pojo.dto.RenameGroupDTO import com.tencent.devops.auth.pojo.vo.IamGroupPoliciesVo +import com.tencent.devops.common.api.annotation.BkInterfaceI18n import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID import com.tencent.devops.common.api.pojo.Result import io.swagger.annotations.Api @@ -55,6 +56,7 @@ interface UserAuthResourceGroupResource { @GET @Path("{groupId}/groupPolicies") @ApiOperation("获取组策略详情") + @BkInterfaceI18n(keyPrefixNames = ["{data[*].action}"]) fun getGroupPolicies( @ApiParam(name = "用户名", required = true) @HeaderParam(AUTH_HEADER_USER_ID) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ActionInfoVo.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ActionInfoVo.kt index 36be7647e0e..d6431201f37 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ActionInfoVo.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ActionInfoVo.kt @@ -1,5 +1,6 @@ package com.tencent.devops.auth.pojo.vo +import com.tencent.devops.common.api.annotation.BkFieldI18n import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -8,6 +9,7 @@ data class ActionInfoVo( @ApiModelProperty("action") val action: String, @ApiModelProperty("动作名") + @BkFieldI18n val actionName: String, @ApiModelProperty("蓝盾-关联资源类型") val resourceType: String, diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt index 43806c8bd13..1b4a349422d 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt @@ -1,6 +1,7 @@ package com.tencent.devops.auth.pojo.vo import com.tencent.devops.auth.pojo.RelatedResourceInfo +import com.tencent.devops.common.api.annotation.BkFieldI18n import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -9,6 +10,7 @@ data class GroupPermissionDetailVo( @ApiModelProperty("操作id") val actionId: String, @ApiModelProperty("操作名") + @BkFieldI18n(convertName = "actionName") val name: String, @ApiModelProperty("关联资源") val relatedResourceInfo: RelatedResourceInfo diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/IamGroupPoliciesVo.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/IamGroupPoliciesVo.kt index ef138c9242c..193789ddfc4 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/IamGroupPoliciesVo.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/IamGroupPoliciesVo.kt @@ -28,6 +28,7 @@ package com.tencent.devops.auth.pojo.vo +import com.tencent.devops.common.api.annotation.BkFieldI18n import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -36,6 +37,7 @@ data class IamGroupPoliciesVo( @ApiModelProperty("操作") val action: String, @ApiModelProperty("操作名") + @BkFieldI18n val actionName: String, @ApiModelProperty("是否该action操作权限") val permission: Boolean diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ResourceTypeInfoVo.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ResourceTypeInfoVo.kt index d8c496ac3de..088ced8c1b9 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ResourceTypeInfoVo.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ResourceTypeInfoVo.kt @@ -1,5 +1,6 @@ package com.tencent.devops.auth.pojo.vo +import com.tencent.devops.common.api.annotation.BkFieldI18n import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -10,6 +11,7 @@ data class ResourceTypeInfoVo( @ApiModelProperty("资源类型") val resourceType: String, @ApiModelProperty("资源类型名") + @BkFieldI18n(keyPrefixName = "ResourceType") val name: String, @ApiModelProperty("父类资源") val parent: String, diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt index e69fbe15297..e0111cabb00 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt @@ -63,6 +63,7 @@ import com.tencent.devops.auth.pojo.ItsmCancelApplicationInfo import com.tencent.devops.auth.pojo.event.AuthResourceGroupCreateEvent import com.tencent.devops.auth.pojo.event.AuthResourceGroupModifyEvent import com.tencent.devops.common.api.exception.ErrorCodeException +import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.api.util.UUIDUtil import com.tencent.devops.common.auth.api.AuthResourceType @@ -141,7 +142,13 @@ class PermissionGradeManagerService @Autowired constructor( params = arrayOf(DefaultGroupType.MANAGER.value), defaultMessage = "${resourceType}_${DefaultGroupType.MANAGER.value} group config not exist" ) - val description = manageGroupConfig.description + + val description = MessageUtil.getMessageByLocale( + messageCode = "${manageGroupConfig.resourceType}.${manageGroupConfig.groupCode}" + + ".AuthResourceGroupConfig.description", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = manageGroupConfig.description + ) val authorizationScopes = permissionGroupPoliciesService.buildAuthorizationScopes( authorizationScopesStr = manageGroupConfig.authorizationScopes, projectCode = projectCode, @@ -165,7 +172,14 @@ class PermissionGradeManagerService @Autowired constructor( .authorization_scopes(authorizationScopes) .subject_scopes(subjectScopes) .sync_perm(true) - .groupName(manageGroupConfig.groupName) + .groupName( + MessageUtil.getMessageByLocale( + messageCode = "${manageGroupConfig.resourceType}.${manageGroupConfig.groupCode}" + + ".AuthResourceGroupConfig.groupName", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = manageGroupConfig.description + ) + ) .build() logger.info("create grade manager|$name|$userId") val gradeManagerId = iamV2ManagerService.createManagerV2(createManagerDTO) @@ -195,7 +209,14 @@ class PermissionGradeManagerService @Autowired constructor( .authorizationScopes(authorizationScopes) .subjectScopes(subjectScopes) .syncPerm(true) - .groupName(manageGroupConfig.groupName) + .groupName( + MessageUtil.getMessageByLocale( + messageCode = "${manageGroupConfig.resourceType}.${manageGroupConfig.groupCode}" + + ".AuthResourceGroupConfig.groupName", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = manageGroupConfig.groupName + ) + ) .applicant(userId) .reason( IamGroupUtils.buildItsmDefaultReason( @@ -280,7 +301,14 @@ class PermissionGradeManagerService @Autowired constructor( .authorizationScopes(authorizationScopes) .subjectScopes(subjectScopes) .syncPerm(true) - .groupName(groupConfig.groupName) + .groupName( + MessageUtil.getMessageByLocale( + messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + + ".AuthResourceGroupConfig.groupName", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = groupConfig.groupName + ) + ) .build() logger.info("update grade manager|$name|${gradeManagerDetail.members}") iamV2ManagerService.updateManagerV2(gradeManagerId, updateManagerDTO) @@ -309,7 +337,14 @@ class PermissionGradeManagerService @Autowired constructor( .authorizationScopes(authorizationScopes) .subjectScopes(subjectScopes) .syncPerm(true) - .groupName(groupConfig.groupName) + .groupName( + MessageUtil.getMessageByLocale( + messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + + ".AuthResourceGroupConfig.groupName", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = groupConfig.groupName + ) + ) .applicant(projectApprovalInfo.updator) .members(gradeManagerDetail.members) .reason( @@ -371,8 +406,18 @@ class PermissionGradeManagerService @Autowired constructor( if (resourceGroupInfo != null) { return@forEach } - val name = groupConfig.groupName - val description = groupConfig.description + val name = MessageUtil.getMessageByLocale( + messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + + ".AuthResourceGroupConfig.groupName", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = groupConfig.groupName + ) + val description = MessageUtil.getMessageByLocale( + messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + + ".AuthResourceGroupConfig.description", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = groupConfig.description + ) val managerRoleGroup = ManagerRoleGroup(name, description, false) val managerRoleGroupDTO = ManagerRoleGroupDTO.builder().groups(listOf(managerRoleGroup)).build() val iamGroupId = iamV2ManagerService.batchCreateRoleGroupV2(gradeManagerId, managerRoleGroupDTO) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt index a9e623922c7..ac2c62da1b4 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt @@ -42,6 +42,7 @@ import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.auth.api.pojo.DefaultGroupType +import com.tencent.devops.common.web.utils.I18nUtil import org.jooq.DSLContext import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired @@ -87,7 +88,12 @@ class PermissionSubsetManagerService @Autowired constructor( resourceCode = resourceCode, resourceName = resourceName ) - val description = managerGroupConfig.description + val description = I18nUtil.getCodeLanMessage( + messageCode = "${managerGroupConfig.resourceType}.${managerGroupConfig.groupCode}" + + ".AuthResourceGroupConfig.description", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = managerGroupConfig.description + ) val authorizationScopes = permissionGroupPoliciesService.buildAuthorizationScopes( authorizationScopesStr = managerGroupConfig.authorizationScopes, projectCode = projectCode, @@ -105,7 +111,14 @@ class PermissionSubsetManagerService @Autowired constructor( .inheritSubjectScope(true) .subjectScopes(listOf()) .syncPerm(syncPerm) - .groupName(managerGroupConfig.groupName) + .groupName( + I18nUtil.getCodeLanMessage( + messageCode = "${managerGroupConfig.resourceType}.${managerGroupConfig.groupCode}" + + ".AuthResourceGroupConfig.groupName", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = managerGroupConfig.groupName + ) + ) .build() return iamV2ManagerService.createSubsetManager( gradeManagerId, @@ -156,7 +169,14 @@ class PermissionSubsetManagerService @Autowired constructor( .inheritSubjectScope(true) .subjectScopes(listOf()) .syncPerm(syncPerm) - .groupName(managerGroupConfig.groupName) + .groupName( + I18nUtil.getCodeLanMessage( + messageCode = "${managerGroupConfig.resourceType}.${managerGroupConfig.groupCode}" + + ".AuthResourceGroupConfig.groupName", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = managerGroupConfig.groupName + ) + ) .build() iamV2ManagerService.updateSubsetManager( subsetManagerId, @@ -234,8 +254,18 @@ class PermissionSubsetManagerService @Autowired constructor( if (resourceGroupInfo != null) { return@forEach } - val name = groupConfig.groupName - val description = groupConfig.description + val name = I18nUtil.getCodeLanMessage( + messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + + ".AuthResourceGroupConfig.groupName", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = groupConfig.groupName + ) + val description = I18nUtil.getCodeLanMessage( + messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + + ".AuthResourceGroupConfig.description", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = groupConfig.description + ) val managerRoleGroup = ManagerRoleGroup(name, description, false) val managerRoleGroupDTO = ManagerRoleGroupDTO.builder().groups(listOf(managerRoleGroup)).build() val iamGroupId = iamV2ManagerService.batchCreateSubsetRoleGroup(subsetManagerId, managerRoleGroupDTO) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt index 55cf9ccf0bc..47faec86a9d 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt @@ -25,12 +25,14 @@ import com.tencent.devops.auth.pojo.vo.ResourceTypeInfoVo import com.tencent.devops.auth.service.iam.PermissionApplyService import com.tencent.devops.auth.service.iam.PermissionService import com.tencent.devops.common.api.exception.ErrorCodeException +import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.auth.api.pojo.DefaultGroupType import com.tencent.devops.common.auth.utils.RbacAuthUtils import com.tencent.devops.common.client.Client import com.tencent.devops.common.service.config.CommonConfig +import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.api.user.UserPipelineViewResource import com.tencent.devops.project.api.service.ServiceProjectTagResource import java.util.concurrent.Executors @@ -372,7 +374,13 @@ class RbacPermissionApplyService @Autowired constructor( auth = isEnablePermission, resourceTypeName = resourceTypeName, resourceName = resourceName, - actionName = actionInfo?.actionName, + actionName = actionInfo?.let { + MessageUtil.getMessageByLocale( + messageCode = "${it.action}.actionName", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = it.actionName + ) + }, groupInfoList = groupInfoList ) } @@ -456,7 +464,12 @@ class RbacPermissionApplyService @Autowired constructor( authApplyRedirectUrl, projectId, projectName, resourceType, resourceName, iamResourceCode, action, resourceGroup.groupName, resourceGroup.relationId ), - groupName = resourceGroup.groupName + groupName = MessageUtil.getMessageByLocale( + messageCode = "${resourceGroup.resourceType}.${resourceGroup.groupCode}" + + ".AuthResourceGroupConfig.groupName", + language = I18nUtil.getDefaultLocaleLanguage(), + defaultMessage = resourceGroup.groupName + ) ) ) } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt index 40013586eb0..13b10b143b0 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt @@ -27,29 +27,46 @@ package com.tencent.devops.auth.cron +import com.tencent.devops.auth.dao.AuthActionDao +import com.tencent.devops.auth.dao.AuthResourceGroupConfigDao +import com.tencent.devops.auth.dao.AuthResourceTypeDao import com.tencent.devops.auth.entity.ManagerChangeType import com.tencent.devops.auth.refresh.dispatch.AuthRefreshDispatch import com.tencent.devops.auth.refresh.event.ManagerOrganizationChangeEvent import com.tencent.devops.auth.service.AuthManagerApprovalService import com.tencent.devops.auth.service.ManagerOrganizationService import com.tencent.devops.auth.service.ManagerUserService +import com.tencent.devops.common.api.constant.SYSTEM +import com.tencent.devops.common.api.util.MessageUtil +import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.client.ClientTokenService import com.tencent.devops.common.redis.RedisLock import com.tencent.devops.common.redis.RedisOperation +import com.tencent.devops.common.service.config.CommonConfig +import com.tencent.devops.model.auth.tables.records.TAuthResourceGroupConfigRecord +import com.tencent.devops.model.auth.tables.records.TAuthResourceTypeRecord +import java.time.LocalDateTime +import java.util.concurrent.Executors +import javax.annotation.PostConstruct +import org.jooq.DSLContext import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Component -import javax.annotation.PostConstruct @Component class AuthCronManager @Autowired constructor( + val dslContext: DSLContext, val managerUserService: ManagerUserService, val managerOrganizationService: ManagerOrganizationService, val refreshDispatch: AuthRefreshDispatch, val clientTokenService: ClientTokenService, val authManagerApprovalService: AuthManagerApprovalService, - val redisOperation: RedisOperation + val redisOperation: RedisOperation, + val authActionDao: AuthActionDao, + val authResourceTypeDao: AuthResourceTypeDao, + val authResourceGroupConfigDao: AuthResourceGroupConfigDao, + val commonConfig: CommonConfig ) { @PostConstruct @@ -57,6 +74,9 @@ class AuthCronManager @Autowired constructor( logger.info("start init system authToken") clientTokenService.setSystemToken(null) logger.info("init system authToken success ${clientTokenService.getSystemToken(null)}") + updateAuthActionI18n() + updateAuthResourceTypeI18n() + updateAuthResourceGroupConfigI18n() } /** @@ -113,9 +133,129 @@ class AuthCronManager @Autowired constructor( } } + private fun updateAuthActionI18n() { + val redisLock = RedisLock(redisOperation, AUTH_ACTION_UPDATE_LOCK, expiredTimeInSeconds) + if (redisLock.tryLock()) { + Executors.newFixedThreadPool(1).submit { + try { + logger.info("start init auth Action I18n") + val authActionI18nMap = mutableMapOf() + var page = PageUtil.DEFAULT_PAGE + do { + val actionRecordResult = authActionDao.list( + dslContext = dslContext, + page = page, + pageSize = PageUtil.DEFAULT_PAGE_SIZE + ) + actionRecordResult.forEach { + val actionName = MessageUtil.getMessageByLocale( + messageCode = "${it.action}.actionName", + language = commonConfig.devopsDefaultLocaleLanguage + ) + authActionI18nMap[it.action] = actionName + } + authActionDao.updateActionName( + dslContext = dslContext, + authActionI18nMap = authActionI18nMap + ) + page ++ + } while (actionRecordResult.size == PageUtil.DEFAULT_PAGE_SIZE) + logger.info("init auth Action I18n end") + } finally { + redisLock.unlock() + } + } + } + } + + private fun updateAuthResourceTypeI18n() { + val redisLock = RedisLock(redisOperation, AUTH_RESOURCE_TYPE_UPDATE_LOCK, expiredTimeInSeconds) + if (redisLock.tryLock()) { + Executors.newFixedThreadPool(1).submit { + try { + logger.info("start init auth resource type I18n") + var page = PageUtil.DEFAULT_PAGE + do { + val authResourceTypes = mutableListOf() + val resourceTypeResult = authResourceTypeDao.list( + dslContext = dslContext, + page = page, + pageSize = PageUtil.DEFAULT_PAGE_SIZE + ) + resourceTypeResult.forEach { + it.name = MessageUtil.getMessageByLocale( + messageCode = "${it.resourceType}.ResourceType.name", + language = commonConfig.devopsDefaultLocaleLanguage + ) + it.desc = MessageUtil.getMessageByLocale( + messageCode = "${it.resourceType}.ResourceType.desc", + language = commonConfig.devopsDefaultLocaleLanguage + ) + it.updateTime = LocalDateTime.now() + it.updateUser = SYSTEM + authResourceTypes.add(it) + } + authResourceTypeDao.batchUpdateAuthResourceType( + dslContext = dslContext, + authActionResourceTypes = authResourceTypes + ) + page++ + } while (resourceTypeResult.size == PageUtil.DEFAULT_PAGE_SIZE) + logger.info("init auth resource type I18n end") + } finally { + redisLock.unlock() + } + } + } + } + + private fun updateAuthResourceGroupConfigI18n() { + val redisLock = RedisLock(redisOperation, AUTH_RESOURCE_TYPE_GROUP_CONFIG_LOCK, expiredTimeInSeconds) + if (redisLock.tryLock()) { + Executors.newFixedThreadPool(1).submit { + try { + logger.info("start init auth resource group config type I18n") + val authAuthResourceGroupConfigs= mutableListOf() + var page = PageUtil.DEFAULT_PAGE + do { + val resourceGroupConfigResult = authResourceGroupConfigDao.list( + dslContext = dslContext, + page = page, + pageSize = PageUtil.DEFAULT_PAGE_SIZE + ) + resourceGroupConfigResult.forEach { + it.groupName = MessageUtil.getMessageByLocale( + messageCode = "${it.resourceType}.${it.groupCode}.AuthResourceGroupConfig.groupName", + language = commonConfig.devopsDefaultLocaleLanguage + ) + it.description = MessageUtil.getMessageByLocale( + messageCode = "${it.resourceType}.${it.groupCode}.AuthResourceGroupConfig.description", + language = commonConfig.devopsDefaultLocaleLanguage + ) + it.updateTime = LocalDateTime.now() + authAuthResourceGroupConfigs.add(it) + } + authResourceGroupConfigDao.batchUpdateAuthResourceGroupConfig( + dslContext, + authAuthResourceGroupConfigs + ) + page++ + } while (resourceGroupConfigResult.size == PageUtil.DEFAULT_PAGE) + logger.info("init auth resource group config I18n end") + } finally { + redisLock.unlock() + } + } + } + } + + companion object { val logger = LoggerFactory.getLogger(AuthCronManager::class.java) private const val AUTH_EXPIRING_MANAGAER_APPROVAL = "auth:expiring:manager:approval" private const val expiredTimeInSeconds = 60L + private const val AUTH_RESOURCE_TYPE_UPDATE_LOCK = "auth:resourceType:update" + private const val AUTH_ACTION_UPDATE_LOCK = "auth:action:update" + private const val AUTH_RESOURCE_TYPE_GROUP_CONFIG_LOCK = "auth:resource:type:group:config:update" } } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthActionDao.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthActionDao.kt index 6bbe9513b8a..22b2f40417f 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthActionDao.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthActionDao.kt @@ -2,6 +2,7 @@ package com.tencent.devops.auth.dao import com.tencent.devops.model.auth.tables.TAuthAction import com.tencent.devops.model.auth.tables.records.TAuthActionRecord +import java.time.LocalDateTime import org.jooq.DSLContext import org.jooq.Result import org.springframework.stereotype.Repository @@ -27,4 +28,33 @@ class AuthActionDao { .fetchAny() } } + + fun list( + dslContext: DSLContext, + page: Int, + pageSize: Int + ): Result { + return with(TAuthAction.T_AUTH_ACTION) { + dslContext.selectFrom(this) + .orderBy(CREATE_TIME.desc(), ACTION) + .limit(pageSize).offset((page - 1) * pageSize) + .fetch() + } + } + + fun updateActionName( + dslContext: DSLContext, + authActionI18nMap: Map + ) { + dslContext.batch( + authActionI18nMap.map { + with(TAuthAction.T_AUTH_ACTION) { + dslContext.update(this) + .set(ACTION_NAME, it.value) + .set(UPDATE_TIME, LocalDateTime.now()) + .where(ACTION.eq(it.key)) + } + } + ).execute() + } } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupConfigDao.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupConfigDao.kt index aefe2567a2e..06f14cefbd1 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupConfigDao.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupConfigDao.kt @@ -98,4 +98,26 @@ class AuthResourceGroupConfigDao { .fetchOne(0, Int::class.java)!! } } + fun list( + dslContext: DSLContext, + page: Int, + pageSize: Int + ): Result { + return with(TAuthResourceGroupConfig.T_AUTH_RESOURCE_GROUP_CONFIG) { + dslContext.selectFrom(this) + .orderBy(CREATE_TIME.desc(), RESOURCE_TYPE, GROUP_CODE) + .limit(pageSize).offset((page - 1) * pageSize) + .fetch() + } + } + + fun batchUpdateAuthResourceGroupConfig( + dslContext: DSLContext, + authAuthResourceGroupConfigs: List + ) { + if (authAuthResourceGroupConfigs.isEmpty()) { + return + } + dslContext.batchUpdate(authAuthResourceGroupConfigs).execute() + } } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceTypeDao.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceTypeDao.kt index 04f4caf5091..756f2e3c6bd 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceTypeDao.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceTypeDao.kt @@ -13,4 +13,27 @@ class AuthResourceTypeDao { dslContext.selectFrom(this).where(DELETE.eq(false)).orderBy(ID.asc()).fetch() } } + + fun list( + dslContext: DSLContext, + page: Int, + pageSize: Int + ): Result { + return with(TAuthResourceType.T_AUTH_RESOURCE_TYPE) { + dslContext.selectFrom(this) + .orderBy(CREATE_TIME.desc(), RESOURCE_TYPE) + .limit(pageSize).offset((page - 1) * pageSize) + .fetch() + } + } + + fun batchUpdateAuthResourceType( + dslContext: DSLContext, + authActionResourceTypes: List + ) { + if (authActionResourceTypes.isEmpty()) { + return + } + dslContext.batchUpdate(authActionResourceTypes).execute() + } } diff --git a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt index 7d973d0fec2..cff60a5861f 100644 --- a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt +++ b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt @@ -43,6 +43,7 @@ import com.tencent.devops.common.notify.enums.NotifyType import com.tencent.devops.common.notify.utils.NotifyUtils import com.tencent.devops.common.redis.RedisLock import com.tencent.devops.common.redis.RedisOperation +import com.tencent.devops.common.service.config.CommonConfig import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.common.wechatwork.WechatWorkRobotService import com.tencent.devops.common.wechatwork.WechatWorkService @@ -66,6 +67,7 @@ import com.tencent.devops.notify.pojo.SendNotifyMessageTemplateRequest import com.tencent.devops.notify.pojo.SubNotifyMessageTemplate import com.tencent.devops.notify.pojo.WechatNotifyMessage import com.tencent.devops.notify.pojo.messageTemplate.MessageTemplate +import java.io.File import java.time.LocalDateTime import java.util.concurrent.Executors import java.util.regex.Pattern @@ -91,7 +93,8 @@ class NotifyMessageTemplateServiceImpl @Autowired constructor( private val wechatWorkService: WechatWorkService, private val wechatWorkRobotService: WechatWorkRobotService, private val redisOperation: RedisOperation, - private val messageTemplateDao: MessageTemplateDao + private val messageTemplateDao: MessageTemplateDao, + private val commonConfig: CommonConfig ) : NotifyMessageTemplateService { companion object { @@ -125,7 +128,7 @@ class NotifyMessageTemplateServiceImpl @Autowired constructor( fun updateMessageTemplate() { val classPathResource = ClassPathResource( - "template_${I18nUtil.getDefaultLocaleLanguage()}.yaml" + "i18n${File.separator}template_${commonConfig.devopsDefaultLocaleLanguage}.yaml" ) val inputStream = classPathResource.inputStream val yamlStr = inputStream.bufferedReader(Charsets.UTF_8).use { it.readText() } diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt index 20442d8362d..4ab6695aa12 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt @@ -33,7 +33,7 @@ import com.tencent.devops.common.api.util.HashUtil import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.redis.RedisLock import com.tencent.devops.common.redis.RedisOperation -import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.common.service.config.CommonConfig import com.tencent.devops.model.quality.tables.records.TQualityControlPointRecord import com.tencent.devops.quality.api.v2.pojo.ControlPointPosition import com.tencent.devops.quality.api.v2.pojo.QualityControlPoint @@ -45,6 +45,7 @@ import com.tencent.devops.quality.dao.v2.QualityRuleBuildHisDao import com.tencent.devops.quality.dao.v2.QualityRuleDao import com.tencent.devops.quality.pojo.po.ControlPointPO import com.tencent.devops.quality.util.ElementUtils +import java.io.File import java.util.concurrent.Executors import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.ThreadPoolExecutor @@ -63,7 +64,8 @@ class QualityControlPointService @Autowired constructor( private val controlPointDao: QualityControlPointDao, private val qualityRuleDao: QualityRuleDao, private val qualityRuleBuildHisDao: QualityRuleBuildHisDao, - private val redisOperation: RedisOperation + private val redisOperation: RedisOperation, + private val commonConfig: CommonConfig ) { @PostConstruct @@ -79,7 +81,7 @@ class QualityControlPointService @Autowired constructor( try { logger.info("start init quality control point") val classPathResource = ClassPathResource( - "controlPoint_${I18nUtil.getDefaultLocaleLanguage()}.json" + "i18n${File.separator}controlPoint_${commonConfig.devopsDefaultLocaleLanguage}.json" ) val inputStream = classPathResource.inputStream val json = inputStream.bufferedReader(Charsets.UTF_8).use { it.readText() } diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt index b50ac3deb2f..888d5445a7f 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt @@ -37,6 +37,7 @@ import com.tencent.devops.common.client.Client import com.tencent.devops.common.quality.pojo.enums.QualityOperation import com.tencent.devops.common.redis.RedisLock import com.tencent.devops.common.redis.RedisOperation +import com.tencent.devops.common.service.config.CommonConfig import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.model.quality.tables.records.TQualityIndicatorRecord import com.tencent.devops.plugin.codecc.CodeccUtils @@ -89,6 +90,7 @@ import com.tencent.devops.quality.pojo.po.QualityIndicatorPO import com.tencent.devops.quality.util.ElementUtils import com.tencent.devops.store.api.atom.ServiceMarketAtomResource import com.tencent.devops.store.pojo.common.enums.StoreProjectTypeEnum +import java.io.File import java.util.Base64 import java.util.concurrent.Executors import javax.annotation.PostConstruct @@ -108,7 +110,8 @@ class QualityIndicatorService @Autowired constructor( private val indicatorDao: QualityIndicatorDao, private val metadataService: QualityMetadataService, private val templateIndicatorMapDao: QualityTemplateIndicatorMapDao, - private val redisOperation: RedisOperation + private val redisOperation: RedisOperation, + val commonConfig: CommonConfig ) { private val encoder = Base64.getEncoder() @@ -126,7 +129,7 @@ class QualityIndicatorService @Autowired constructor( try { logger.info("start init quality indicator") val classPathResource = ClassPathResource( - "indicator_${I18nUtil.getDefaultLocaleLanguage()}.json" + "i18n${File.separator}indicator_${commonConfig.devopsDefaultLocaleLanguage}.json" ) val inputStream = classPathResource.inputStream val json = inputStream.bufferedReader(Charsets.UTF_8).use { it.readText() } @@ -337,7 +340,7 @@ class QualityIndicatorService @Autowired constructor( if (indicatorDao.create(userId, indicatorUpdate, dslContext) > 0) { return Msg(0, I18nUtil.getCodeLanMessage(BK_CREATE_SUCCESS), true) } - return Msg(-1, I18nUtil.getCodeLanMessage(messageCode = BK_CREATE_FAIL, language = userId), false) + return Msg(-1, I18nUtil.getCodeLanMessage(BK_CREATE_FAIL), false) } fun userDelete(userId: String, id: Long): Boolean { diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt index e3df29614b3..fcd81e939ae 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt @@ -33,6 +33,7 @@ import com.tencent.devops.common.api.util.HashUtil import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.redis.RedisLock import com.tencent.devops.common.redis.RedisOperation +import com.tencent.devops.common.service.config.CommonConfig import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.model.quality.tables.records.TQualityMetadataRecord import com.tencent.devops.quality.api.v2.pojo.QualityIndicatorMetadata @@ -41,6 +42,7 @@ import com.tencent.devops.quality.api.v2.pojo.op.ElementNameData import com.tencent.devops.quality.api.v2.pojo.op.QualityMetaData import com.tencent.devops.quality.dao.v2.QualityMetadataDao import com.tencent.devops.quality.pojo.po.QualityMetadataPO +import java.io.File import java.util.concurrent.Executors import javax.annotation.PostConstruct import org.jooq.DSLContext @@ -55,7 +57,8 @@ import org.springframework.stereotype.Service class QualityMetadataService @Autowired constructor( private val dslContext: DSLContext, private val metadataDao: QualityMetadataDao, - private val redisOperation: RedisOperation + private val redisOperation: RedisOperation, + val commonConfig: CommonConfig ) { companion object { private val logger = LoggerFactory.getLogger(QualityMetadataService::class.java) @@ -74,7 +77,7 @@ class QualityMetadataService @Autowired constructor( try { logger.info("start init quality metadata") val classPathResource = ClassPathResource( - "metadata_${I18nUtil.getDefaultLocaleLanguage()}.json" + "i18n${File.separator}metadata_${commonConfig.devopsDefaultLocaleLanguage}.json" ) val inputStream = classPathResource.inputStream val json = inputStream.bufferedReader(Charsets.UTF_8).use { it.readText() } diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt index f7302e955aa..4b5e4a9dfcb 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt @@ -33,7 +33,7 @@ import com.tencent.devops.common.api.util.HashUtil import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.redis.RedisLock import com.tencent.devops.common.redis.RedisOperation -import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.common.service.config.CommonConfig import com.tencent.devops.quality.api.v2.pojo.ControlPointPosition import com.tencent.devops.quality.api.v2.pojo.RuleIndicatorSet import com.tencent.devops.quality.api.v2.pojo.RuleTemplate @@ -45,6 +45,7 @@ import com.tencent.devops.quality.dao.v2.QualityIndicatorDao import com.tencent.devops.quality.dao.v2.QualityRuleTemplateDao import com.tencent.devops.quality.dao.v2.QualityTemplateIndicatorMapDao import com.tencent.devops.quality.pojo.po.QualityRuleTemplatePO +import java.io.File import java.util.concurrent.Executors import javax.annotation.PostConstruct import org.jooq.DSLContext @@ -63,7 +64,8 @@ class QualityTemplateService @Autowired constructor( private val qualityControlPointDao: QualityControlPointDao, private val ruleTemplateIndicatorDao: QualityTemplateIndicatorMapDao, private val indicatorDao: QualityIndicatorDao, - private val redisOperation: RedisOperation + private val redisOperation: RedisOperation, + val commonConfig: CommonConfig ) { @PostConstruct @@ -79,7 +81,7 @@ class QualityTemplateService @Autowired constructor( try { logger.info("start init quality rule template") val classPathResource = ClassPathResource( - "ruleTemplate_${I18nUtil.getDefaultLocaleLanguage()}.json" + "i18n${File.separator}ruleTemplate_${commonConfig.devopsDefaultLocaleLanguage}.json" ) val inputStream = classPathResource.inputStream val json = inputStream.bufferedReader(Charsets.UTF_8).use { it.readText() } diff --git a/support-files/i18n/auth/message_en_US.properties b/support-files/i18n/auth/message_en_US.properties index a1b5a0744a2..a38bd47bc53 100644 --- a/support-files/i18n/auth/message_en_US.properties +++ b/support-files/i18n/auth/message_en_US.properties @@ -80,3 +80,179 @@ bkRefuseRenew=Refusal to renew bkWeworkRobotNotifyMessage=**BK-CI Super Administrator Permission Renewal Application Approval**\nApplicant: {0}\nAuthorization Name: {1}\nAuthorization Details: {2}\nUser Permission Expiration Time: {3}\nPlease select whether to agree to the user renewal permission\n bkYouAgreeRenew=You have chosen to consent to user renewal bkYouRefuseRenew=You've chosen to decline user renewal + +cert_create.actionName=Cert Create +cert_delete.actionName=Cert Delete +cert_edit.actionName=Cert Edit +cert_list.actionName=Cert List +cert_use.actionName=Cert Use +cert_view.actionName=Cert View +codecc_ignore_type_manage.actionName=CodeCC Ignore Type Manage +codecc_rule_set_create.actionName=CodeCC Rule Set Create +codecc_rule_set_list.actionName=CodeCC Rule Set List +codecc_task_analyze.actionName=CodeCC Task Analyze +codecc_task_create.actionName=CodeCC Task Create +codecc_task_list.actionName=CodeCC Task List +codecc_task_manage.actionName=CodeCC Task Manage Permissions +codecc_task_manage-defect.actionName=CodeCC Task Manage Defect +codecc_task_manage-permissions.actionName=CodeCC Task Manage Permissions +codecc_task_setting.actionName=CodeCC Task Setting +codecc_task_view-defect.actionName=CodeCC Defect Detail View +codecc_task_view-report.actionName=CodeCC Task Report View +credential_create.actionName=Credential Create +credential_delete.actionName=Credential Delete +credential_edit.actionName=Credential Edit +credential_list.actionName=Credential List +credential_use.actionName=Credential Use +credential_view.actionName=Credential View +env_node_create.actionName=Node Create +env_node_delete.actionName=Node Delete +env_node_edit.actionName=Node Edit +env_node_list.actionName=Node List +env_node_use.actionName=Node Use +env_node_view.actionName=Node View +environment_create.actionName=Environment Create +environment_delete.actionName=Environment Delete +environment_edit.actionName=Environment Edit +environment_list.actionName=Environment List +environment_use.actionName=Environment Use +environment_view.actionName=Environment View +experience_group_create.actionName=Experience Group Create +experience_group_delete.actionName=Experience Group Delete +experience_group_edit.actionName=Experience Group Edit +experience_group_list.actionName=Experience Group List +experience_group_view.actionName=Experience Group View +experience_task_create.actionName=Experience Task Create +experience_task_delete.actionName=Experience Task Delete +experience_task_edit.actionName=Experience Task Edit +experience_task_list.actionName=Experience Task List +experience_task_view.actionName=Experience Task View +pipeline_create.actionName=Pipeline Create +pipeline_delete.actionName=Pipeline Delete +pipeline_download.actionName=Pipeline Download +pipeline_edit.actionName=Pipeline Edit +pipeline_execute.actionName=Pipeline Execute +pipeline_list.actionName=Pipeline List +pipeline_manage.actionName=Pipeline Manage +pipeline_share.actionName=Pipeline Share +pipeline_view.actionName=Pipeline View +project_edit.actionName=Project Edit +project_enable.actionName=Project Enable +project_list.actionName=Project List +project_manage.actionName=Project Manage +project_view.actionName=Project View +project_visit.actionName=Project Visit +quality_group_create.actionName=Andon Notice Group Create +quality_group_delete.actionName=Andon Notice Group Delete +quality_group_edit.actionName=Andon Notice Group Edit +quality_group_list.actionName=Andon Notice Group List +repertory_create.actionName=Repository Create +repertory_delete.actionName=Repository Delete +repertory_edit.actionName=Repository Edit +repertory_list.actionName=Repository List +repertory_use.actionName=Repository Use +repertory_view.actionName=Repository View +rule_create.actionName=Andon Rule Create +rule_delete.actionName=Andon Rule Delete +rule_edit.actionName=Andon Rule Edit +rule_enable.actionName=Andon Rule Enable +rule_list.actionName=Andon Rule List + +cert.manager.AuthResourceGroupConfig.description=Certificate owner, who has all the operation permissions of the current certificate +cert.user.AuthResourceGroupConfig.description=Certificate consumer, you can use this certificate in the pipeline +codecc_task.editor.AuthResourceGroupConfig.description=The task editor has all the permissions for the current task except for rights management +codecc_task.executor.AuthResourceGroupConfig.description=Task executor, who can view and execute tasks +codecc_task.manager.AuthResourceGroupConfig.description=Task owner, who can manage all permissions for the current task +codecc_task.viewer.AuthResourceGroupConfig.description=Task viewer, you can view the task +credential.manager.AuthResourceGroupConfig.description=The credential owner has all the operation rights of the current credential +credential.user.AuthResourceGroupConfig.description=Credential user, which can be used in the pipeline +env_node.manager.AuthResourceGroupConfig.description=The node owner has all the operation permissions of the current node +env_node.user.AuthResourceGroupConfig.description=Node consumer, you can use this node in the pipeline +environment.manager.AuthResourceGroupConfig.description=The owner of the environment, who has all the operational permissions of the current environment +environment.user.AuthResourceGroupConfig.description=Users of the environment, which can be used in the pipeline +experience_group.manager.AuthResourceGroupConfig.description=The owner of the version experience group has all the operation rights of the current version experience group +experience_task.manager.AuthResourceGroupConfig.description=The owner of the version experience has all the operation rights of the current version experience +pipeline.editor.AuthResourceGroupConfig.description=The pipeline editor has all the permissions of the current pipeline except for rights management +pipeline.executor.AuthResourceGroupConfig.description=Pipeline executor, can view and execute pipeline, download or share products +pipeline.manager.AuthResourceGroupConfig.description=Pipeline owner, who can manage the permissions of the current pipeline +pipeline.viewer.AuthResourceGroupConfig.description=Pipeline viewer can view pipeline, download or share products +pipeline_group.editor.AuthResourceGroupConfig.description=You can view, edit, and execute pipelines within a group +pipeline_group.executor.AuthResourceGroupConfig.description=You can view and execute the pipelining within the group +pipeline_group.manager.AuthResourceGroupConfig.description=The pipeline group administrator can manage the pipelines in the group and add editors, executors and viewers to the pipelines in the group in batch. +pipeline_group.viewer.AuthResourceGroupConfig.description=You can view the pipelining within the group +project.developer.AuthResourceGroupConfig.description=Developers can create pipelines, code bases, credentials, certificates, environments, nodes, Codecc tasks, Codecc rule sets, download and share artifacts in the project's custom repository +project.maintainer.AuthResourceGroupConfig.description=Operation and maintenance personnel, you can create pipelines, code bases, credentials, certificates, environments, nodes, download and share products in the project custom warehouse +project.manager.AuthResourceGroupConfig.description=The project administrator has the authority to operate and manage all resources under the project. You can add users to the project, remove users from the project, approve applications to join the project, and approve permission renewal applications for users in the project-level user group. +project.pm.AuthResourceGroupConfig.description=Product personnel, you can view the pipeline list, download or share products. +project.qc.AuthResourceGroupConfig.description=Quality control staff, manage quality red line rules. +project.tester.AuthResourceGroupConfig.description=Testers can create test lines and related resources, download or share products. +project.visitor.AuthResourceGroupConfig.description=For visitors, you can view a list of pipelines. +quality_group.manager.AuthResourceGroupConfig.description=The owner of the quality red line notification group has all the operation permissions of the current quality red line notification group +repertory.manager.AuthResourceGroupConfig.description=The owner of the code base has all the permissions to operate the current code base. +repertory.user.AuthResourceGroupConfig.description=Code base users, you can use this code base in the pipeline +rule.manager.AuthResourceGroupConfig.description=The owner of the quality red line rule has all the operation rights of the current quality red line rule. +cert.manager.AuthResourceGroupConfig.groupName=Owner +cert.user.AuthResourceGroupConfig.groupName=User +codecc_task.editor.AuthResourceGroupConfig.groupName=Editor +codecc_task.executor.AuthResourceGroupConfig.groupName=Executor +codecc_task.manager.AuthResourceGroupConfig.groupName=Owner +codecc_task.viewer.AuthResourceGroupConfig.groupName=Viewer +credential.manager.AuthResourceGroupConfig.groupName=Owner +credential.user.AuthResourceGroupConfig.groupName=User +env_node.manager.AuthResourceGroupConfig.groupName=Owner +env_node.user.AuthResourceGroupConfig.groupName=User +environment.manager.AuthResourceGroupConfig.groupName=Owner +environment.user.AuthResourceGroupConfig.groupName=User +experience_group.manager.AuthResourceGroupConfig.groupName=Owner +experience_task.manager.AuthResourceGroupConfig.groupName=Owner +pipeline.editor.AuthResourceGroupConfig.groupName=Editor +pipeline.executor.AuthResourceGroupConfig.groupName=Executor +pipeline.manager.AuthResourceGroupConfig.groupName=Owner +pipeline.viewer.AuthResourceGroupConfig.groupName=Viewer +pipeline_group.editor.AuthResourceGroupConfig.groupName=Editor +pipeline_group.executor.AuthResourceGroupConfig.groupName=Executor +pipeline_group.manager.AuthResourceGroupConfig.groupName=Owner +pipeline_group.viewer.AuthResourceGroupConfig.groupName=Viewer +project.developer.AuthResourceGroupConfig.groupName=Developer +project.maintainer.AuthResourceGroupConfig.groupName=Operation and maintenance personnel +project.manager.AuthResourceGroupConfig.groupName=Administrator +project.pm.AuthResourceGroupConfig.groupName=Product personnel +project.qc.AuthResourceGroupConfig.groupName=Quality control personnel +project.tester.AuthResourceGroupConfig.groupName=Tester +project.visitor.AuthResourceGroupConfig.groupName=Visitors +quality_group.manager.AuthResourceGroupConfig.groupName=Owner +repertory.manager.AuthResourceGroupConfig.groupName=Owner +repertory.user.AuthResourceGroupConfig.groupName=User +rule.manager.AuthResourceGroupConfig.groupName=Owner + +cert.ResourceType.desc=Cert +codecc_ignore_type.ResourceType.desc=Codecc Ignore Type +codecc_rule_set.ResourceType.desc=Codecc Rule Set +codecc_task.ResourceType.desc=Codecc Task +credential.ResourceType.desc=Credential +env_node.ResourceType.desc=Node +environment.ResourceType.desc=Environment +experience_group.ResourceType.desc=Experience Group +experience_task.ResourceType.desc=Experience Task +pipeline.ResourceType.desc=Pipeline +pipeline_group.ResourceType.desc=Pipeline Group +project.ResourceType.desc=Project +quality_group.ResourceType.desc=Andon Notice Group +repertory.ResourceType.desc=Repository +rule.ResourceType.desc=Andon Rule +cert.ResourceType.name=Cert +codecc_ignore_type.ResourceType.name=Codecc Ignore Type +codecc_rule_set.ResourceType.name=Codecc Rule Set +codecc_task.ResourceType.name=Codecc Task +credential.ResourceType.name=Credential +env_node.ResourceType.name=Node +environment.ResourceType.name=Environment +experience_group.ResourceType.name=Experience Group +experience_task.ResourceType.name=Experience Task +pipeline.ResourceType.name=Pipeline +pipeline_group.ResourceType.name=Pipeline Group +project.ResourceType.name=Project +quality_group.ResourceType.name=Andon Notice Group +repertory.ResourceType.name=Repository +rule.ResourceType.name=Andon Rule + diff --git a/support-files/i18n/auth/message_zh_CN.properties b/support-files/i18n/auth/message_zh_CN.properties index 63e37a54ed7..12f89be1fbd 100644 --- a/support-files/i18n/auth/message_zh_CN.properties +++ b/support-files/i18n/auth/message_zh_CN.properties @@ -80,3 +80,179 @@ bkRefuseRenew=拒绝续期 bkWeworkRobotNotifyMessage=**蓝盾超级管理员权限续期申请审批**\n申请人:{0}\n授权名称:{1}\n授权详情:{2}\n用户权限过期时间:{3}\n请选择是否同意用户续期权限\n bkYouAgreeRenew=你已选择同意用户续期 bkYouRefuseRenew=你已选择拒绝用户续期 + +cert_create.actionName=创建证书 +cert_delete.actionName=删除证书 +cert_edit.actionName=编辑证书 +cert_list.actionName=证书列表 +cert_use.actionName=使用证书 +cert_view.actionName=查看证书 +codecc_ignore_type_manage.actionName=忽略配置 +codecc_rule_set_create.actionName=规则集创建 +codecc_rule_set_list.actionName=规则集列表 +codecc_task_analyze.actionName=分析任务 +codecc_task_create.actionName=新建任务 +codecc_task_list.actionName=任务列表 +codecc_task_manage.actionName=任务权限管理 +codecc_task_manage-defect.actionName=问题管理 +codecc_task_manage-permissions.actionName=任务权限管理 +codecc_task_setting.actionName=任务设置 +codecc_task_view-defect.actionName=查看问题列表和详情 +codecc_task_view-report.actionName=查看报表 +credential_create.actionName=创建凭据 +credential_delete.actionName=删除凭据 +credential_edit.actionName=编辑凭据 +credential_list.actionName=凭据列表 +credential_use.actionName=使用凭据 +credential_view.actionName=查看凭据 +env_node_create.actionName=创建节点 +env_node_delete.actionName=删除节点 +env_node_edit.actionName=编辑节点 +env_node_list.actionName=节点列表 +env_node_use.actionName=使用节点 +env_node_view.actionName=查看节点 +environment_create.actionName=创建环境 +environment_delete.actionName=删除环境 +environment_edit.actionName=编辑环境 +environment_list.actionName=环境列表 +environment_use.actionName=使用环境 +environment_view.actionName=查看环境 +experience_group_create.actionName=创建版本体验用户组 +experience_group_delete.actionName=删除版本体验用户组 +experience_group_edit.actionName=编辑版本体验用户组 +experience_group_list.actionName=版本体验用户组列表 +experience_group_view.actionName=查看版本体验用户组 +experience_task_create.actionName=创建版本体验任务 +experience_task_delete.actionName=下架版本体验任务 +experience_task_edit.actionName=编辑版本体验任务 +experience_task_list.actionName=版本体验任务列表 +experience_task_view.actionName=查看版本体验任务 +pipeline_create.actionName=创建流水线 +pipeline_delete.actionName=删除流水线 +pipeline_download.actionName=下载制品 +pipeline_edit.actionName=编辑流水线 +pipeline_execute.actionName=执行流水线 +pipeline_list.actionName=流水线列表 +pipeline_manage.actionName=流水线权限管理 +pipeline_share.actionName=分享制品 +pipeline_view.actionName=查看流水线 +project_edit.actionName=编辑项目 +project_enable.actionName=禁用.action/启用项目 +project_list.actionName=项目列表 +project_manage.actionName=项目权限管理 +project_view.actionName=查看项目 +project_visit.actionName=访问项目 +quality_group_create.actionName=创建质量红线规则用户组 +quality_group_delete.actionName=删除质量红线规则用户组 +quality_group_edit.actionName=编辑质量红线规则用户组 +quality_group_list.actionName=质量红线规则用户组列表 +repertory_create.actionName=关联代码库 +repertory_delete.actionName=删除代码库 +repertory_edit.actionName=编辑代码库 +repertory_list.actionName=代码库列表 +repertory_use.actionName=使用代码库 +repertory_view.actionName=查看代码库 +rule_create.actionName=创建质量红线规则 +rule_delete.actionName=删除质量红线规则 +rule_edit.actionName=编辑质量红线规则 +rule_enable.actionName=启用.action/停用质量红线规则 +rule_list.actionName=质量红线规则列表 + +cert.manager.AuthResourceGroupConfig.description=证书拥有者,拥有当前证书的所有操作权限 +cert.user.AuthResourceGroupConfig.description=证书使用者,可以在流水线中使用此证书 +codecc_task.editor.AuthResourceGroupConfig.description=任务编辑者,拥有当前任务除了权限管理之外的所有权限 +codecc_task.executor.AuthResourceGroupConfig.description=任务执行者,可以查看和执行任务 +codecc_task.manager.AuthResourceGroupConfig.description=任务拥有者,可以管理当前任务的所有权限 +codecc_task.viewer.AuthResourceGroupConfig.description=任务查看者,可以查看任务 +credential.manager.AuthResourceGroupConfig.description=凭据拥有者,拥有当前凭据的所有操作权限 +credential.user.AuthResourceGroupConfig.description=凭据使用者,可以在流水线中使用此凭据 +env_node.manager.AuthResourceGroupConfig.description=节点拥有者,拥有当前节点的所有操作权限 +env_node.user.AuthResourceGroupConfig.description=节点使用者,可以在流水线中使用此节点 +environment.manager.AuthResourceGroupConfig.description=环境拥有者,拥有当前环境的所有操作权限 +environment.user.AuthResourceGroupConfig.description=环境使用者,可以在流水线中使用此环境 +experience_group.manager.AuthResourceGroupConfig.description=版本体验组拥有者,拥有当前版本体验组的所有操作权限 +experience_task.manager.AuthResourceGroupConfig.description=版本体验拥有者,拥有当前版本体验的所有操作权限 +pipeline.editor.AuthResourceGroupConfig.description=流水线编辑者,拥有当前流水线除了权限管理之外的所有权限 +pipeline.executor.AuthResourceGroupConfig.description=流水线执行者,可以查看和执行流水线,下载或分享制品 +pipeline.manager.AuthResourceGroupConfig.description=流水线拥有者,可以管理当前流水线的权限 +pipeline.viewer.AuthResourceGroupConfig.description=流水线查看者,可以查看流水线,下载或分享制品 +pipeline_group.editor.AuthResourceGroupConfig.description=可以查看、编辑、执行组内的流水线 +pipeline_group.executor.AuthResourceGroupConfig.description=可以查看、执行组内的流水线 +pipeline_group.manager.AuthResourceGroupConfig.description=流水线组管理员,可以管理组中的流水线,给组内流水线批量添加编辑者、执行者、查看者 +pipeline_group.viewer.AuthResourceGroupConfig.description=可以查看组内的流水线 +project.developer.AuthResourceGroupConfig.description=开发人员,可以创建流水线、代码库、凭据、证书、环境、节点、Codecc任务、Codecc规则集,下载和分享项目自定义仓库中的制品 +project.maintainer.AuthResourceGroupConfig.description=运维人员,可以创建流水线、代码库、凭据、证书、环境、节点,下载和分享项目自定义仓库中的制品 +project.manager.AuthResourceGroupConfig.description=项目管理员,拥有项目下所有资源的操作和管理权限。可以添加用户到项目,从项目下移除用户,审批加入项目的申请,以及审批项目级用户组中用户的权限续期申请。 +project.pm.AuthResourceGroupConfig.description=产品人员,可以查看流水线列表,下载或分享制品。 +project.qc.AuthResourceGroupConfig.description=质管人员,管理质量红线规则。 +project.tester.AuthResourceGroupConfig.description=测试人员,可以创建测试流水线以及相关资源,下载或分享制品。 +project.visitor.AuthResourceGroupConfig.description=访客,可以查看流水线列表。 +quality_group.manager.AuthResourceGroupConfig.description=质量红线通知组拥有者,拥有当前质量红线通知组的所有操作权限 +repertory.manager.AuthResourceGroupConfig.description=代码库拥有者,拥有当前代码库的所有操作权限 +repertory.user.AuthResourceGroupConfig.description=代码库使用者,可以在流水线中使用此代码库 +rule.manager.AuthResourceGroupConfig.description=质量红线规则拥有者,拥有当前质量红线规则的所有操作权限 +cert.manager.AuthResourceGroupConfig.groupName=拥有者 +cert.user.AuthResourceGroupConfig.groupName=使用者 +codecc_task.editor.AuthResourceGroupConfig.groupName=编辑者 +codecc_task.executor.AuthResourceGroupConfig.groupName=执行者 +codecc_task.manager.AuthResourceGroupConfig.groupName=拥有者 +codecc_task.viewer.AuthResourceGroupConfig.groupName=查看者 +credential.manager.AuthResourceGroupConfig.groupName=拥有者 +credential.user.AuthResourceGroupConfig.groupName=使用者 +env_node.manager.AuthResourceGroupConfig.groupName=拥有者 +env_node.user.AuthResourceGroupConfig.groupName=使用者 +environment.manager.AuthResourceGroupConfig.groupName=拥有者 +environment.user.AuthResourceGroupConfig.groupName=使用者 +experience_group.manager.AuthResourceGroupConfig.groupName=拥有者 +experience_task.manager.AuthResourceGroupConfig.groupName=拥有者 +pipeline.editor.AuthResourceGroupConfig.groupName=编辑者 +pipeline.executor.AuthResourceGroupConfig.groupName=执行者 +pipeline.manager.AuthResourceGroupConfig.groupName=拥有者 +pipeline.viewer.AuthResourceGroupConfig.groupName=查看者 +pipeline_group.editor.AuthResourceGroupConfig.groupName=编辑者 +pipeline_group.executor.AuthResourceGroupConfig.groupName=执行者 +pipeline_group.manager.AuthResourceGroupConfig.groupName=拥有者 +pipeline_group.viewer.AuthResourceGroupConfig.groupName=查看者 +project.developer.AuthResourceGroupConfig.groupName=开发人员 +project.maintainer.AuthResourceGroupConfig.groupName=运维人员 +project.manager.AuthResourceGroupConfig.groupName=管理员 +project.pm.AuthResourceGroupConfig.groupName=产品人员 +project.qc.AuthResourceGroupConfig.groupName=质管人员 +project.tester.AuthResourceGroupConfig.groupName=测试人员 +project.visitor.AuthResourceGroupConfig.groupName=访客 +quality_group.manager.AuthResourceGroupConfig.groupName=拥有者 +repertory.manager.AuthResourceGroupConfig.groupName=拥有者 +repertory.user.AuthResourceGroupConfig.groupName=使用者 +rule.manager.AuthResourceGroupConfig.groupName=拥有者 + +cert.ResourceType.desc=证书 +codecc_ignore_type.ResourceType.desc=CodeCC忽略类型 +codecc_rule_set.ResourceType.desc=CodeCC规则集 +codecc_task.ResourceType.desc=CodeCC任务 +credential.ResourceType.desc=凭据 +env_node.ResourceType.desc=节点 +environment.ResourceType.desc=环境 +experience_group.ResourceType.desc=版本体验用户组 +experience_task.ResourceType.desc=版本体验任务 +pipeline.ResourceType.desc=流水线 +pipeline_group.ResourceType.desc=流水线组 +project.ResourceType.desc=项目 +quality_group.ResourceType.desc=质量红线通知组 +repertory.ResourceType.desc=代码库 +rule.ResourceType.desc=质量红线规则 +cert.ResourceType.name=证书 +codecc_ignore_type.ResourceType.name=CodeCC忽略类型 +codecc_rule_set.ResourceType.name=CodeCC规则集 +codecc_task.ResourceType.name=CodeCC任务 +credential.ResourceType.name=凭据 +env_node.ResourceType.name=节点 +environment.ResourceType.name=环境 +experience_group.ResourceType.name=版本体验用户组 +experience_task.ResourceType.name=版本体验任务 +pipeline.ResourceType.name=流水线 +pipeline_group.ResourceType.name=流水线组 +project.ResourceType.name=项目 +quality_group.ResourceType.name=质量红线通知组 +repertory.ResourceType.name=代码库 +rule.ResourceType.name=质量红线规则 + From f6d8491aaa5cc6818ca3a44f61c21f26db793156 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Mon, 5 Jun 2023 17:47:11 +0800 Subject: [PATCH 010/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/service/RbacPermissionApplyService.kt | 2 +- .../kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt | 5 ++--- .../devops/quality/service/v2/QualityMetadataService.kt | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt index 47faec86a9d..0914292c036 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt @@ -380,7 +380,7 @@ class RbacPermissionApplyService @Autowired constructor( language = I18nUtil.getDefaultLocaleLanguage(), defaultMessage = it.actionName ) - }, + }, groupInfoList = groupInfoList ) } diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt index 13b10b143b0..dabe318593d 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt @@ -215,7 +215,7 @@ class AuthCronManager @Autowired constructor( Executors.newFixedThreadPool(1).submit { try { logger.info("start init auth resource group config type I18n") - val authAuthResourceGroupConfigs= mutableListOf() + val authAuthResourceGroupConfigs = mutableListOf() var page = PageUtil.DEFAULT_PAGE do { val resourceGroupConfigResult = authResourceGroupConfigDao.list( @@ -248,8 +248,7 @@ class AuthCronManager @Autowired constructor( } } } - - + companion object { val logger = LoggerFactory.getLogger(AuthCronManager::class.java) private const val AUTH_EXPIRING_MANAGAER_APPROVAL = "auth:expiring:manager:approval" diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt index fcd81e939ae..d36520cb64f 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt @@ -34,7 +34,6 @@ import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.redis.RedisLock import com.tencent.devops.common.redis.RedisOperation import com.tencent.devops.common.service.config.CommonConfig -import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.model.quality.tables.records.TQualityMetadataRecord import com.tencent.devops.quality.api.v2.pojo.QualityIndicatorMetadata import com.tencent.devops.quality.api.v2.pojo.enums.QualityDataType From 3393a72ce3853eb2158d69abf5ad030bdbd8804a Mon Sep 17 00:00:00 2001 From: yjieliang Date: Mon, 5 Jun 2023 18:06:19 +0800 Subject: [PATCH 011/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt index dabe318593d..289a944c6c0 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt @@ -248,7 +248,6 @@ class AuthCronManager @Autowired constructor( } } } - companion object { val logger = LoggerFactory.getLogger(AuthCronManager::class.java) private const val AUTH_EXPIRING_MANAGAER_APPROVAL = "auth:expiring:manager:approval" From 8a296740c6143bda05e3670c31855776a8191872 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Mon, 5 Jun 2023 18:57:12 +0800 Subject: [PATCH 012/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/quality/service/v2/QualityIndicatorService.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt index 888d5445a7f..a3b3fef1c9a 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt @@ -340,7 +340,11 @@ class QualityIndicatorService @Autowired constructor( if (indicatorDao.create(userId, indicatorUpdate, dslContext) > 0) { return Msg(0, I18nUtil.getCodeLanMessage(BK_CREATE_SUCCESS), true) } - return Msg(-1, I18nUtil.getCodeLanMessage(BK_CREATE_FAIL), false) + return Msg( + -1, + I18nUtil.getCodeLanMessage(messageCode = BK_CREATE_FAIL, language = I18nUtil.getLanguage(userId)), + false + ) } fun userDelete(userId: String, id: Long): Boolean { From e0b3e5e4729cfd2b810a9814bd9df435470aabb9 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Mon, 5 Jun 2023 19:44:31 +0800 Subject: [PATCH 013/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../i18n/auth/message_en_US.properties | 155 +++++++++--------- .../i18n/auth/message_zh_CN.properties | 47 +++--- 2 files changed, 100 insertions(+), 102 deletions(-) diff --git a/support-files/i18n/auth/message_en_US.properties b/support-files/i18n/auth/message_en_US.properties index a38bd47bc53..48b02020692 100644 --- a/support-files/i18n/auth/message_en_US.properties +++ b/support-files/i18n/auth/message_en_US.properties @@ -93,9 +93,8 @@ codecc_rule_set_list.actionName=CodeCC Rule Set List codecc_task_analyze.actionName=CodeCC Task Analyze codecc_task_create.actionName=CodeCC Task Create codecc_task_list.actionName=CodeCC Task List -codecc_task_manage.actionName=CodeCC Task Manage Permissions +codecc_task_manage.actionName=CodeCC Task Manage codecc_task_manage-defect.actionName=CodeCC Task Manage Defect -codecc_task_manage-permissions.actionName=CodeCC Task Manage Permissions codecc_task_setting.actionName=CodeCC Task Setting codecc_task_view-defect.actionName=CodeCC Defect Detail View codecc_task_view-report.actionName=CodeCC Task Report View @@ -105,6 +104,36 @@ credential_edit.actionName=Credential Edit credential_list.actionName=Credential List credential_use.actionName=Credential Use credential_view.actionName=Credential View +pipeline_create.actionName=Pipeline Create +pipeline_delete.actionName=Pipeline Delete +pipeline_download.actionName=Pipeline Download +pipeline_edit.actionName=Pipeline Edit +pipeline_execute.actionName=Pipeline Execute +pipeline_list.actionName=Pipeline List +pipeline_manage.actionName=Pipeline Manage +pipeline_share.actionName=Pipeline Share +pipeline_view.actionName=Pipeline View +project_edit.actionName=Project Edit +project_enable.actionName=Project Enable +project_list.actionName=Project List +project_manage.actionName=Project Manage +project_view.actionName=Project View +project_visit.actionName=Project Visit +quality_group_create.actionName=Quality Notice Group Create +quality_group_delete.actionName=Quality Notice Group Delete +quality_group_edit.actionName=Quality Notice Group Edit +quality_group_list.actionName=Quality Notice Group List +repertory_create.actionName=Repository Create +repertory_delete.actionName=Repository Delete +repertory_edit.actionName=Repository Edit +repertory_list.actionName=Repository List +repertory_use.actionName=Repository Use +repertory_view.actionName=Repository View +rule_create.actionName=Quality Rule Create +rule_delete.actionName=Quality Rule Delete +rule_edit.actionName=Quality Rule Edit +rule_enable.actionName=Quality Rule Enable +rule_list.actionName=Quality Rule List env_node_create.actionName=Node Create env_node_delete.actionName=Node Delete env_node_edit.actionName=Node Edit @@ -127,70 +156,41 @@ experience_task_delete.actionName=Experience Task Delete experience_task_edit.actionName=Experience Task Edit experience_task_list.actionName=Experience Task List experience_task_view.actionName=Experience Task View -pipeline_create.actionName=Pipeline Create -pipeline_delete.actionName=Pipeline Delete -pipeline_download.actionName=Pipeline Download -pipeline_edit.actionName=Pipeline Edit -pipeline_execute.actionName=Pipeline Execute -pipeline_list.actionName=Pipeline List -pipeline_manage.actionName=Pipeline Manage -pipeline_share.actionName=Pipeline Share -pipeline_view.actionName=Pipeline View -project_edit.actionName=Project Edit -project_enable.actionName=Project Enable -project_list.actionName=Project List -project_manage.actionName=Project Manage -project_view.actionName=Project View -project_visit.actionName=Project Visit -quality_group_create.actionName=Andon Notice Group Create -quality_group_delete.actionName=Andon Notice Group Delete -quality_group_edit.actionName=Andon Notice Group Edit -quality_group_list.actionName=Andon Notice Group List -repertory_create.actionName=Repository Create -repertory_delete.actionName=Repository Delete -repertory_edit.actionName=Repository Edit -repertory_list.actionName=Repository List -repertory_use.actionName=Repository Use -repertory_view.actionName=Repository View -rule_create.actionName=Andon Rule Create -rule_delete.actionName=Andon Rule Delete -rule_edit.actionName=Andon Rule Edit -rule_enable.actionName=Andon Rule Enable -rule_list.actionName=Andon Rule List -cert.manager.AuthResourceGroupConfig.description=Certificate owner, who has all the operation permissions of the current certificate -cert.user.AuthResourceGroupConfig.description=Certificate consumer, you can use this certificate in the pipeline -codecc_task.editor.AuthResourceGroupConfig.description=The task editor has all the permissions for the current task except for rights management -codecc_task.executor.AuthResourceGroupConfig.description=Task executor, who can view and execute tasks -codecc_task.manager.AuthResourceGroupConfig.description=Task owner, who can manage all permissions for the current task -codecc_task.viewer.AuthResourceGroupConfig.description=Task viewer, you can view the task -credential.manager.AuthResourceGroupConfig.description=The credential owner has all the operation rights of the current credential -credential.user.AuthResourceGroupConfig.description=Credential user, which can be used in the pipeline -env_node.manager.AuthResourceGroupConfig.description=The node owner has all the operation permissions of the current node -env_node.user.AuthResourceGroupConfig.description=Node consumer, you can use this node in the pipeline -environment.manager.AuthResourceGroupConfig.description=The owner of the environment, who has all the operational permissions of the current environment -environment.user.AuthResourceGroupConfig.description=Users of the environment, which can be used in the pipeline -experience_group.manager.AuthResourceGroupConfig.description=The owner of the version experience group has all the operation rights of the current version experience group -experience_task.manager.AuthResourceGroupConfig.description=The owner of the version experience has all the operation rights of the current version experience -pipeline.editor.AuthResourceGroupConfig.description=The pipeline editor has all the permissions of the current pipeline except for rights management -pipeline.executor.AuthResourceGroupConfig.description=Pipeline executor, can view and execute pipeline, download or share products -pipeline.manager.AuthResourceGroupConfig.description=Pipeline owner, who can manage the permissions of the current pipeline -pipeline.viewer.AuthResourceGroupConfig.description=Pipeline viewer can view pipeline, download or share products -pipeline_group.editor.AuthResourceGroupConfig.description=You can view, edit, and execute pipelines within a group -pipeline_group.executor.AuthResourceGroupConfig.description=You can view and execute the pipelining within the group -pipeline_group.manager.AuthResourceGroupConfig.description=The pipeline group administrator can manage the pipelines in the group and add editors, executors and viewers to the pipelines in the group in batch. -pipeline_group.viewer.AuthResourceGroupConfig.description=You can view the pipelining within the group -project.developer.AuthResourceGroupConfig.description=Developers can create pipelines, code bases, credentials, certificates, environments, nodes, Codecc tasks, Codecc rule sets, download and share artifacts in the project's custom repository -project.maintainer.AuthResourceGroupConfig.description=Operation and maintenance personnel, you can create pipelines, code bases, credentials, certificates, environments, nodes, download and share products in the project custom warehouse -project.manager.AuthResourceGroupConfig.description=The project administrator has the authority to operate and manage all resources under the project. You can add users to the project, remove users from the project, approve applications to join the project, and approve permission renewal applications for users in the project-level user group. -project.pm.AuthResourceGroupConfig.description=Product personnel, you can view the pipeline list, download or share products. -project.qc.AuthResourceGroupConfig.description=Quality control staff, manage quality red line rules. -project.tester.AuthResourceGroupConfig.description=Testers can create test lines and related resources, download or share products. -project.visitor.AuthResourceGroupConfig.description=For visitors, you can view a list of pipelines. -quality_group.manager.AuthResourceGroupConfig.description=The owner of the quality red line notification group has all the operation permissions of the current quality red line notification group -repertory.manager.AuthResourceGroupConfig.description=The owner of the code base has all the permissions to operate the current code base. -repertory.user.AuthResourceGroupConfig.description=Code base users, you can use this code base in the pipeline -rule.manager.AuthResourceGroupConfig.description=The owner of the quality red line rule has all the operation rights of the current quality red line rule. +cert.manager.AuthResourceGroupConfig.description=Certificate owner has all permissions of the current certificate +cert.user.AuthResourceGroupConfig.description=Certificate user can use this certificate in the pipeline +codecc_task.editor.AuthResourceGroupConfig.description=task editor, who has all the permissions of the current task except permission management +codecc_task.executor.AuthResourceGroupConfig.description=task executors, who can view and execute the current task +codecc_task.manager.AuthResourceGroupConfig.description=task owner, who can manage the permissions of the current task +codecc_task.viewer.AuthResourceGroupConfig.description=task viewer, who can view the current task +credential.manager.AuthResourceGroupConfig.description=Credential owner has all permissions of the current credential +credential.user.AuthResourceGroupConfig.description=Credential user can use this credential in the pipeline +env_node.manager.AuthResourceGroupConfig.description=Agent owner has all permissions of the current agent +env_node.user.AuthResourceGroupConfig.description=Agent user can use this agent in the pipeline +environment.manager.AuthResourceGroupConfig.description=Agent-pool owner has all permissions for the current pool. +environment.user.AuthResourceGroupConfig.description=Agent-pool user can use this pool in the pipeline +experience_group.manager.AuthResourceGroupConfig.description=Experience user group owner has member management permissions for the current group +experience_task.manager.AuthResourceGroupConfig.description=Experience task owner has all permissions of the current task +pipeline.editor.AuthResourceGroupConfig.description=Pipeline editor has all permissions for the current pipeline except for permission management +pipeline.executor.AuthResourceGroupConfig.description=Pipeline executor can view and execute the pipeline, as well as download or share artifacts +pipeline.manager.AuthResourceGroupConfig.description=Pipeline owner can manage the permissions of the current pipeline +pipeline.viewer.AuthResourceGroupConfig.description=Pipeline viewer can view pipelines, download or share artifacts +pipeline_group.editor.AuthResourceGroupConfig.description=Can view, edit, and execute pipelines in the group +pipeline_group.executor.AuthResourceGroupConfig.description=Can view and execute the pipelines in the group +pipeline_group.manager.AuthResourceGroupConfig.description=The pipeline group owner can manage the pipelines in the group, and add editors, executors, and viewers to the pipelines in the group in batches +pipeline_group.viewer.AuthResourceGroupConfig.description=Can view the pipelines in the group +project.developer.AuthResourceGroupConfig.description=Developer can create pipelines, repos, credentials, certificates, agent pools, agents, codecc tasks, codecc rule sets, download and share artifacts in the custom-path artifactory +project.maintainer.AuthResourceGroupConfig.description=SRE can create pipelines, repos, credentials, certificates, agent pools, agents, download and share artifacts in the custom-path artifactory +project.manager.AuthResourceGroupConfig.description=Project owner has all permissions for this project +project.pm.AuthResourceGroupConfig.description=PM can view the pipeline list, download or share artifacts in the custom-path artifactory +project.qc.AuthResourceGroupConfig.description=QC can manage quality red line rules +project.tester.AuthResourceGroupConfig.description=QA can create pipelines, repos, credentials, certificates, agent pools, agents, codecc tasks, codecc rule sets, download and share artifacts in the custom-path artifactory +project.visitor.AuthResourceGroupConfig.description=Guest can view the pipeline list +quality_group.manager.AuthResourceGroupConfig.description=Quality red-line notification group owner has all permissions for the current quality red-line notification group +repertory.manager.AuthResourceGroupConfig.description=Repository owner has all permissions of the current repository +repertory.user.AuthResourceGroupConfig.description=Repository user can use this repository in the pipeline +rule.manager.AuthResourceGroupConfig.description=Quality red-line rule owner has all permissions for the current quality red-line rule + cert.manager.AuthResourceGroupConfig.groupName=Owner cert.user.AuthResourceGroupConfig.groupName=User codecc_task.editor.AuthResourceGroupConfig.groupName=Editor @@ -214,21 +214,21 @@ pipeline_group.executor.AuthResourceGroupConfig.groupName=Executor pipeline_group.manager.AuthResourceGroupConfig.groupName=Owner pipeline_group.viewer.AuthResourceGroupConfig.groupName=Viewer project.developer.AuthResourceGroupConfig.groupName=Developer -project.maintainer.AuthResourceGroupConfig.groupName=Operation and maintenance personnel -project.manager.AuthResourceGroupConfig.groupName=Administrator -project.pm.AuthResourceGroupConfig.groupName=Product personnel -project.qc.AuthResourceGroupConfig.groupName=Quality control personnel -project.tester.AuthResourceGroupConfig.groupName=Tester -project.visitor.AuthResourceGroupConfig.groupName=Visitors +project.maintainer.AuthResourceGroupConfig.groupName=SRE +project.manager.AuthResourceGroupConfig.groupName=Owner +project.pm.AuthResourceGroupConfig.groupName=PM +project.qc.AuthResourceGroupConfig.groupName=QC +project.tester.AuthResourceGroupConfig.groupName=QA +project.visitor.AuthResourceGroupConfig.groupName=Guest quality_group.manager.AuthResourceGroupConfig.groupName=Owner repertory.manager.AuthResourceGroupConfig.groupName=Owner repertory.user.AuthResourceGroupConfig.groupName=User rule.manager.AuthResourceGroupConfig.groupName=Owner cert.ResourceType.desc=Cert -codecc_ignore_type.ResourceType.desc=Codecc Ignore Type -codecc_rule_set.ResourceType.desc=Codecc Rule Set -codecc_task.ResourceType.desc=Codecc Task +codecc_ignore_type.ResourceType.desc=CodeCC Ignore Type +codecc_rule_set.ResourceType.desc=CodeCC Rule Set +codecc_task.ResourceType.desc=CodeCC Task credential.ResourceType.desc=Credential env_node.ResourceType.desc=Node environment.ResourceType.desc=Environment @@ -241,9 +241,9 @@ quality_group.ResourceType.desc=Andon Notice Group repertory.ResourceType.desc=Repository rule.ResourceType.desc=Andon Rule cert.ResourceType.name=Cert -codecc_ignore_type.ResourceType.name=Codecc Ignore Type -codecc_rule_set.ResourceType.name=Codecc Rule Set -codecc_task.ResourceType.name=Codecc Task +codecc_ignore_type.ResourceType.name=CodeCC Ignore Type +codecc_rule_set.ResourceType.name=CodeCC Rule Set +codecc_task.ResourceType.name=CodeCC Task credential.ResourceType.name=Credential env_node.ResourceType.name=Node environment.ResourceType.name=Environment @@ -255,4 +255,3 @@ project.ResourceType.name=Project quality_group.ResourceType.name=Andon Notice Group repertory.ResourceType.name=Repository rule.ResourceType.name=Andon Rule - diff --git a/support-files/i18n/auth/message_zh_CN.properties b/support-files/i18n/auth/message_zh_CN.properties index 12f89be1fbd..d5361f40056 100644 --- a/support-files/i18n/auth/message_zh_CN.properties +++ b/support-files/i18n/auth/message_zh_CN.properties @@ -95,7 +95,6 @@ codecc_task_create.actionName=新建任务 codecc_task_list.actionName=任务列表 codecc_task_manage.actionName=任务权限管理 codecc_task_manage-defect.actionName=问题管理 -codecc_task_manage-permissions.actionName=任务权限管理 codecc_task_setting.actionName=任务设置 codecc_task_view-defect.actionName=查看问题列表和详情 codecc_task_view-report.actionName=查看报表 @@ -105,28 +104,6 @@ credential_edit.actionName=编辑凭据 credential_list.actionName=凭据列表 credential_use.actionName=使用凭据 credential_view.actionName=查看凭据 -env_node_create.actionName=创建节点 -env_node_delete.actionName=删除节点 -env_node_edit.actionName=编辑节点 -env_node_list.actionName=节点列表 -env_node_use.actionName=使用节点 -env_node_view.actionName=查看节点 -environment_create.actionName=创建环境 -environment_delete.actionName=删除环境 -environment_edit.actionName=编辑环境 -environment_list.actionName=环境列表 -environment_use.actionName=使用环境 -environment_view.actionName=查看环境 -experience_group_create.actionName=创建版本体验用户组 -experience_group_delete.actionName=删除版本体验用户组 -experience_group_edit.actionName=编辑版本体验用户组 -experience_group_list.actionName=版本体验用户组列表 -experience_group_view.actionName=查看版本体验用户组 -experience_task_create.actionName=创建版本体验任务 -experience_task_delete.actionName=下架版本体验任务 -experience_task_edit.actionName=编辑版本体验任务 -experience_task_list.actionName=版本体验任务列表 -experience_task_view.actionName=查看版本体验任务 pipeline_create.actionName=创建流水线 pipeline_delete.actionName=删除流水线 pipeline_download.actionName=下载制品 @@ -157,6 +134,28 @@ rule_delete.actionName=删除质量红线规则 rule_edit.actionName=编辑质量红线规则 rule_enable.actionName=启用.action/停用质量红线规则 rule_list.actionName=质量红线规则列表 +env_node_create.actionName=创建节点 +env_node_delete.actionName=删除节点 +env_node_edit.actionName=编辑节点 +env_node_list.actionName=节点列表 +env_node_use.actionName=使用节点 +env_node_view.actionName=查看节点 +environment_create.actionName=创建环境 +environment_delete.actionName=删除环境 +environment_edit.actionName=编辑环境 +environment_list.actionName=环境列表 +environment_use.actionName=使用环境 +environment_view.actionName=查看环境 +experience_group_create.actionName=创建版本体验用户组 +experience_group_delete.actionName=删除版本体验用户组 +experience_group_edit.actionName=编辑版本体验用户组 +experience_group_list.actionName=版本体验用户组列表 +experience_group_view.actionName=查看版本体验用户组 +experience_task_create.actionName=创建版本体验任务 +experience_task_delete.actionName=下架版本体验任务 +experience_task_edit.actionName=编辑版本体验任务 +experience_task_list.actionName=版本体验任务列表 +experience_task_view.actionName=查看版本体验任务 cert.manager.AuthResourceGroupConfig.description=证书拥有者,拥有当前证书的所有操作权限 cert.user.AuthResourceGroupConfig.description=证书使用者,可以在流水线中使用此证书 @@ -191,6 +190,7 @@ quality_group.manager.AuthResourceGroupConfig.description=质量红线通知组 repertory.manager.AuthResourceGroupConfig.description=代码库拥有者,拥有当前代码库的所有操作权限 repertory.user.AuthResourceGroupConfig.description=代码库使用者,可以在流水线中使用此代码库 rule.manager.AuthResourceGroupConfig.description=质量红线规则拥有者,拥有当前质量红线规则的所有操作权限 + cert.manager.AuthResourceGroupConfig.groupName=拥有者 cert.user.AuthResourceGroupConfig.groupName=使用者 codecc_task.editor.AuthResourceGroupConfig.groupName=编辑者 @@ -255,4 +255,3 @@ project.ResourceType.name=项目 quality_group.ResourceType.name=质量红线通知组 repertory.ResourceType.name=代码库 rule.ResourceType.name=质量红线规则 - From 639ee368534f0e65ccb5c70980347f8432de29eb Mon Sep 17 00:00:00 2001 From: yjieliang Date: Mon, 5 Jun 2023 20:15:43 +0800 Subject: [PATCH 014/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notify/service/NotifyMessageTemplateServiceImpl.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt index cff60a5861f..4423760f4b3 100644 --- a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt +++ b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt @@ -116,9 +116,11 @@ class NotifyMessageTemplateServiceImpl @Autowired constructor( if (redisLock.tryLock()) { Executors.newFixedThreadPool(1).submit { try { - logger.info("start init MessageTemplate") + logger.info("start initMessageTemplate") updateMessageTemplate() - logger.info("start init succeed") + logger.info("start initMessageTemplate succeed") + } catch (e: Exception) { + logger.debug("start initMessageTemplate fail! error:$e") } finally { redisLock.unlock() } From 6d8ac028e71f7aa1710997fa44fa266eed8ca75b Mon Sep 17 00:00:00 2001 From: yjieliang Date: Tue, 6 Jun 2023 12:24:36 +0800 Subject: [PATCH 015/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- support-files/i18n/notify/template_en_US.yaml | 78 +++++++++---------- support-files/i18n/notify/template_zh_CN.yaml | 78 +++++++++---------- 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/support-files/i18n/notify/template_en_US.yaml b/support-files/i18n/notify/template_en_US.yaml index 7b6a1db768b..9071b2385e2 100644 --- a/support-files/i18n/notify/template_en_US.yaml +++ b/support-files/i18n/notify/template_en_US.yaml @@ -13,7 +13,7 @@ title: "Add notification to atom members of the store" body: "The administrator of the [${storeName}] atom of the store [${storeAdmin}] has added you as a member of the atom" creator: "system" - modifior: "system" + modifier: "system" - index: 1 id: "15a1e5f8642c4d7196270329531bf4cb" templateCode: "MANUAL_REVIEW_STAGE_REJECT_TO_TRIGGER_TEMPLATE" @@ -33,7 +33,7 @@ title: "The pipeline under the project [${projectName}] [${pipelineName}] # ${buildNum} builds Stage audit" body: "The build has been rejected by \"${rejectUserId}\" with a pipeline status of \"Stage successful\".\nReasons for rejection:\n${suggest}\n[click on the computer side] (${reviewUrl})\n[click on mobile] (${reviewAppUrl})" creator: "system" - modifior: "system" + modifier: "system" - index: 2 id: "168b9b44b7104647b2102355180a2837" templateCode: "UPDATE_TEMPLATE_INSTANCE_NOTIFY_TEMPLATE" @@ -49,7 +49,7 @@ title: "[${projectName}] Project pipeline instance update" body: "You have successfully updated ${successPipelineNum} instances under the [${projectName}] project:\n${successPipelineMsg}\nAmong them, ${failurePipelineNum} instances failed to update:\n${failurePipelineMsg}\n\nView details: ${instanceListUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 3 id: "1be5b658d4aa465a9f9a1d0af44c8384" templateCode: "QUALITY_AUDIT_NOTIFY_TEMPLATE_V2" @@ -65,7 +65,7 @@ title: "[BK-CI quality Red Line] Intercept Notification-to be reviewed" body: "${title}\nProject: ${projectName}\nTrigger: ${cc}\nIntercept time: ${time}\n${result}\nPipeline link: ${url}" creator: "system" - modifior: "system" + modifier: "system" - index: 4 id: "1dd8f74e334e4c41a20f4187b4e0e992" templateCode: "EXTENSION_RELEASE_SUCCESS_TEMPLATE" @@ -81,7 +81,7 @@ title: "The store extension [${name}] V$ {version} has been successfully released" body: "\nThe store extension [${name}] V$ {version} has been successfully released" creator: "system" - modifior: "system" + modifier: "system" - index: 5 id: "20e4ac3f11ff4866b95a82b30b9032a1" templateCode: "STORE_COMMENT_NOTIFY_TEMPLATE" @@ -96,7 +96,7 @@ title: "[BK-CI Store] comment notice" body: "${userId} commented on ${storeName}\nRating: ${score}\nComment: ${commentContent}\n[reply | ${url}]" creator: "system" - modifior: "system" + modifier: "system" - index: 6 id: "2d8c427026b049dc98630507f5e3fa38" templateCode: "PIPELINE_SHUTDOWN_SUCCESS_NOTIFY_TEMPLATE_DETAIL" @@ -112,7 +112,7 @@ title: "BK-CI pipeline [${pipelineName}] # ${buildNum} built successfully" body: "✔️ ${successContent}\nView details: ${detailUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 7 id: "2e9227b122024a5a83c46a9f41b94aad" templateCode: "STORE_COMMENT_REPLY_NOTIFY_TEMPLATE" @@ -127,7 +127,7 @@ title: "[BK-CI Store] comment notice" body: "${userId} replied to ${replyToUser} on ${storeName}\n${replyContent} / / @ ${replyToUser}: ${replyComment}\n[reply | ${url}]" creator: "system" - modifior: "system" + modifier: "system" - index: 8 id: "30c94a920c79453da784124ab41fb068" templateCode: "ATOM_CODECC_QUALIFIED_TEMPLATE" @@ -137,7 +137,7 @@ priority: 0 source: 0 creator: "system" - modifior: "system" + modifier: "system" - index: 9 id: "37ef4157cc254021ac7278b70f211f5e" templateCode: "MANUAL_REVIEW_ATOM_NOTIFY_TEMPLATE" @@ -158,7 +158,7 @@ title: "${content}" body: "Audit description:\n${reviewDesc}\nComputer side: [to audit] (${reviewUrl})\nMobile: [check] (${reviewAppUrl})" creator: "system" - modifior: "system" + modifier: "system" - index: 10 id: "3a39413a67bf404184dbd4e9309ebeb8" templateCode: "QUALITY_NOTIFY_TEMPLATE" @@ -174,7 +174,7 @@ title: "[blue Shield quality Red Line] Audit notice" body: "${pipelineName} (# ${buildNo}) is blocked and needs to be audited\nProject: ${projectName}\nIntercept time: ${time} ${result}\nAudit link: ${url}" creator: "system" - modifior: "system" + modifier: "system" - index: 11 id: "3ea6c5e18d4b41a3890a150d1df16f4d" templateCode: "IMAGE_EXECUTE_NULL_NOTIFY_TPL" @@ -189,7 +189,7 @@ title: "${imageCode} (${imageVersion}) Image execution exception" body: "[view build link | ${url}] ${projectCode} under the ${projectCode} project of ${imageCode} (${imageVersion}) image execution exception, pipelineId:$ {pipelineId}, buildId:$ {buildId}" creator: "system" - modifior: "system" + modifier: "system" - index: 12 id: "3fbf09f0511b424ab4480e18d6674349" templateCode: "STREAM_V2_BUILD_TEMPLATE" @@ -199,7 +199,7 @@ priority: 0 source: 0 creator: "system" - modifior: "system" + modifier: "system" - index: 13 id: "4589771c46b248079444a0e18e46a3fe" templateCode: "IMAGE_RELEASE_AUDIT_PASS_TEMPLATE" @@ -215,7 +215,7 @@ title: "The store image [${name}] V$ {version} has been approved and released successfully" body: "The store image [${name}] V$ {version} has been approved and released successfully" creator: "system" - modifior: "system" + modifier: "system" - index: 14 id: "502f34f94a0d4bc7abe7c55f4e93da46" templateCode: "PIPELINE_WEBHOOK_REGISTER_FAILURE_NOTIFY_TEMPLATE" @@ -230,7 +230,7 @@ title: "pipeline【${pipelineName}】Trigger callback registration failed" body: "The pipeline you just saved【${pipelineName}】Trigger callback registration failed,Reason for failure: ${elementNames}See details: ${pipelineEditUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 15 id: "698634fd3bae40378eeb24c8d6a5c91c" templateCode: "TEMPLATE_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -246,7 +246,7 @@ title: " store template [${name}] V$ {version} failed approval" body: " store template [${name}] V$ {version} failed approval" creator: "system" - modifior: "system" + modifier: "system" - index: 16 id: "6a3db6f561f44d4895518e881a3cb53b" templateCode: "PIPELINE_SHUTDOWN_FAILURE_NOTIFY_TEMPLATE" @@ -262,7 +262,7 @@ title: "Failed to build Blue Shield pipeline [${pipelineName}] # ${buildNum}" body: "❌${failContent}" creator: "system" - modifior: "system" + modifier: "system" - index: 17 id: "6c00ffb0de6f485eb301940ca639d04d" templateCode: "TEMPLATE_RELEASE_AUDIT_PASS_TEMPLATE" @@ -278,7 +278,7 @@ title: "The store template [${name}] has been approved and released successfully." body: "The store template [${name}] has been approved and released successfully." creator: "system" - modifior: "system" + modifier: "system" - index: 18 id: "7a64b8cd997b49858964ac34079bf234" templateCode: "QUALITY_AUDIT_NOTIFY_TEMPLATE" @@ -294,7 +294,7 @@ title: "[blue Shield quality Red Line] Audit notice" body: "${pipelineName} (# ${buildNo}) is blocked and needs to be audited\nProject: ${projectName}\nIntercept time: ${time} ${result}\nAudit link: ${url}" creator: "system" - modifior: "system" + modifier: "system" - index: 19 id: "7dee6377c27344818836ef1f035a14d1" templateCode: "MANUAL_REVIEW_STAGE_NOTIFY_TO_TRIGGER_TEMPLATE" @@ -309,7 +309,7 @@ title: "The pipeline under the project [${projectName}] [${pipelineName}] # ${buildNum} builds Stage audit" body: "The current build needs to be manually approved before the follow-up process is carried out. Please wait patiently for the audit, or contact the auditor ${reviewers} for processing.\n${reviewDesc}\nClick ${reviewUrl} on the computer side\nClick ${reviewAppUrl} on the mobile phone" creator: "system" - modifior: "system" + modifier: "system" - index: 20 id: "91fb62ef51a24266ae0946112e094190" templateCode: "GITCI_V2_BUILD_TEMPLATE" @@ -319,7 +319,7 @@ priority: 0 source: 0 creator: "system" - modifior: "system" + modifier: "system" - index: 21 id: "92055af946b64850a193e1090865642e" templateCode: "ATOM_CODECC_FAILED_TEMPLATE" @@ -329,7 +329,7 @@ priority: 0 source: 0 creator: "system" - modifior: "system" + modifier: "system" - index: 22 id: "92c4e65e4cd2432eb326789ce503d698" templateCode: "PIPELINE_SHUTDOWN_FAILURE_NOTIFY_TEMPLATE_DETAIL" @@ -345,7 +345,7 @@ title: "Failed to build Blue Shield pipeline [${pipelineName}] # ${buildNum}" body: "❌ ${failContent}\n\nView details: ${detailUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 23 id: "96c0a1adaca7428eb0b2d69820923d52" templateCode: "EXTENSION_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -361,7 +361,7 @@ title: " store extension [${name}] V$ {version} failed audit" body: " store extension [${name}] V$ {version} failed audit, rejected reason: ${serviceStatusMsg}" creator: "system" - modifior: "system" + modifier: "system" - index: 24 id: "a9b46a21ed7949ddb946e5186b9102c1" templateCode: "EXTENSION_RELEASE_FAIL_TEMPLATE" @@ -377,7 +377,7 @@ title: "Failed to release store extension [${name}] V$ {version}" body: "Failed to release store extension [${name}] V$ {version}" creator: "system" - modifior: "system" + modifier: "system" - index: 25 id: "bf0ca37469cf448a86875bb2f11517c5" templateCode: "PIPELINE_STARTUP_NOTIFY_TEMPLATE_DETAIL" @@ -393,7 +393,7 @@ title: "Blue Shield pipeline [${pipelineName}] # ${buildNum} starts execution" body: "[${projectName}]-[${pipelineName}] # ${buildNum} start to view details: ${detailUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 26 id: "cbdd75de2c7f40a6a3bc1dfd909020a7" templateCode: "STORE_MEMBER_DELETE_ATOM" @@ -409,7 +409,7 @@ title: "Notification of removal of atom members in store" body: "The administrator of the store's [${storeName}] atom [${storeAdmin}] has removed you from the list of members of the atom" creator: "system" - modifior: "system" + modifier: "system" - index: 27 id: "cd7cecc126744f13a60d655d0af116af" templateCode: "PIPELINE_STARTUP_NOTIFY_TEMPLATE" @@ -425,7 +425,7 @@ title: "Blue Shield pipeline [${pipelineName}] # ${buildNum} starts execution" body: "[${projectName}]-[${pipelineName}] # ${buildNum} start execution" creator: "system" - modifior: "system" + modifier: "system" - index: 28 id: "cff00f19e6884862b6f9afe0f608e91e" templateCode: "PIPELINE_SHUTDOWN_SUCCESS_NOTIFY_TEMPLATE" @@ -441,7 +441,7 @@ title: "Blue Shield pipeline [${pipelineName}] # ${buildNum} built successfully" body: "✔️${successContent}" creator: "system" - modifior: "system" + modifier: "system" - index: 29 id: "d58e5895dfab4136ac898d93e3bff3ac" templateCode: "PIPELINE_TRIGGER_REVIEW_NOTIFY_TEMPLATE" @@ -457,7 +457,7 @@ title: "Pipeline [${pipelineName}] # ${buildNum} build under project [${projectName}] triggers audit" body: "Trigger: ${triggerUser}\n\nAuditor: ${reviewers}\n\nClick ${reviewUrl} on the computer side\nClick ${reviewAppUrl} on the mobile phone" creator: "system" - modifior: "system" + modifier: "system" - index: 30 id: "d77a91dd09994c54b14f118956e0d6e9" templateCode: "PIPELINE_TASK_PAUSE_NOTIFY" @@ -472,7 +472,7 @@ title: "Blue Shield pipeline [${BK_CI_PIPELINE_NAME}] # ${BK_CI_BUILD_NUM} construction paused" body: "[${BK_CI_PROJECT_NAME_CN}]-[${BK_CI_PIPELINE_NAME}] # ${BK_CI_BUILD_NUM} paused before executing [${taskName}], triggered by: ${BK_CI_START_USER_ID} [to handle | ${url}]" creator: "system" - modifior: "system" + modifier: "system" - index: 31 id: "d7d9e1a773fe4a658f6c51b80da282ea" templateCode: "QUALITY_END_NOTIFY_TEMPLATE" @@ -488,7 +488,7 @@ title: "[blue Shield quality Red Line] Intercept Notification" body: "${pipelineName} (# ${buildNo}) is blocked\nProject: ${projectName}\nIntercept time: ${time}\nIntercept indicator: ${thresholdListString}\nFor more information: ${url}" creator: "system" - modifior: "system" + modifier: "system" - index: 32 id: "dff46cd92eab458b96b25be0d7a61054" templateCode: "ATOM_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -504,7 +504,7 @@ title: "The store atom [${name}] V$ {version} failed the audit" body: "The store atom [${name}] V$ {version} failed the audit" creator: "system" - modifior: "system" + modifier: "system" - index: 33 id: "e961fd2ccc1c4f5d8eefaac9d51b5cb0" templateCode: "ATOM_RELEASE_AUDIT_PASS_TEMPLATE" @@ -520,7 +520,7 @@ title: "The store atom [${name}] V$ {version} has been approved and released successfully" body: "The store atom [${name}] V$ {version} has been approved and released successfully" creator: "system" - modifior: "system" + modifier: "system" - index: 34 id: "ea98239a51a74f8db0a012a809bc1116" templateCode: "IMAGE_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -536,7 +536,7 @@ title: "The store image [${name}] V$ {version} failed the audit." body: " store image [${name}] V$ {version} failed review, rejected because of ${imageStatusMsg}" creator: "system" - modifior: "system" + modifier: "system" - index: 35 id: "f0663e7ac2b74130ada0408bdce8cd20" templateCode: "QUALITY_END_NOTIFY_TEMPLATE_V2" @@ -552,7 +552,7 @@ title: "[blue Shield quality Red Line] Intercept Notification-terminated" body: "${title}\nProject: ${projectName}\nTrigger: ${cc}\nIntercept time: ${time}\n${result}\nPipeline link: ${url}" creator: "system" - modifior: "system" + modifier: "system" - index: 36 id: "f0949ab70cc04aa5b1bc787d5a47eba7" templateCode: "MANUAL_REVIEW_STAGE_NOTIFY_TEMPLATE" @@ -573,7 +573,7 @@ title: "The pipeline under the project [${projectName}] [${pipelineName}] # ${buildNum} builds Stage audit" body: "The build status is stage sucess, and an audit of \"${reviewers}\" is required to execute the subsequent process.\n\nAudit description:\n${reviewDesc}\n\n[click on the computer side] (${reviewUrl})\n[click on mobile] (${reviewAppUrl})" creator: "system" - modifior: "system" + modifier: "system" - index: 37 id: "f5c17a3f5dcd4c9ea7cf7a16a16e7135" templateCode: "ATOM_COLLABORATOR_APPLY_REFUSE" @@ -589,7 +589,7 @@ title: "[blue Shield Store] collaboration application was rejected" body: "The administrator of the pipelined atom [${atomName}] [${atomAdmin}] rejected your collaboration application for the reason: ${approveMsg}" creator: "system" - modifior: "system" + modifier: "system" - index: 38 id: "1e7864726dd04311b21019bcceddfee8" templateCode: "PIPELINE_CALLBACK_DISABLE_NOTIFY_TEMPLATE" @@ -604,4 +604,4 @@ title: "bk-ci pipeline callback interface is abnormal" body: "project【${projectName}】Registered【${events}】Event callback interface【${callbackUrl}】It is now disabled due to multiple failed calls\pipeline url:${pipelineListUrl}" creator: "system" - modifior: "system" + modifier: "system" diff --git a/support-files/i18n/notify/template_zh_CN.yaml b/support-files/i18n/notify/template_zh_CN.yaml index 691c929af24..ac9aabbf215 100644 --- a/support-files/i18n/notify/template_zh_CN.yaml +++ b/support-files/i18n/notify/template_zh_CN.yaml @@ -13,7 +13,7 @@ title: "研发商店插件成员添加通知" body: "研发商店的【${storeName}】插件的管理员【${storeAdmin}】已将您添加为该插件的成员" creator: "system" - modifior: "system" + modifier: "system" - index: 1 id: "15a1e5f8642c4d7196270329531bf4cb" templateCode: "MANUAL_REVIEW_STAGE_REJECT_TO_TRIGGER_TEMPLATE" @@ -33,7 +33,7 @@ title: "项目【${projectName}】下的流水线【${pipelineName}】#${buildNum} 构建Stage审核" body: "构建已被「${rejectUserId}」驳回,流水线状态为「 Stage成功」。\n驳回理由: \n${suggest} \n[电脑端点击](${reviewUrl}) \n[手机端点击](${reviewAppUrl})" creator: "system" - modifior: "system" + modifier: "system" - index: 2 id: "168b9b44b7104647b2102355180a2837" templateCode: "UPDATE_TEMPLATE_INSTANCE_NOTIFY_TEMPLATE" @@ -49,7 +49,7 @@ title: "【${projectName}】项目流水线实例更新" body: "您在【${projectName}】项目下已成功更新${successPipelineNum}条实例: \n${successPipelineMsg}\n其中${failurePipelineNum}条实例更新失败: \n${failurePipelineMsg}\n\n查看详情: ${instanceListUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 3 id: "1be5b658d4aa465a9f9a1d0af44c8384" templateCode: "QUALITY_AUDIT_NOTIFY_TEMPLATE_V2" @@ -65,7 +65,7 @@ title: "【蓝盾质量红线】拦截通知-待审核" body: "${title}\n所属项目: ${projectName}\n触发人: ${cc}\n拦截时间: ${time}\n${result}\n流水线链接: ${url}" creator: "system" - modifior: "system" + modifier: "system" - index: 4 id: "1dd8f74e334e4c41a20f4187b4e0e992" templateCode: "EXTENSION_RELEASE_SUCCESS_TEMPLATE" @@ -81,7 +81,7 @@ title: "研发商店扩展【${name}】V${version} 成功发布" body: "\n研发商店扩展【${name}】V${version} 成功发布" creator: "system" - modifior: "system" + modifier: "system" - index: 5 id: "20e4ac3f11ff4866b95a82b30b9032a1" templateCode: "STORE_COMMENT_NOTIFY_TEMPLATE" @@ -96,7 +96,7 @@ title: "【蓝盾研发商店】评论通知" body: "${userId} 评论了 ${storeName}\n评分: ${score}\n评论: ${commentContent}\n[去回复 | ${url}]" creator: "system" - modifior: "system" + modifier: "system" - index: 6 id: "2d8c427026b049dc98630507f5e3fa38" templateCode: "PIPELINE_SHUTDOWN_SUCCESS_NOTIFY_TEMPLATE_DETAIL" @@ -112,7 +112,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 构建成功" body: "✔️${successContent}\n查看详情:${detailUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 7 id: "2e9227b122024a5a83c46a9f41b94aad" templateCode: "STORE_COMMENT_REPLY_NOTIFY_TEMPLATE" @@ -127,7 +127,7 @@ title: "【蓝盾研发商店】评论通知" body: "${userId} 在 ${storeName} 回复了 ${replyToUser}\n${replyContent}//@${replyToUser}: ${replyComment}\n[去回复 | ${url}]" creator: "system" - modifior: "system" + modifier: "system" - index: 8 id: "30c94a920c79453da784124ab41fb068" templateCode: "ATOM_CODECC_QUALIFIED_TEMPLATE" @@ -137,7 +137,7 @@ priority: 0 source: 0 creator: "system" - modifior: "system" + modifier: "system" - index: 9 id: "37ef4157cc254021ac7278b70f211f5e" templateCode: "MANUAL_REVIEW_ATOM_NOTIFY_TEMPLATE" @@ -158,7 +158,7 @@ title: "${content}" body: "审核说明: \n${reviewDesc} \n电脑端: [去审核](${reviewUrl}) \n手机端: [去审核](${reviewAppUrl})" creator: "system" - modifior: "system" + modifier: "system" - index: 10 id: "3a39413a67bf404184dbd4e9309ebeb8" templateCode: "QUALITY_NOTIFY_TEMPLATE" @@ -174,7 +174,7 @@ title: "【蓝盾质量红线】审核通知" body: "${pipelineName}(#${buildNo})被拦截,需要审核\n所属项目: ${projectName}\n拦截时间: ${time} ${result}\n审核链接: ${url}" creator: "system" - modifior: "system" + modifier: "system" - index: 11 id: "3ea6c5e18d4b41a3890a150d1df16f4d" templateCode: "IMAGE_EXECUTE_NULL_NOTIFY_TPL" @@ -189,7 +189,7 @@ title: "${imageCode}(${imageVersion}) 镜像执行异常" body: "[查看构建链接|${url}] ${userId} 的 ${projectCode} 项目下的 ${imageCode}(${imageVersion}) 镜像执行异常,pipelineId:${pipelineId},buildId:${buildId}" creator: "system" - modifior: "system" + modifier: "system" - index: 12 id: "3fbf09f0511b424ab4480e18d6674349" templateCode: "STREAM_V2_BUILD_TEMPLATE" @@ -199,7 +199,7 @@ priority: 0 source: 0 creator: "system" - modifior: "system" + modifier: "system" - index: 13 id: "4589771c46b248079444a0e18e46a3fe" templateCode: "IMAGE_RELEASE_AUDIT_PASS_TEMPLATE" @@ -215,7 +215,7 @@ title: "研发商店镜像【${name}】V${version} 审核通过,成功发布" body: "研发商店镜像【${name}】V${version} 审核通过,成功发布" creator: "system" - modifior: "system" + modifier: "system" - index: 14 id: "502f34f94a0d4bc7abe7c55f4e93da46" templateCode: "PIPELINE_WEBHOOK_REGISTER_FAILURE_NOTIFY_TEMPLATE" @@ -230,7 +230,7 @@ title: "流水线【${pipelineName}】触发器回调注册失败" body: "你刚刚保存的流水线【${pipelineName}】触发器回调注册失败,失败原因: ${elementNames}查看详情: ${pipelineEditUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 15 id: "698634fd3bae40378eeb24c8d6a5c91c" templateCode: "TEMPLATE_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -246,7 +246,7 @@ title: "研发商店模板【${name}】V${version} 审核不通过" body: "研发商店模板【${name}】V${version} 审核不通过" creator: "system" - modifior: "system" + modifier: "system" - index: 16 id: "6a3db6f561f44d4895518e881a3cb53b" templateCode: "PIPELINE_SHUTDOWN_FAILURE_NOTIFY_TEMPLATE" @@ -262,7 +262,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 构建失败" body: "❌${failContent}" creator: "system" - modifior: "system" + modifier: "system" - index: 17 id: "6c00ffb0de6f485eb301940ca639d04d" templateCode: "TEMPLATE_RELEASE_AUDIT_PASS_TEMPLATE" @@ -278,7 +278,7 @@ title: "研发商店模板【${name}】审核通过,成功发布" body: "研发商店模板【${name}】审核通过,成功发布" creator: "system" - modifior: "system" + modifier: "system" - index: 18 id: "7a64b8cd997b49858964ac34079bf234" templateCode: "QUALITY_AUDIT_NOTIFY_TEMPLATE" @@ -294,7 +294,7 @@ title: "【蓝盾质量红线】审核通知" body: "${pipelineName}(#${buildNo})被拦截,需要审核\n所属项目: ${projectName}\n拦截时间: ${time} ${result}\n审核链接: ${url}" creator: "system" - modifior: "system" + modifier: "system" - index: 19 id: "7dee6377c27344818836ef1f035a14d1" templateCode: "MANUAL_REVIEW_STAGE_NOTIFY_TO_TRIGGER_TEMPLATE" @@ -309,7 +309,7 @@ title: "项目【${projectName}】下的流水线【${pipelineName}】#${buildNum} 构建Stage审核" body: "当前构建需人工审核通过后才执行后续流程,请耐心等待审核,或联系审核人${reviewers}处理。\n${reviewDesc} \n电脑端点击 ${reviewUrl} \n手机端点击 ${reviewAppUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 20 id: "91fb62ef51a24266ae0946112e094190" templateCode: "GITCI_V2_BUILD_TEMPLATE" @@ -319,7 +319,7 @@ priority: 0 source: 0 creator: "system" - modifior: "system" + modifier: "system" - index: 21 id: "92055af946b64850a193e1090865642e" templateCode: "ATOM_CODECC_FAILED_TEMPLATE" @@ -329,7 +329,7 @@ priority: 0 source: 0 creator: "system" - modifior: "system" + modifier: "system" - index: 22 id: "92c4e65e4cd2432eb326789ce503d698" templateCode: "PIPELINE_SHUTDOWN_FAILURE_NOTIFY_TEMPLATE_DETAIL" @@ -345,7 +345,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 构建失败" body: "❌${failContent}\n\n查看详情:${detailUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 23 id: "96c0a1adaca7428eb0b2d69820923d52" templateCode: "EXTENSION_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -361,7 +361,7 @@ title: "研发商店扩展【${name}】V${version} 审核不通过" body: "研发商店扩展【${name}】V${version} 审核不通过,驳回原因: ${serviceStatusMsg}" creator: "system" - modifior: "system" + modifier: "system" - index: 24 id: "a9b46a21ed7949ddb946e5186b9102c1" templateCode: "EXTENSION_RELEASE_FAIL_TEMPLATE" @@ -377,7 +377,7 @@ title: "研发商店扩展【${name}】V${version} 发布失败" body: "研发商店扩展【${name}】V${version} 发布失败" creator: "system" - modifior: "system" + modifier: "system" - index: 25 id: "bf0ca37469cf448a86875bb2f11517c5" templateCode: "PIPELINE_STARTUP_NOTIFY_TEMPLATE_DETAIL" @@ -393,7 +393,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 开始执行" body: "【${projectName}】-【${pipelineName}】#${buildNum} 开始执行查看详情:${detailUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 26 id: "cbdd75de2c7f40a6a3bc1dfd909020a7" templateCode: "STORE_MEMBER_DELETE_ATOM" @@ -409,7 +409,7 @@ title: "研发商店插件成员移除通知" body: "研发商店的【${storeName}】插件的管理员【${storeAdmin}】已将您从该插件的成员列表中移除" creator: "system" - modifior: "system" + modifier: "system" - index: 27 id: "cd7cecc126744f13a60d655d0af116af" templateCode: "PIPELINE_STARTUP_NOTIFY_TEMPLATE" @@ -425,7 +425,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 开始执行" body: "【${projectName}】-【${pipelineName}】#${buildNum} 开始执行" creator: "system" - modifior: "system" + modifier: "system" - index: 28 id: "cff00f19e6884862b6f9afe0f608e91e" templateCode: "PIPELINE_SHUTDOWN_SUCCESS_NOTIFY_TEMPLATE" @@ -441,7 +441,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 构建成功" body: "✔️${successContent}" creator: "system" - modifior: "system" + modifier: "system" - index: 29 id: "d58e5895dfab4136ac898d93e3bff3ac" templateCode: "PIPELINE_TRIGGER_REVIEW_NOTIFY_TEMPLATE" @@ -457,7 +457,7 @@ title: "项目【${projectName}】下的流水线【${pipelineName}】#${buildNum} 构建触发审核" body: "触发人: ${triggerUser}\n\n审核人: ${reviewers}\n\n电脑端点击 ${reviewUrl}\n手机端点击 ${reviewAppUrl}" creator: "system" - modifior: "system" + modifier: "system" - index: 30 id: "d77a91dd09994c54b14f118956e0d6e9" templateCode: "PIPELINE_TASK_PAUSE_NOTIFY" @@ -472,7 +472,7 @@ title: "蓝盾流水线【${BK_CI_PIPELINE_NAME}】#${BK_CI_BUILD_NUM} 构建暂停" body: "【${BK_CI_PROJECT_NAME_CN}】-【${BK_CI_PIPELINE_NAME}】#${BK_CI_BUILD_NUM} 在执行【${taskName}】前暂停,触发人: ${BK_CI_START_USER_ID}[去处理 | ${url}" creator: "system" - modifior: "system" + modifier: "system" - index: 31 id: "d7d9e1a773fe4a658f6c51b80da282ea" templateCode: "QUALITY_END_NOTIFY_TEMPLATE" @@ -488,7 +488,7 @@ title: "【蓝盾质量红线】拦截通知" body: "${pipelineName}(#${buildNo})被拦截\n所属项目: ${projectName}\n拦截时间: ${time}\n拦截指标: ${thresholdListString}\n详情链接: ${url}" creator: "system" - modifior: "system" + modifier: "system" - index: 32 id: "dff46cd92eab458b96b25be0d7a61054" templateCode: "ATOM_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -504,7 +504,7 @@ title: "研发商店插件【${name}】V${version} 审核不通过" body: "研发商店插件【${name}】V${version} 审核不通过" creator: "system" - modifior: "system" + modifier: "system" - index: 33 id: "e961fd2ccc1c4f5d8eefaac9d51b5cb0" templateCode: "ATOM_RELEASE_AUDIT_PASS_TEMPLATE" @@ -520,7 +520,7 @@ title: "研发商店插件【${name}】V${version} 审核通过,成功发布" body: "研发商店插件【${name}】V${version} 审核通过,成功发布" creator: "system" - modifior: "system" + modifier: "system" - index: 34 id: "ea98239a51a74f8db0a012a809bc1116" templateCode: "IMAGE_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -536,7 +536,7 @@ title: "研发商店镜像【${name}】V${version} 审核不通过" body: "研发商店镜像【${name}】V${version} 审核不通过,驳回原因: ${imageStatusMsg}" creator: "system" - modifior: "system" + modifier: "system" - index: 35 id: "f0663e7ac2b74130ada0408bdce8cd20" templateCode: "QUALITY_END_NOTIFY_TEMPLATE_V2" @@ -552,7 +552,7 @@ title: "【蓝盾质量红线】拦截通知-已终止" body: "${title}\n所属项目: ${projectName}\n触发人: ${cc}\n拦截时间: ${time}\n${result}\n流水线链接: ${url}" creator: "system" - modifior: "system" + modifier: "system" - index: 36 id: "f0949ab70cc04aa5b1bc787d5a47eba7" templateCode: "MANUAL_REVIEW_STAGE_NOTIFY_TEMPLATE" @@ -573,7 +573,7 @@ title: "项目【${projectName}】下的流水线【${pipelineName}】#${buildNum} 构建Stage审核" body: "构建状态为stage sucess,需要「${reviewers}」的审核才执行后续流程\n\n审核说明: \n${reviewDesc}\n\n[电脑端点击](${reviewUrl})\n[手机端点击](${reviewAppUrl})" creator: "system" - modifior: "system" + modifier: "system" - index: 37 id: "f5c17a3f5dcd4c9ea7cf7a16a16e7135" templateCode: "ATOM_COLLABORATOR_APPLY_REFUSE" @@ -589,7 +589,7 @@ title: "【蓝盾研发商店】协作申请被驳回" body: "流水线插件【${atomName}】的管理员【${atomAdmin}】驳回了你的协作申请,驳回原因: ${approveMsg}" creator: "system" - modifior: "system" + modifier: "system" - index: 38 id: "1e7864726dd04311b21019bcceddfee8" templateCode: "PIPELINE_CALLBACK_DISABLE_NOTIFY_TEMPLATE" @@ -604,4 +604,4 @@ title: "蓝盾流水线回调接口异常" body: "项目【${projectName}】所注册的【${events}】事件回调接口【${callbackUrl}】因多次调用失败,现已被禁用\n流水线链接:${pipelineListUrl}" creator: "system" - modifior: "system" + modifier: "system" From 0ceb2b572c9225b28219a10a3b162e38ecead21e Mon Sep 17 00:00:00 2001 From: yjieliang Date: Tue, 6 Jun 2023 12:24:56 +0800 Subject: [PATCH 016/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notify/service/NotifyMessageTemplateServiceImpl.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt index 4423760f4b3..b3a94246c3c 100644 --- a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt +++ b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt @@ -116,11 +116,10 @@ class NotifyMessageTemplateServiceImpl @Autowired constructor( if (redisLock.tryLock()) { Executors.newFixedThreadPool(1).submit { try { - logger.info("start initMessageTemplate") + logger.info("start init MessageTemplate") updateMessageTemplate() - logger.info("start initMessageTemplate succeed") } catch (e: Exception) { - logger.debug("start initMessageTemplate fail! error:$e") + logger.debug("start init MessageTemplate fail! error:$e") } finally { redisLock.unlock() } From ea53d3acee3ebf9353597faa33faa92d1d21ec7c Mon Sep 17 00:00:00 2001 From: yjieliang Date: Tue, 6 Jun 2023 14:58:26 +0800 Subject: [PATCH 017/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pojo/messageTemplate/MessageTemplate.kt | 2 +- .../NotifyMessageTemplateServiceImpl.kt | 2 +- support-files/i18n/notify/template_en_US.yaml | 78 +++++++++---------- support-files/i18n/notify/template_zh_CN.yaml | 78 +++++++++---------- 4 files changed, 80 insertions(+), 80 deletions(-) diff --git a/src/backend/ci/core/notify/api-notify/src/main/kotlin/com/tencent/devops/notify/pojo/messageTemplate/MessageTemplate.kt b/src/backend/ci/core/notify/api-notify/src/main/kotlin/com/tencent/devops/notify/pojo/messageTemplate/MessageTemplate.kt index eda14d933c9..6e46c610ac5 100644 --- a/src/backend/ci/core/notify/api-notify/src/main/kotlin/com/tencent/devops/notify/pojo/messageTemplate/MessageTemplate.kt +++ b/src/backend/ci/core/notify/api-notify/src/main/kotlin/com/tencent/devops/notify/pojo/messageTemplate/MessageTemplate.kt @@ -58,5 +58,5 @@ data class MessageTemplate( @ApiModelProperty("创建人", required = true) val creator: String, @ApiModelProperty("修改人", required = true) - val modifier: String + val modifior: String ) diff --git a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt index b3a94246c3c..6f0180359a3 100644 --- a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt +++ b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt @@ -155,7 +155,7 @@ class NotifyMessageTemplateServiceImpl @Autowired constructor( this.title = wechatTemplate.title this.sender = wechatTemplate.sender this.creator = template.creator - this.modifior = template.modifier + this.modifior = template.modifior this.createTime = LocalDateTime.now() this.updateTime = LocalDateTime.now() } diff --git a/support-files/i18n/notify/template_en_US.yaml b/support-files/i18n/notify/template_en_US.yaml index 9071b2385e2..7b6a1db768b 100644 --- a/support-files/i18n/notify/template_en_US.yaml +++ b/support-files/i18n/notify/template_en_US.yaml @@ -13,7 +13,7 @@ title: "Add notification to atom members of the store" body: "The administrator of the [${storeName}] atom of the store [${storeAdmin}] has added you as a member of the atom" creator: "system" - modifier: "system" + modifior: "system" - index: 1 id: "15a1e5f8642c4d7196270329531bf4cb" templateCode: "MANUAL_REVIEW_STAGE_REJECT_TO_TRIGGER_TEMPLATE" @@ -33,7 +33,7 @@ title: "The pipeline under the project [${projectName}] [${pipelineName}] # ${buildNum} builds Stage audit" body: "The build has been rejected by \"${rejectUserId}\" with a pipeline status of \"Stage successful\".\nReasons for rejection:\n${suggest}\n[click on the computer side] (${reviewUrl})\n[click on mobile] (${reviewAppUrl})" creator: "system" - modifier: "system" + modifior: "system" - index: 2 id: "168b9b44b7104647b2102355180a2837" templateCode: "UPDATE_TEMPLATE_INSTANCE_NOTIFY_TEMPLATE" @@ -49,7 +49,7 @@ title: "[${projectName}] Project pipeline instance update" body: "You have successfully updated ${successPipelineNum} instances under the [${projectName}] project:\n${successPipelineMsg}\nAmong them, ${failurePipelineNum} instances failed to update:\n${failurePipelineMsg}\n\nView details: ${instanceListUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 3 id: "1be5b658d4aa465a9f9a1d0af44c8384" templateCode: "QUALITY_AUDIT_NOTIFY_TEMPLATE_V2" @@ -65,7 +65,7 @@ title: "[BK-CI quality Red Line] Intercept Notification-to be reviewed" body: "${title}\nProject: ${projectName}\nTrigger: ${cc}\nIntercept time: ${time}\n${result}\nPipeline link: ${url}" creator: "system" - modifier: "system" + modifior: "system" - index: 4 id: "1dd8f74e334e4c41a20f4187b4e0e992" templateCode: "EXTENSION_RELEASE_SUCCESS_TEMPLATE" @@ -81,7 +81,7 @@ title: "The store extension [${name}] V$ {version} has been successfully released" body: "\nThe store extension [${name}] V$ {version} has been successfully released" creator: "system" - modifier: "system" + modifior: "system" - index: 5 id: "20e4ac3f11ff4866b95a82b30b9032a1" templateCode: "STORE_COMMENT_NOTIFY_TEMPLATE" @@ -96,7 +96,7 @@ title: "[BK-CI Store] comment notice" body: "${userId} commented on ${storeName}\nRating: ${score}\nComment: ${commentContent}\n[reply | ${url}]" creator: "system" - modifier: "system" + modifior: "system" - index: 6 id: "2d8c427026b049dc98630507f5e3fa38" templateCode: "PIPELINE_SHUTDOWN_SUCCESS_NOTIFY_TEMPLATE_DETAIL" @@ -112,7 +112,7 @@ title: "BK-CI pipeline [${pipelineName}] # ${buildNum} built successfully" body: "✔️ ${successContent}\nView details: ${detailUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 7 id: "2e9227b122024a5a83c46a9f41b94aad" templateCode: "STORE_COMMENT_REPLY_NOTIFY_TEMPLATE" @@ -127,7 +127,7 @@ title: "[BK-CI Store] comment notice" body: "${userId} replied to ${replyToUser} on ${storeName}\n${replyContent} / / @ ${replyToUser}: ${replyComment}\n[reply | ${url}]" creator: "system" - modifier: "system" + modifior: "system" - index: 8 id: "30c94a920c79453da784124ab41fb068" templateCode: "ATOM_CODECC_QUALIFIED_TEMPLATE" @@ -137,7 +137,7 @@ priority: 0 source: 0 creator: "system" - modifier: "system" + modifior: "system" - index: 9 id: "37ef4157cc254021ac7278b70f211f5e" templateCode: "MANUAL_REVIEW_ATOM_NOTIFY_TEMPLATE" @@ -158,7 +158,7 @@ title: "${content}" body: "Audit description:\n${reviewDesc}\nComputer side: [to audit] (${reviewUrl})\nMobile: [check] (${reviewAppUrl})" creator: "system" - modifier: "system" + modifior: "system" - index: 10 id: "3a39413a67bf404184dbd4e9309ebeb8" templateCode: "QUALITY_NOTIFY_TEMPLATE" @@ -174,7 +174,7 @@ title: "[blue Shield quality Red Line] Audit notice" body: "${pipelineName} (# ${buildNo}) is blocked and needs to be audited\nProject: ${projectName}\nIntercept time: ${time} ${result}\nAudit link: ${url}" creator: "system" - modifier: "system" + modifior: "system" - index: 11 id: "3ea6c5e18d4b41a3890a150d1df16f4d" templateCode: "IMAGE_EXECUTE_NULL_NOTIFY_TPL" @@ -189,7 +189,7 @@ title: "${imageCode} (${imageVersion}) Image execution exception" body: "[view build link | ${url}] ${projectCode} under the ${projectCode} project of ${imageCode} (${imageVersion}) image execution exception, pipelineId:$ {pipelineId}, buildId:$ {buildId}" creator: "system" - modifier: "system" + modifior: "system" - index: 12 id: "3fbf09f0511b424ab4480e18d6674349" templateCode: "STREAM_V2_BUILD_TEMPLATE" @@ -199,7 +199,7 @@ priority: 0 source: 0 creator: "system" - modifier: "system" + modifior: "system" - index: 13 id: "4589771c46b248079444a0e18e46a3fe" templateCode: "IMAGE_RELEASE_AUDIT_PASS_TEMPLATE" @@ -215,7 +215,7 @@ title: "The store image [${name}] V$ {version} has been approved and released successfully" body: "The store image [${name}] V$ {version} has been approved and released successfully" creator: "system" - modifier: "system" + modifior: "system" - index: 14 id: "502f34f94a0d4bc7abe7c55f4e93da46" templateCode: "PIPELINE_WEBHOOK_REGISTER_FAILURE_NOTIFY_TEMPLATE" @@ -230,7 +230,7 @@ title: "pipeline【${pipelineName}】Trigger callback registration failed" body: "The pipeline you just saved【${pipelineName}】Trigger callback registration failed,Reason for failure: ${elementNames}See details: ${pipelineEditUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 15 id: "698634fd3bae40378eeb24c8d6a5c91c" templateCode: "TEMPLATE_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -246,7 +246,7 @@ title: " store template [${name}] V$ {version} failed approval" body: " store template [${name}] V$ {version} failed approval" creator: "system" - modifier: "system" + modifior: "system" - index: 16 id: "6a3db6f561f44d4895518e881a3cb53b" templateCode: "PIPELINE_SHUTDOWN_FAILURE_NOTIFY_TEMPLATE" @@ -262,7 +262,7 @@ title: "Failed to build Blue Shield pipeline [${pipelineName}] # ${buildNum}" body: "❌${failContent}" creator: "system" - modifier: "system" + modifior: "system" - index: 17 id: "6c00ffb0de6f485eb301940ca639d04d" templateCode: "TEMPLATE_RELEASE_AUDIT_PASS_TEMPLATE" @@ -278,7 +278,7 @@ title: "The store template [${name}] has been approved and released successfully." body: "The store template [${name}] has been approved and released successfully." creator: "system" - modifier: "system" + modifior: "system" - index: 18 id: "7a64b8cd997b49858964ac34079bf234" templateCode: "QUALITY_AUDIT_NOTIFY_TEMPLATE" @@ -294,7 +294,7 @@ title: "[blue Shield quality Red Line] Audit notice" body: "${pipelineName} (# ${buildNo}) is blocked and needs to be audited\nProject: ${projectName}\nIntercept time: ${time} ${result}\nAudit link: ${url}" creator: "system" - modifier: "system" + modifior: "system" - index: 19 id: "7dee6377c27344818836ef1f035a14d1" templateCode: "MANUAL_REVIEW_STAGE_NOTIFY_TO_TRIGGER_TEMPLATE" @@ -309,7 +309,7 @@ title: "The pipeline under the project [${projectName}] [${pipelineName}] # ${buildNum} builds Stage audit" body: "The current build needs to be manually approved before the follow-up process is carried out. Please wait patiently for the audit, or contact the auditor ${reviewers} for processing.\n${reviewDesc}\nClick ${reviewUrl} on the computer side\nClick ${reviewAppUrl} on the mobile phone" creator: "system" - modifier: "system" + modifior: "system" - index: 20 id: "91fb62ef51a24266ae0946112e094190" templateCode: "GITCI_V2_BUILD_TEMPLATE" @@ -319,7 +319,7 @@ priority: 0 source: 0 creator: "system" - modifier: "system" + modifior: "system" - index: 21 id: "92055af946b64850a193e1090865642e" templateCode: "ATOM_CODECC_FAILED_TEMPLATE" @@ -329,7 +329,7 @@ priority: 0 source: 0 creator: "system" - modifier: "system" + modifior: "system" - index: 22 id: "92c4e65e4cd2432eb326789ce503d698" templateCode: "PIPELINE_SHUTDOWN_FAILURE_NOTIFY_TEMPLATE_DETAIL" @@ -345,7 +345,7 @@ title: "Failed to build Blue Shield pipeline [${pipelineName}] # ${buildNum}" body: "❌ ${failContent}\n\nView details: ${detailUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 23 id: "96c0a1adaca7428eb0b2d69820923d52" templateCode: "EXTENSION_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -361,7 +361,7 @@ title: " store extension [${name}] V$ {version} failed audit" body: " store extension [${name}] V$ {version} failed audit, rejected reason: ${serviceStatusMsg}" creator: "system" - modifier: "system" + modifior: "system" - index: 24 id: "a9b46a21ed7949ddb946e5186b9102c1" templateCode: "EXTENSION_RELEASE_FAIL_TEMPLATE" @@ -377,7 +377,7 @@ title: "Failed to release store extension [${name}] V$ {version}" body: "Failed to release store extension [${name}] V$ {version}" creator: "system" - modifier: "system" + modifior: "system" - index: 25 id: "bf0ca37469cf448a86875bb2f11517c5" templateCode: "PIPELINE_STARTUP_NOTIFY_TEMPLATE_DETAIL" @@ -393,7 +393,7 @@ title: "Blue Shield pipeline [${pipelineName}] # ${buildNum} starts execution" body: "[${projectName}]-[${pipelineName}] # ${buildNum} start to view details: ${detailUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 26 id: "cbdd75de2c7f40a6a3bc1dfd909020a7" templateCode: "STORE_MEMBER_DELETE_ATOM" @@ -409,7 +409,7 @@ title: "Notification of removal of atom members in store" body: "The administrator of the store's [${storeName}] atom [${storeAdmin}] has removed you from the list of members of the atom" creator: "system" - modifier: "system" + modifior: "system" - index: 27 id: "cd7cecc126744f13a60d655d0af116af" templateCode: "PIPELINE_STARTUP_NOTIFY_TEMPLATE" @@ -425,7 +425,7 @@ title: "Blue Shield pipeline [${pipelineName}] # ${buildNum} starts execution" body: "[${projectName}]-[${pipelineName}] # ${buildNum} start execution" creator: "system" - modifier: "system" + modifior: "system" - index: 28 id: "cff00f19e6884862b6f9afe0f608e91e" templateCode: "PIPELINE_SHUTDOWN_SUCCESS_NOTIFY_TEMPLATE" @@ -441,7 +441,7 @@ title: "Blue Shield pipeline [${pipelineName}] # ${buildNum} built successfully" body: "✔️${successContent}" creator: "system" - modifier: "system" + modifior: "system" - index: 29 id: "d58e5895dfab4136ac898d93e3bff3ac" templateCode: "PIPELINE_TRIGGER_REVIEW_NOTIFY_TEMPLATE" @@ -457,7 +457,7 @@ title: "Pipeline [${pipelineName}] # ${buildNum} build under project [${projectName}] triggers audit" body: "Trigger: ${triggerUser}\n\nAuditor: ${reviewers}\n\nClick ${reviewUrl} on the computer side\nClick ${reviewAppUrl} on the mobile phone" creator: "system" - modifier: "system" + modifior: "system" - index: 30 id: "d77a91dd09994c54b14f118956e0d6e9" templateCode: "PIPELINE_TASK_PAUSE_NOTIFY" @@ -472,7 +472,7 @@ title: "Blue Shield pipeline [${BK_CI_PIPELINE_NAME}] # ${BK_CI_BUILD_NUM} construction paused" body: "[${BK_CI_PROJECT_NAME_CN}]-[${BK_CI_PIPELINE_NAME}] # ${BK_CI_BUILD_NUM} paused before executing [${taskName}], triggered by: ${BK_CI_START_USER_ID} [to handle | ${url}]" creator: "system" - modifier: "system" + modifior: "system" - index: 31 id: "d7d9e1a773fe4a658f6c51b80da282ea" templateCode: "QUALITY_END_NOTIFY_TEMPLATE" @@ -488,7 +488,7 @@ title: "[blue Shield quality Red Line] Intercept Notification" body: "${pipelineName} (# ${buildNo}) is blocked\nProject: ${projectName}\nIntercept time: ${time}\nIntercept indicator: ${thresholdListString}\nFor more information: ${url}" creator: "system" - modifier: "system" + modifior: "system" - index: 32 id: "dff46cd92eab458b96b25be0d7a61054" templateCode: "ATOM_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -504,7 +504,7 @@ title: "The store atom [${name}] V$ {version} failed the audit" body: "The store atom [${name}] V$ {version} failed the audit" creator: "system" - modifier: "system" + modifior: "system" - index: 33 id: "e961fd2ccc1c4f5d8eefaac9d51b5cb0" templateCode: "ATOM_RELEASE_AUDIT_PASS_TEMPLATE" @@ -520,7 +520,7 @@ title: "The store atom [${name}] V$ {version} has been approved and released successfully" body: "The store atom [${name}] V$ {version} has been approved and released successfully" creator: "system" - modifier: "system" + modifior: "system" - index: 34 id: "ea98239a51a74f8db0a012a809bc1116" templateCode: "IMAGE_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -536,7 +536,7 @@ title: "The store image [${name}] V$ {version} failed the audit." body: " store image [${name}] V$ {version} failed review, rejected because of ${imageStatusMsg}" creator: "system" - modifier: "system" + modifior: "system" - index: 35 id: "f0663e7ac2b74130ada0408bdce8cd20" templateCode: "QUALITY_END_NOTIFY_TEMPLATE_V2" @@ -552,7 +552,7 @@ title: "[blue Shield quality Red Line] Intercept Notification-terminated" body: "${title}\nProject: ${projectName}\nTrigger: ${cc}\nIntercept time: ${time}\n${result}\nPipeline link: ${url}" creator: "system" - modifier: "system" + modifior: "system" - index: 36 id: "f0949ab70cc04aa5b1bc787d5a47eba7" templateCode: "MANUAL_REVIEW_STAGE_NOTIFY_TEMPLATE" @@ -573,7 +573,7 @@ title: "The pipeline under the project [${projectName}] [${pipelineName}] # ${buildNum} builds Stage audit" body: "The build status is stage sucess, and an audit of \"${reviewers}\" is required to execute the subsequent process.\n\nAudit description:\n${reviewDesc}\n\n[click on the computer side] (${reviewUrl})\n[click on mobile] (${reviewAppUrl})" creator: "system" - modifier: "system" + modifior: "system" - index: 37 id: "f5c17a3f5dcd4c9ea7cf7a16a16e7135" templateCode: "ATOM_COLLABORATOR_APPLY_REFUSE" @@ -589,7 +589,7 @@ title: "[blue Shield Store] collaboration application was rejected" body: "The administrator of the pipelined atom [${atomName}] [${atomAdmin}] rejected your collaboration application for the reason: ${approveMsg}" creator: "system" - modifier: "system" + modifior: "system" - index: 38 id: "1e7864726dd04311b21019bcceddfee8" templateCode: "PIPELINE_CALLBACK_DISABLE_NOTIFY_TEMPLATE" @@ -604,4 +604,4 @@ title: "bk-ci pipeline callback interface is abnormal" body: "project【${projectName}】Registered【${events}】Event callback interface【${callbackUrl}】It is now disabled due to multiple failed calls\pipeline url:${pipelineListUrl}" creator: "system" - modifier: "system" + modifior: "system" diff --git a/support-files/i18n/notify/template_zh_CN.yaml b/support-files/i18n/notify/template_zh_CN.yaml index ac9aabbf215..691c929af24 100644 --- a/support-files/i18n/notify/template_zh_CN.yaml +++ b/support-files/i18n/notify/template_zh_CN.yaml @@ -13,7 +13,7 @@ title: "研发商店插件成员添加通知" body: "研发商店的【${storeName}】插件的管理员【${storeAdmin}】已将您添加为该插件的成员" creator: "system" - modifier: "system" + modifior: "system" - index: 1 id: "15a1e5f8642c4d7196270329531bf4cb" templateCode: "MANUAL_REVIEW_STAGE_REJECT_TO_TRIGGER_TEMPLATE" @@ -33,7 +33,7 @@ title: "项目【${projectName}】下的流水线【${pipelineName}】#${buildNum} 构建Stage审核" body: "构建已被「${rejectUserId}」驳回,流水线状态为「 Stage成功」。\n驳回理由: \n${suggest} \n[电脑端点击](${reviewUrl}) \n[手机端点击](${reviewAppUrl})" creator: "system" - modifier: "system" + modifior: "system" - index: 2 id: "168b9b44b7104647b2102355180a2837" templateCode: "UPDATE_TEMPLATE_INSTANCE_NOTIFY_TEMPLATE" @@ -49,7 +49,7 @@ title: "【${projectName}】项目流水线实例更新" body: "您在【${projectName}】项目下已成功更新${successPipelineNum}条实例: \n${successPipelineMsg}\n其中${failurePipelineNum}条实例更新失败: \n${failurePipelineMsg}\n\n查看详情: ${instanceListUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 3 id: "1be5b658d4aa465a9f9a1d0af44c8384" templateCode: "QUALITY_AUDIT_NOTIFY_TEMPLATE_V2" @@ -65,7 +65,7 @@ title: "【蓝盾质量红线】拦截通知-待审核" body: "${title}\n所属项目: ${projectName}\n触发人: ${cc}\n拦截时间: ${time}\n${result}\n流水线链接: ${url}" creator: "system" - modifier: "system" + modifior: "system" - index: 4 id: "1dd8f74e334e4c41a20f4187b4e0e992" templateCode: "EXTENSION_RELEASE_SUCCESS_TEMPLATE" @@ -81,7 +81,7 @@ title: "研发商店扩展【${name}】V${version} 成功发布" body: "\n研发商店扩展【${name}】V${version} 成功发布" creator: "system" - modifier: "system" + modifior: "system" - index: 5 id: "20e4ac3f11ff4866b95a82b30b9032a1" templateCode: "STORE_COMMENT_NOTIFY_TEMPLATE" @@ -96,7 +96,7 @@ title: "【蓝盾研发商店】评论通知" body: "${userId} 评论了 ${storeName}\n评分: ${score}\n评论: ${commentContent}\n[去回复 | ${url}]" creator: "system" - modifier: "system" + modifior: "system" - index: 6 id: "2d8c427026b049dc98630507f5e3fa38" templateCode: "PIPELINE_SHUTDOWN_SUCCESS_NOTIFY_TEMPLATE_DETAIL" @@ -112,7 +112,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 构建成功" body: "✔️${successContent}\n查看详情:${detailUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 7 id: "2e9227b122024a5a83c46a9f41b94aad" templateCode: "STORE_COMMENT_REPLY_NOTIFY_TEMPLATE" @@ -127,7 +127,7 @@ title: "【蓝盾研发商店】评论通知" body: "${userId} 在 ${storeName} 回复了 ${replyToUser}\n${replyContent}//@${replyToUser}: ${replyComment}\n[去回复 | ${url}]" creator: "system" - modifier: "system" + modifior: "system" - index: 8 id: "30c94a920c79453da784124ab41fb068" templateCode: "ATOM_CODECC_QUALIFIED_TEMPLATE" @@ -137,7 +137,7 @@ priority: 0 source: 0 creator: "system" - modifier: "system" + modifior: "system" - index: 9 id: "37ef4157cc254021ac7278b70f211f5e" templateCode: "MANUAL_REVIEW_ATOM_NOTIFY_TEMPLATE" @@ -158,7 +158,7 @@ title: "${content}" body: "审核说明: \n${reviewDesc} \n电脑端: [去审核](${reviewUrl}) \n手机端: [去审核](${reviewAppUrl})" creator: "system" - modifier: "system" + modifior: "system" - index: 10 id: "3a39413a67bf404184dbd4e9309ebeb8" templateCode: "QUALITY_NOTIFY_TEMPLATE" @@ -174,7 +174,7 @@ title: "【蓝盾质量红线】审核通知" body: "${pipelineName}(#${buildNo})被拦截,需要审核\n所属项目: ${projectName}\n拦截时间: ${time} ${result}\n审核链接: ${url}" creator: "system" - modifier: "system" + modifior: "system" - index: 11 id: "3ea6c5e18d4b41a3890a150d1df16f4d" templateCode: "IMAGE_EXECUTE_NULL_NOTIFY_TPL" @@ -189,7 +189,7 @@ title: "${imageCode}(${imageVersion}) 镜像执行异常" body: "[查看构建链接|${url}] ${userId} 的 ${projectCode} 项目下的 ${imageCode}(${imageVersion}) 镜像执行异常,pipelineId:${pipelineId},buildId:${buildId}" creator: "system" - modifier: "system" + modifior: "system" - index: 12 id: "3fbf09f0511b424ab4480e18d6674349" templateCode: "STREAM_V2_BUILD_TEMPLATE" @@ -199,7 +199,7 @@ priority: 0 source: 0 creator: "system" - modifier: "system" + modifior: "system" - index: 13 id: "4589771c46b248079444a0e18e46a3fe" templateCode: "IMAGE_RELEASE_AUDIT_PASS_TEMPLATE" @@ -215,7 +215,7 @@ title: "研发商店镜像【${name}】V${version} 审核通过,成功发布" body: "研发商店镜像【${name}】V${version} 审核通过,成功发布" creator: "system" - modifier: "system" + modifior: "system" - index: 14 id: "502f34f94a0d4bc7abe7c55f4e93da46" templateCode: "PIPELINE_WEBHOOK_REGISTER_FAILURE_NOTIFY_TEMPLATE" @@ -230,7 +230,7 @@ title: "流水线【${pipelineName}】触发器回调注册失败" body: "你刚刚保存的流水线【${pipelineName}】触发器回调注册失败,失败原因: ${elementNames}查看详情: ${pipelineEditUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 15 id: "698634fd3bae40378eeb24c8d6a5c91c" templateCode: "TEMPLATE_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -246,7 +246,7 @@ title: "研发商店模板【${name}】V${version} 审核不通过" body: "研发商店模板【${name}】V${version} 审核不通过" creator: "system" - modifier: "system" + modifior: "system" - index: 16 id: "6a3db6f561f44d4895518e881a3cb53b" templateCode: "PIPELINE_SHUTDOWN_FAILURE_NOTIFY_TEMPLATE" @@ -262,7 +262,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 构建失败" body: "❌${failContent}" creator: "system" - modifier: "system" + modifior: "system" - index: 17 id: "6c00ffb0de6f485eb301940ca639d04d" templateCode: "TEMPLATE_RELEASE_AUDIT_PASS_TEMPLATE" @@ -278,7 +278,7 @@ title: "研发商店模板【${name}】审核通过,成功发布" body: "研发商店模板【${name}】审核通过,成功发布" creator: "system" - modifier: "system" + modifior: "system" - index: 18 id: "7a64b8cd997b49858964ac34079bf234" templateCode: "QUALITY_AUDIT_NOTIFY_TEMPLATE" @@ -294,7 +294,7 @@ title: "【蓝盾质量红线】审核通知" body: "${pipelineName}(#${buildNo})被拦截,需要审核\n所属项目: ${projectName}\n拦截时间: ${time} ${result}\n审核链接: ${url}" creator: "system" - modifier: "system" + modifior: "system" - index: 19 id: "7dee6377c27344818836ef1f035a14d1" templateCode: "MANUAL_REVIEW_STAGE_NOTIFY_TO_TRIGGER_TEMPLATE" @@ -309,7 +309,7 @@ title: "项目【${projectName}】下的流水线【${pipelineName}】#${buildNum} 构建Stage审核" body: "当前构建需人工审核通过后才执行后续流程,请耐心等待审核,或联系审核人${reviewers}处理。\n${reviewDesc} \n电脑端点击 ${reviewUrl} \n手机端点击 ${reviewAppUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 20 id: "91fb62ef51a24266ae0946112e094190" templateCode: "GITCI_V2_BUILD_TEMPLATE" @@ -319,7 +319,7 @@ priority: 0 source: 0 creator: "system" - modifier: "system" + modifior: "system" - index: 21 id: "92055af946b64850a193e1090865642e" templateCode: "ATOM_CODECC_FAILED_TEMPLATE" @@ -329,7 +329,7 @@ priority: 0 source: 0 creator: "system" - modifier: "system" + modifior: "system" - index: 22 id: "92c4e65e4cd2432eb326789ce503d698" templateCode: "PIPELINE_SHUTDOWN_FAILURE_NOTIFY_TEMPLATE_DETAIL" @@ -345,7 +345,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 构建失败" body: "❌${failContent}\n\n查看详情:${detailUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 23 id: "96c0a1adaca7428eb0b2d69820923d52" templateCode: "EXTENSION_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -361,7 +361,7 @@ title: "研发商店扩展【${name}】V${version} 审核不通过" body: "研发商店扩展【${name}】V${version} 审核不通过,驳回原因: ${serviceStatusMsg}" creator: "system" - modifier: "system" + modifior: "system" - index: 24 id: "a9b46a21ed7949ddb946e5186b9102c1" templateCode: "EXTENSION_RELEASE_FAIL_TEMPLATE" @@ -377,7 +377,7 @@ title: "研发商店扩展【${name}】V${version} 发布失败" body: "研发商店扩展【${name}】V${version} 发布失败" creator: "system" - modifier: "system" + modifior: "system" - index: 25 id: "bf0ca37469cf448a86875bb2f11517c5" templateCode: "PIPELINE_STARTUP_NOTIFY_TEMPLATE_DETAIL" @@ -393,7 +393,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 开始执行" body: "【${projectName}】-【${pipelineName}】#${buildNum} 开始执行查看详情:${detailUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 26 id: "cbdd75de2c7f40a6a3bc1dfd909020a7" templateCode: "STORE_MEMBER_DELETE_ATOM" @@ -409,7 +409,7 @@ title: "研发商店插件成员移除通知" body: "研发商店的【${storeName}】插件的管理员【${storeAdmin}】已将您从该插件的成员列表中移除" creator: "system" - modifier: "system" + modifior: "system" - index: 27 id: "cd7cecc126744f13a60d655d0af116af" templateCode: "PIPELINE_STARTUP_NOTIFY_TEMPLATE" @@ -425,7 +425,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 开始执行" body: "【${projectName}】-【${pipelineName}】#${buildNum} 开始执行" creator: "system" - modifier: "system" + modifior: "system" - index: 28 id: "cff00f19e6884862b6f9afe0f608e91e" templateCode: "PIPELINE_SHUTDOWN_SUCCESS_NOTIFY_TEMPLATE" @@ -441,7 +441,7 @@ title: "蓝盾流水线【${pipelineName}】#${buildNum} 构建成功" body: "✔️${successContent}" creator: "system" - modifier: "system" + modifior: "system" - index: 29 id: "d58e5895dfab4136ac898d93e3bff3ac" templateCode: "PIPELINE_TRIGGER_REVIEW_NOTIFY_TEMPLATE" @@ -457,7 +457,7 @@ title: "项目【${projectName}】下的流水线【${pipelineName}】#${buildNum} 构建触发审核" body: "触发人: ${triggerUser}\n\n审核人: ${reviewers}\n\n电脑端点击 ${reviewUrl}\n手机端点击 ${reviewAppUrl}" creator: "system" - modifier: "system" + modifior: "system" - index: 30 id: "d77a91dd09994c54b14f118956e0d6e9" templateCode: "PIPELINE_TASK_PAUSE_NOTIFY" @@ -472,7 +472,7 @@ title: "蓝盾流水线【${BK_CI_PIPELINE_NAME}】#${BK_CI_BUILD_NUM} 构建暂停" body: "【${BK_CI_PROJECT_NAME_CN}】-【${BK_CI_PIPELINE_NAME}】#${BK_CI_BUILD_NUM} 在执行【${taskName}】前暂停,触发人: ${BK_CI_START_USER_ID}[去处理 | ${url}" creator: "system" - modifier: "system" + modifior: "system" - index: 31 id: "d7d9e1a773fe4a658f6c51b80da282ea" templateCode: "QUALITY_END_NOTIFY_TEMPLATE" @@ -488,7 +488,7 @@ title: "【蓝盾质量红线】拦截通知" body: "${pipelineName}(#${buildNo})被拦截\n所属项目: ${projectName}\n拦截时间: ${time}\n拦截指标: ${thresholdListString}\n详情链接: ${url}" creator: "system" - modifier: "system" + modifior: "system" - index: 32 id: "dff46cd92eab458b96b25be0d7a61054" templateCode: "ATOM_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -504,7 +504,7 @@ title: "研发商店插件【${name}】V${version} 审核不通过" body: "研发商店插件【${name}】V${version} 审核不通过" creator: "system" - modifier: "system" + modifior: "system" - index: 33 id: "e961fd2ccc1c4f5d8eefaac9d51b5cb0" templateCode: "ATOM_RELEASE_AUDIT_PASS_TEMPLATE" @@ -520,7 +520,7 @@ title: "研发商店插件【${name}】V${version} 审核通过,成功发布" body: "研发商店插件【${name}】V${version} 审核通过,成功发布" creator: "system" - modifier: "system" + modifior: "system" - index: 34 id: "ea98239a51a74f8db0a012a809bc1116" templateCode: "IMAGE_RELEASE_AUDIT_REFUSE_TEMPLATE" @@ -536,7 +536,7 @@ title: "研发商店镜像【${name}】V${version} 审核不通过" body: "研发商店镜像【${name}】V${version} 审核不通过,驳回原因: ${imageStatusMsg}" creator: "system" - modifier: "system" + modifior: "system" - index: 35 id: "f0663e7ac2b74130ada0408bdce8cd20" templateCode: "QUALITY_END_NOTIFY_TEMPLATE_V2" @@ -552,7 +552,7 @@ title: "【蓝盾质量红线】拦截通知-已终止" body: "${title}\n所属项目: ${projectName}\n触发人: ${cc}\n拦截时间: ${time}\n${result}\n流水线链接: ${url}" creator: "system" - modifier: "system" + modifior: "system" - index: 36 id: "f0949ab70cc04aa5b1bc787d5a47eba7" templateCode: "MANUAL_REVIEW_STAGE_NOTIFY_TEMPLATE" @@ -573,7 +573,7 @@ title: "项目【${projectName}】下的流水线【${pipelineName}】#${buildNum} 构建Stage审核" body: "构建状态为stage sucess,需要「${reviewers}」的审核才执行后续流程\n\n审核说明: \n${reviewDesc}\n\n[电脑端点击](${reviewUrl})\n[手机端点击](${reviewAppUrl})" creator: "system" - modifier: "system" + modifior: "system" - index: 37 id: "f5c17a3f5dcd4c9ea7cf7a16a16e7135" templateCode: "ATOM_COLLABORATOR_APPLY_REFUSE" @@ -589,7 +589,7 @@ title: "【蓝盾研发商店】协作申请被驳回" body: "流水线插件【${atomName}】的管理员【${atomAdmin}】驳回了你的协作申请,驳回原因: ${approveMsg}" creator: "system" - modifier: "system" + modifior: "system" - index: 38 id: "1e7864726dd04311b21019bcceddfee8" templateCode: "PIPELINE_CALLBACK_DISABLE_NOTIFY_TEMPLATE" @@ -604,4 +604,4 @@ title: "蓝盾流水线回调接口异常" body: "项目【${projectName}】所注册的【${events}】事件回调接口【${callbackUrl}】因多次调用失败,现已被禁用\n流水线链接:${pipelineListUrl}" creator: "system" - modifier: "system" + modifior: "system" From a3367c516a5f4bdfe023bd7dfc21bb3d34030ef3 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Tue, 6 Jun 2023 14:59:18 +0800 Subject: [PATCH 018/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notify/service/NotifyMessageTemplateServiceImpl.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt index 6f0180359a3..051052b6dee 100644 --- a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt +++ b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt @@ -168,7 +168,7 @@ class NotifyMessageTemplateServiceImpl @Autowired constructor( this.body = weworkGroupTemplate.body this.title = weworkGroupTemplate.title this.creator = template.creator - this.modifior = template.modifier + this.modifior = template.modifior this.createTime = LocalDateTime.now() this.updateTime = LocalDateTime.now() } @@ -182,7 +182,7 @@ class NotifyMessageTemplateServiceImpl @Autowired constructor( this.title = weworkTemplate.title this.sender = weworkTemplate.sender this.creator = template.creator - this.modifior = template.modifier + this.modifior = template.modifior this.createTime = LocalDateTime.now() this.updateTime = LocalDateTime.now() } @@ -197,7 +197,7 @@ class NotifyMessageTemplateServiceImpl @Autowired constructor( this.bodyFormat = emailTemplate.bodyFormat?.getValue()?.toByte() this.emailType = emailTemplate.emailType?.getValue()?.toByte() this.creator = template.creator - this.modifior = template.modifier + this.modifior = template.modifior this.createTime = LocalDateTime.now() this.updateTime = LocalDateTime.now() } From cc43036a1cd523bd9c31cd3b176877100c3d19a0 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Wed, 7 Jun 2023 10:11:01 +0800 Subject: [PATCH 019/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/common/log/constant/LogMessageCode.kt | 1 + .../devops/log/service/impl/RbacLogPermissionService.kt | 4 ++-- .../notify/service/NotifyMessageTemplateServiceImpl.kt | 3 ++- .../devops/quality/service/v2/QualityControlPointService.kt | 2 ++ .../devops/quality/service/v2/QualityIndicatorService.kt | 2 ++ .../devops/quality/service/v2/QualityMetadataService.kt | 4 +++- .../devops/quality/service/v2/QualityTemplateService.kt | 2 ++ support-files/i18n/log/message_en_US.properties | 1 + support-files/i18n/log/message_zh_CN.properties | 1 + support-files/i18n/message_en_US.properties | 6 +++--- 10 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/backend/ci/core/log/api-log/src/main/kotlin/com/tencent/devops/common/log/constant/LogMessageCode.kt b/src/backend/ci/core/log/api-log/src/main/kotlin/com/tencent/devops/common/log/constant/LogMessageCode.kt index e81ace0e7e2..d24b4a09aa3 100644 --- a/src/backend/ci/core/log/api-log/src/main/kotlin/com/tencent/devops/common/log/constant/LogMessageCode.kt +++ b/src/backend/ci/core/log/api-log/src/main/kotlin/com/tencent/devops/common/log/constant/LogMessageCode.kt @@ -25,6 +25,7 @@ object LogMessageCode { const val PRINT_QUEUE_LIMIT = "2108005" // log print queue exceeds the limit const val PRINT_IS_DISABLED = "2108006" // log print config is disabled const val FILE_NOT_FOUND_CHECK_PATH = "2108007" // 未找到 {0} 文件,请检查路径是否正确: + const val ERROR_PIPELINE_NOT_EXISTS = "2108008" // 流水线{0}不存在 const val BK_FAILED_INSERT_DATA = "bkFailedInsertData" // 蓝盾ES集群插入数据失败 const val BK_ES_CLUSTER_RECOVERY = "bkEsClusterRecovery" // 蓝盾ES集群恢复 diff --git a/src/backend/ci/core/log/biz-log-sample/src/main/kotlin/com/tencent/devops/log/service/impl/RbacLogPermissionService.kt b/src/backend/ci/core/log/biz-log-sample/src/main/kotlin/com/tencent/devops/log/service/impl/RbacLogPermissionService.kt index e1fc6cea25f..4c478394efb 100644 --- a/src/backend/ci/core/log/biz-log-sample/src/main/kotlin/com/tencent/devops/log/service/impl/RbacLogPermissionService.kt +++ b/src/backend/ci/core/log/biz-log-sample/src/main/kotlin/com/tencent/devops/log/service/impl/RbacLogPermissionService.kt @@ -7,10 +7,10 @@ import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.auth.utils.RbacAuthUtils import com.tencent.devops.common.client.Client import com.tencent.devops.common.client.ClientTokenService +import com.tencent.devops.common.log.constant.LogMessageCode import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.log.service.LogPermissionService import com.tencent.devops.process.api.service.ServicePipelineResource -import com.tencent.devops.process.constant.ProcessMessageCode import org.springframework.beans.factory.annotation.Autowired class RbacLogPermissionService @Autowired constructor( @@ -29,7 +29,7 @@ class RbacLogPermissionService @Autowired constructor( pipelineId = pipelineId, channelCode = null ).data ?: throw ErrorCodeException( - errorCode = ProcessMessageCode.ERROR_PIPELINE_NOT_EXISTS + errorCode = LogMessageCode.ERROR_PIPELINE_NOT_EXISTS ) // 兼容CodeCC场景,CodeCC创建的流水线未向权限中心注册,调鉴权接口会报错。 return pipelineInfo.channelCode != ChannelCode.BS || diff --git a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt index 051052b6dee..5829beb7711 100644 --- a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt +++ b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt @@ -118,8 +118,9 @@ class NotifyMessageTemplateServiceImpl @Autowired constructor( try { logger.info("start init MessageTemplate") updateMessageTemplate() + logger.info("start init MessageTemplate succeed") } catch (e: Exception) { - logger.debug("start init MessageTemplate fail! error:$e") + logger.warn("start init MessageTemplate fail! error:$e") } finally { redisLock.unlock() } diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt index 4ab6695aa12..08ea2930789 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt @@ -88,6 +88,8 @@ class QualityControlPointService @Autowired constructor( val controlPointPOs = JsonUtil.to(json, object : TypeReference>() {}) controlPointDao.batchCrateControlPoint(dslContext, controlPointPOs) logger.info("init quality control point end") + } catch (e: Exception) { + logger.debug("init quality control point fail! error:$e") } finally { redisLock.unlock() } diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt index a3b3fef1c9a..e4f980e7e61 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt @@ -136,6 +136,8 @@ class QualityIndicatorService @Autowired constructor( val qualityIndicatorPOs = JsonUtil.to(json, object : TypeReference>() {}) indicatorDao.batchCrateQualityIndicator(dslContext, qualityIndicatorPOs) logger.info("init quality indicator end") + } catch (e: Exception) { + logger.debug("init quality indicator fail! error:$e") } finally { redisLock.unlock() } diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt index d36520cb64f..ffa2d22db21 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt @@ -83,7 +83,9 @@ class QualityMetadataService @Autowired constructor( val qualityMetadataPOs = JsonUtil.to(json, object : TypeReference>() {}) metadataDao.batchCrateQualityMetadata(dslContext, qualityMetadataPOs) logger.info("init quality metadata end") - } finally { + } catch (e: Exception) { + logger.debug("init quality metadata fail! error:$e") + } finally { redisLock.unlock() } } diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt index 4b5e4a9dfcb..6debc0a0c45 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt @@ -89,6 +89,8 @@ class QualityTemplateService @Autowired constructor( JsonUtil.to(json, object : TypeReference>() {}) ruleTemplateDao.batchCrateQualityRuleTemplate(dslContext, qualityRuleTemplatePOs) logger.info("init quality rule template end") + } catch (e: Exception) { + logger.debug("init quality rule template fail! error:$e") } finally { redisLock.unlock() } diff --git a/support-files/i18n/log/message_en_US.properties b/support-files/i18n/log/message_en_US.properties index f6b337cf418..d4c0e73d873 100644 --- a/support-files/i18n/log/message_en_US.properties +++ b/support-files/i18n/log/message_en_US.properties @@ -5,6 +5,7 @@ 2108005=log print queue exceeds the limit 2108006=log print config is disabled 2108007=The {0} file was not found, please check that the path is correct: +2108008=Pipeline {0} does not exist bkFailedInsertData=BK-CI ES cluster failed to insert data bkEsClusterRecovery=BK-CI ES cluster recovery bkFailure=failure diff --git a/support-files/i18n/log/message_zh_CN.properties b/support-files/i18n/log/message_zh_CN.properties index 417603b47c3..dc92a2ac0d9 100644 --- a/support-files/i18n/log/message_zh_CN.properties +++ b/support-files/i18n/log/message_zh_CN.properties @@ -5,6 +5,7 @@ 2108005=log print queue exceeds the limit 2108006=log print config is disabled 2108007=未找到 {0} 文件,请检查路径是否正确: +2108008=流水线{0}不存在 bkFailedInsertData=蓝盾ES集群插入数据失败 bkEsClusterRecovery=蓝盾ES集群恢复 bkFailure=失效 diff --git a/support-files/i18n/message_en_US.properties b/support-files/i18n/message_en_US.properties index c128234dfa5..950751e6b67 100644 --- a/support-files/i18n/message_en_US.properties +++ b/support-files/i18n/message_en_US.properties @@ -400,15 +400,15 @@ buildType.ESXi=Bk-ci shield public build resources buildType.MACOS=Bk-ci public build resources(NEW) buildType.WINDOWS=Cloud hosting: windows on DevCloud buildType.KUBERNETES=Kubernetes build resources -buildType.PUBLIC_DEVCLOUD=public: Docker on DevCloud -buildType.PUBLIC_BCS=public: Docker on Bcs +buildType.PUBLIC_DEVCLOUD=Public: Docker on DevCloud +buildType.PUBLIC_BCS=Public: Docker on Bcs buildType.THIRD_PARTY_AGENT_ID=Private: Single build machine buildType.THIRD_PARTY_AGENT_ENV=Private: Build the cluster buildType.THIRD_PARTY_PCG=PCG public build resources buildType.THIRD_PARTY_DEVCLOUD=Tencent devCloud(Cloud devnet resource) buildType.GIT_CI=Git CI buildType.DOCKER=Docker Public builder -buildType.STREAM=stream +buildType.STREAM=Stream buildType.AGENT_LESS=No compilation environment language.zh_CN=Simplified Chinese language.en_US=English From b5bad659f8c4db6c1259815f0957771e9c15a53c Mon Sep 17 00:00:00 2001 From: yjieliang Date: Wed, 7 Jun 2023 10:41:47 +0800 Subject: [PATCH 020/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/quality/service/v2/QualityMetadataService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt index ffa2d22db21..e221be0d8c2 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt @@ -85,7 +85,7 @@ class QualityMetadataService @Autowired constructor( logger.info("init quality metadata end") } catch (e: Exception) { logger.debug("init quality metadata fail! error:$e") - } finally { + } finally { redisLock.unlock() } } From 0da014421ec2c45e72c97f74d8ea358b59487d29 Mon Sep 17 00:00:00 2001 From: carlyin <449036249@qq.com> Date: Wed, 7 Jun 2023 15:52:48 +0800 Subject: [PATCH 021/166] =?UTF-8?q?feat:=E8=93=9D=E7=9B=BE=E5=86=85?= =?UTF-8?q?=E7=BD=AE=E6=8F=92=E4=BB=B6=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=20#8900?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/ServiceArchiveAtomFileResource.kt | 3 --- .../ServiceArchiveAtomFileResourceImpl.kt | 2 -- .../resources/UserArchiveAtomResourceImpl.kt | 1 - .../artifactory/service/ArchiveAtomService.kt | 1 - .../service/impl/ArchiveAtomServiceImpl.kt | 4 +--- .../devops/store/pojo/atom/ReleaseInfo.kt | 2 +- .../atom/impl/MarketAtomArchiveServiceImpl.kt | 24 ++++++++++++------- .../service/atom/impl/OpAtomServiceImpl.kt | 3 +-- .../store/utils/AtomReleaseTxtAnalysisUtil.kt | 5 ++-- 9 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/backend/ci/core/artifactory/api-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/api/ServiceArchiveAtomFileResource.kt b/src/backend/ci/core/artifactory/api-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/api/ServiceArchiveAtomFileResource.kt index f8dbe9dccfe..b6527485f57 100644 --- a/src/backend/ci/core/artifactory/api-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/api/ServiceArchiveAtomFileResource.kt +++ b/src/backend/ci/core/artifactory/api-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/api/ServiceArchiveAtomFileResource.kt @@ -61,9 +61,6 @@ interface ServiceArchiveAtomFileResource { @ApiParam("项目编码", required = true) @QueryParam("projectCode") projectCode: String, - @ApiParam("插件ID", required = true) - @QueryParam("atomId") - atomId: String, @ApiParam("插件代码", required = true) @QueryParam("atomCode") atomCode: String, diff --git a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/resources/ServiceArchiveAtomFileResourceImpl.kt b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/resources/ServiceArchiveAtomFileResourceImpl.kt index 69deffd5078..d6875f7c933 100644 --- a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/resources/ServiceArchiveAtomFileResourceImpl.kt +++ b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/resources/ServiceArchiveAtomFileResourceImpl.kt @@ -50,7 +50,6 @@ class ServiceArchiveAtomFileResourceImpl @Autowired constructor( override fun archiveAtomFile( userId: String, projectCode: String, - atomId: String, atomCode: String, version: String, releaseType: ReleaseTypeEnum, @@ -62,7 +61,6 @@ class ServiceArchiveAtomFileResourceImpl @Autowired constructor( userId = userId, inputStream = inputStream, disposition = disposition, - atomId = atomId, archiveAtomRequest = ArchiveAtomRequest( projectCode = projectCode, atomCode = atomCode, diff --git a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/resources/UserArchiveAtomResourceImpl.kt b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/resources/UserArchiveAtomResourceImpl.kt index dbbb79f4995..11c05b00293 100644 --- a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/resources/UserArchiveAtomResourceImpl.kt +++ b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/resources/UserArchiveAtomResourceImpl.kt @@ -58,7 +58,6 @@ class UserArchiveAtomResourceImpl @Autowired constructor(private val archiveAtom userId = userId, inputStream = inputStream, disposition = disposition, - atomId = atomId, archiveAtomRequest = ArchiveAtomRequest( projectCode = projectCode, atomCode = atomCode, diff --git a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/ArchiveAtomService.kt b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/ArchiveAtomService.kt index bb4cea03e12..7de063454ba 100644 --- a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/ArchiveAtomService.kt +++ b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/ArchiveAtomService.kt @@ -43,7 +43,6 @@ interface ArchiveAtomService { userId: String, inputStream: InputStream, disposition: FormDataContentDisposition, - atomId: String, archiveAtomRequest: ArchiveAtomRequest ): Result diff --git a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomServiceImpl.kt b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomServiceImpl.kt index ec2fbfd93cf..bedbac15888 100644 --- a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomServiceImpl.kt +++ b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomServiceImpl.kt @@ -93,10 +93,9 @@ abstract class ArchiveAtomServiceImpl : ArchiveAtomService { userId: String, inputStream: InputStream, disposition: FormDataContentDisposition, - atomId: String, archiveAtomRequest: ArchiveAtomRequest ): Result { - logger.info("archiveAtom userId:$userId,atomId:$atomId,archiveAtomRequest:$archiveAtomRequest") + logger.info("archiveAtom userId:$userId,archiveAtomRequest:$archiveAtomRequest") // 校验用户上传的插件包是否合法 val projectCode = archiveAtomRequest.projectCode val atomCode = archiveAtomRequest.atomCode @@ -237,7 +236,6 @@ abstract class ArchiveAtomServiceImpl : ArchiveAtomService { userId = userId, inputStream = inputStream, disposition = disposition, - atomId = atomId, archiveAtomRequest = archiveAtomRequest ) if (archiveAtomResult.isNotOk()) { diff --git a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/ReleaseInfo.kt b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/ReleaseInfo.kt index 4419a38cc50..17041f6ff79 100644 --- a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/ReleaseInfo.kt +++ b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/ReleaseInfo.kt @@ -38,7 +38,7 @@ import io.swagger.annotations.ApiModelProperty @ApiModel("插件发布部署模型") data class ReleaseInfo( @ApiModelProperty("项目编码", required = true) - var projectId: String, + var projectId: String = "", @ApiModelProperty("插件名称", required = true) @field:BkField(patternStyle = BkStyleEnum.NAME_STYLE) var name: String, diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt index c378dc72c2f..f9a6dcf6c32 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt @@ -33,6 +33,7 @@ import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.client.Client +import com.tencent.devops.common.pipeline.pojo.element.market.MarketBuildLessAtomElement import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.store.dao.atom.AtomDao import com.tencent.devops.store.dao.atom.MarketAtomDao @@ -107,14 +108,6 @@ class MarketAtomArchiveServiceImpl : MarketAtomArchiveService { releaseType: ReleaseTypeEnum?, os: String? ): Result { - // 校验用户是否是该插件的开发成员 - val flag = storeMemberDao.isStoreMember(dslContext, userId, atomCode, StoreTypeEnum.ATOM.type.toByte()) - if (!flag) { - throw ErrorCodeException( - errorCode = CommonMessageCode.PERMISSION_DENIED, - params = arrayOf(atomCode) - ) - } val atomCount = atomDao.countByCode(dslContext, atomCode) if (atomCount < 0) { return I18nUtil.generateResponseDataObject( @@ -124,6 +117,21 @@ class MarketAtomArchiveServiceImpl : MarketAtomArchiveService { ) } val atomRecord = atomDao.getNewestAtomByCode(dslContext, atomCode)!! + if (atomRecord.classType != atomCode) { + // 校验用户是否是该插件的开发成员 + val flag = storeMemberDao.isStoreMember( + dslContext = dslContext, + userId = userId, + storeCode = atomCode, + storeType = StoreTypeEnum.ATOM.type.toByte() + ) + if (!flag) { + throw ErrorCodeException( + errorCode = CommonMessageCode.PERMISSION_DENIED, + params = arrayOf(atomCode) + ) + } + } // 不是重新上传的包才需要校验版本号 if (null != releaseType) { val osList = JsonUtil.getObjectMapper().readValue(os, ArrayList::class.java) as ArrayList diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt index 6bc1dc95ba9..f245df1c9b2 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt @@ -414,7 +414,6 @@ class OpAtomServiceImpl @Autowired constructor( if (addMarketAtomResult.isNotOk()) { return Result(data = false, message = addMarketAtomResult.message) } - val atomId = addMarketAtomResult.data!! // 远程logo资源不做处理 if (!releaseInfo.logoUrl.startsWith("http")) { // 解析logoUrl @@ -475,7 +474,6 @@ class OpAtomServiceImpl @Autowired constructor( val archiveAtomResult = AtomReleaseTxtAnalysisUtil.serviceArchiveAtomFile( userId = userId, projectCode = releaseInfo.projectId, - atomId = atomId, atomCode = atomCode, version = releaseInfo.versionInfo.version, serviceUrlPrefix = client.getServiceUrl(ServiceArchiveAtomFileResource::class), @@ -536,6 +534,7 @@ class OpAtomServiceImpl @Autowired constructor( if (releaseInfo.configInfo.defaultFlag) { setDefault(userId, atomCode) } + val atomId = updateMarketAtomResult.data!! // 确认测试通过 return atomReleaseService.passTest(userId, atomId) } diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/utils/AtomReleaseTxtAnalysisUtil.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/utils/AtomReleaseTxtAnalysisUtil.kt index ab230e90b93..2da3463f509 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/utils/AtomReleaseTxtAnalysisUtil.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/utils/AtomReleaseTxtAnalysisUtil.kt @@ -197,7 +197,6 @@ object AtomReleaseTxtAnalysisUtil { fun serviceArchiveAtomFile( userId: String, projectCode: String, - atomId: String, atomCode: String, serviceUrlPrefix: String, releaseType: String, @@ -206,8 +205,8 @@ object AtomReleaseTxtAnalysisUtil { os: String ): Result { val serviceUrl = "$serviceUrlPrefix/service/artifactories/archiveAtom" + - "?userId=$userId&projectCode=$projectCode&atomId=$atomId&atomCode=$atomCode" + - "&version=$version&releaseType=$releaseType&os=$os" + "?userId=$userId&projectCode=$projectCode&atomCode=$atomCode" + + "&version=$version&releaseType=$releaseType&os=$os" OkhttpUtils.uploadFile(serviceUrl, file).use { response -> response.body!!.string() if (!response.isSuccessful) { From f7abd3b47a1f8b30ab33ba50ac185d72dc764ca2 Mon Sep 17 00:00:00 2001 From: carlyin <449036249@qq.com> Date: Wed, 7 Jun 2023 15:54:49 +0800 Subject: [PATCH 022/166] =?UTF-8?q?feat:=E8=93=9D=E7=9B=BE=E5=86=85?= =?UTF-8?q?=E7=BD=AE=E6=8F=92=E4=BB=B6=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=20#8900?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/atom/impl/OpAtomServiceImpl.kt | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt index f245df1c9b2..a8c80ffb9ac 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt @@ -400,19 +400,21 @@ class OpAtomServiceImpl @Autowired constructor( language = I18nUtil.getLanguage(userId) ) } - // 新增插件 - val addMarketAtomResult = atomReleaseService.addMarketAtom( - userId, - MarketAtomCreateRequest( - projectCode = releaseInfo.projectId, - atomCode = atomCode, - name = releaseInfo.name, - language = releaseInfo.language, - frontendType = releaseInfo.configInfo.frontendType + if (releaseInfo.versionInfo.releaseType == ReleaseTypeEnum.NEW) { + // 新增插件 + val addMarketAtomResult = atomReleaseService.addMarketAtom( + userId, + MarketAtomCreateRequest( + projectCode = releaseInfo.projectId, + atomCode = atomCode, + name = releaseInfo.name, + language = releaseInfo.language, + frontendType = releaseInfo.configInfo.frontendType + ) ) - ) - if (addMarketAtomResult.isNotOk()) { - return Result(data = false, message = addMarketAtomResult.message) + if (addMarketAtomResult.isNotOk()) { + return Result(data = false, message = addMarketAtomResult.message) + } } // 远程logo资源不做处理 if (!releaseInfo.logoUrl.startsWith("http")) { From ef9dccceafa848dc6551f8b43a41ceccd6469632 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Wed, 7 Jun 2023 16:40:37 +0800 Subject: [PATCH 023/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2020_ci_notify-update_v2.0_mysql.sql | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql diff --git a/support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql b/support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql new file mode 100644 index 00000000000..b7c16e8fa33 --- /dev/null +++ b/support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql @@ -0,0 +1,61 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * 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. + */ + +USE devops_ci_notify; +SET NAMES utf8mb4; + +DROP PROCEDURE IF EXISTS ci_notify_schema_update; + +DELIMITER +CREATE PROCEDURE ci_notify_schema_update() +BEGIN + + DECLARE db VARCHAR(100); + SET AUTOCOMMIT = 0; +SELECT DATABASE() INTO db; + + IF NOT EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'T_COMMON_NOTIFY_MESSAGE_TEMPLATE' + AND INDEX_NAME = '`idx_code`') THEN + ALTER TABLE T_COMMON_NOTIFY_MESSAGE_TEMPLATE DROP INDEX `idx_code`; + END IF; + + IF NOT EXISTS(SELECT 1 + FROM information_schema.statistics + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'T_COMMON_NOTIFY_MESSAGE_TEMPLATE') THEN + ALTER TABLE `T_COMMON_NOTIFY_MESSAGE_TEMPLATE` ADD UNIQUE INDEX UNI_TCNMT_TEMPLATE_CODE (TEMPLATE_CODE); + END IF; + +COMMIT; +END +DELIMITER ; +COMMIT; + +CALL ci_notify_schema_update(); From 584c4edede6a3edaaa846790c004047a61963b9b Mon Sep 17 00:00:00 2001 From: yjieliang Date: Wed, 7 Jun 2023 19:31:42 +0800 Subject: [PATCH 024/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/constant/AuthI18nConstants.kt | 5 + .../service/PermissionGradeManagerService.kt | 38 ++-- .../service/PermissionSubsetManagerService.kt | 17 +- .../service/RbacPermissionApplyService.kt | 12 +- .../devops/auth/cron/AuthCronManager.kt | 14 +- .../web/interceptor/BkWriterInterceptor.kt | 2 +- .../i18n/auth/message_en_US.properties | 192 +++++++++--------- .../i18n/auth/message_zh_CN.properties | 192 +++++++++--------- 8 files changed, 237 insertions(+), 235 deletions(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/constant/AuthI18nConstants.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/constant/AuthI18nConstants.kt index 5287409e683..6faf03948be 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/constant/AuthI18nConstants.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/constant/AuthI18nConstants.kt @@ -1,6 +1,11 @@ package com.tencent.devops.auth.constant object AuthI18nConstants { + const val RESOURCE_TYPE_NAME_SUFFIX = ".resourceType.name" + const val RESOURCE_TYPE_DESC_SUFFIX = ".resourceType.desc" + const val AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX = ".authResourceGroupConfig.groupName" + const val AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX = ".authResourceGroupConfig.description" + const val ACTION_NAME_SUFFIX = ".actionName" const val BK_AGREE_RENEW = "bkAgreeRenew" // 同意续期 const val BK_YOU_AGREE_RENEW = "bkYouAgreeRenew" // 你已选择同意用户续期 const val BK_REFUSE_RENEW = "bkRefuseRenew" // 拒绝续期 diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt index e0111cabb00..95c19d26aa0 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt @@ -46,6 +46,8 @@ import com.tencent.bk.sdk.iam.dto.manager.dto.ManagerRoleGroupDTO import com.tencent.bk.sdk.iam.dto.manager.dto.SearchGroupDTO import com.tencent.bk.sdk.iam.dto.manager.dto.UpdateManagerDTO import com.tencent.bk.sdk.iam.service.v2.V2ManagerService +import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX +import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX import com.tencent.devops.auth.constant.AuthI18nConstants.BK_AUTH_SECRECY import com.tencent.devops.auth.constant.AuthI18nConstants.BK_CREATE_BKCI_PROJECT_APPLICATION import com.tencent.devops.auth.constant.AuthI18nConstants.BK_CREATE_PROJECT_APPROVAL @@ -63,7 +65,6 @@ import com.tencent.devops.auth.pojo.ItsmCancelApplicationInfo import com.tencent.devops.auth.pojo.event.AuthResourceGroupCreateEvent import com.tencent.devops.auth.pojo.event.AuthResourceGroupModifyEvent import com.tencent.devops.common.api.exception.ErrorCodeException -import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.api.util.UUIDUtil import com.tencent.devops.common.auth.api.AuthResourceType @@ -143,10 +144,9 @@ class PermissionGradeManagerService @Autowired constructor( defaultMessage = "${resourceType}_${DefaultGroupType.MANAGER.value} group config not exist" ) - val description = MessageUtil.getMessageByLocale( + val description = I18nUtil.getCodeLanMessage( messageCode = "${manageGroupConfig.resourceType}.${manageGroupConfig.groupCode}" + - ".AuthResourceGroupConfig.description", - language = I18nUtil.getDefaultLocaleLanguage(), + AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX, defaultMessage = manageGroupConfig.description ) val authorizationScopes = permissionGroupPoliciesService.buildAuthorizationScopes( @@ -173,10 +173,9 @@ class PermissionGradeManagerService @Autowired constructor( .subject_scopes(subjectScopes) .sync_perm(true) .groupName( - MessageUtil.getMessageByLocale( + I18nUtil.getCodeLanMessage( messageCode = "${manageGroupConfig.resourceType}.${manageGroupConfig.groupCode}" + - ".AuthResourceGroupConfig.groupName", - language = I18nUtil.getDefaultLocaleLanguage(), + AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX, defaultMessage = manageGroupConfig.description ) ) @@ -210,10 +209,9 @@ class PermissionGradeManagerService @Autowired constructor( .subjectScopes(subjectScopes) .syncPerm(true) .groupName( - MessageUtil.getMessageByLocale( + I18nUtil.getCodeLanMessage( messageCode = "${manageGroupConfig.resourceType}.${manageGroupConfig.groupCode}" + - ".AuthResourceGroupConfig.groupName", - language = I18nUtil.getDefaultLocaleLanguage(), + ".authResourceGroupConfig.groupName", defaultMessage = manageGroupConfig.groupName ) ) @@ -302,10 +300,9 @@ class PermissionGradeManagerService @Autowired constructor( .subjectScopes(subjectScopes) .syncPerm(true) .groupName( - MessageUtil.getMessageByLocale( + I18nUtil.getCodeLanMessage( messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - ".AuthResourceGroupConfig.groupName", - language = I18nUtil.getDefaultLocaleLanguage(), + ".authResourceGroupConfig.groupName", defaultMessage = groupConfig.groupName ) ) @@ -338,10 +335,9 @@ class PermissionGradeManagerService @Autowired constructor( .subjectScopes(subjectScopes) .syncPerm(true) .groupName( - MessageUtil.getMessageByLocale( + I18nUtil.getCodeLanMessage( messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - ".AuthResourceGroupConfig.groupName", - language = I18nUtil.getDefaultLocaleLanguage(), + ".authResourceGroupConfig.groupName", defaultMessage = groupConfig.groupName ) ) @@ -406,16 +402,14 @@ class PermissionGradeManagerService @Autowired constructor( if (resourceGroupInfo != null) { return@forEach } - val name = MessageUtil.getMessageByLocale( + val name = I18nUtil.getCodeLanMessage( messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - ".AuthResourceGroupConfig.groupName", - language = I18nUtil.getDefaultLocaleLanguage(), + ".authResourceGroupConfig.groupName", defaultMessage = groupConfig.groupName ) - val description = MessageUtil.getMessageByLocale( + val description = I18nUtil.getCodeLanMessage( messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - ".AuthResourceGroupConfig.description", - language = I18nUtil.getDefaultLocaleLanguage(), + ".authResourceGroupConfig.description", defaultMessage = groupConfig.description ) val managerRoleGroup = ManagerRoleGroup(name, description, false) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt index ac2c62da1b4..c7dd7229e41 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt @@ -34,6 +34,8 @@ import com.tencent.bk.sdk.iam.dto.manager.dto.CreateSubsetManagerDTO import com.tencent.bk.sdk.iam.dto.manager.dto.ManagerRoleGroupDTO import com.tencent.bk.sdk.iam.dto.manager.dto.UpdateSubsetManagerDTO import com.tencent.bk.sdk.iam.service.v2.V2ManagerService +import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX +import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX import com.tencent.devops.auth.constant.AuthMessageCode import com.tencent.devops.auth.dao.AuthResourceGroupConfigDao import com.tencent.devops.auth.dao.AuthResourceGroupDao @@ -90,8 +92,7 @@ class PermissionSubsetManagerService @Autowired constructor( ) val description = I18nUtil.getCodeLanMessage( messageCode = "${managerGroupConfig.resourceType}.${managerGroupConfig.groupCode}" + - ".AuthResourceGroupConfig.description", - language = I18nUtil.getDefaultLocaleLanguage(), + AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX, defaultMessage = managerGroupConfig.description ) val authorizationScopes = permissionGroupPoliciesService.buildAuthorizationScopes( @@ -114,8 +115,7 @@ class PermissionSubsetManagerService @Autowired constructor( .groupName( I18nUtil.getCodeLanMessage( messageCode = "${managerGroupConfig.resourceType}.${managerGroupConfig.groupCode}" + - ".AuthResourceGroupConfig.groupName", - language = I18nUtil.getDefaultLocaleLanguage(), + AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX, defaultMessage = managerGroupConfig.groupName ) ) @@ -172,8 +172,7 @@ class PermissionSubsetManagerService @Autowired constructor( .groupName( I18nUtil.getCodeLanMessage( messageCode = "${managerGroupConfig.resourceType}.${managerGroupConfig.groupCode}" + - ".AuthResourceGroupConfig.groupName", - language = I18nUtil.getDefaultLocaleLanguage(), + AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX, defaultMessage = managerGroupConfig.groupName ) ) @@ -256,14 +255,12 @@ class PermissionSubsetManagerService @Autowired constructor( } val name = I18nUtil.getCodeLanMessage( messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - ".AuthResourceGroupConfig.groupName", - language = I18nUtil.getDefaultLocaleLanguage(), + AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX, defaultMessage = groupConfig.groupName ) val description = I18nUtil.getCodeLanMessage( messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - ".AuthResourceGroupConfig.description", - language = I18nUtil.getDefaultLocaleLanguage(), + AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX, defaultMessage = groupConfig.description ) val managerRoleGroup = ManagerRoleGroup(name, description, false) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt index 0914292c036..963ece4c7ee 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt @@ -8,6 +8,8 @@ import com.tencent.bk.sdk.iam.dto.manager.V2ManagerRoleGroupInfo import com.tencent.bk.sdk.iam.dto.manager.dto.SearchGroupDTO import com.tencent.bk.sdk.iam.dto.manager.vo.V2ManagerRoleGroupVO import com.tencent.bk.sdk.iam.service.v2.V2ManagerService +import com.tencent.devops.auth.constant.AuthI18nConstants.ACTION_NAME_SUFFIX +import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX import com.tencent.devops.auth.constant.AuthMessageCode import com.tencent.devops.auth.dao.AuthResourceGroupConfigDao import com.tencent.devops.auth.dao.AuthResourceGroupDao @@ -375,9 +377,8 @@ class RbacPermissionApplyService @Autowired constructor( resourceTypeName = resourceTypeName, resourceName = resourceName, actionName = actionInfo?.let { - MessageUtil.getMessageByLocale( - messageCode = "${it.action}.actionName", - language = I18nUtil.getDefaultLocaleLanguage(), + I18nUtil.getCodeLanMessage( + messageCode = "${it.action}$ACTION_NAME_SUFFIX", defaultMessage = it.actionName ) }, @@ -464,10 +465,9 @@ class RbacPermissionApplyService @Autowired constructor( authApplyRedirectUrl, projectId, projectName, resourceType, resourceName, iamResourceCode, action, resourceGroup.groupName, resourceGroup.relationId ), - groupName = MessageUtil.getMessageByLocale( + groupName = I18nUtil.getCodeLanMessage( messageCode = "${resourceGroup.resourceType}.${resourceGroup.groupCode}" + - ".AuthResourceGroupConfig.groupName", - language = I18nUtil.getDefaultLocaleLanguage(), + AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX, defaultMessage = resourceGroup.groupName ) ) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt index 289a944c6c0..699c6ec7e68 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt @@ -27,6 +27,10 @@ package com.tencent.devops.auth.cron +import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX +import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX +import com.tencent.devops.auth.constant.AuthI18nConstants.RESOURCE_TYPE_DESC_SUFFIX +import com.tencent.devops.auth.constant.AuthI18nConstants.RESOURCE_TYPE_NAME_SUFFIX import com.tencent.devops.auth.dao.AuthActionDao import com.tencent.devops.auth.dao.AuthResourceGroupConfigDao import com.tencent.devops.auth.dao.AuthResourceTypeDao @@ -184,11 +188,11 @@ class AuthCronManager @Autowired constructor( ) resourceTypeResult.forEach { it.name = MessageUtil.getMessageByLocale( - messageCode = "${it.resourceType}.ResourceType.name", + messageCode = it.resourceType + RESOURCE_TYPE_NAME_SUFFIX, language = commonConfig.devopsDefaultLocaleLanguage ) it.desc = MessageUtil.getMessageByLocale( - messageCode = "${it.resourceType}.ResourceType.desc", + messageCode = it.resourceType + RESOURCE_TYPE_DESC_SUFFIX, language = commonConfig.devopsDefaultLocaleLanguage ) it.updateTime = LocalDateTime.now() @@ -225,11 +229,13 @@ class AuthCronManager @Autowired constructor( ) resourceGroupConfigResult.forEach { it.groupName = MessageUtil.getMessageByLocale( - messageCode = "${it.resourceType}.${it.groupCode}.AuthResourceGroupConfig.groupName", + messageCode = "${it.resourceType}.${it.groupCode}" + + AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX, language = commonConfig.devopsDefaultLocaleLanguage ) it.description = MessageUtil.getMessageByLocale( - messageCode = "${it.resourceType}.${it.groupCode}.AuthResourceGroupConfig.description", + messageCode = "${it.resourceType}.${it.groupCode}" + + AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX, language = commonConfig.devopsDefaultLocaleLanguage ) it.updateTime = LocalDateTime.now() diff --git a/src/backend/ci/core/common/common-web/src/main/kotlin/com/tencent/devops/common/web/interceptor/BkWriterInterceptor.kt b/src/backend/ci/core/common/common-web/src/main/kotlin/com/tencent/devops/common/web/interceptor/BkWriterInterceptor.kt index c171840ee5a..4f5ab6d9cb2 100644 --- a/src/backend/ci/core/common/common-web/src/main/kotlin/com/tencent/devops/common/web/interceptor/BkWriterInterceptor.kt +++ b/src/backend/ci/core/common/common-web/src/main/kotlin/com/tencent/devops/common/web/interceptor/BkWriterInterceptor.kt @@ -131,7 +131,7 @@ class BkWriterInterceptor : WriterInterceptor { val fieldKeySuffixName = if (i18nFieldInfo.translateType == I18nTranslateTypeEnum.NAME) { // 如果注解上配置了字段转换名称,则使用转换名称进行国际化翻译 i18nFieldInfo.convertName.ifBlank { - lastNodeName + i18nFieldInfo.convertName } } else { MessageUtil.getFieldValue(i18nFieldInfo.field, i18nFieldInfo.entity)?.toString() ?: "" diff --git a/support-files/i18n/auth/message_en_US.properties b/support-files/i18n/auth/message_en_US.properties index 48b02020692..c385af13f1e 100644 --- a/support-files/i18n/auth/message_en_US.properties +++ b/support-files/i18n/auth/message_en_US.properties @@ -157,101 +157,101 @@ experience_task_edit.actionName=Experience Task Edit experience_task_list.actionName=Experience Task List experience_task_view.actionName=Experience Task View -cert.manager.AuthResourceGroupConfig.description=Certificate owner has all permissions of the current certificate -cert.user.AuthResourceGroupConfig.description=Certificate user can use this certificate in the pipeline -codecc_task.editor.AuthResourceGroupConfig.description=task editor, who has all the permissions of the current task except permission management -codecc_task.executor.AuthResourceGroupConfig.description=task executors, who can view and execute the current task -codecc_task.manager.AuthResourceGroupConfig.description=task owner, who can manage the permissions of the current task -codecc_task.viewer.AuthResourceGroupConfig.description=task viewer, who can view the current task -credential.manager.AuthResourceGroupConfig.description=Credential owner has all permissions of the current credential -credential.user.AuthResourceGroupConfig.description=Credential user can use this credential in the pipeline -env_node.manager.AuthResourceGroupConfig.description=Agent owner has all permissions of the current agent -env_node.user.AuthResourceGroupConfig.description=Agent user can use this agent in the pipeline -environment.manager.AuthResourceGroupConfig.description=Agent-pool owner has all permissions for the current pool. -environment.user.AuthResourceGroupConfig.description=Agent-pool user can use this pool in the pipeline -experience_group.manager.AuthResourceGroupConfig.description=Experience user group owner has member management permissions for the current group -experience_task.manager.AuthResourceGroupConfig.description=Experience task owner has all permissions of the current task -pipeline.editor.AuthResourceGroupConfig.description=Pipeline editor has all permissions for the current pipeline except for permission management -pipeline.executor.AuthResourceGroupConfig.description=Pipeline executor can view and execute the pipeline, as well as download or share artifacts -pipeline.manager.AuthResourceGroupConfig.description=Pipeline owner can manage the permissions of the current pipeline -pipeline.viewer.AuthResourceGroupConfig.description=Pipeline viewer can view pipelines, download or share artifacts -pipeline_group.editor.AuthResourceGroupConfig.description=Can view, edit, and execute pipelines in the group -pipeline_group.executor.AuthResourceGroupConfig.description=Can view and execute the pipelines in the group -pipeline_group.manager.AuthResourceGroupConfig.description=The pipeline group owner can manage the pipelines in the group, and add editors, executors, and viewers to the pipelines in the group in batches -pipeline_group.viewer.AuthResourceGroupConfig.description=Can view the pipelines in the group -project.developer.AuthResourceGroupConfig.description=Developer can create pipelines, repos, credentials, certificates, agent pools, agents, codecc tasks, codecc rule sets, download and share artifacts in the custom-path artifactory -project.maintainer.AuthResourceGroupConfig.description=SRE can create pipelines, repos, credentials, certificates, agent pools, agents, download and share artifacts in the custom-path artifactory -project.manager.AuthResourceGroupConfig.description=Project owner has all permissions for this project -project.pm.AuthResourceGroupConfig.description=PM can view the pipeline list, download or share artifacts in the custom-path artifactory -project.qc.AuthResourceGroupConfig.description=QC can manage quality red line rules -project.tester.AuthResourceGroupConfig.description=QA can create pipelines, repos, credentials, certificates, agent pools, agents, codecc tasks, codecc rule sets, download and share artifacts in the custom-path artifactory -project.visitor.AuthResourceGroupConfig.description=Guest can view the pipeline list -quality_group.manager.AuthResourceGroupConfig.description=Quality red-line notification group owner has all permissions for the current quality red-line notification group -repertory.manager.AuthResourceGroupConfig.description=Repository owner has all permissions of the current repository -repertory.user.AuthResourceGroupConfig.description=Repository user can use this repository in the pipeline -rule.manager.AuthResourceGroupConfig.description=Quality red-line rule owner has all permissions for the current quality red-line rule +cert.manager.authResourceGroupConfig.description=Certificate owner has all permissions of the current certificate +cert.user.authResourceGroupConfig.description=Certificate user can use this certificate in the pipeline +codecc_task.editor.authResourceGroupConfig.description=task editor, who has all the permissions of the current task except permission management +codecc_task.executor.authResourceGroupConfig.description=task executors, who can view and execute the current task +codecc_task.manager.authResourceGroupConfig.description=task owner, who can manage the permissions of the current task +codecc_task.viewer.authResourceGroupConfig.description=task viewer, who can view the current task +credential.manager.authResourceGroupConfig.description=Credential owner has all permissions of the current credential +credential.user.authResourceGroupConfig.description=Credential user can use this credential in the pipeline +env_node.manager.authResourceGroupConfig.description=Agent owner has all permissions of the current agent +env_node.user.authResourceGroupConfig.description=Agent user can use this agent in the pipeline +environment.manager.authResourceGroupConfig.description=Agent-pool owner has all permissions for the current pool. +environment.user.authResourceGroupConfig.description=Agent-pool user can use this pool in the pipeline +experience_group.manager.authResourceGroupConfig.description=Experience user group owner has member management permissions for the current group +experience_task.manager.authResourceGroupConfig.description=Experience task owner has all permissions of the current task +pipeline.editor.authResourceGroupConfig.description=Pipeline editor has all permissions for the current pipeline except for permission management +pipeline.executor.authResourceGroupConfig.description=Pipeline executor can view and execute the pipeline, as well as download or share artifacts +pipeline.manager.authResourceGroupConfig.description=Pipeline owner can manage the permissions of the current pipeline +pipeline.viewer.authResourceGroupConfig.description=Pipeline viewer can view pipelines, download or share artifacts +pipeline_group.editor.authResourceGroupConfig.description=Can view, edit, and execute pipelines in the group +pipeline_group.executor.authResourceGroupConfig.description=Can view and execute the pipelines in the group +pipeline_group.manager.authResourceGroupConfig.description=The pipeline group owner can manage the pipelines in the group, and add editors, executors, and viewers to the pipelines in the group in batches +pipeline_group.viewer.authResourceGroupConfig.description=Can view the pipelines in the group +project.developer.authResourceGroupConfig.description=Developer can create pipelines, repos, credentials, certificates, agent pools, agents, codecc tasks, codecc rule sets, download and share artifacts in the custom-path artifactory +project.maintainer.authResourceGroupConfig.description=SRE can create pipelines, repos, credentials, certificates, agent pools, agents, download and share artifacts in the custom-path artifactory +project.manager.authResourceGroupConfig.description=Project owner has all permissions for this project +project.pm.authResourceGroupConfig.description=PM can view the pipeline list, download or share artifacts in the custom-path artifactory +project.qc.authResourceGroupConfig.description=QC can manage quality red line rules +project.tester.authResourceGroupConfig.description=QA can create pipelines, repos, credentials, certificates, agent pools, agents, codecc tasks, codecc rule sets, download and share artifacts in the custom-path artifactory +project.visitor.authResourceGroupConfig.description=Guest can view the pipeline list +quality_group.manager.authResourceGroupConfig.description=Quality red-line notification group owner has all permissions for the current quality red-line notification group +repertory.manager.authResourceGroupConfig.description=Repository owner has all permissions of the current repository +repertory.user.authResourceGroupConfig.description=Repository user can use this repository in the pipeline +rule.manager.authResourceGroupConfig.description=Quality red-line rule owner has all permissions for the current quality red-line rule -cert.manager.AuthResourceGroupConfig.groupName=Owner -cert.user.AuthResourceGroupConfig.groupName=User -codecc_task.editor.AuthResourceGroupConfig.groupName=Editor -codecc_task.executor.AuthResourceGroupConfig.groupName=Executor -codecc_task.manager.AuthResourceGroupConfig.groupName=Owner -codecc_task.viewer.AuthResourceGroupConfig.groupName=Viewer -credential.manager.AuthResourceGroupConfig.groupName=Owner -credential.user.AuthResourceGroupConfig.groupName=User -env_node.manager.AuthResourceGroupConfig.groupName=Owner -env_node.user.AuthResourceGroupConfig.groupName=User -environment.manager.AuthResourceGroupConfig.groupName=Owner -environment.user.AuthResourceGroupConfig.groupName=User -experience_group.manager.AuthResourceGroupConfig.groupName=Owner -experience_task.manager.AuthResourceGroupConfig.groupName=Owner -pipeline.editor.AuthResourceGroupConfig.groupName=Editor -pipeline.executor.AuthResourceGroupConfig.groupName=Executor -pipeline.manager.AuthResourceGroupConfig.groupName=Owner -pipeline.viewer.AuthResourceGroupConfig.groupName=Viewer -pipeline_group.editor.AuthResourceGroupConfig.groupName=Editor -pipeline_group.executor.AuthResourceGroupConfig.groupName=Executor -pipeline_group.manager.AuthResourceGroupConfig.groupName=Owner -pipeline_group.viewer.AuthResourceGroupConfig.groupName=Viewer -project.developer.AuthResourceGroupConfig.groupName=Developer -project.maintainer.AuthResourceGroupConfig.groupName=SRE -project.manager.AuthResourceGroupConfig.groupName=Owner -project.pm.AuthResourceGroupConfig.groupName=PM -project.qc.AuthResourceGroupConfig.groupName=QC -project.tester.AuthResourceGroupConfig.groupName=QA -project.visitor.AuthResourceGroupConfig.groupName=Guest -quality_group.manager.AuthResourceGroupConfig.groupName=Owner -repertory.manager.AuthResourceGroupConfig.groupName=Owner -repertory.user.AuthResourceGroupConfig.groupName=User -rule.manager.AuthResourceGroupConfig.groupName=Owner +cert.manager.authResourceGroupConfig.groupName=Owner +cert.user.authResourceGroupConfig.groupName=User +codecc_task.editor.authResourceGroupConfig.groupName=Editor +codecc_task.executor.authResourceGroupConfig.groupName=Executor +codecc_task.manager.authResourceGroupConfig.groupName=Owner +codecc_task.viewer.authResourceGroupConfig.groupName=Viewer +credential.manager.authResourceGroupConfig.groupName=Owner +credential.user.authResourceGroupConfig.groupName=User +env_node.manager.authResourceGroupConfig.groupName=Owner +env_node.user.authResourceGroupConfig.groupName=User +environment.manager.authResourceGroupConfig.groupName=Owner +environment.user.authResourceGroupConfig.groupName=User +experience_group.manager.authResourceGroupConfig.groupName=Owner +experience_task.manager.authResourceGroupConfig.groupName=Owner +pipeline.editor.authResourceGroupConfig.groupName=Editor +pipeline.executor.authResourceGroupConfig.groupName=Executor +pipeline.manager.authResourceGroupConfig.groupName=Owner +pipeline.viewer.authResourceGroupConfig.groupName=Viewer +pipeline_group.editor.authResourceGroupConfig.groupName=Editor +pipeline_group.executor.authResourceGroupConfig.groupName=Executor +pipeline_group.manager.authResourceGroupConfig.groupName=Owner +pipeline_group.viewer.authResourceGroupConfig.groupName=Viewer +project.developer.authResourceGroupConfig.groupName=Developer +project.maintainer.authResourceGroupConfig.groupName=SRE +project.manager.authResourceGroupConfig.groupName=Owner +project.pm.authResourceGroupConfig.groupName=PM +project.qc.authResourceGroupConfig.groupName=QC +project.tester.authResourceGroupConfig.groupName=QA +project.visitor.authResourceGroupConfig.groupName=Guest +quality_group.manager.authResourceGroupConfig.groupName=Owner +repertory.manager.authResourceGroupConfig.groupName=Owner +repertory.user.authResourceGroupConfig.groupName=User +rule.manager.authResourceGroupConfig.groupName=Owner -cert.ResourceType.desc=Cert -codecc_ignore_type.ResourceType.desc=CodeCC Ignore Type -codecc_rule_set.ResourceType.desc=CodeCC Rule Set -codecc_task.ResourceType.desc=CodeCC Task -credential.ResourceType.desc=Credential -env_node.ResourceType.desc=Node -environment.ResourceType.desc=Environment -experience_group.ResourceType.desc=Experience Group -experience_task.ResourceType.desc=Experience Task -pipeline.ResourceType.desc=Pipeline -pipeline_group.ResourceType.desc=Pipeline Group -project.ResourceType.desc=Project -quality_group.ResourceType.desc=Andon Notice Group -repertory.ResourceType.desc=Repository -rule.ResourceType.desc=Andon Rule -cert.ResourceType.name=Cert -codecc_ignore_type.ResourceType.name=CodeCC Ignore Type -codecc_rule_set.ResourceType.name=CodeCC Rule Set -codecc_task.ResourceType.name=CodeCC Task -credential.ResourceType.name=Credential -env_node.ResourceType.name=Node -environment.ResourceType.name=Environment -experience_group.ResourceType.name=Experience Group -experience_task.ResourceType.name=Experience Task -pipeline.ResourceType.name=Pipeline -pipeline_group.ResourceType.name=Pipeline Group -project.ResourceType.name=Project -quality_group.ResourceType.name=Andon Notice Group -repertory.ResourceType.name=Repository -rule.ResourceType.name=Andon Rule +cert.resourceType.desc=Cert +codecc_ignore_type.resourceType.desc=CodeCC Ignore Type +codecc_rule_set.resourceType.desc=CodeCC Rule Set +codecc_task.resourceType.desc=CodeCC Task +credential.resourceType.desc=Credential +env_node.resourceType.desc=Node +environment.resourceType.desc=Environment +experience_group.resourceType.desc=Experience Group +experience_task.resourceType.desc=Experience Task +pipeline.resourceType.desc=Pipeline +pipeline_group.resourceType.desc=Pipeline Group +project.resourceType.desc=Project +quality_group.resourceType.desc=Andon Notice Group +repertory.resourceType.desc=Repository +rule.resourceType.desc=Andon Rule +cert.resourceType.name=Cert +codecc_ignore_type.resourceType.name=CodeCC Ignore Type +codecc_rule_set.resourceType.name=CodeCC Rule Set +codecc_task.resourceType.name=CodeCC Task +credential.resourceType.name=Credential +env_node.resourceType.name=Node +environment.resourceType.name=Environment +experience_group.resourceType.name=Experience Group +experience_task.resourceType.name=Experience Task +pipeline.resourceType.name=Pipeline +pipeline_group.resourceType.name=Pipeline Group +project.resourceType.name=Project +quality_group.resourceType.name=Andon Notice Group +repertory.resourceType.name=Repository +rule.resourceType.name=Andon Rule diff --git a/support-files/i18n/auth/message_zh_CN.properties b/support-files/i18n/auth/message_zh_CN.properties index d5361f40056..914a57c10d0 100644 --- a/support-files/i18n/auth/message_zh_CN.properties +++ b/support-files/i18n/auth/message_zh_CN.properties @@ -157,101 +157,101 @@ experience_task_edit.actionName=编辑版本体验任务 experience_task_list.actionName=版本体验任务列表 experience_task_view.actionName=查看版本体验任务 -cert.manager.AuthResourceGroupConfig.description=证书拥有者,拥有当前证书的所有操作权限 -cert.user.AuthResourceGroupConfig.description=证书使用者,可以在流水线中使用此证书 -codecc_task.editor.AuthResourceGroupConfig.description=任务编辑者,拥有当前任务除了权限管理之外的所有权限 -codecc_task.executor.AuthResourceGroupConfig.description=任务执行者,可以查看和执行任务 -codecc_task.manager.AuthResourceGroupConfig.description=任务拥有者,可以管理当前任务的所有权限 -codecc_task.viewer.AuthResourceGroupConfig.description=任务查看者,可以查看任务 -credential.manager.AuthResourceGroupConfig.description=凭据拥有者,拥有当前凭据的所有操作权限 -credential.user.AuthResourceGroupConfig.description=凭据使用者,可以在流水线中使用此凭据 -env_node.manager.AuthResourceGroupConfig.description=节点拥有者,拥有当前节点的所有操作权限 -env_node.user.AuthResourceGroupConfig.description=节点使用者,可以在流水线中使用此节点 -environment.manager.AuthResourceGroupConfig.description=环境拥有者,拥有当前环境的所有操作权限 -environment.user.AuthResourceGroupConfig.description=环境使用者,可以在流水线中使用此环境 -experience_group.manager.AuthResourceGroupConfig.description=版本体验组拥有者,拥有当前版本体验组的所有操作权限 -experience_task.manager.AuthResourceGroupConfig.description=版本体验拥有者,拥有当前版本体验的所有操作权限 -pipeline.editor.AuthResourceGroupConfig.description=流水线编辑者,拥有当前流水线除了权限管理之外的所有权限 -pipeline.executor.AuthResourceGroupConfig.description=流水线执行者,可以查看和执行流水线,下载或分享制品 -pipeline.manager.AuthResourceGroupConfig.description=流水线拥有者,可以管理当前流水线的权限 -pipeline.viewer.AuthResourceGroupConfig.description=流水线查看者,可以查看流水线,下载或分享制品 -pipeline_group.editor.AuthResourceGroupConfig.description=可以查看、编辑、执行组内的流水线 -pipeline_group.executor.AuthResourceGroupConfig.description=可以查看、执行组内的流水线 -pipeline_group.manager.AuthResourceGroupConfig.description=流水线组管理员,可以管理组中的流水线,给组内流水线批量添加编辑者、执行者、查看者 -pipeline_group.viewer.AuthResourceGroupConfig.description=可以查看组内的流水线 -project.developer.AuthResourceGroupConfig.description=开发人员,可以创建流水线、代码库、凭据、证书、环境、节点、Codecc任务、Codecc规则集,下载和分享项目自定义仓库中的制品 -project.maintainer.AuthResourceGroupConfig.description=运维人员,可以创建流水线、代码库、凭据、证书、环境、节点,下载和分享项目自定义仓库中的制品 -project.manager.AuthResourceGroupConfig.description=项目管理员,拥有项目下所有资源的操作和管理权限。可以添加用户到项目,从项目下移除用户,审批加入项目的申请,以及审批项目级用户组中用户的权限续期申请。 -project.pm.AuthResourceGroupConfig.description=产品人员,可以查看流水线列表,下载或分享制品。 -project.qc.AuthResourceGroupConfig.description=质管人员,管理质量红线规则。 -project.tester.AuthResourceGroupConfig.description=测试人员,可以创建测试流水线以及相关资源,下载或分享制品。 -project.visitor.AuthResourceGroupConfig.description=访客,可以查看流水线列表。 -quality_group.manager.AuthResourceGroupConfig.description=质量红线通知组拥有者,拥有当前质量红线通知组的所有操作权限 -repertory.manager.AuthResourceGroupConfig.description=代码库拥有者,拥有当前代码库的所有操作权限 -repertory.user.AuthResourceGroupConfig.description=代码库使用者,可以在流水线中使用此代码库 -rule.manager.AuthResourceGroupConfig.description=质量红线规则拥有者,拥有当前质量红线规则的所有操作权限 +cert.manager.authResourceGroupConfig.description=证书拥有者,拥有当前证书的所有操作权限 +cert.user.authResourceGroupConfig.description=证书使用者,可以在流水线中使用此证书 +codecc_task.editor.authResourceGroupConfig.description=任务编辑者,拥有当前任务除了权限管理之外的所有权限 +codecc_task.executor.authResourceGroupConfig.description=任务执行者,可以查看和执行任务 +codecc_task.manager.authResourceGroupConfig.description=任务拥有者,可以管理当前任务的所有权限 +codecc_task.viewer.authResourceGroupConfig.description=任务查看者,可以查看任务 +credential.manager.authResourceGroupConfig.description=凭据拥有者,拥有当前凭据的所有操作权限 +credential.user.authResourceGroupConfig.description=凭据使用者,可以在流水线中使用此凭据 +env_node.manager.authResourceGroupConfig.description=节点拥有者,拥有当前节点的所有操作权限 +env_node.user.authResourceGroupConfig.description=节点使用者,可以在流水线中使用此节点 +environment.manager.authResourceGroupConfig.description=环境拥有者,拥有当前环境的所有操作权限 +environment.user.authResourceGroupConfig.description=环境使用者,可以在流水线中使用此环境 +experience_group.manager.authResourceGroupConfig.description=版本体验组拥有者,拥有当前版本体验组的所有操作权限 +experience_task.manager.authResourceGroupConfig.description=版本体验拥有者,拥有当前版本体验的所有操作权限 +pipeline.editor.authResourceGroupConfig.description=流水线编辑者,拥有当前流水线除了权限管理之外的所有权限 +pipeline.executor.authResourceGroupConfig.description=流水线执行者,可以查看和执行流水线,下载或分享制品 +pipeline.manager.authResourceGroupConfig.description=流水线拥有者,可以管理当前流水线的权限 +pipeline.viewer.authResourceGroupConfig.description=流水线查看者,可以查看流水线,下载或分享制品 +pipeline_group.editor.authResourceGroupConfig.description=可以查看、编辑、执行组内的流水线 +pipeline_group.executor.authResourceGroupConfig.description=可以查看、执行组内的流水线 +pipeline_group.manager.authResourceGroupConfig.description=流水线组管理员,可以管理组中的流水线,给组内流水线批量添加编辑者、执行者、查看者 +pipeline_group.viewer.authResourceGroupConfig.description=可以查看组内的流水线 +project.developer.authResourceGroupConfig.description=开发人员,可以创建流水线、代码库、凭据、证书、环境、节点、Codecc任务、Codecc规则集,下载和分享项目自定义仓库中的制品 +project.maintainer.authResourceGroupConfig.description=运维人员,可以创建流水线、代码库、凭据、证书、环境、节点,下载和分享项目自定义仓库中的制品 +project.manager.authResourceGroupConfig.description=项目管理员,拥有项目下所有资源的操作和管理权限。可以添加用户到项目,从项目下移除用户,审批加入项目的申请,以及审批项目级用户组中用户的权限续期申请。 +project.pm.authResourceGroupConfig.description=产品人员,可以查看流水线列表,下载或分享制品。 +project.qc.authResourceGroupConfig.description=质管人员,管理质量红线规则。 +project.tester.authResourceGroupConfig.description=测试人员,可以创建测试流水线以及相关资源,下载或分享制品。 +project.visitor.authResourceGroupConfig.description=访客,可以查看流水线列表。 +quality_group.manager.authResourceGroupConfig.description=质量红线通知组拥有者,拥有当前质量红线通知组的所有操作权限 +repertory.manager.authResourceGroupConfig.description=代码库拥有者,拥有当前代码库的所有操作权限 +repertory.user.authResourceGroupConfig.description=代码库使用者,可以在流水线中使用此代码库 +rule.manager.authResourceGroupConfig.description=质量红线规则拥有者,拥有当前质量红线规则的所有操作权限 -cert.manager.AuthResourceGroupConfig.groupName=拥有者 -cert.user.AuthResourceGroupConfig.groupName=使用者 -codecc_task.editor.AuthResourceGroupConfig.groupName=编辑者 -codecc_task.executor.AuthResourceGroupConfig.groupName=执行者 -codecc_task.manager.AuthResourceGroupConfig.groupName=拥有者 -codecc_task.viewer.AuthResourceGroupConfig.groupName=查看者 -credential.manager.AuthResourceGroupConfig.groupName=拥有者 -credential.user.AuthResourceGroupConfig.groupName=使用者 -env_node.manager.AuthResourceGroupConfig.groupName=拥有者 -env_node.user.AuthResourceGroupConfig.groupName=使用者 -environment.manager.AuthResourceGroupConfig.groupName=拥有者 -environment.user.AuthResourceGroupConfig.groupName=使用者 -experience_group.manager.AuthResourceGroupConfig.groupName=拥有者 -experience_task.manager.AuthResourceGroupConfig.groupName=拥有者 -pipeline.editor.AuthResourceGroupConfig.groupName=编辑者 -pipeline.executor.AuthResourceGroupConfig.groupName=执行者 -pipeline.manager.AuthResourceGroupConfig.groupName=拥有者 -pipeline.viewer.AuthResourceGroupConfig.groupName=查看者 -pipeline_group.editor.AuthResourceGroupConfig.groupName=编辑者 -pipeline_group.executor.AuthResourceGroupConfig.groupName=执行者 -pipeline_group.manager.AuthResourceGroupConfig.groupName=拥有者 -pipeline_group.viewer.AuthResourceGroupConfig.groupName=查看者 -project.developer.AuthResourceGroupConfig.groupName=开发人员 -project.maintainer.AuthResourceGroupConfig.groupName=运维人员 -project.manager.AuthResourceGroupConfig.groupName=管理员 -project.pm.AuthResourceGroupConfig.groupName=产品人员 -project.qc.AuthResourceGroupConfig.groupName=质管人员 -project.tester.AuthResourceGroupConfig.groupName=测试人员 -project.visitor.AuthResourceGroupConfig.groupName=访客 -quality_group.manager.AuthResourceGroupConfig.groupName=拥有者 -repertory.manager.AuthResourceGroupConfig.groupName=拥有者 -repertory.user.AuthResourceGroupConfig.groupName=使用者 -rule.manager.AuthResourceGroupConfig.groupName=拥有者 +cert.manager.authResourceGroupConfig.groupName=拥有者 +cert.user.authResourceGroupConfig.groupName=使用者 +codecc_task.editor.authResourceGroupConfig.groupName=编辑者 +codecc_task.executor.authResourceGroupConfig.groupName=执行者 +codecc_task.manager.authResourceGroupConfig.groupName=拥有者 +codecc_task.viewer.authResourceGroupConfig.groupName=查看者 +credential.manager.authResourceGroupConfig.groupName=拥有者 +credential.user.authResourceGroupConfig.groupName=使用者 +env_node.manager.authResourceGroupConfig.groupName=拥有者 +env_node.user.authResourceGroupConfig.groupName=使用者 +environment.manager.authResourceGroupConfig.groupName=拥有者 +environment.user.authResourceGroupConfig.groupName=使用者 +experience_group.manager.authResourceGroupConfig.groupName=拥有者 +experience_task.manager.authResourceGroupConfig.groupName=拥有者 +pipeline.editor.authResourceGroupConfig.groupName=编辑者 +pipeline.executor.authResourceGroupConfig.groupName=执行者 +pipeline.manager.authResourceGroupConfig.groupName=拥有者 +pipeline.viewer.authResourceGroupConfig.groupName=查看者 +pipeline_group.editor.authResourceGroupConfig.groupName=编辑者 +pipeline_group.executor.authResourceGroupConfig.groupName=执行者 +pipeline_group.manager.authResourceGroupConfig.groupName=拥有者 +pipeline_group.viewer.authResourceGroupConfig.groupName=查看者 +project.developer.authResourceGroupConfig.groupName=开发人员 +project.maintainer.authResourceGroupConfig.groupName=运维人员 +project.manager.authResourceGroupConfig.groupName=管理员 +project.pm.authResourceGroupConfig.groupName=产品人员 +project.qc.authResourceGroupConfig.groupName=质管人员 +project.tester.authResourceGroupConfig.groupName=测试人员 +project.visitor.authResourceGroupConfig.groupName=访客 +quality_group.manager.authResourceGroupConfig.groupName=拥有者 +repertory.manager.authResourceGroupConfig.groupName=拥有者 +repertory.user.authResourceGroupConfig.groupName=使用者 +rule.manager.authResourceGroupConfig.groupName=拥有者 -cert.ResourceType.desc=证书 -codecc_ignore_type.ResourceType.desc=CodeCC忽略类型 -codecc_rule_set.ResourceType.desc=CodeCC规则集 -codecc_task.ResourceType.desc=CodeCC任务 -credential.ResourceType.desc=凭据 -env_node.ResourceType.desc=节点 -environment.ResourceType.desc=环境 -experience_group.ResourceType.desc=版本体验用户组 -experience_task.ResourceType.desc=版本体验任务 -pipeline.ResourceType.desc=流水线 -pipeline_group.ResourceType.desc=流水线组 -project.ResourceType.desc=项目 -quality_group.ResourceType.desc=质量红线通知组 -repertory.ResourceType.desc=代码库 -rule.ResourceType.desc=质量红线规则 -cert.ResourceType.name=证书 -codecc_ignore_type.ResourceType.name=CodeCC忽略类型 -codecc_rule_set.ResourceType.name=CodeCC规则集 -codecc_task.ResourceType.name=CodeCC任务 -credential.ResourceType.name=凭据 -env_node.ResourceType.name=节点 -environment.ResourceType.name=环境 -experience_group.ResourceType.name=版本体验用户组 -experience_task.ResourceType.name=版本体验任务 -pipeline.ResourceType.name=流水线 -pipeline_group.ResourceType.name=流水线组 -project.ResourceType.name=项目 -quality_group.ResourceType.name=质量红线通知组 -repertory.ResourceType.name=代码库 -rule.ResourceType.name=质量红线规则 +cert.resourceType.desc=证书 +codecc_ignore_type.resourceType.desc=CodeCC忽略类型 +codecc_rule_set.resourceType.desc=CodeCC规则集 +codecc_task.resourceType.desc=CodeCC任务 +credential.resourceType.desc=凭据 +env_node.resourceType.desc=节点 +environment.resourceType.desc=环境 +experience_group.resourceType.desc=版本体验用户组 +experience_task.resourceType.desc=版本体验任务 +pipeline.resourceType.desc=流水线 +pipeline_group.resourceType.desc=流水线组 +project.resourceType.desc=项目 +quality_group.resourceType.desc=质量红线通知组 +repertory.resourceType.desc=代码库 +rule.resourceType.desc=质量红线规则 +cert.resourceType.name=证书 +codecc_ignore_type.resourceType.name=CodeCC忽略类型 +codecc_rule_set.resourceType.name=CodeCC规则集 +codecc_task.resourceType.name=CodeCC任务 +credential.resourceType.name=凭据 +env_node.resourceType.name=节点 +environment.resourceType.name=环境 +experience_group.resourceType.name=版本体验用户组 +experience_task.resourceType.name=版本体验任务 +pipeline.resourceType.name=流水线 +pipeline_group.resourceType.name=流水线组 +project.resourceType.name=项目 +quality_group.resourceType.name=质量红线通知组 +repertory.resourceType.name=代码库 +rule.resourceType.name=质量红线规则 From a19deee6126f7dda1bbf01b053945c3235b73804 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Wed, 7 Jun 2023 19:45:58 +0800 Subject: [PATCH 025/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/auth/service/RbacPermissionApplyService.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt index 963ece4c7ee..2c43deae543 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt @@ -27,7 +27,6 @@ import com.tencent.devops.auth.pojo.vo.ResourceTypeInfoVo import com.tencent.devops.auth.service.iam.PermissionApplyService import com.tencent.devops.auth.service.iam.PermissionService import com.tencent.devops.common.api.exception.ErrorCodeException -import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.auth.api.pojo.DefaultGroupType From f251c2ecc562d0b522a127412575680236732379 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Wed, 7 Jun 2023 20:01:31 +0800 Subject: [PATCH 026/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notify/service/NotifyMessageTemplateServiceImpl.kt | 8 ++++---- .../quality/service/v2/QualityControlPointService.kt | 8 ++++---- .../devops/quality/service/v2/QualityIndicatorService.kt | 8 ++++---- .../devops/quality/service/v2/QualityMetadataService.kt | 8 ++++---- .../devops/quality/service/v2/QualityTemplateService.kt | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt index 5829beb7711..183cfc27721 100644 --- a/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt +++ b/src/backend/ci/core/notify/biz-notify/src/main/kotlin/com/tencent/devops/notify/service/NotifyMessageTemplateServiceImpl.kt @@ -113,14 +113,14 @@ class NotifyMessageTemplateServiceImpl @Autowired constructor( expiredTimeInSeconds = 60 ) - if (redisLock.tryLock()) { - Executors.newFixedThreadPool(1).submit { + Executors.newFixedThreadPool(1).submit { + if (redisLock.tryLock()) { try { logger.info("start init MessageTemplate") updateMessageTemplate() logger.info("start init MessageTemplate succeed") - } catch (e: Exception) { - logger.warn("start init MessageTemplate fail! error:$e") + } catch (ignored: Throwable) { + logger.warn("start init MessageTemplate fail! error:${ignored.message}") } finally { redisLock.unlock() } diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt index 08ea2930789..627b460696d 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityControlPointService.kt @@ -76,8 +76,8 @@ class QualityControlPointService @Autowired constructor( expiredTimeInSeconds = 60 ) - if (redisLock.tryLock()) { - Executors.newFixedThreadPool(1).submit { + Executors.newFixedThreadPool(1).submit { + if (redisLock.tryLock()) { try { logger.info("start init quality control point") val classPathResource = ClassPathResource( @@ -88,8 +88,8 @@ class QualityControlPointService @Autowired constructor( val controlPointPOs = JsonUtil.to(json, object : TypeReference>() {}) controlPointDao.batchCrateControlPoint(dslContext, controlPointPOs) logger.info("init quality control point end") - } catch (e: Exception) { - logger.debug("init quality control point fail! error:$e") + } catch (ignored: Throwable) { + logger.warn("init quality control point fail! error:${ignored.message}") } finally { redisLock.unlock() } diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt index e4f980e7e61..ba8d5487088 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt @@ -124,8 +124,8 @@ class QualityIndicatorService @Autowired constructor( expiredTimeInSeconds = 60 ) - if (redisLock.tryLock()) { - Executors.newFixedThreadPool(1).submit { + Executors.newFixedThreadPool(1).submit { + if (redisLock.tryLock()) { try { logger.info("start init quality indicator") val classPathResource = ClassPathResource( @@ -136,8 +136,8 @@ class QualityIndicatorService @Autowired constructor( val qualityIndicatorPOs = JsonUtil.to(json, object : TypeReference>() {}) indicatorDao.batchCrateQualityIndicator(dslContext, qualityIndicatorPOs) logger.info("init quality indicator end") - } catch (e: Exception) { - logger.debug("init quality indicator fail! error:$e") + } catch (ignored: Throwable) { + logger.warn("init quality indicator fail! error:${ignored.message}") } finally { redisLock.unlock() } diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt index e221be0d8c2..18ce1783de1 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityMetadataService.kt @@ -71,8 +71,8 @@ class QualityMetadataService @Autowired constructor( expiredTimeInSeconds = 60 ) - if (redisLock.tryLock()) { - Executors.newFixedThreadPool(1).submit { + Executors.newFixedThreadPool(1).submit { + if (redisLock.tryLock()) { try { logger.info("start init quality metadata") val classPathResource = ClassPathResource( @@ -83,8 +83,8 @@ class QualityMetadataService @Autowired constructor( val qualityMetadataPOs = JsonUtil.to(json, object : TypeReference>() {}) metadataDao.batchCrateQualityMetadata(dslContext, qualityMetadataPOs) logger.info("init quality metadata end") - } catch (e: Exception) { - logger.debug("init quality metadata fail! error:$e") + } catch (ignored: Throwable) { + logger.warn("init quality metadata fail! error:${ignored.message}") } finally { redisLock.unlock() } diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt index 6debc0a0c45..1fd5e6f8a2b 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityTemplateService.kt @@ -76,8 +76,8 @@ class QualityTemplateService @Autowired constructor( expiredTimeInSeconds = 60 ) - if (redisLock.tryLock()) { - Executors.newFixedThreadPool(1).submit { + Executors.newFixedThreadPool(1).submit { + if (redisLock.tryLock()) { try { logger.info("start init quality rule template") val classPathResource = ClassPathResource( @@ -89,8 +89,8 @@ class QualityTemplateService @Autowired constructor( JsonUtil.to(json, object : TypeReference>() {}) ruleTemplateDao.batchCrateQualityRuleTemplate(dslContext, qualityRuleTemplatePOs) logger.info("init quality rule template end") - } catch (e: Exception) { - logger.debug("init quality rule template fail! error:$e") + } catch (ignored: Throwable) { + logger.warn("init quality rule template fail! error:${ignored.message}") } finally { redisLock.unlock() } From 79c2e6460eefb0e06dd4a4ef0f39b6e263c3fd37 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Thu, 8 Jun 2023 09:58:40 +0800 Subject: [PATCH 027/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/common/web/interceptor/BkWriterInterceptor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/common/common-web/src/main/kotlin/com/tencent/devops/common/web/interceptor/BkWriterInterceptor.kt b/src/backend/ci/core/common/common-web/src/main/kotlin/com/tencent/devops/common/web/interceptor/BkWriterInterceptor.kt index 4f5ab6d9cb2..c171840ee5a 100644 --- a/src/backend/ci/core/common/common-web/src/main/kotlin/com/tencent/devops/common/web/interceptor/BkWriterInterceptor.kt +++ b/src/backend/ci/core/common/common-web/src/main/kotlin/com/tencent/devops/common/web/interceptor/BkWriterInterceptor.kt @@ -131,7 +131,7 @@ class BkWriterInterceptor : WriterInterceptor { val fieldKeySuffixName = if (i18nFieldInfo.translateType == I18nTranslateTypeEnum.NAME) { // 如果注解上配置了字段转换名称,则使用转换名称进行国际化翻译 i18nFieldInfo.convertName.ifBlank { - i18nFieldInfo.convertName + lastNodeName } } else { MessageUtil.getFieldValue(i18nFieldInfo.field, i18nFieldInfo.entity)?.toString() ?: "" From d47ffa59f6eddbbcbbac02e862e6f6303638b034 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Thu, 8 Jun 2023 11:26:11 +0800 Subject: [PATCH 028/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/auth/api/user/UserAuthApplyResource.kt | 2 +- .../kotlin/com/tencent/devops/auth/pojo/RelatedResourceInfo.kt | 2 ++ .../com/tencent/devops/auth/pojo/vo/ResourceTypeInfoVo.kt | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt index 3ed454a6791..0dbf078763f 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt @@ -80,7 +80,7 @@ interface UserAuthApplyResource { @GET @Path("{groupId}/getGroupPermissionDetail") @ApiOperation("查询用户组权限详情") - @BkInterfaceI18n(keyPrefixNames = ["{data[*].actionId}"]) + @BkInterfaceI18n(keyPrefixNames = ["{data[*].actionId}", "{data[*].relatedResourceInfo.type}"]) fun getGroupPermissionDetail( @ApiParam(name = "用户名", required = true) @HeaderParam(AUTH_HEADER_USER_ID) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/RelatedResourceInfo.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/RelatedResourceInfo.kt index 41c8cbabd37..b27a0f5f0a5 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/RelatedResourceInfo.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/RelatedResourceInfo.kt @@ -1,6 +1,7 @@ package com.tencent.devops.auth.pojo import com.tencent.bk.sdk.iam.dto.InstancesDTO +import com.tencent.devops.common.api.annotation.BkFieldI18n import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -9,6 +10,7 @@ data class RelatedResourceInfo( @ApiModelProperty("资源类型") val type: String, @ApiModelProperty("资源类型名") + @BkFieldI18n(keyPrefixName = "resourceType") val name: String, @ApiModelProperty("资源实例") val instances: InstancesDTO diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ResourceTypeInfoVo.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ResourceTypeInfoVo.kt index 088ced8c1b9..96c0d493e23 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ResourceTypeInfoVo.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/ResourceTypeInfoVo.kt @@ -11,7 +11,7 @@ data class ResourceTypeInfoVo( @ApiModelProperty("资源类型") val resourceType: String, @ApiModelProperty("资源类型名") - @BkFieldI18n(keyPrefixName = "ResourceType") + @BkFieldI18n(keyPrefixName = "resourceType") val name: String, @ApiModelProperty("父类资源") val parent: String, From f405ee2d34e48620381b37504b180baf2e1ccdec Mon Sep 17 00:00:00 2001 From: yjieliang Date: Thu, 8 Jun 2023 11:57:26 +0800 Subject: [PATCH 029/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/common/api/constant/CommonMessageCode.kt | 2 +- support-files/i18n/message_en_US.properties | 2 +- support-files/i18n/message_zh_CN.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/constant/CommonMessageCode.kt b/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/constant/CommonMessageCode.kt index 91fa17ff841..66e1a5d92fb 100644 --- a/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/constant/CommonMessageCode.kt +++ b/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/constant/CommonMessageCode.kt @@ -193,7 +193,7 @@ object CommonMessageCode { const val BK_CREATE_SERVICE = "bkCreateService" // 创建{0}服务 const val BK_SESSION_ID = "bkSessionId" // 会话ID const val BK_GROUP_ID = "bkGroupId" // 群ID - const val BK_THIS_GROUP_ID = "bkThisGroupId" // 本群ID='{0}'。PS:群ID可用于蓝盾平台上任意企业微信群通知。 + const val BK_THIS_GROUP_ID = "bkThisGroupId" // 本群ID={0}。PS:群ID可用于蓝盾平台上任意企业微信群通知。 const val BK_MISSING_RESOURCE_DEPENDENCY = "bkMissingResourceDependency" // 依赖的资源不存在 const val BK_REQUEST_TIMED_OUT = "bkRequestTimedOut" // 请求超时 diff --git a/support-files/i18n/message_en_US.properties b/support-files/i18n/message_en_US.properties index 950751e6b67..d5a8660d611 100644 --- a/support-files/i18n/message_en_US.properties +++ b/support-files/i18n/message_en_US.properties @@ -252,7 +252,7 @@ bkSeeDetails=View details bkSessionId=Session ID bkStartPullImage=Start pulling the image. Image name: bkTableContents=Table content -bkThisGroupId=This group ID=' {0}'. PS: group ID can be used for any WeChat group notification on BK-CI platform. +bkThisGroupId=This group ID={0}. PS: group ID can be used for any WeChat group notification on BK-CI platform. bkUserGroupCrateTime={0} User Group: {1}, created by {2} on bkUserRatingAdminCrateTime={0} Rating Admin, created by {1} on bkSecondLevelAdminCreate={0} second-level administrator, created by {1} diff --git a/support-files/i18n/message_zh_CN.properties b/support-files/i18n/message_zh_CN.properties index abfd3925b82..ae500bbbb80 100644 --- a/support-files/i18n/message_zh_CN.properties +++ b/support-files/i18n/message_zh_CN.properties @@ -252,7 +252,7 @@ bkSeeDetails=查看详情 bkSessionId=会话ID bkStartPullImage=开始拉取镜像,镜像名称: bkTableContents=表格内容 -bkThisGroupId=本群ID='{0}'。PS:群ID可用于蓝盾平台上任意企业微信群通知。 +bkThisGroupId=本群ID={0}。PS:群ID可用于蓝盾平台上任意企业微信群通知。 bkUserGroupCrateTime={0} 用户组:{1},由{2} 创建于 bkUserRatingAdminCrateTime={0} 分级管理员,由{1} 创建于 bkSecondLevelAdminCreate={0} 二级管理员, 由{1} 创建于 From f824f31c52f17272b65a5a231646b9414c925ca9 Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Thu, 8 Jun 2023 18:06:59 +0800 Subject: [PATCH 030/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/service/RbacPermissionResourceService.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionResourceService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionResourceService.kt index 455e1d45355..77b9e699c97 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionResourceService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionResourceService.kt @@ -162,13 +162,13 @@ class RbacPermissionResourceService( enable = resourceType != AuthResourceType.PIPELINE_GROUP.value, relationId = managerId.toString() ) - } catch (exception: Exception) { + } catch (ignore: Exception) { if (resourceType == AuthResourceType.PROJECT.value) { iamV2ManagerService.deleteManagerV2(managerId.toString()) } else { iamV2ManagerService.deleteSubsetManager(managerId.toString()) } - logger.warn("create resource failed|$userId|$projectCode|$resourceType|$resourceName", exception) + logger.warn("create resource failed|$userId|$projectCode|$resourceType|$resourceName", ignore) throw ErrorCodeException( errorCode = ERROR_RESOURCE_CREATE_FAIL, defaultMessage = "create resource failed|$userId|$projectCode|$resourceType|$resourceName" From 7f6599a7991678f11ac84d9ff5d9ffec3edb2a35 Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Thu, 8 Jun 2023 16:37:08 +0800 Subject: [PATCH 031/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/kotlin/constants/Versions.kt | 2 +- .../auth/config/RbacAuthConfiguration.kt | 12 +- .../service/RbacPermissionProjectService.kt | 4 +- .../auth/service/RbacPermissionService.kt | 25 ++- .../service/migrate/AbMigratePolicyService.kt | 148 +++++++++++++++--- .../service/migrate/MigrateV0PolicyService.kt | 54 ++++--- .../service/migrate/MigrateV3PolicyService.kt | 41 +++-- .../migrate/RbacPermissionMigrateService.kt | 6 + .../migrate/AbMigratePolicyServiceTest.kt | 2 + .../migrate/MigrateV0PolicyServiceTest.kt | 3 +- .../migrate/MigrateV3PolicyServiceTest.kt | 3 +- .../auth/dao/AuthResourceGroupConfigDao.kt | 11 ++ .../5001_ci_auth-init_dml_mysql.sql | 28 +++- 13 files changed, 269 insertions(+), 70 deletions(-) diff --git a/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt b/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt index 116cb0c6c11..b854d5ce6b8 100644 --- a/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt +++ b/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt @@ -45,5 +45,5 @@ object Versions { const val jjwt = "0.11.5" const val Okhttp = "4.9.0" const val jgit = "5.13.1.202206130422-r" - const val iam = "1.0.20-SNAPSHOT" + const val iam = "1.0.21-SNAPSHOT" } diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/config/RbacAuthConfiguration.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/config/RbacAuthConfiguration.kt index ec82b45f410..34c450fa3e8 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/config/RbacAuthConfiguration.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/config/RbacAuthConfiguration.kt @@ -338,7 +338,8 @@ class RbacAuthConfiguration { permissionService: PermissionService, rbacCacheService: RbacCacheService, authMigrationDao: AuthMigrationDao, - deptService: DeptService + deptService: DeptService, + permissionGroupPoliciesService: PermissionGroupPoliciesService ) = MigrateV3PolicyService( v2ManagerService = v2ManagerService, iamConfiguration = iamConfiguration, @@ -351,7 +352,8 @@ class RbacAuthConfiguration { permissionService = permissionService, rbacCacheService = rbacCacheService, authMigrationDao = authMigrationDao, - deptService = deptService + deptService = deptService, + permissionGroupPoliciesService = permissionGroupPoliciesService ) @Bean @@ -367,7 +369,8 @@ class RbacAuthConfiguration { permissionService: PermissionService, rbacCacheService: RbacCacheService, authMigrationDao: AuthMigrationDao, - deptService: DeptService + deptService: DeptService, + permissionGroupPoliciesService: PermissionGroupPoliciesService ) = MigrateV0PolicyService( v2ManagerService = v2ManagerService, iamConfiguration = iamConfiguration, @@ -380,7 +383,8 @@ class RbacAuthConfiguration { permissionService = permissionService, rbacCacheService = rbacCacheService, authMigrationDao = authMigrationDao, - deptService = deptService + deptService = deptService, + permissionGroupPoliciesService = permissionGroupPoliciesService ) @Bean diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionProjectService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionProjectService.kt index 0cc5900a2b0..656b6d89960 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionProjectService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionProjectService.kt @@ -155,13 +155,13 @@ class RbacPermissionProjectService( try { val useAction = RbacAuthUtils.buildAction(AuthPermission.get(action), AuthResourceType.PROJECT) val instanceMap = authHelper.groupRbacInstanceByType(userId, useAction) - val projectList = instanceMap[AuthResourceType.PROJECT.value] ?: emptyList() - return if (projectList.contains("*")) { + return if (instanceMap.contains("*")) { logger.info("super manager has all project|$userId") authResourceService.getAllResourceCode( resourceType = AuthResourceType.PROJECT.value ) } else { + val projectList = instanceMap[AuthResourceType.PROJECT.value] ?: emptyList() logger.info("get user projects:$projectList") projectList } diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt index fe97437fa7f..3443aa48c31 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt @@ -424,7 +424,7 @@ class RbacPermissionService constructor( if (rbacCacheService.checkProjectManager(userId = userId, projectCode = projectCode)) { return actions.associate { val authPermission = it.substringAfterLast("_") - AuthPermission.get(authPermission) to resources.map { it.resourceCode } + AuthPermission.get(authPermission) to resources.map { resource -> resource.resourceCode } } } val instanceList = resources.map { resource -> @@ -452,12 +452,23 @@ class RbacPermissionService constructor( actions.parallelStream().forEach { action -> MDC.put(TraceTag.BIZID, traceId) val authPermission = action.substringAfterLast("_") - val iamResourceCodes = authHelper.isAllowed(userId, action, instanceList) - permissionMap[AuthPermission.get(authPermission)] = authResourceCodeConverter.batchIamCode2Code( - projectCode = projectCode, - resourceType = resourceType, - iamResourceCodes = iamResourceCodes - ) + // 具有action管理员权限,那么有所有资源权限 + if (permissionSuperManagerService.reviewManagerCheck( + userId = userId, + projectCode = projectCode, + resourceType = resourceType, + action = action + ) + ) { + permissionMap[AuthPermission.get(authPermission)] = resources.map { it.resourceCode } + } else { + val iamResourceCodes = authHelper.isAllowed(userId, action, instanceList) + permissionMap[AuthPermission.get(authPermission)] = authResourceCodeConverter.batchIamCode2Code( + projectCode = projectCode, + resourceType = resourceType, + iamResourceCodes = iamResourceCodes + ) + } } return permissionMap } finally { diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt index c6f8749b4fe..7ac651b9bbc 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt @@ -46,6 +46,7 @@ import com.tencent.devops.auth.dao.AuthResourceGroupConfigDao import com.tencent.devops.auth.dao.AuthResourceGroupDao import com.tencent.devops.auth.pojo.migrate.MigrateTaskDataResult import com.tencent.devops.auth.service.DeptService +import com.tencent.devops.auth.service.PermissionGroupPoliciesService import com.tencent.devops.auth.service.RbacCacheService import com.tencent.devops.auth.service.iam.PermissionService import com.tencent.devops.auth.service.migrate.MigrateIamApiService.Companion.GROUP_API_POLICY @@ -77,7 +78,8 @@ abstract class AbMigratePolicyService( private val authMigrationDao: AuthMigrationDao, private val permissionService: PermissionService, private val rbacCacheService: RbacCacheService, - private val deptService: DeptService + private val deptService: DeptService, + private val permissionGroupPoliciesService: PermissionGroupPoliciesService ) { companion object { @@ -249,7 +251,7 @@ abstract class AbMigratePolicyService( abstract fun getGroupName(projectName: String, result: MigrateTaskDataResult): String - fun migrateUserCustomPolicy(projectCode: String, version: String) { + fun migrateUserCustomPolicy(projectCode: String, projectName: String, version: String) { logger.info("start to migrate user custom policy|$projectCode") val startEpoch = System.currentTimeMillis() try { @@ -266,6 +268,7 @@ abstract class AbMigratePolicyService( ) loopMigrateUserCustom( projectCode = projectCode, + projectName = projectName, managerGroupId = managerGroupId, version = version ) @@ -278,6 +281,7 @@ abstract class AbMigratePolicyService( private fun loopMigrateUserCustom( projectCode: String, + projectName: String, managerGroupId: Int, version: String ): Int { @@ -294,6 +298,7 @@ abstract class AbMigratePolicyService( ) migrateUserCustom( projectCode = projectCode, + projectName = projectName, managerGroupId = managerGroupId, results = taskDataResp.results ) @@ -305,6 +310,7 @@ abstract class AbMigratePolicyService( private fun migrateUserCustom( projectCode: String, + projectName: String, managerGroupId: Int, results: List ) { @@ -321,6 +327,7 @@ abstract class AbMigratePolicyService( val groupId = matchResourceGroup( userId = userId, projectCode = projectCode, + projectName = projectName, managerGroupId = managerGroupId, permission = permission ) @@ -340,6 +347,7 @@ abstract class AbMigratePolicyService( abstract fun matchResourceGroup( userId: String, projectCode: String, + projectName: String, managerGroupId: Int, permission: AuthorizationScopes ): Int? @@ -363,32 +371,82 @@ abstract class AbMigratePolicyService( ).all { it.value } // 没有action的权限,匹配资源默认用户组权限 if (!hasPermission) { - rbacCacheService.getGroupConfigAction(resourceType).forEach groupConfig@{ groupConfig -> - if (groupConfig.actions.containsAll(actions)) { - val groupId = authResourceGroupDao.get( - dslContext = dslContext, - projectCode = projectCode, - resourceType = resourceType, - resourceCode = resourceCode, - groupCode = groupConfig.groupCode - )?.relationId?.toInt() - logger.info( - "user match resource group" + - "|$userId|$actions|$projectCode|$resourceCode|${groupConfig.groupCode}|$groupId" - ) - return groupId - } + return getMatchResourceGroupId( + resourceType = resourceType, + actions = actions, + projectCode = projectCode, + resourceCode = resourceCode, + userId = userId + ).second ?: run { + logger.info("user not match resource group|$userId|$actions$projectCode|$resourceCode") + null } - logger.info("user not match resource group|$userId|$actions$projectCode|$resourceCode") } else { logger.info( - "user has resource action permission" + - "|$userId|$resourceCode|$actions$projectCode|$resourceCode" + "user has resource action permission|$userId|$resourceCode|$actions$projectCode|$resourceCode" ) } return null } + /** + * 匹配或创建项目资源用户组 + * + * 有任意资源权限,直接匹配项目下资源权限组,如果没有匹配到,则创建 + */ + protected fun matchOrCreateProjectResourceGroup( + userId: String, + projectCode: String, + projectName: String, + actions: List, + managerGroupId: Int + ): Int? { + val (groupConfigId, groupId) = getMatchResourceGroupId( + resourceType = AuthResourceType.PROJECT.value, + actions = actions, + projectCode = projectCode, + resourceCode = projectCode, + userId = userId + ) + return groupId ?: run { + groupConfigId?.let { + createProjectResourceGroup( + groupConfigId = groupConfigId, + gradeManagerId = managerGroupId, + projectCode = projectCode, + projectName = projectName + ) + } + } + } + + private fun getMatchResourceGroupId( + resourceType: String, + actions: List, + projectCode: String, + resourceCode: String, + userId: String + ): Pair { + rbacCacheService.getGroupConfigAction(resourceType).forEach groupConfig@{ groupConfig -> + if (groupConfig.actions.containsAll(actions)) { + val groupId = authResourceGroupDao.get( + dslContext = dslContext, + projectCode = projectCode, + resourceType = resourceType, + resourceCode = resourceCode, + groupCode = groupConfig.groupCode + )?.relationId?.toInt() + logger.info( + "user match resource group" + + "|$userId|$actions|$projectCode|$resourceCode|${groupConfig.groupCode}|$groupId" + ) + return Pair(groupConfig.id, groupId) + } + } + return Pair(null, null) + } + + private fun createRbacGroup( groupName: String, gradeManagerId: Int, @@ -430,6 +488,56 @@ abstract class AbMigratePolicyService( return groupId } + + /** + * 创建项目级资源用户组 + * + * 针对用户自定义权限,当用户有资源任意权限,如有任意流水线执行权限,项目默认组不能匹配该action,需要创建项目级流水线执行者组,用于管理这类权限 + */ + private fun createProjectResourceGroup( + groupConfigId: Long, + gradeManagerId: Int, + projectCode: String, + projectName: String + ): Int? { + logger.info("create project resource group|$groupConfigId|$gradeManagerId|$projectCode|$projectName") + val groupConfig = authResourceGroupConfigDao.getById(dslContext = dslContext, id = groupConfigId) ?: run { + logger.warn("group config not found|id:$groupConfigId") + return null + } + val managerRoleGroup = ManagerRoleGroup().apply { + name = groupConfig.groupName + description = groupConfig.description + } + val managerRoleGroupDTO = ManagerRoleGroupDTO.builder() + .groups(listOf(managerRoleGroup)) + .createAttributes(false) + .build() + val iamGroupId = v2ManagerService.batchCreateRoleGroupV2(gradeManagerId, managerRoleGroupDTO) + + authResourceGroupDao.create( + dslContext = dslContext, + projectCode = projectCode, + resourceType = AuthResourceType.PROJECT.value, + resourceCode = projectCode, + resourceName = projectName, + iamResourceCode = projectCode, + groupCode = groupConfig.groupCode, + groupName = groupConfig.groupName, + defaultGroup = false, + relationId = iamGroupId.toString() + ) + permissionGroupPoliciesService.grantGroupPermission( + authorizationScopesStr = groupConfig.authorizationScopes, + projectCode = projectCode, + projectName = projectName, + iamResourceCode = projectCode, + resourceName = projectName, + iamGroupId = iamGroupId + ) + return iamGroupId + } + private fun calculateGroupCount(projectCode: String, beforeGroupCount: Int) { val afterGroupCount = authResourceGroupDao.countByResourceCode( dslContext = dslContext, diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt index e10ce32fbe0..1a3fdccd1da 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt @@ -43,11 +43,13 @@ import com.tencent.devops.auth.dao.AuthResourceGroupDao import com.tencent.devops.auth.pojo.migrate.MigrateTaskDataResult import com.tencent.devops.auth.service.AuthResourceCodeConverter import com.tencent.devops.auth.service.DeptService +import com.tencent.devops.auth.service.PermissionGroupPoliciesService import com.tencent.devops.auth.service.RbacCacheService import com.tencent.devops.auth.service.iam.PermissionService import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType import java.util.concurrent.TimeUnit +import org.apache.commons.lang3.RandomUtils import org.jooq.DSLContext import org.slf4j.LoggerFactory @@ -64,7 +66,8 @@ class MigrateV0PolicyService constructor( private val permissionService: PermissionService, private val rbacCacheService: RbacCacheService, private val authMigrationDao: AuthMigrationDao, - private val deptService: DeptService + private val deptService: DeptService, + private val permissionGroupPoliciesService: PermissionGroupPoliciesService ) : AbMigratePolicyService( v2ManagerService = v2ManagerService, iamConfiguration = iamConfiguration, @@ -75,16 +78,15 @@ class MigrateV0PolicyService constructor( authMigrationDao = authMigrationDao, permissionService = permissionService, rbacCacheService = rbacCacheService, - deptService = deptService + deptService = deptService, + permissionGroupPoliciesService = permissionGroupPoliciesService ) { companion object { private val logger = LoggerFactory.getLogger(MigrateV0PolicyService::class.java) - // v0默认用户组过期时间 2038-01-01 - private const val V0_DEFAULT_GROUP_EXPIRED_AT = 2145888000L - // v0用户自定义组默认360天 - private const val V0_CUSTOM_GROUP_EXPIRED_DAY = 360L + // v0默认用户组过期时间,2年或者3年 + private val V0_GROUP_EXPIRED_DAY = listOf(180L, 360L, 720L, 1080L) // v0的资源类型group(版本体验、质量红线组),task(版本体验、codecc任务)存在重复,iam迁移时添加了serviceCode,所以需要转换 private val oldActionMappingNewAction = mapOf( @@ -283,6 +285,7 @@ class MigrateV0PolicyService constructor( override fun matchResourceGroup( userId: String, projectCode: String, + projectName: String, managerGroupId: Int, permission: AuthorizationScopes ): Int? { @@ -290,18 +293,26 @@ class MigrateV0PolicyService constructor( val resourceType = oldResourceTypeMappingNewResourceType[resource.type] ?: resource.type val userActions = permission.actions.map { it.id } logger.info("find match resource group|$projectCode|$resourceType|$userActions") - if (resource.paths.isEmpty() || resource.paths[0].isEmpty()) { - logger.info("resource paths is empty,skip|$projectCode|$resourceType|$userActions") - return null + // 项目下任意资源 + return if (resource.paths.isEmpty() || resource.paths[0].isEmpty()) { + val finalUserActions = replaceOrRemoveAction(userActions) + matchOrCreateProjectResourceGroup( + userId = userId, + projectCode = projectCode, + projectName = projectName, + actions = finalUserActions, + managerGroupId = managerGroupId + ) + } else { + val v0ResourceCode = resource.paths[0][0].id + v0MatchMinResourceGroup( + userId = userId, + projectCode = projectCode, + resourceType = resourceType, + v0ResourceCode = v0ResourceCode, + userActions = userActions + ) } - val v0ResourceCode = resource.paths[0][0].id - return v0MatchMinResourceGroup( - userId = userId, - projectCode = projectCode, - resourceType = resourceType, - v0ResourceCode = v0ResourceCode, - userActions = userActions - ) } private fun v0MatchMinResourceGroup( @@ -350,11 +361,14 @@ class MigrateV0PolicyService constructor( } override fun batchAddGroupMember(groupId: Int, defaultGroup: Boolean, members: List?) { - val expiredAt = if (defaultGroup) { - V0_DEFAULT_GROUP_EXPIRED_AT + val expiredDay = if (defaultGroup) { + // 默认用户组,2年或3年随机过期 + V0_GROUP_EXPIRED_DAY[RandomUtils.nextInt(2, 3)] } else { - System.currentTimeMillis() / MILLISECOND + TimeUnit.DAYS.toSeconds(V0_CUSTOM_GROUP_EXPIRED_DAY) + // 自定义用户组,半年或者一年过期 + V0_GROUP_EXPIRED_DAY[RandomUtils.nextInt(0, 1)] } + val expiredAt= System.currentTimeMillis() / MILLISECOND + TimeUnit.DAYS.toSeconds(expiredDay) members?.forEach member@{ member -> val managerMember = ManagerMember(member.type, member.id) val managerMemberGroupDTO = ManagerMemberGroupDTO.builder() diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt index 7a020febb3c..ef880cfe0f5 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt @@ -44,9 +44,12 @@ import com.tencent.devops.auth.dao.AuthResourceGroupDao import com.tencent.devops.auth.pojo.migrate.MigrateTaskDataResult import com.tencent.devops.auth.service.AuthResourceCodeConverter import com.tencent.devops.auth.service.DeptService +import com.tencent.devops.auth.service.PermissionGroupPoliciesService import com.tencent.devops.auth.service.RbacCacheService import com.tencent.devops.auth.service.iam.PermissionService +import com.tencent.devops.common.api.util.DateTimeUtil import com.tencent.devops.common.auth.api.AuthResourceType +import java.util.Calendar import org.jooq.DSLContext import org.slf4j.LoggerFactory @@ -73,7 +76,8 @@ class MigrateV3PolicyService constructor( private val permissionService: PermissionService, private val rbacCacheService: RbacCacheService, private val authMigrationDao: AuthMigrationDao, - private val deptService: DeptService + private val deptService: DeptService, + private val permissionGroupPoliciesService: PermissionGroupPoliciesService ) : AbMigratePolicyService( v2ManagerService = v2ManagerService, iamConfiguration = iamConfiguration, @@ -84,7 +88,8 @@ class MigrateV3PolicyService constructor( authMigrationDao = authMigrationDao, permissionService = permissionService, rbacCacheService = rbacCacheService, - deptService = deptService + deptService = deptService, + permissionGroupPoliciesService = permissionGroupPoliciesService ) { companion object { @@ -238,6 +243,7 @@ class MigrateV3PolicyService constructor( override fun matchResourceGroup( userId: String, projectCode: String, + projectName: String, managerGroupId: Int, permission: AuthorizationScopes ): Int? { @@ -262,13 +268,18 @@ class MigrateV3PolicyService constructor( v3ResourceCode = projectCode, userActions = permission.actions.map { it.id } ) - isSkipMatchResourceGroup(resource) -> { - logger.info( - "user cannot match all resources and matching will be skipped|" + - "$userId|$projectCode|$resourceType|$userActions" + // 项目任意资源 + isAnyResource(resource) -> { + val finalUserActions = replaceOrRemoveAction(userActions) + matchOrCreateProjectResourceGroup( + userId = userId, + projectCode = projectCode, + projectName = projectName, + actions = finalUserActions, + managerGroupId = managerGroupId ) - null } + // 具体资源权限 resource.paths[0].size >= 2 -> { v3MatchMinResourceGroup( userId = userId, @@ -282,10 +293,12 @@ class MigrateV3PolicyService constructor( } } - private fun isSkipMatchResourceGroup( + /** + * 有项目下任意资源权限 + */ + private fun isAnyResource( resource: ManagerResources ): Boolean { - // 项目下所有的资源不能找到对应的用户组,直接跳过,如自定义权限是项目下所有流水线pipeline_execute权限,默认的用户组是不能匹配改策略 return resource.paths[0].size >= 2 && resource.paths[0][1].id == "*" || (resource.paths[0].size == 1 && resource.paths[0][0].type == AuthResourceType.PROJECT.value) } @@ -342,14 +355,16 @@ class MigrateV3PolicyService constructor( override fun batchAddGroupMember(groupId: Int, defaultGroup: Boolean, members: List?) { members?.forEach member@{ member -> - // 过期的用户直接移除 - if (member.expiredAt * MILLISECOND < System.currentTimeMillis()) { - return@member + // 已过期用户,迁移时无法添加到用户组成员,增加1分钟添加到iam就过期,方便用户续期 + val expiredAt = if (member.expiredAt * MILLISECOND < System.currentTimeMillis()) { + DateTimeUtil.getFutureDateFromNow(Calendar.MINUTE, 1).time + } else { + member.expiredAt } val managerMember = ManagerMember(member.type, member.id) val managerMemberGroupDTO = ManagerMemberGroupDTO.builder() .members(listOf(managerMember)) - .expiredAt(member.expiredAt) + .expiredAt(expiredAt) .build() v2ManagerService.createRoleGroupMemberV2(groupId, managerMemberGroupDTO) } diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt index 0d4f512133c..6ea6821a5f4 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt @@ -50,6 +50,7 @@ import com.tencent.devops.project.api.service.ServiceProjectApprovalResource import com.tencent.devops.project.api.service.ServiceProjectResource import com.tencent.devops.project.api.service.ServiceProjectTagResource import com.tencent.devops.project.pojo.ProjectVO +import java.util.concurrent.CompletionException import org.jooq.DSLContext import org.slf4j.LoggerFactory import org.slf4j.MDC @@ -330,6 +331,7 @@ class RbacPermissionMigrateService constructor( watcher.start("migrateUserCustomPolicy") migrateV3PolicyService.migrateUserCustomPolicy( projectCode = projectCode, + projectName = projectName, version = version ) // 对比迁移结果 @@ -359,6 +361,7 @@ class RbacPermissionMigrateService constructor( watcher.start("migrateUserCustomPolicy") migrateV0PolicyService.migrateUserCustomPolicy( projectCode = projectCode, + projectName = projectName, version = version ) // 对比迁移结果 @@ -399,6 +402,9 @@ class RbacPermissionMigrateService constructor( is ErrorCodeException -> { exception.defaultMessage } + is CompletionException -> { + exception.cause?.message + } else -> { exception.toString() } diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyServiceTest.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyServiceTest.kt index 88fb6a17592..586f6b17d5b 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyServiceTest.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyServiceTest.kt @@ -38,6 +38,7 @@ import com.tencent.devops.auth.dao.AuthResourceGroupDao import com.tencent.devops.auth.pojo.migrate.MigrateTaskDataResult import com.tencent.devops.auth.service.AuthResourceCodeConverter import com.tencent.devops.auth.service.DeptService +import com.tencent.devops.auth.service.PermissionGroupPoliciesService import com.tencent.devops.auth.service.RbacCacheService import com.tencent.devops.auth.service.iam.PermissionService import com.tencent.devops.common.api.util.JsonUtil @@ -61,6 +62,7 @@ open class AbMigratePolicyServiceTest : BkCiAbstractTest() { val migrateResourceCodeConverter: MigrateResourceCodeConverter = mockk() val authResourceCodeConverter: AuthResourceCodeConverter = mockk() val deptService: DeptService = mockk() + val permissionGroupPoliciesService: PermissionGroupPoliciesService = mockk() @BeforeEach fun before() { diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyServiceTest.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyServiceTest.kt index 467ff492f5a..f538ed99f09 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyServiceTest.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyServiceTest.kt @@ -50,7 +50,8 @@ class MigrateV0PolicyServiceTest : AbMigratePolicyServiceTest() { permissionService = permissionService, rbacCacheService = rbacCacheService, authMigrationDao = authMigrationDao, - deptService = deptService + deptService = deptService, + permissionGroupPoliciesService = permissionGroupPoliciesService ), recordPrivateCalls = true ) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyServiceTest.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyServiceTest.kt index 08ad356ede9..2a9e5e215b3 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyServiceTest.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/test/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyServiceTest.kt @@ -56,7 +56,8 @@ class MigrateV3PolicyServiceTest : AbMigratePolicyServiceTest() { permissionService = permissionService, rbacCacheService = rbacCacheService, authMigrationDao = authMigrationDao, - deptService = deptService + deptService = deptService, + permissionGroupPoliciesService = permissionGroupPoliciesService ), recordPrivateCalls = true ) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupConfigDao.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupConfigDao.kt index aefe2567a2e..183c2f1e212 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupConfigDao.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupConfigDao.kt @@ -87,6 +87,17 @@ class AuthResourceGroupConfigDao { } } + fun getById( + dslContext: DSLContext, + id: Long + ): TAuthResourceGroupConfigRecord? { + return with(TAuthResourceGroupConfig.T_AUTH_RESOURCE_GROUP_CONFIG) { + dslContext.selectFrom(this) + .where(ID.eq(id)) + .fetchOne() + } + } + fun countByResourceType( dslContext: DSLContext, resourceType: String diff --git a/support-files/sql/5001_init_dml/5001_ci_auth-init_dml_mysql.sql b/support-files/sql/5001_init_dml/5001_ci_auth-init_dml_mysql.sql index efa5533ea28..ca58301ec50 100644 --- a/support-files/sql/5001_init_dml/5001_ci_auth-init_dml_mysql.sql +++ b/support-files/sql/5001_init_dml/5001_ci_auth-init_dml_mysql.sql @@ -177,4 +177,30 @@ REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `G REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(30, "codecc_task", "manager", "Owner", 0, 'task owner, who can manage the permissions of the current task', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_analyze\"},{\"id\":\"codecc_task_manage-defect\"},{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_setting\"},{\"id\":\"codecc_task_manage\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"},{\"system\":\"#system#\",\"type\":\"codecc_task\",\"id\":\"#resourceCode#\",\"name\":\"#resourceName#\"}]]}]}]', '[\"codecc_task_analyze\",\"codecc_task_manage-defect\",\"codecc_task_view-defect\",\"codecc_task_view-report\",\"codecc_task_setting\",\"codecc_task_manage\", \"codecc_task_list\"]'); REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(31, "codecc_task", "editor", "Editor", 0, 'task editor, who has all the permissions of the current task except permission management', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_analyze\"},{\"id\":\"codecc_task_manage-defect\"},{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_setting\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"},{\"system\":\"#system#\",\"type\":\"codecc_task\",\"id\":\"#resourceCode#\",\"name\":\"#resourceName#\"}]]}]}]', '[\"codecc_task_analyze\",\"codecc_task_manage-defect\",\"codecc_task_view-defect\",\"codecc_task_view-report\",\"codecc_task_setting\", \"codecc_task_list\"]'); REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(32, "codecc_task", "executor", "Executor", 0, 'task executors, who can view and execute the current task', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_analyze\"},{\"id\":\"codecc_task_manage-defect\"},{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"},{\"system\":\"#system#\",\"type\":\"codecc_task\",\"id\":\"#resourceCode#\",\"name\":\"#resourceName#\"}]]}]}]', '[\"codecc_task_analyze\",\"codecc_task_manage-defect\",\"codecc_task_view-defect\",\"codecc_task_view-report\", \"codecc_task_list\"]'); -REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(33, "codecc_task", "viewer", "Viewer", 0, 'task viewer, who can view the current task', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"},{\"system\":\"#system#\",\"type\":\"codecc_task\",\"id\":\"#resourceCode#\",\"name\":\"#resourceName#\"}]]}]}]', '[\"codecc_task_view-defect\",\"codecc_task_view-report\", \"codecc_task_list\"]'); \ No newline at end of file +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(33, "codecc_task", "viewer", "Viewer", 0, 'task viewer, who can view the current task', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"},{\"system\":\"#system#\",\"type\":\"codecc_task\",\"id\":\"#resourceCode#\",\"name\":\"#resourceName#\"}]]}]}]', '[\"codecc_task_view-defect\",\"codecc_task_view-report\", \"codecc_task_list\"]'); + +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(34, "project", "pipeline_manager", "Any-Pipeline-Owner", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_view\"},{\"id\":\"pipeline_edit\"},{\"id\":\"pipeline_delete\"},{\"id\":\"pipeline_execute\"},{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"},{\"id\":\"pipeline_manage\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"pipeline_view\",\"pipeline_edit\",\"pipeline_delete\",\"pipeline_execute\",\"pipeline_list\",\"pipeline_download\",\"pipeline_share\",\"pipeline_manage\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(35, "project", "pipeline_editor", "Any-Pipeline-Editor", 1, 'AMigrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_view\"},{\"id\":\"pipeline_edit\"},{\"id\":\"pipeline_execute\"},{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"pipeline_view\",\"pipeline_edit\",\"pipeline_execute\",\"pipeline_list\",\"pipeline_download\",\"pipeline_share\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(36, "project", "pipeline_executor", "Any-Pipeline-Executor", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_view\"},{\"id\":\"pipeline_execute\"},{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"pipeline_view\",\"pipeline_execute\",\"pipeline_list\",\"pipeline_download\",\"pipeline_share\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(37, "project", "pipeline_viewer", "Any-Pipeline-Viewer", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_view\"},{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"pipeline_view\",\"pipeline_list\",\"pipeline_download\",\"pipeline_share\"]'); + +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(38, "project", "credential_manager", "Any-Credential-Owner", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"credential_view\"},{\"id\":\"credential_edit\"},{\"id\":\"credential_delete\"},{\"id\":\"credential_list\"},{\"id\":\"credential_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"credential\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"credential_view\",\"credential_edit\",\"credential_delete\",\"credential_list\",\"credential_use\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(39, "project", "credential_user", "Any-Credential-User", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"credential_view\"},{\"id\":\"credential_list\"},{\"id\":\"credential_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"credential\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"credential_view\",\"credential_list\",\"credential_use\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(40, "project", "cert_manager", "Any-Cert-Owner", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"cert_view\"},{\"id\":\"cert_edit\"},{\"id\":\"cert_delete\"},{\"id\":\"cert_list\"},{\"id\":\"cert_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"cert\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"cert_view\",\"cert_edit\",\"cert_delete\",\"cert_list\",\"cert_use\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(41, "project", "cert_user", "Any-Cert-User", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"cert_view\"},{\"id\":\"cert_list\"},{\"id\":\"cert_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"cert\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"cert_view\",\"cert_list\",\"cert_use\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(42, "project", "repertory_manager", "Any-Repertory-Owner", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_view\"},{\"id\":\"repertory_edit\"},{\"id\":\"repertory_delete\"},{\"id\":\"repertory_list\"},{\"id\":\"repertory_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"repertory_view\",\"repertory_edit\",\"repertory_delete\",\"repertory_list\",\"repertory_use\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(43, "project", "repertory_user", "Any-Repertory-User", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_view\"},{\"id\":\"repertory_list\"},{\"id\":\"repertory_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"repertory_view\",\"repertory_list\",\"repertory_use\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(44, "project", "environment_manager", "Any-Environment-Owner", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"environment_view\"},{\"id\":\"environment_edit\"},{\"id\":\"environment_delete\"},{\"id\":\"environment_list\"},{\"id\":\"environment_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"environment\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"environment_view\",\"environment_edit\",\"environment_delete\",\"environment_list\",\"environment_use\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(45, "project", "environment_user", "Any-Environment-User", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"environment_view\"},{\"id\":\"environment_list\"},{\"id\":\"environment_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"environment\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"environment_view\",\"environment_list\",\"environment_use\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(46, "project", "env_node_manager", "Any-Env-Node-Owner", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"env_node_view\"},{\"id\":\"env_node_edit\"},{\"id\":\"env_node_delete\"},{\"id\":\"env_node_list\"},{\"id\":\"env_node_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"env_node\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"env_node_view\",\"env_node_edit\",\"env_node_delete\",\"env_node_list\",\"env_node_use\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(47, "project", "env_node_user", "Any-Env-Node-User", 1, 'Migrated to user-defined permissions' ,'[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"env_node_view\"},{\"id\":\"env_node_list\"},{\"id\":\"env_node_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"env_node\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"env_node_view\",\"env_node_list\",\"env_node_use\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(48, "project", "rule_manager", "Any-Rule-Owner", 1, 'Migrated to user-defined permissions' , '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_edit\"},{\"id\":\"rule_delete\"},{\"id\":\"rule_enable\"},{\"id\":\"rule_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"rule_edit\",\"rule_delete\",\"rule_enable\", \"rule_list\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(49, "project", "quality_group_manager", "Any-Quality-Group-Owner", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_edit\"},{\"id\":\"quality_group_delete\"},{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"quality_group_edit\",\"quality_group_delete\", \"quality_group_list\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(50, "project", "experience_task_manager", "Any-Experience-Task-Owner", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_task_view\"},{\"id\":\"experience_task_edit\"},{\"id\":\"experience_task_delete\"},{\"id\":\"experience_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"experience_task_view\",\"experience_task_edit\",\"experience_task_delete\",\"experience_task_list\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(51, "project", "experience_group_manager", "Any-Experience-Group-Owner", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_group_view\"},{\"id\":\"experience_group_edit\"},{\"id\":\"experience_group_delete\"},{\"id\":\"experience_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"experience_group_view\",\"experience_group_edit\",\"experience_group_delete\",\"experience_group_list\"]'); + +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(52, "project", "codecc_task_manager", "Any-Codecc-Task-Owner", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_analyze\"},{\"id\":\"codecc_task_manage-defect\"},{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_setting\"},{\"id\":\"codecc_task_manage\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"codecc_task_analyze\",\"codecc_task_manage-defect\",\"codecc_task_view-defect\",\"codecc_task_view-report\",\"codecc_task_setting\",\"codecc_task_manage\", \"codecc_task_list\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(53, "project", "codecc_task_editor", "Any-Codecc-Task-Editor", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_analyze\"},{\"id\":\"codecc_task_manage-defect\"},{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_setting\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"codecc_task_analyze\",\"codecc_task_manage-defect\",\"codecc_task_view-defect\",\"codecc_task_view-report\",\"codecc_task_setting\", \"codecc_task_list\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(54, "project", "codecc_task_executor", "Any-Codecc-Task-Executor", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_analyze\"},{\"id\":\"codecc_task_manage-defect\"},{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"codecc_task_analyze\",\"codecc_task_manage-defect\",\"codecc_task_view-defect\",\"codecc_task_view-report\", \"codecc_task_list\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(55, "project", "codecc_task_viewer", "Any-Codecc-Task-Viewer", 1, 'Migrated to user-defined permissions', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"codecc_task_view-defect\",\"codecc_task_view-report\", \"codecc_task_list\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(55, "project", "codecc_task_viewer", "Any-Codecc-Task-Viewer", 1, 'Any codecc task viewer, who can view any task', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"codecc_task_view-defect\",\"codecc_task_view-report\", \"codecc_task_list\"]'); \ No newline at end of file From ad1079e245c9e0f39f2f5c151718a8f507ea3957 Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Thu, 8 Jun 2023 21:18:52 +0800 Subject: [PATCH 032/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/service/RbacPermissionResourceGroupService.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionResourceGroupService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionResourceGroupService.kt index 10a0a27952c..6d626a50cf2 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionResourceGroupService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionResourceGroupService.kt @@ -336,7 +336,9 @@ class RbacPermissionResourceGroupService @Autowired constructor( v2PageInfoDTO.page = PageUtil.DEFAULT_PAGE val gradeManagerRoleGroupList = iamV2ManagerService.getGradeManagerRoleGroupV2(projectInfo.relationId, searchGroupDTO, v2PageInfoDTO) - if (gradeManagerRoleGroupList.results.isNotEmpty()) { + if (gradeManagerRoleGroupList.results.isNotEmpty() && + gradeManagerRoleGroupList.results.map { it.name }.contains(groupName) + ) { throw ErrorCodeException( errorCode = GROUP_EXIST, defaultMessage = "group name already exists" From 1851451386ec924e8af94181e288f2d3556bf709 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 8 Jun 2023 21:33:08 +0800 Subject: [PATCH 033/166] =?UTF-8?q?feat=EF=BC=9A=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E9=97=AE=E9=A2=98=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20#8955=20=E5=A2=9E=E5=8A=A0task=E8=A1=A8post=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pipeline/record/BuildRecordContainer.kt | 3 +- .../pojo/pipeline/record/BuildRecordTask.kt | 3 ++ .../process/dao/record/BuildRecordTaskDao.kt | 27 ++++++++++++------ .../service/PipelineContainerService.kt | 4 ++- .../engine/service/PipelineRuntimeService.kt | 3 +- .../sql/1001_ci_process_ddl_mysql.sql | 1 + .../2020_ci_process-update_v2.0_mysql.sql | 28 +++++++++++++++++++ 7 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 support-files/sql/2003_v2.x/2020_ci_process-update_v2.0_mysql.sql diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordContainer.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordContainer.kt index cda8887e009..0e83caed429 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordContainer.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordContainer.kt @@ -134,7 +134,8 @@ data class BuildRecordContainer( taskSeq = index, status = buildStatus?.name, taskVar = mutableMapOf(), - timestamps = mapOf() + timestamps = mapOf(), + elementPostInfo = element.additionalOptions?.elementPostInfo ) ) } diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt index b5acb79c962..3a895351397 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt @@ -28,6 +28,7 @@ package com.tencent.devops.process.pojo.pipeline.record import com.tencent.devops.common.pipeline.enums.BuildRecordTimeStamp +import com.tencent.devops.common.pipeline.pojo.element.ElementPostInfo import com.tencent.devops.common.pipeline.pojo.time.BuildTimestampType import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -55,6 +56,8 @@ data class BuildRecordTask( val executeCount: Int, @ApiModelProperty("执行变量", required = true) var taskVar: MutableMap, + @ApiModelProperty("插件post信息", required = false) + val elementPostInfo: ElementPostInfo?, @ApiModelProperty("插件类型标识", required = true) val classType: String, @ApiModelProperty("市场插件标识", required = true) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt index 492601d95b4..59898dee274 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt @@ -31,6 +31,7 @@ import com.fasterxml.jackson.core.type.TypeReference import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.pipeline.enums.BuildRecordTimeStamp import com.tencent.devops.common.pipeline.enums.BuildStatus +import com.tencent.devops.common.pipeline.pojo.element.ElementPostInfo import com.tencent.devops.common.pipeline.pojo.time.BuildTimestampType import com.tencent.devops.model.process.tables.TPipelineBuildRecordTask import com.tencent.devops.model.process.tables.records.TPipelineBuildRecordTaskRecord @@ -39,7 +40,7 @@ import com.tencent.devops.process.pojo.KEY_TASK_ID import com.tencent.devops.process.pojo.pipeline.record.BuildRecordTask import org.jooq.Condition import org.jooq.DSLContext -import org.jooq.Record17 +import org.jooq.Record18 import org.jooq.RecordMapper import org.jooq.impl.DSL import org.jooq.util.mysql.MySQLDSL @@ -69,7 +70,8 @@ class BuildRecordTaskDao { STATUS, TASK_SEQ, ATOM_CODE, - TIMESTAMPS + TIMESTAMPS, + POST_INFO ).also { insert -> records.forEach { record -> insert.values( @@ -87,7 +89,8 @@ class BuildRecordTaskDao { record.status, record.taskSeq, record.atomCode, - JsonUtil.toJson(record.timestamps, false) + JsonUtil.toJson(record.timestamps, false), + record.elementPostInfo?.let { JsonUtil.toJson(it, false) } ) } }.onDuplicateKeyUpdate() @@ -200,7 +203,7 @@ class BuildRecordTaskDao { val result = dslContext.select( BUILD_ID, PROJECT_ID, PIPELINE_ID, RESOURCE_VERSION, STAGE_ID, CONTAINER_ID, TASK_ID, TASK_SEQ, EXECUTE_COUNT, TASK_VAR, CLASS_TYPE, ATOM_CODE, STATUS, ORIGIN_CLASS_TYPE, - START_TIME, END_TIME, TIMESTAMPS + START_TIME, END_TIME, TIMESTAMPS, POST_INFO ).from(this).join(max).on( TASK_ID.eq(max.field(KEY_TASK_ID, String::class.java)) .and(EXECUTE_COUNT.eq(max.field(KEY_EXECUTE_COUNT, Int::class.java))) @@ -227,7 +230,7 @@ class BuildRecordTaskDao { val result = dslContext.select( BUILD_ID, PROJECT_ID, PIPELINE_ID, RESOURCE_VERSION, STAGE_ID, CONTAINER_ID, TASK_ID, TASK_SEQ, EXECUTE_COUNT, TASK_VAR, CLASS_TYPE, ATOM_CODE, STATUS, ORIGIN_CLASS_TYPE, - START_TIME, END_TIME, TIMESTAMPS + START_TIME, END_TIME, TIMESTAMPS, POST_INFO ).from(this).where(conditions).orderBy(TASK_SEQ.asc()).fetch() return result.map { record -> generateBuildRecordTask(record) @@ -236,8 +239,8 @@ class BuildRecordTaskDao { } private fun TPipelineBuildRecordTask.generateBuildRecordTask( - record: Record17 + record: Record18 ) = BuildRecordTask( buildId = record[BUILD_ID], @@ -260,7 +263,10 @@ class BuildRecordTaskDao { endTime = record[END_TIME], timestamps = record[TIMESTAMPS]?.let { JsonUtil.to(it, object : TypeReference>() {}) - } ?: mapOf() + } ?: mapOf(), + elementPostInfo = record[POST_INFO]?.let { + JsonUtil.to(it, object : TypeReference() {}) + } ) fun getRecord( @@ -305,7 +311,10 @@ class BuildRecordTaskDao { endTime = endTime, timestamps = timestamps?.let { JsonUtil.to(it, object : TypeReference>() {}) - } ?: mapOf() + } ?: mapOf(), + elementPostInfo = postInfo?.let { + JsonUtil.to(it, object : TypeReference() {}) + } ) } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineContainerService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineContainerService.kt index 9e0b04819f2..2902addec50 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineContainerService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineContainerService.kt @@ -337,6 +337,7 @@ class PipelineContainerService @Autowired constructor( originClassType = atomElement.getClassType(), resourceVersion = resourceVersion, timestamps = mapOf(), + elementPostInfo = atomElement.additionalOptions?.elementPostInfo, // 对矩阵产生的插件特殊表示类型 taskVar = mutableMapOf( "@type" to MatrixStatusElement.classType, @@ -433,7 +434,8 @@ class PipelineContainerService @Autowired constructor( taskId = atomElement.id!!, classType = atomElement.getClassType(), atomCode = atomElement.getTaskAtom(), executeCount = context.executeCount, resourceVersion = context.resourceVersion, taskSeq = taskSeq, status = status.name, - taskVar = mutableMapOf(), timestamps = mapOf() + taskVar = mutableMapOf(), timestamps = mapOf(), + elementPostInfo = atomElement.additionalOptions?.elementPostInfo ) ) return@nextElement diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt index 624fadbc929..1e7cc6e8570 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt @@ -1129,7 +1129,8 @@ class PipelineRuntimeService @Autowired constructor( stageId = it.stageId, containerId = it.containerId, taskSeq = it.taskSeq, taskId = it.taskId, classType = it.taskType, atomCode = it.atomCode ?: it.taskAtom, executeCount = it.executeCount ?: 1, resourceVersion = resourceVersion, - taskVar = mutableMapOf(), timestamps = mapOf() + taskVar = mutableMapOf(), timestamps = mapOf(), + elementPostInfo = it.additionalOptions?.elementPostInfo ) ) } diff --git a/support-files/sql/1001_ci_process_ddl_mysql.sql b/support-files/sql/1001_ci_process_ddl_mysql.sql index 749a4785674..263b9fa264a 100644 --- a/support-files/sql/1001_ci_process_ddl_mysql.sql +++ b/support-files/sql/1001_ci_process_ddl_mysql.sql @@ -1159,6 +1159,7 @@ CREATE TABLE IF NOT EXISTS `T_PIPELINE_BUILD_RECORD_TASK` ( `EXECUTE_COUNT` int(11) NOT NULL DEFAULT '1' COMMENT '执行次数', `STATUS` varchar(32) DEFAULT NULL COMMENT '构建状态', `TASK_VAR` mediumtext NOT NULL COMMENT '当次执行的变量记录', + `POST_INFO` text DEFAULT NULL COMMENT '市场插件的POST关联信息', `CLASS_TYPE` varchar(64) NOT NULL DEFAULT '' COMMENT '项目ID', `ATOM_CODE` varchar(128) NOT NULL DEFAULT '' COMMENT '插件的唯一标识', `ORIGIN_CLASS_TYPE` varchar(64) DEFAULT NULL COMMENT '所在矩阵组ID', diff --git a/support-files/sql/2003_v2.x/2020_ci_process-update_v2.0_mysql.sql b/support-files/sql/2003_v2.x/2020_ci_process-update_v2.0_mysql.sql new file mode 100644 index 00000000000..2f083e64962 --- /dev/null +++ b/support-files/sql/2003_v2.x/2020_ci_process-update_v2.0_mysql.sql @@ -0,0 +1,28 @@ +USE devops_ci_process; +SET NAMES utf8mb4; + +DROP PROCEDURE IF EXISTS ci_process_schema_update; + +DELIMITER + +CREATE PROCEDURE ci_process_schema_update() +BEGIN + + DECLARE db VARCHAR(100); + SET AUTOCOMMIT = 0; + SELECT DATABASE() INTO db; + + IF NOT EXISTS(SELECT 1 + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'T_PIPELINE_BUILD_RECORD_TASK' + AND COLUMN_NAME = 'POST_INFO') THEN + ALTER TABLE `T_PIPELINE_BUILD_RECORD_TASK` + ADD COLUMN `POST_INFO` text DEFAULT NULL COMMENT '市场插件的POST关联信息'; + END IF; + + COMMIT; +END +DELIMITER ; +COMMIT; +CALL ci_process_schema_update(); From 74027dafc30e6d961f268ae12cb64c4b3259f9dc Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Thu, 8 Jun 2023 22:10:11 +0800 Subject: [PATCH 034/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/migrate/AbMigratePolicyService.kt | 23 +++++++++++-------- .../service/migrate/MigrateV0PolicyService.kt | 4 ++-- .../service/migrate/MigrateV3PolicyService.kt | 6 ++--- .../migrate/RbacPermissionMigrateService.kt | 6 +++-- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt index 7ac651b9bbc..dca3c55f710 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt @@ -251,7 +251,12 @@ abstract class AbMigratePolicyService( abstract fun getGroupName(projectName: String, result: MigrateTaskDataResult): String - fun migrateUserCustomPolicy(projectCode: String, projectName: String, version: String) { + fun migrateUserCustomPolicy( + projectCode: String, + projectName: String, + version: String, + gradeManagerId: Int + ) { logger.info("start to migrate user custom policy|$projectCode") val startEpoch = System.currentTimeMillis() try { @@ -269,7 +274,7 @@ abstract class AbMigratePolicyService( loopMigrateUserCustom( projectCode = projectCode, projectName = projectName, - managerGroupId = managerGroupId, + gradeManagerId = gradeManagerId, version = version ) } finally { @@ -282,7 +287,7 @@ abstract class AbMigratePolicyService( private fun loopMigrateUserCustom( projectCode: String, projectName: String, - managerGroupId: Int, + gradeManagerId: Int, version: String ): Int { var page = 1 @@ -299,7 +304,7 @@ abstract class AbMigratePolicyService( migrateUserCustom( projectCode = projectCode, projectName = projectName, - managerGroupId = managerGroupId, + gradeManagerId = gradeManagerId, results = taskDataResp.results ) page++ @@ -311,7 +316,7 @@ abstract class AbMigratePolicyService( private fun migrateUserCustom( projectCode: String, projectName: String, - managerGroupId: Int, + gradeManagerId: Int, results: List ) { results.forEach { result -> @@ -328,7 +333,7 @@ abstract class AbMigratePolicyService( userId = userId, projectCode = projectCode, projectName = projectName, - managerGroupId = managerGroupId, + gradeManagerId = gradeManagerId, permission = permission ) if (groupId != null) { @@ -348,7 +353,7 @@ abstract class AbMigratePolicyService( userId: String, projectCode: String, projectName: String, - managerGroupId: Int, + gradeManagerId: Int, permission: AuthorizationScopes ): Int? @@ -399,7 +404,7 @@ abstract class AbMigratePolicyService( projectCode: String, projectName: String, actions: List, - managerGroupId: Int + gradeManagerId: Int ): Int? { val (groupConfigId, groupId) = getMatchResourceGroupId( resourceType = AuthResourceType.PROJECT.value, @@ -412,7 +417,7 @@ abstract class AbMigratePolicyService( groupConfigId?.let { createProjectResourceGroup( groupConfigId = groupConfigId, - gradeManagerId = managerGroupId, + gradeManagerId = gradeManagerId, projectCode = projectCode, projectName = projectName ) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt index 1a3fdccd1da..d3fb6e67b7b 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt @@ -286,7 +286,7 @@ class MigrateV0PolicyService constructor( userId: String, projectCode: String, projectName: String, - managerGroupId: Int, + gradeManagerId: Int, permission: AuthorizationScopes ): Int? { val resource = permission.resources[0] @@ -301,7 +301,7 @@ class MigrateV0PolicyService constructor( projectCode = projectCode, projectName = projectName, actions = finalUserActions, - managerGroupId = managerGroupId + gradeManagerId = gradeManagerId ) } else { val v0ResourceCode = resource.paths[0][0].id diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt index ef880cfe0f5..115ea2d60a9 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt @@ -244,7 +244,7 @@ class MigrateV3PolicyService constructor( userId: String, projectCode: String, projectName: String, - managerGroupId: Int, + gradeManagerId: Int, permission: AuthorizationScopes ): Int? { // v3资源都只有一层 @@ -258,7 +258,7 @@ class MigrateV3PolicyService constructor( } return when { // 如果有all_action,直接加入管理员组 - userActions.contains(Constants.ALL_ACTION) -> managerGroupId + userActions.contains(Constants.ALL_ACTION) -> gradeManagerId // 项目类型 resource.type == AuthResourceType.PROJECT.value -> v3MatchMinResourceGroup( @@ -276,7 +276,7 @@ class MigrateV3PolicyService constructor( projectCode = projectCode, projectName = projectName, actions = finalUserActions, - managerGroupId = managerGroupId + gradeManagerId = gradeManagerId ) } // 具体资源权限 diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt index 6ea6821a5f4..0490b0a58d3 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt @@ -332,7 +332,8 @@ class RbacPermissionMigrateService constructor( migrateV3PolicyService.migrateUserCustomPolicy( projectCode = projectCode, projectName = projectName, - version = version + version = version, + gradeManagerId = gradeManagerId ) // 对比迁移结果 watcher.start("comparePolicy") @@ -362,7 +363,8 @@ class RbacPermissionMigrateService constructor( migrateV0PolicyService.migrateUserCustomPolicy( projectCode = projectCode, projectName = projectName, - version = version + version = version, + gradeManagerId = gradeManagerId ) // 对比迁移结果 watcher.start("comparePolicy") From 6ac322b348ef33820cfe5396c120a8a754582dd6 Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Thu, 8 Jun 2023 22:52:20 +0800 Subject: [PATCH 035/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/service/migrate/AbMigratePolicyService.kt | 2 -- .../devops/auth/service/migrate/MigrateV0PolicyService.kt | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt index dca3c55f710..ae7cc10682b 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt @@ -451,7 +451,6 @@ abstract class AbMigratePolicyService( return Pair(null, null) } - private fun createRbacGroup( groupName: String, gradeManagerId: Int, @@ -493,7 +492,6 @@ abstract class AbMigratePolicyService( return groupId } - /** * 创建项目级资源用户组 * diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt index d3fb6e67b7b..51282be64cd 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt @@ -368,7 +368,7 @@ class MigrateV0PolicyService constructor( // 自定义用户组,半年或者一年过期 V0_GROUP_EXPIRED_DAY[RandomUtils.nextInt(0, 1)] } - val expiredAt= System.currentTimeMillis() / MILLISECOND + TimeUnit.DAYS.toSeconds(expiredDay) + val expiredAt = System.currentTimeMillis() / MILLISECOND + TimeUnit.DAYS.toSeconds(expiredDay) members?.forEach member@{ member -> val managerMember = ManagerMember(member.type, member.id) val managerMemberGroupDTO = ManagerMemberGroupDTO.builder() From 91444ed09c8b34c8247d65a2088a08187f0aa812 Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Fri, 9 Jun 2023 10:53:19 +0800 Subject: [PATCH 036/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/service/RbacPermissionService.kt | 11 +++-- .../service/migrate/AbMigratePolicyService.kt | 46 ++++++++++++------- .../service/migrate/MigrateV0PolicyService.kt | 1 + .../service/migrate/MigrateV3PolicyService.kt | 1 + 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt index 3443aa48c31..cf3796c56f9 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt @@ -76,6 +76,9 @@ class RbacPermissionService constructor( } } + /** + * 如果没有具体资源,则校验是否有项目下任意资源权限 + */ override fun validateUserResourcePermission( userId: String, action: String, @@ -86,8 +89,8 @@ class RbacPermissionService constructor( userId = userId, action = action, projectCode = projectCode, - resourceType = AuthResourceType.PROJECT.value, - resourceCode = projectCode, + resourceType = resourceType!!, + resourceCode = "*", relationResourceType = null ) } @@ -102,8 +105,8 @@ class RbacPermissionService constructor( ): Boolean { val resource = if (resourceType == AuthResourceType.PROJECT.value) { AuthResourceInstance( - resourceType = resourceType, - resourceCode = resourceCode + resourceType = AuthResourceType.PROJECT.value, + resourceCode = projectCode ) } else { val projectResourceInstance = AuthResourceInstance( diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt index ae7cc10682b..98ccbacfc77 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt @@ -367,6 +367,7 @@ abstract class AbMigratePolicyService( resourceCode: String, actions: List ): Int? { + // 判断用户是否已有资源actions权限 val hasPermission = permissionService.batchValidateUserResourcePermission( userId = userId, actions = actions, @@ -374,24 +375,21 @@ abstract class AbMigratePolicyService( resourceCode = resourceCode, resourceType = resourceType ).all { it.value } - // 没有action的权限,匹配资源默认用户组权限 - if (!hasPermission) { - return getMatchResourceGroupId( - resourceType = resourceType, - actions = actions, - projectCode = projectCode, - resourceCode = resourceCode, - userId = userId - ).second ?: run { - logger.info("user not match resource group|$userId|$actions$projectCode|$resourceCode") - null - } - } else { - logger.info( - "user has resource action permission|$userId|$resourceCode|$actions$projectCode|$resourceCode" - ) + + if (hasPermission) { + logger.info("user has resource action permission|$userId|$actions$projectCode|$resourceCode") + return null + } + return getMatchResourceGroupId( + resourceType = resourceType, + actions = actions, + projectCode = projectCode, + resourceCode = resourceCode, + userId = userId + ).second ?: run { + logger.info("user not match resource group|$userId|$actions$projectCode|$resourceCode") + null } - return null } /** @@ -403,9 +401,23 @@ abstract class AbMigratePolicyService( userId: String, projectCode: String, projectName: String, + resourceType: String, actions: List, gradeManagerId: Int ): Int? { + // 判断用户是否已有项目任意资源actions权限 + val hasPermission = actions.all { action -> + permissionService.validateUserResourcePermission( + userId = userId, + action = action, + projectCode = projectCode, + resourceType = resourceType + ) + } + if (hasPermission) { + logger.info("user has project any resource permission|$userId|$actions$projectCode") + return null + } val (groupConfigId, groupId) = getMatchResourceGroupId( resourceType = AuthResourceType.PROJECT.value, actions = actions, diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt index 51282be64cd..38d3f73a302 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt @@ -300,6 +300,7 @@ class MigrateV0PolicyService constructor( userId = userId, projectCode = projectCode, projectName = projectName, + resourceType = resourceType, actions = finalUserActions, gradeManagerId = gradeManagerId ) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt index 115ea2d60a9..43e474b1ebf 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt @@ -275,6 +275,7 @@ class MigrateV3PolicyService constructor( userId = userId, projectCode = projectCode, projectName = projectName, + resourceType = resourceType, actions = finalUserActions, gradeManagerId = gradeManagerId ) From 926b895e7d8ba3d418c06397ef63089ed248fc9f Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 9 Jun 2023 11:04:57 +0800 Subject: [PATCH 037/166] =?UTF-8?q?feat=EF=BC=9A=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E9=97=AE=E9=A2=98=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20#8955=20=E8=A1=A5=E5=85=85websocket=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/pojo/pipeline/record/BuildRecordTask.kt | 2 +- .../engine/service/PipelineBuildQualityService.kt | 2 +- .../process/engine/service/PipelineRuntimeService.kt | 11 ++++++++--- .../engine/service/detail/BaseBuildDetailService.kt | 2 +- .../websocket/service/PipelineWebsocketService.kt | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt index 3a895351397..bf3b02c0870 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt @@ -57,7 +57,7 @@ data class BuildRecordTask( @ApiModelProperty("执行变量", required = true) var taskVar: MutableMap, @ApiModelProperty("插件post信息", required = false) - val elementPostInfo: ElementPostInfo?, + val elementPostInfo: ElementPostInfo? = null, @ApiModelProperty("插件类型标识", required = true) val classType: String, @ApiModelProperty("市场插件标识", required = true) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineBuildQualityService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineBuildQualityService.kt index 0cb33385585..9654cbe8083 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineBuildQualityService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineBuildQualityService.kt @@ -457,7 +457,7 @@ class PipelineBuildQualityService( pipelineId = task.pipelineId, userId = task.starter, buildId = task.buildId, - refreshTypes = RefreshType.DETAIL.binary + refreshTypes = RefreshType.DETAIL.binary or RefreshType.RECORD.binary ) ) return AtomResponse(BuildStatus.RUNNING) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt index 1e7cc6e8570..4b3e0041a7c 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt @@ -1315,7 +1315,7 @@ class PipelineRuntimeService @Autowired constructor( userId = userId, buildId = buildId, // 刷新历史列表和详情页面 - refreshTypes = RefreshType.DETAIL.binary + refreshTypes = RefreshType.DETAIL.binary or RefreshType.RECORD.binary ), // 广播构建排队事件 PipelineBuildQueueBroadCastEvent( source = "startQueue", @@ -1568,7 +1568,10 @@ class PipelineRuntimeService @Autowired constructor( userId = latestRunningBuild.userId, buildId = latestRunningBuild.buildId, // 刷新历史列表、详情、状态页面 - refreshTypes = RefreshType.HISTORY.binary or RefreshType.DETAIL.binary or RefreshType.STATUS.binary + refreshTypes = RefreshType.HISTORY.binary or + RefreshType.DETAIL.binary or + RefreshType.STATUS.binary or + RefreshType.RECORD.binary ) ) @@ -1634,7 +1637,9 @@ class PipelineRuntimeService @Autowired constructor( buildId = buildId, // 刷新详情、状态页面 // #3400 在BuildEnd处会有HISTORY,历史列表此处不需要,减少负载 - refreshTypes = RefreshType.DETAIL.binary or RefreshType.STATUS.binary + refreshTypes = RefreshType.DETAIL.binary or + RefreshType.STATUS.binary or + RefreshType.RECORD.binary ) ) logger.info("[$pipelineId]|finishLatestRunningBuild-$buildId|status=$status") diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/detail/BaseBuildDetailService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/detail/BaseBuildDetailService.kt index 44472f1e843..31d2e367b79 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/detail/BaseBuildDetailService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/detail/BaseBuildDetailService.kt @@ -253,7 +253,7 @@ open class BaseBuildDetailService constructor( pipelineId = pipelineBuildInfo.pipelineId, userId = pipelineBuildInfo.startUser, buildId = buildId, - refreshTypes = RefreshType.DETAIL.binary + refreshTypes = RefreshType.DETAIL.binary or RefreshType.RECORD.binary ) ) } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/websocket/service/PipelineWebsocketService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/websocket/service/PipelineWebsocketService.kt index 86dc850705e..169d36d7bcf 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/websocket/service/PipelineWebsocketService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/websocket/service/PipelineWebsocketService.kt @@ -176,7 +176,7 @@ class PipelineWebsocketService @Autowired constructor( executeCount = executeCount ) ) - logger.debug("status websocket: page[$page], buildId:[$buildId],pipelineId:[$pipelineId],project:[$projectId]") + logger.debug("record websocket: page[$page], buildId:[$buildId],pipelineId:[$pipelineId],project:[$projectId]") return RecordWebsocketPush( buildId = buildId, projectId = projectId, From 166390e4e537b725d47e68c8d3becc9d547fdb48 Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Fri, 9 Jun 2023 11:53:56 +0800 Subject: [PATCH 038/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/service/migrate/AbMigratePolicyService.kt | 6 ++++++ .../devops/auth/service/migrate/MigrateV0PolicyService.kt | 1 + .../devops/auth/service/migrate/MigrateV3PolicyService.kt | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt index 98ccbacfc77..008b70684f1 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt @@ -275,6 +275,7 @@ abstract class AbMigratePolicyService( projectCode = projectCode, projectName = projectName, gradeManagerId = gradeManagerId, + managerGroupId = managerGroupId, version = version ) } finally { @@ -288,6 +289,7 @@ abstract class AbMigratePolicyService( projectCode: String, projectName: String, gradeManagerId: Int, + managerGroupId: Int, version: String ): Int { var page = 1 @@ -305,6 +307,7 @@ abstract class AbMigratePolicyService( projectCode = projectCode, projectName = projectName, gradeManagerId = gradeManagerId, + managerGroupId = managerGroupId, results = taskDataResp.results ) page++ @@ -317,6 +320,7 @@ abstract class AbMigratePolicyService( projectCode: String, projectName: String, gradeManagerId: Int, + managerGroupId: Int, results: List ) { results.forEach { result -> @@ -334,6 +338,7 @@ abstract class AbMigratePolicyService( projectCode = projectCode, projectName = projectName, gradeManagerId = gradeManagerId, + managerGroupId = managerGroupId, permission = permission ) if (groupId != null) { @@ -354,6 +359,7 @@ abstract class AbMigratePolicyService( projectCode: String, projectName: String, gradeManagerId: Int, + managerGroupId: Int, permission: AuthorizationScopes ): Int? diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt index 38d3f73a302..278052c08b8 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt @@ -287,6 +287,7 @@ class MigrateV0PolicyService constructor( projectCode: String, projectName: String, gradeManagerId: Int, + managerGroupId: Int, permission: AuthorizationScopes ): Int? { val resource = permission.resources[0] diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt index 43e474b1ebf..fac3fa3558a 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt @@ -245,6 +245,7 @@ class MigrateV3PolicyService constructor( projectCode: String, projectName: String, gradeManagerId: Int, + managerGroupId: Int, permission: AuthorizationScopes ): Int? { // v3资源都只有一层 @@ -258,7 +259,7 @@ class MigrateV3PolicyService constructor( } return when { // 如果有all_action,直接加入管理员组 - userActions.contains(Constants.ALL_ACTION) -> gradeManagerId + userActions.contains(Constants.ALL_ACTION) -> managerGroupId // 项目类型 resource.type == AuthResourceType.PROJECT.value -> v3MatchMinResourceGroup( From 89de0d56045a70cec6199803715bcca2ef49283a Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Fri, 9 Jun 2023 12:27:33 +0800 Subject: [PATCH 039/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/service/migrate/AbMigratePolicyService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt index 008b70684f1..7d2c392a000 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt @@ -421,7 +421,7 @@ abstract class AbMigratePolicyService( ) } if (hasPermission) { - logger.info("user has project any resource permission|$userId|$actions$projectCode") + logger.info("user has project any resource permission|$userId|$actions|$projectCode") return null } val (groupConfigId, groupId) = getMatchResourceGroupId( From 5c0fe0657a09a1d6a3d75bbc0fb784a40af67d5e Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Fri, 9 Jun 2023 14:49:59 +0800 Subject: [PATCH 040/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/service/migrate/AbMigratePolicyService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt index 7d2c392a000..8981b902926 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt @@ -328,7 +328,7 @@ abstract class AbMigratePolicyService( val userId = result.subject.id // 离职人员,直接忽略 if (deptService.getUserInfo(userId = "admin", name = userId) == null) { - logger.warn("user has left, skip custom policy migration|${result.projectId}|$userId") + logger.warn("user has resigned, skip custom policy migration|${result.projectId}|$userId") return@forEach } From 41af68237d9495b578e323965ca07964e50ae328 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Fri, 9 Jun 2023 15:26:15 +0800 Subject: [PATCH 041/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/pojo/vo/GroupPermissionDetailVo.kt | 1 + .../service/PermissionGradeManagerService.kt | 52 +++---------------- .../devops/auth/cron/AuthCronManager.kt | 12 ++--- .../quality/service/v2/QualityRuleService.kt | 2 +- .../2020_ci_notify-update_v2.0_mysql.sql | 5 +- 5 files changed, 18 insertions(+), 54 deletions(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt index 1b4a349422d..50ad5f3c75f 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt @@ -13,5 +13,6 @@ data class GroupPermissionDetailVo( @BkFieldI18n(convertName = "actionName") val name: String, @ApiModelProperty("关联资源") + @BkFieldI18n val relatedResourceInfo: RelatedResourceInfo ) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt index 95c19d26aa0..72d9a7c68c2 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt @@ -46,8 +46,6 @@ import com.tencent.bk.sdk.iam.dto.manager.dto.ManagerRoleGroupDTO import com.tencent.bk.sdk.iam.dto.manager.dto.SearchGroupDTO import com.tencent.bk.sdk.iam.dto.manager.dto.UpdateManagerDTO import com.tencent.bk.sdk.iam.service.v2.V2ManagerService -import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX -import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX import com.tencent.devops.auth.constant.AuthI18nConstants.BK_AUTH_SECRECY import com.tencent.devops.auth.constant.AuthI18nConstants.BK_CREATE_BKCI_PROJECT_APPLICATION import com.tencent.devops.auth.constant.AuthI18nConstants.BK_CREATE_PROJECT_APPROVAL @@ -144,11 +142,7 @@ class PermissionGradeManagerService @Autowired constructor( defaultMessage = "${resourceType}_${DefaultGroupType.MANAGER.value} group config not exist" ) - val description = I18nUtil.getCodeLanMessage( - messageCode = "${manageGroupConfig.resourceType}.${manageGroupConfig.groupCode}" + - AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX, - defaultMessage = manageGroupConfig.description - ) + val description = manageGroupConfig.description val authorizationScopes = permissionGroupPoliciesService.buildAuthorizationScopes( authorizationScopesStr = manageGroupConfig.authorizationScopes, projectCode = projectCode, @@ -172,13 +166,7 @@ class PermissionGradeManagerService @Autowired constructor( .authorization_scopes(authorizationScopes) .subject_scopes(subjectScopes) .sync_perm(true) - .groupName( - I18nUtil.getCodeLanMessage( - messageCode = "${manageGroupConfig.resourceType}.${manageGroupConfig.groupCode}" + - AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX, - defaultMessage = manageGroupConfig.description - ) - ) + .groupName(manageGroupConfig.groupName) .build() logger.info("create grade manager|$name|$userId") val gradeManagerId = iamV2ManagerService.createManagerV2(createManagerDTO) @@ -208,13 +196,7 @@ class PermissionGradeManagerService @Autowired constructor( .authorizationScopes(authorizationScopes) .subjectScopes(subjectScopes) .syncPerm(true) - .groupName( - I18nUtil.getCodeLanMessage( - messageCode = "${manageGroupConfig.resourceType}.${manageGroupConfig.groupCode}" + - ".authResourceGroupConfig.groupName", - defaultMessage = manageGroupConfig.groupName - ) - ) + .groupName(manageGroupConfig.groupName) .applicant(userId) .reason( IamGroupUtils.buildItsmDefaultReason( @@ -299,13 +281,7 @@ class PermissionGradeManagerService @Autowired constructor( .authorizationScopes(authorizationScopes) .subjectScopes(subjectScopes) .syncPerm(true) - .groupName( - I18nUtil.getCodeLanMessage( - messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - ".authResourceGroupConfig.groupName", - defaultMessage = groupConfig.groupName - ) - ) + .groupName(groupConfig.groupName) .build() logger.info("update grade manager|$name|${gradeManagerDetail.members}") iamV2ManagerService.updateManagerV2(gradeManagerId, updateManagerDTO) @@ -334,13 +310,7 @@ class PermissionGradeManagerService @Autowired constructor( .authorizationScopes(authorizationScopes) .subjectScopes(subjectScopes) .syncPerm(true) - .groupName( - I18nUtil.getCodeLanMessage( - messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - ".authResourceGroupConfig.groupName", - defaultMessage = groupConfig.groupName - ) - ) + .groupName(groupConfig.groupName) .applicant(projectApprovalInfo.updator) .members(gradeManagerDetail.members) .reason( @@ -402,16 +372,8 @@ class PermissionGradeManagerService @Autowired constructor( if (resourceGroupInfo != null) { return@forEach } - val name = I18nUtil.getCodeLanMessage( - messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - ".authResourceGroupConfig.groupName", - defaultMessage = groupConfig.groupName - ) - val description = I18nUtil.getCodeLanMessage( - messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - ".authResourceGroupConfig.description", - defaultMessage = groupConfig.description - ) + val name = groupConfig.groupName + val description = groupConfig.description val managerRoleGroup = ManagerRoleGroup(name, description, false) val managerRoleGroupDTO = ManagerRoleGroupDTO.builder().groups(listOf(managerRoleGroup)).build() val iamGroupId = iamV2ManagerService.batchCreateRoleGroupV2(gradeManagerId, managerRoleGroupDTO) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt index 699c6ec7e68..b159d70a10c 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt @@ -139,8 +139,8 @@ class AuthCronManager @Autowired constructor( private fun updateAuthActionI18n() { val redisLock = RedisLock(redisOperation, AUTH_ACTION_UPDATE_LOCK, expiredTimeInSeconds) - if (redisLock.tryLock()) { - Executors.newFixedThreadPool(1).submit { + Executors.newFixedThreadPool(1).submit { + if (redisLock.tryLock()) { try { logger.info("start init auth Action I18n") val authActionI18nMap = mutableMapOf() @@ -174,8 +174,8 @@ class AuthCronManager @Autowired constructor( private fun updateAuthResourceTypeI18n() { val redisLock = RedisLock(redisOperation, AUTH_RESOURCE_TYPE_UPDATE_LOCK, expiredTimeInSeconds) - if (redisLock.tryLock()) { - Executors.newFixedThreadPool(1).submit { + Executors.newFixedThreadPool(1).submit { + if (redisLock.tryLock()) { try { logger.info("start init auth resource type I18n") var page = PageUtil.DEFAULT_PAGE @@ -215,8 +215,8 @@ class AuthCronManager @Autowired constructor( private fun updateAuthResourceGroupConfigI18n() { val redisLock = RedisLock(redisOperation, AUTH_RESOURCE_TYPE_GROUP_CONFIG_LOCK, expiredTimeInSeconds) - if (redisLock.tryLock()) { - Executors.newFixedThreadPool(1).submit { + Executors.newFixedThreadPool(1).submit { + if (redisLock.tryLock()) { try { logger.info("start init auth resource group config type I18n") val authAuthResourceGroupConfigs = mutableListOf() diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityRuleService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityRuleService.kt index 7e8600163b3..fc578554f6c 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityRuleService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityRuleService.kt @@ -199,7 +199,7 @@ class QualityRuleService @Autowired constructor( fun userUpdateEnable(userId: String, projectId: String, ruleHashId: String, enable: Boolean) { val ruleId = HashUtil.decodeIdToLong(ruleHashId) - val permission = AuthPermission.EXECUTE + val permission = AuthPermission.ENABLE logger.info("user($userId) update the rule($ruleId) in project($projectId) to $enable") qualityPermissionService.validateRulePermission( userId = userId, diff --git a/support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql b/support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql index b7c16e8fa33..0de71002283 100644 --- a/support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql +++ b/support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql @@ -38,7 +38,7 @@ BEGIN SET AUTOCOMMIT = 0; SELECT DATABASE() INTO db; - IF NOT EXISTS(SELECT 1 + IF EXISTS(SELECT 1 FROM information_schema.statistics WHERE TABLE_SCHEMA = db AND TABLE_NAME = 'T_COMMON_NOTIFY_MESSAGE_TEMPLATE' @@ -49,7 +49,8 @@ SELECT DATABASE() INTO db; IF NOT EXISTS(SELECT 1 FROM information_schema.statistics WHERE TABLE_SCHEMA = db - AND TABLE_NAME = 'T_COMMON_NOTIFY_MESSAGE_TEMPLATE') THEN + AND TABLE_NAME = 'T_COMMON_NOTIFY_MESSAGE_TEMPLATE' + AND INDEX_NAME = 'UNI_TCNMT_TEMPLATE_CODE') THEN ALTER TABLE `T_COMMON_NOTIFY_MESSAGE_TEMPLATE` ADD UNIQUE INDEX UNI_TCNMT_TEMPLATE_CODE (TEMPLATE_CODE); END IF; From 2357b89b0fde90d4c28e0aaf316987015fac97f1 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Fri, 9 Jun 2023 15:44:30 +0800 Subject: [PATCH 042/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/service/RbacPermissionApplyService.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt index 2c43deae543..fc0e5bf673b 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt @@ -8,6 +8,7 @@ import com.tencent.bk.sdk.iam.dto.manager.V2ManagerRoleGroupInfo import com.tencent.bk.sdk.iam.dto.manager.dto.SearchGroupDTO import com.tencent.bk.sdk.iam.dto.manager.vo.V2ManagerRoleGroupVO import com.tencent.bk.sdk.iam.service.v2.V2ManagerService +import com.tencent.devops.auth.constant.AuthI18nConstants import com.tencent.devops.auth.constant.AuthI18nConstants.ACTION_NAME_SUFFIX import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX import com.tencent.devops.auth.constant.AuthMessageCode @@ -27,6 +28,7 @@ import com.tencent.devops.auth.pojo.vo.ResourceTypeInfoVo import com.tencent.devops.auth.service.iam.PermissionApplyService import com.tencent.devops.auth.service.iam.PermissionService import com.tencent.devops.common.api.exception.ErrorCodeException +import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.auth.api.pojo.DefaultGroupType @@ -332,7 +334,10 @@ class RbacPermissionApplyService @Autowired constructor( // 判断action是否为空 val actionInfo = if (action != null) rbacCacheService.getActionInfo(action) else null val iamRelatedResourceType = actionInfo?.relatedResourceType ?: resourceType - val resourceTypeName = rbacCacheService.getResourceTypeInfo(resourceType).name + val resourceTypeName = MessageUtil.getMessageByLocale( + messageCode = resourceType + AuthI18nConstants.RESOURCE_TYPE_NAME_SUFFIX, + language = I18nUtil.getDefaultLocaleLanguage() + ) val projectInfo = authResourceService.get( projectCode = projectId, From a0cdafb8807d2111602a3076ca8375db2a5c06ce Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Fri, 9 Jun 2023 15:45:14 +0800 Subject: [PATCH 043/166] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=9E=84=E5=BB=BA=E7=8E=AF=E5=A2=83=E7=9A=84=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E6=9C=BA=E5=88=97=E8=A1=A8=20#8947?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../environment/api/ServiceNodeResource.kt | 18 ++++++++ .../tencent/devops/environment/dao/NodeDao.kt | 7 +++- .../resources/ServiceNodeResourceImpl.kt | 21 ++++++++++ .../devops/environment/service/EnvService.kt | 41 ++++++++++++++++++- .../devops/environment/service/NodeService.kt | 19 ++++++--- .../environment/ApigwEnvironmentResourceV4.kt | 18 ++++++++ .../devops/openapi/utils/markdown/Table.kt | 4 +- .../ApigwEnvironmentResourceV4Impl.kt | 10 +++++ .../openapi/service/doc/DocumentService.kt | 5 ++- 9 files changed, 132 insertions(+), 11 deletions(-) diff --git a/src/backend/ci/core/environment/api-environment/src/main/kotlin/com/tencent/devops/environment/api/ServiceNodeResource.kt b/src/backend/ci/core/environment/api-environment/src/main/kotlin/com/tencent/devops/environment/api/ServiceNodeResource.kt index 03a1230b633..b30fdfaec12 100644 --- a/src/backend/ci/core/environment/api-environment/src/main/kotlin/com/tencent/devops/environment/api/ServiceNodeResource.kt +++ b/src/backend/ci/core/environment/api-environment/src/main/kotlin/com/tencent/devops/environment/api/ServiceNodeResource.kt @@ -173,4 +173,22 @@ interface ServiceNodeResource { @QueryParam("agentId") agentId: String ): Result + + @ApiOperation("指定构建环境获取所有节点信息") + @GET + @Path("/projects/{projectId}/third_party_env2nodes") + fun thirdPartyEnv2Nodes( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID(项目英文名)", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("环境 hashId (envHashId和envName选填一项)", required = false) + @QueryParam("envHashId") + envHashId: String?, + @ApiParam("环境名称", required = false) + @QueryParam("envName (envHashId和envName选填一项)") + envName: String? + ): Result> } diff --git a/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/dao/NodeDao.kt b/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/dao/NodeDao.kt index 0d0f81ee094..2a84a56ebee 100644 --- a/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/dao/NodeDao.kt +++ b/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/dao/NodeDao.kt @@ -61,11 +61,16 @@ class NodeDao { } } - fun listThirdpartyNodes(dslContext: DSLContext, projectId: String): List { + fun listThirdpartyNodes( + dslContext: DSLContext, + projectId: String, + nodeIds: Collection? = null + ): List { with(TNode.T_NODE) { return dslContext.selectFrom(this) .where(PROJECT_ID.eq(projectId)) .and(NODE_TYPE.eq(NodeType.THIRDPARTY.name)) + .let { if (nodeIds != null) it.and(NODE_ID.`in`(nodeIds)) else it } .orderBy(NODE_ID.desc()) .fetch() } diff --git a/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/resources/ServiceNodeResourceImpl.kt b/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/resources/ServiceNodeResourceImpl.kt index 3f3a7f430e5..2c97843e970 100644 --- a/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/resources/ServiceNodeResourceImpl.kt +++ b/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/resources/ServiceNodeResourceImpl.kt @@ -119,4 +119,25 @@ class ServiceNodeResourceImpl @Autowired constructor( nodeService.deleteNodeByAgentId(userId, projectId, agentId) return Result(true) } + + override fun thirdPartyEnv2Nodes( + userId: String, + projectId: String, + envHashId: String?, + envName: String? + ): Result> { + if (envHashId.isNullOrBlank() && envName.isNullOrBlank()) { + throw ErrorCodeException( + errorCode = CommonMessageCode.ERROR_NEED_PARAM_, + params = arrayOf("envHashId") + ) + } + val envId = envHashId ?: envName?.let { + envService.getByName(projectId, it)?.envHashId + } ?: throw ErrorCodeException( + errorCode = CommonMessageCode.ERROR_NEED_PARAM_, + params = arrayOf("envName") + ) + return Result(envService.thirdPartyEnv2Nodes(userId, projectId, envId)) + } } diff --git a/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/service/EnvService.kt b/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/service/EnvService.kt index dcc9e3aa12d..4264bea07ec 100644 --- a/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/service/EnvService.kt +++ b/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/service/EnvService.kt @@ -69,6 +69,7 @@ import com.tencent.devops.environment.pojo.EnvWithNodeCount import com.tencent.devops.environment.pojo.EnvWithPermission import com.tencent.devops.environment.pojo.EnvironmentId import com.tencent.devops.environment.pojo.NodeBaseInfo +import com.tencent.devops.environment.pojo.NodeWithPermission import com.tencent.devops.environment.pojo.SharedProjectInfo import com.tencent.devops.environment.pojo.enums.EnvType import com.tencent.devops.environment.pojo.enums.NodeStatus @@ -80,11 +81,11 @@ import com.tencent.devops.environment.utils.AgentStatusUtils.getAgentStatus import com.tencent.devops.environment.utils.NodeStringIdUtils import com.tencent.devops.model.environment.tables.records.TEnvRecord import com.tencent.devops.project.api.service.ServiceProjectResource -import java.text.SimpleDateFormat import org.jooq.DSLContext import org.jooq.impl.DSL import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service +import java.text.SimpleDateFormat @Service @Suppress("ALL") @@ -97,6 +98,7 @@ class EnvService @Autowired constructor( private val slaveGatewayService: SlaveGatewayService, private val environmentPermissionService: EnvironmentPermissionService, private val envShareProjectDao: EnvShareProjectDao, + private val nodeService: NodeService, private val client: Client ) : IEnvService { @@ -513,6 +515,22 @@ class EnvService @Autowired constructor( return resultMap } + fun thirdPartyEnv2Nodes( + userId: String, + projectId: String, + envHashId: String + ): List { + val envId = HashUtil.decodeIdToLong(envHashId) + if (!environmentPermissionService.checkEnvPermission(userId, projectId, envId, AuthPermission.VIEW)) { + throw PermissionForbiddenException( + message = I18nUtil.getCodeLanMessage(ERROR_ENV_NO_VIEW_PERMISSSION) + ) + } + val envNodes = envNodeDao.list(dslContext, projectId, listOf(envId)) + val nodes = nodeDao.listThirdpartyNodes(dslContext, projectId, envNodes.map { it.nodeId }) + return nodeService.formatNodeWithPermissions(userId, projectId, nodes) + } + override fun listAllEnvNodes(userId: String, projectId: String, envHashIds: List): List { val envIds = envHashIds.map { HashUtil.decodeIdToLong(it) } val canViewEnvIdList = environmentPermissionService.listEnvByViewPermission(userId, projectId) @@ -702,6 +720,27 @@ class EnvService @Autowired constructor( ) } + fun getByName(projectId: String, envName: String): EnvWithPermission? { + return envDao.getByEnvName(dslContext, projectId, envName)?.let { + EnvWithPermission( + envHashId = HashUtil.encodeLongId(it.envId), + name = it.envName, + desc = it.envDesc, + envType = if (it.envType == EnvType.TEST.name) EnvType.DEV.name else it.envType, // 兼容性代码 + nodeCount = null, + envVars = jacksonObjectMapper().readValue(it.envVars), + createdUser = it.createdUser, + createdTime = it.createdTime.timestamp(), + updatedUser = it.updatedUser, + updatedTime = it.updatedTime.timestamp(), + canEdit = null, + canDelete = null, + canUse = null, + projectName = null + ) + } + } + private fun format(records: List): List { return records.map { EnvWithPermission( diff --git a/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/service/NodeService.kt b/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/service/NodeService.kt index 88b4ea8805a..34012499241 100644 --- a/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/service/NodeService.kt +++ b/src/backend/ci/core/environment/biz-environment/src/main/kotlin/com/tencent/devops/environment/service/NodeService.kt @@ -53,16 +53,17 @@ import com.tencent.devops.environment.service.node.NodeActionFactory import com.tencent.devops.environment.service.slave.SlaveGatewayService import com.tencent.devops.environment.utils.AgentStatusUtils.getAgentStatus import com.tencent.devops.environment.utils.NodeStringIdUtils -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 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 @Service @Suppress("ALL") @@ -131,6 +132,14 @@ class NodeService @Autowired constructor( return emptyList() } + return formatNodeWithPermissions(userId, projectId, nodeRecordList) + } + + fun formatNodeWithPermissions( + userId: String, + projectId: String, + nodeRecordList: List + ): List { val permissionMap = environmentPermissionService.listNodeByPermissions( userId = userId, projectId = projectId, permissions = setOf(AuthPermission.USE, AuthPermission.EDIT, AuthPermission.DELETE) diff --git a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/environment/ApigwEnvironmentResourceV4.kt b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/environment/ApigwEnvironmentResourceV4.kt index c8e194ef7e4..2c04282286e 100644 --- a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/environment/ApigwEnvironmentResourceV4.kt +++ b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/environment/ApigwEnvironmentResourceV4.kt @@ -359,4 +359,22 @@ interface ApigwEnvironmentResourceV4 { @ApiParam(value = "共享的项目列表", required = true) sharedProjects: SharedProjectInfoWrap ): Result + + @ApiOperation("指定构建环境获取所有节点信息", tags = ["v4_user_third_party_env2nodes", "v4_app_third_party_env2nodes"]) + @GET + @Path("/third_party_env2nodes") + fun thirdPartyEnv2Nodes( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID(项目英文名)", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("环境 hashId (envHashId和envName选填一项)", required = false) + @QueryParam("envHashId") + envHashId: String?, + @ApiParam("环境名称", required = false) + @QueryParam("envName (envHashId和envName选填一项)") + envName: String? + ): Result> } diff --git a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/utils/markdown/Table.kt b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/utils/markdown/Table.kt index 71f5891f124..b9804c4fee7 100644 --- a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/utils/markdown/Table.kt +++ b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/utils/markdown/Table.kt @@ -1,6 +1,6 @@ package com.tencent.devops.openapi.utils.markdown -import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.openapi.constant.OpenAPIMessageCode.BK_NO_SUCH_PARAMETER import com.tencent.devops.openapi.utils.markdown.MarkdownCharacter.FILL import com.tencent.devops.openapi.utils.markdown.MarkdownCharacter.MIN_FILL @@ -20,7 +20,7 @@ class Table( val body = StringBuffer() if (rows.isEmpty()) { body.append( - Text(6, I18nUtil.getCodeLanMessage(BK_NO_SUCH_PARAMETER), "") + Text(6, MessageUtil.getMessageByLocale(BK_NO_SUCH_PARAMETER, "zh_CN"), "") ) return body.toString() } diff --git a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/environment/ApigwEnvironmentResourceV4Impl.kt b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/environment/ApigwEnvironmentResourceV4Impl.kt index c37c6b30818..ebbaa79aa9b 100644 --- a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/environment/ApigwEnvironmentResourceV4Impl.kt +++ b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/environment/ApigwEnvironmentResourceV4Impl.kt @@ -208,6 +208,16 @@ class ApigwEnvironmentResourceV4Impl @Autowired constructor( return client.get(ServiceEnvironmentResource::class).setShareEnv(userId, projectId, envHashId, sharedProjects) } + override fun thirdPartyEnv2Nodes( + userId: String, + projectId: String, + envHashId: String?, + envName: String? + ): Result> { + logger.info("OPENAPI_ENVIRONMENT_V4|$userId|third party env2nodes|$projectId|$envHashId|$envName") + return client.get(ServiceNodeResource::class).thirdPartyEnv2Nodes(userId, projectId, envHashId, envName) + } + companion object { private val logger = LoggerFactory.getLogger(ApigwEnvironmentResourceV4Impl::class.java) } diff --git a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/service/doc/DocumentService.kt b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/service/doc/DocumentService.kt index aab2e6dc337..6fbab9689cc 100644 --- a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/service/doc/DocumentService.kt +++ b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/service/doc/DocumentService.kt @@ -30,7 +30,7 @@ import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_APP_CODE import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID import com.tencent.devops.common.api.util.FileUtil import com.tencent.devops.common.api.util.JsonUtil -import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.openapi.constant.OpenAPIMessageCode.BK_ALL_MODEL_DATA import com.tencent.devops.openapi.constant.OpenAPIMessageCode.BK_APPLICATION_STATE_REQUIRED import com.tencent.devops.openapi.constant.OpenAPIMessageCode.BK_BODY_PARAMETER @@ -827,8 +827,9 @@ class DocumentService { } private fun getI18n(code: String, params: Array? = null): String { - return I18nUtil.getCodeLanMessage( + return MessageUtil.getMessageByLocale( messageCode = code, + language = "zh_CN", params = params ) } From aa8adc8652bf8b29d65a3a5de588a26fba83c63a Mon Sep 17 00:00:00 2001 From: yjieliang Date: Fri, 9 Jun 2023 15:50:19 +0800 Subject: [PATCH 044/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/PermissionGradeManagerService.kt | 1 - .../service/PermissionSubsetManagerService.kt | 37 +++---------------- 2 files changed, 5 insertions(+), 33 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt index 72d9a7c68c2..e69fbe15297 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt @@ -141,7 +141,6 @@ class PermissionGradeManagerService @Autowired constructor( params = arrayOf(DefaultGroupType.MANAGER.value), defaultMessage = "${resourceType}_${DefaultGroupType.MANAGER.value} group config not exist" ) - val description = manageGroupConfig.description val authorizationScopes = permissionGroupPoliciesService.buildAuthorizationScopes( authorizationScopesStr = manageGroupConfig.authorizationScopes, diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt index c7dd7229e41..a9e623922c7 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionSubsetManagerService.kt @@ -34,8 +34,6 @@ import com.tencent.bk.sdk.iam.dto.manager.dto.CreateSubsetManagerDTO import com.tencent.bk.sdk.iam.dto.manager.dto.ManagerRoleGroupDTO import com.tencent.bk.sdk.iam.dto.manager.dto.UpdateSubsetManagerDTO import com.tencent.bk.sdk.iam.service.v2.V2ManagerService -import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX -import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX import com.tencent.devops.auth.constant.AuthMessageCode import com.tencent.devops.auth.dao.AuthResourceGroupConfigDao import com.tencent.devops.auth.dao.AuthResourceGroupDao @@ -44,7 +42,6 @@ import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.auth.api.pojo.DefaultGroupType -import com.tencent.devops.common.web.utils.I18nUtil import org.jooq.DSLContext import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired @@ -90,11 +87,7 @@ class PermissionSubsetManagerService @Autowired constructor( resourceCode = resourceCode, resourceName = resourceName ) - val description = I18nUtil.getCodeLanMessage( - messageCode = "${managerGroupConfig.resourceType}.${managerGroupConfig.groupCode}" + - AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX, - defaultMessage = managerGroupConfig.description - ) + val description = managerGroupConfig.description val authorizationScopes = permissionGroupPoliciesService.buildAuthorizationScopes( authorizationScopesStr = managerGroupConfig.authorizationScopes, projectCode = projectCode, @@ -112,13 +105,7 @@ class PermissionSubsetManagerService @Autowired constructor( .inheritSubjectScope(true) .subjectScopes(listOf()) .syncPerm(syncPerm) - .groupName( - I18nUtil.getCodeLanMessage( - messageCode = "${managerGroupConfig.resourceType}.${managerGroupConfig.groupCode}" + - AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX, - defaultMessage = managerGroupConfig.groupName - ) - ) + .groupName(managerGroupConfig.groupName) .build() return iamV2ManagerService.createSubsetManager( gradeManagerId, @@ -169,13 +156,7 @@ class PermissionSubsetManagerService @Autowired constructor( .inheritSubjectScope(true) .subjectScopes(listOf()) .syncPerm(syncPerm) - .groupName( - I18nUtil.getCodeLanMessage( - messageCode = "${managerGroupConfig.resourceType}.${managerGroupConfig.groupCode}" + - AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX, - defaultMessage = managerGroupConfig.groupName - ) - ) + .groupName(managerGroupConfig.groupName) .build() iamV2ManagerService.updateSubsetManager( subsetManagerId, @@ -253,16 +234,8 @@ class PermissionSubsetManagerService @Autowired constructor( if (resourceGroupInfo != null) { return@forEach } - val name = I18nUtil.getCodeLanMessage( - messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX, - defaultMessage = groupConfig.groupName - ) - val description = I18nUtil.getCodeLanMessage( - messageCode = "${groupConfig.resourceType}.${groupConfig.groupCode}" + - AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX, - defaultMessage = groupConfig.description - ) + val name = groupConfig.groupName + val description = groupConfig.description val managerRoleGroup = ManagerRoleGroup(name, description, false) val managerRoleGroupDTO = ManagerRoleGroupDTO.builder().groups(listOf(managerRoleGroup)).build() val iamGroupId = iamV2ManagerService.batchCreateSubsetRoleGroup(subsetManagerId, managerRoleGroupDTO) From 431976b8a060424e85b184e842d23ad100e44dc0 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Fri, 9 Jun 2023 16:17:15 +0800 Subject: [PATCH 045/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/auth/service/RbacPermissionApplyService.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt index fc0e5bf673b..3d51b68ee11 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt @@ -334,9 +334,9 @@ class RbacPermissionApplyService @Autowired constructor( // 判断action是否为空 val actionInfo = if (action != null) rbacCacheService.getActionInfo(action) else null val iamRelatedResourceType = actionInfo?.relatedResourceType ?: resourceType - val resourceTypeName = MessageUtil.getMessageByLocale( + val resourceTypeName = I18nUtil.getCodeLanMessage( messageCode = resourceType + AuthI18nConstants.RESOURCE_TYPE_NAME_SUFFIX, - language = I18nUtil.getDefaultLocaleLanguage() + defaultMessage = rbacCacheService.getResourceTypeInfo(resourceType).name ) val projectInfo = authResourceService.get( From 191e8cd3a9eb425925738c3937460b224ac735f5 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 9 Jun 2023 16:23:19 +0800 Subject: [PATCH 046/166] =?UTF-8?q?feat=EF=BC=9A=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E9=97=AE=E9=A2=98=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20#8955=20=E8=A1=A5=E5=85=85websocket=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/process/dao/record/BuildRecordTaskDao.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt index 59898dee274..8e599a44f79 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt @@ -240,7 +240,8 @@ class BuildRecordTaskDao { private fun TPipelineBuildRecordTask.generateBuildRecordTask( record: Record18 + String, String, Int, Int, String, String, String, + String, String, LocalDateTime, LocalDateTime, String, String> ) = BuildRecordTask( buildId = record[BUILD_ID], From c97a277b2f4ec5e5ee9b47f25d967d3f0bba4b43 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Fri, 9 Jun 2023 16:24:29 +0800 Subject: [PATCH 047/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/auth/service/RbacPermissionApplyService.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt index 3d51b68ee11..0140570627f 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt @@ -28,7 +28,6 @@ import com.tencent.devops.auth.pojo.vo.ResourceTypeInfoVo import com.tencent.devops.auth.service.iam.PermissionApplyService import com.tencent.devops.auth.service.iam.PermissionService import com.tencent.devops.common.api.exception.ErrorCodeException -import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.auth.api.pojo.DefaultGroupType From 8f2ba2c312f8eb16b76ae72764ac882318307533 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Fri, 9 Jun 2023 16:47:30 +0800 Subject: [PATCH 048/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt index 50ad5f3c75f..f3d90a1cf22 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt @@ -13,6 +13,6 @@ data class GroupPermissionDetailVo( @BkFieldI18n(convertName = "actionName") val name: String, @ApiModelProperty("关联资源") - @BkFieldI18n + @BkFieldI18n(reusePrefixFlag = false) val relatedResourceInfo: RelatedResourceInfo ) From 50a1afb6536d18e982284d2af62738b274577828 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 9 Jun 2023 17:22:55 +0800 Subject: [PATCH 049/166] =?UTF-8?q?feat=EF=BC=9A=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E9=97=AE=E9=A2=98=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20#8955=20=E8=A1=A5=E5=85=85websocket=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/common/pipeline/EnvReplacementParser.kt | 3 ++- .../process/engine/service/detail/BaseBuildDetailService.kt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/EnvReplacementParser.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/EnvReplacementParser.kt index 23360b887ae..7fea8cabdbf 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/EnvReplacementParser.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/EnvReplacementParser.kt @@ -50,7 +50,8 @@ import java.io.InputStreamReader "ComplexCondition", "ComplexMethod", "NestedBlockDepth", - "ReturnCount" + "ReturnCount", + "LongParameterList" ) object EnvReplacementParser { diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/detail/BaseBuildDetailService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/detail/BaseBuildDetailService.kt index 31d2e367b79..9ff2e78c3c2 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/detail/BaseBuildDetailService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/detail/BaseBuildDetailService.kt @@ -253,7 +253,8 @@ open class BaseBuildDetailService constructor( pipelineId = pipelineBuildInfo.pipelineId, userId = pipelineBuildInfo.startUser, buildId = buildId, - refreshTypes = RefreshType.DETAIL.binary or RefreshType.RECORD.binary + refreshTypes = RefreshType.DETAIL.binary or RefreshType.RECORD.binary, + executeCount = pipelineBuildInfo.executeCount ) ) } From 34057099f68d062e88fe65c7a6cca84d1892570d Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Fri, 9 Jun 2023 17:41:55 +0800 Subject: [PATCH 050/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/service/RbacPermissionService.kt | 14 +++++++++----- .../5001_init_dml/5001_ci_auth-init_dml_mysql.sql | 10 +++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt index cf3796c56f9..9792b4c172c 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt @@ -155,11 +155,15 @@ class RbacPermissionService constructor( ) { return true } - val iamResourceCode = authResourceCodeConverter.code2IamCode( - projectCode = projectCode, - resourceType = resource.resourceType, - resourceCode = resource.resourceCode - ) ?: return false + val iamResourceCode = if (resource.resourceCode == "*") { + resource.resourceCode + } else { + authResourceCodeConverter.code2IamCode( + projectCode = projectCode, + resourceType = resource.resourceType, + resourceCode = resource.resourceCode + ) + } ?: return false val subject = SubjectDTO.builder() .id(userId) .type(ManagerScopesEnum.getType(ManagerScopesEnum.USER)) diff --git a/support-files/sql/5001_init_dml/5001_ci_auth-init_dml_mysql.sql b/support-files/sql/5001_init_dml/5001_ci_auth-init_dml_mysql.sql index ca58301ec50..8aeeeab6f62 100644 --- a/support-files/sql/5001_init_dml/5001_ci_auth-init_dml_mysql.sql +++ b/support-files/sql/5001_init_dml/5001_ci_auth-init_dml_mysql.sql @@ -142,11 +142,11 @@ REPLACE INTO T_AUTH_ACTION(`ACTION`, RESOURCE_TYPE, RELATED_RESOURCE_TYPE, ACTI ('quality_group_list', 'quality_group', 'quality_group', 'Quality Notice Group List', 'Quality Notice Group List', 'system', 0, 'view'); REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(1, "project", "manager", "Owner", 0, 'Project owner has all permissions for this project', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_view\"},{\"id\":\"project_edit\"},{\"id\":\"project_enable\"},{\"id\":\"project_list\"},{\"id\":\"project_manage\"},{\"id\":\"pipeline_create\"},{\"id\":\"codecc_task_create\"},{\"id\":\"codecc_rule_set_create\"},{\"id\":\"codecc_rule_set_list\"},{\"id\":\"repertory_create\"},{\"id\":\"credential_create\"},{\"id\":\"cert_create\"},{\"id\":\"environment_create\"},{\"id\":\"env_node_create\"},{\"id\":\"experience_task_create\"},{\"id\":\"experience_group_create\"},{\"id\":\"rule_create\"},{\"id\":\"quality_group_create\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_view\"},{\"id\":\"pipeline_edit\"},{\"id\":\"pipeline_delete\"},{\"id\":\"pipeline_execute\"},{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"},{\"id\":\"pipeline_manage\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_analyze\"},{\"id\":\"codecc_task_manage-defect\"},{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_setting\"},{\"id\":\"codecc_task_manage\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_view\"},{\"id\":\"repertory_edit\"},{\"id\":\"repertory_delete\"},{\"id\":\"repertory_list\"},{\"id\":\"repertory_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"credential_view\"},{\"id\":\"credential_edit\"},{\"id\":\"credential_delete\"},{\"id\":\"credential_list\"},{\"id\":\"credential_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"credential\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"cert_view\"},{\"id\":\"cert_edit\"},{\"id\":\"cert_delete\"},{\"id\":\"cert_list\"},{\"id\":\"cert_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"cert\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"environment_view\"},{\"id\":\"environment_edit\"},{\"id\":\"environment_delete\"},{\"id\":\"environment_list\"},{\"id\":\"environment_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"environment\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"env_node_view\"},{\"id\":\"env_node_edit\"},{\"id\":\"env_node_delete\"},{\"id\":\"env_node_list\"},{\"id\":\"env_node_use\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"env_node\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_task_view\"},{\"id\":\"experience_task_edit\"},{\"id\":\"experience_task_delete\"},{\"id\":\"experience_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_group_view\"},{\"id\":\"experience_group_edit\"},{\"id\":\"experience_group_delete\"},{\"id\":\"experience_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_edit\"},{\"id\":\"rule_delete\"},{\"id\":\"rule_list\"},{\"id\":\"rule_enable\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_edit\"},{\"id\":\"quality_group_delete\"},{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_view\",\"project_edit\",\"project_enable\",\"project_list\",\"project_manage\"]'); -REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(2, "project", "developer", "Developer", 0, 'Developer can create pipelines, repos, credentials, certificates, agent pools, agents, codecc tasks, codecc rule sets, download and share artifacts in the custom-path artifactory', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_list\"},{\"id\":\"pipeline_create\"},{\"id\":\"codecc_task_create\"},{\"id\":\"codecc_rule_set_create\"},{\"id\":\"codecc_rule_set_list\"},{\"id\":\"repertory_create\"},{\"id\":\"credential_create\"},{\"id\":\"cert_create\"},{\"id\":\"environment_create\"},{\"id\":\"env_node_create\"},{\"id\":\"experience_task_create\"},{\"id\":\"experience_group_create\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"credential_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"credential\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"cert_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"cert\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"environment_view\"},{\"id\":\"environment_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"environment\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"env_node_view\"},{\"id\":\"env_node_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"env_node\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_task_view\"},{\"id\":\"experience_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_group_view\"},{\"id\":\"experience_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_list\"]'); -REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(3, "project", "maintainer", "SRE", 0, 'SRE can create pipelines, repos, credentials, certificates, agent pools, agents, download and share artifacts in the custom-path artifactory', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_list\"},{\"id\":\"pipeline_create\"},{\"id\":\"codecc_task_create\"},{\"id\":\"codecc_rule_set_list\"},{\"id\":\"repertory_create\"},{\"id\":\"credential_create\"},{\"id\":\"cert_create\"},{\"id\":\"environment_create\"},{\"id\":\"env_node_create\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"credential_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"credential\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"cert_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"cert\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"environment_view\"},{\"id\":\"environment_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"environment\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"env_node_view\"},{\"id\":\"env_node_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"env_node\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_task_view\"},{\"id\":\"experience_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_group_view\"},{\"id\":\"experience_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_list\"]'); -REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(4, "project", "pm", "PM", 0, 'PM can view the pipeline list, download or share artifacts in the custom-path artifactory', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_list\"},{\"id\":\"codecc_rule_set_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"credential_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"credential\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"cert_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"cert\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"environment_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"environment\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"env_node_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"env_node\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_task_view\"},{\"id\":\"experience_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_group_view\"},{\"id\":\"experience_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_list\"]'); -REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(5, "project", "tester", "QA", 0, 'QA can create pipelines, repos, credentials, certificates, agent pools, agents, codecc tasks, codecc rule sets, download and share artifacts in the custom-path artifactory', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_list\"},{\"id\":\"pipeline_create\"},{\"id\":\"codecc_task_create\"},{\"id\":\"codecc_rule_set_create\"},{\"id\":\"codecc_rule_set_list\"},{\"id\":\"repertory_create\"},{\"id\":\"credential_create\"},{\"id\":\"cert_create\"},{\"id\":\"environment_create\"},{\"id\":\"env_node_create\"},{\"id\":\"experience_task_create\"},{\"id\":\"experience_group_create\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"credential_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"credential\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"cert_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"cert\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"environment_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"environment\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"env_node_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"env_node\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_task_view\"},{\"id\":\"experience_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_group_view\"},{\"id\":\"experience_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_list\"]'); -REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(6, "project", "qc", "QC", 0, 'QC can manage quality red line rules', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_list\"},{\"id\":\"codecc_rule_set_list\"},{\"id\":\"rule_create\"},{\"id\":\"quality_group_create\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_edit\"},{\"id\":\"rule_delete\"},{\"id\":\"rule_enable\"},{\"id\":\"rule_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_edit\"},{\"id\":\"quality_group_delete\"},{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_list\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(2, "project", "developer", "Developer", 0, 'Developer can create pipelines, repos, credentials, certificates, agent pools, agents, codecc tasks, codecc rule sets, download and share artifacts in the custom-path artifactory', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_list\"},{\"id\":\"pipeline_create\"},{\"id\":\"codecc_task_create\"},{\"id\":\"codecc_rule_set_create\"},{\"id\":\"codecc_rule_set_list\"},{\"id\":\"repertory_create\"},{\"id\":\"credential_create\"},{\"id\":\"cert_create\"},{\"id\":\"environment_create\"},{\"id\":\"env_node_create\"},{\"id\":\"experience_task_create\"},{\"id\":\"experience_group_create\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"credential_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"credential\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"cert_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"cert\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"environment_view\"},{\"id\":\"environment_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"environment\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"env_node_view\"},{\"id\":\"env_node_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"env_node\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_task_view\"},{\"id\":\"experience_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_group_view\"},{\"id\":\"experience_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_list\",\"pipeline_create\",\"codecc_task_create\",\"codecc_rule_set_create\",\"codecc_rule_set_list\",\"repertory_create\",\"credential_create\",\"cert_create\",\"environment_create\",\"env_node_create\",\"experience_task_create\",\"experience_group_create\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(3, "project", "maintainer", "SRE", 0, 'SRE can create pipelines, repos, credentials, certificates, agent pools, agents, download and share artifacts in the custom-path artifactory', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_list\"},{\"id\":\"pipeline_create\"},{\"id\":\"codecc_task_create\"},{\"id\":\"codecc_rule_set_list\"},{\"id\":\"repertory_create\"},{\"id\":\"credential_create\"},{\"id\":\"cert_create\"},{\"id\":\"environment_create\"},{\"id\":\"env_node_create\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"credential_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"credential\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"cert_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"cert\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"environment_view\"},{\"id\":\"environment_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"environment\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"env_node_view\"},{\"id\":\"env_node_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"env_node\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_task_view\"},{\"id\":\"experience_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_group_view\"},{\"id\":\"experience_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_list\",\"pipeline_create\",\"codecc_task_create\",\"codecc_rule_set_create\",\"codecc_rule_set_list\",\"repertory_create\",\"credential_create\",\"cert_create\",\"environment_create\",\"env_node_create\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(4, "project", "pm", "PM", 0, 'PM can view the pipeline list, download or share artifacts in the custom-path artifactory', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_list\"},{\"id\":\"codecc_rule_set_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"credential_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"credential\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"cert_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"cert\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"environment_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"environment\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"env_node_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"env_node\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_task_view\"},{\"id\":\"experience_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_group_view\"},{\"id\":\"experience_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_list\",\"codecc_rule_set_list\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(5, "project", "tester", "QA", 0, 'QA can create pipelines, repos, credentials, certificates, agent pools, agents, codecc tasks, codecc rule sets, download and share artifacts in the custom-path artifactory', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_list\"},{\"id\":\"pipeline_create\"},{\"id\":\"codecc_task_create\"},{\"id\":\"codecc_rule_set_create\"},{\"id\":\"codecc_rule_set_list\"},{\"id\":\"repertory_create\"},{\"id\":\"credential_create\"},{\"id\":\"cert_create\"},{\"id\":\"environment_create\"},{\"id\":\"env_node_create\"},{\"id\":\"experience_task_create\"},{\"id\":\"experience_group_create\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"credential_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"credential\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"cert_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"cert\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"environment_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"environment\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"env_node_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"env_node\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_task_view\"},{\"id\":\"experience_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"experience_group_view\"},{\"id\":\"experience_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"experience_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_list\",\"pipeline_create\",\"codecc_task_create\",\"codecc_rule_set_create\",\"codecc_rule_set_list\",\"repertory_create\",\"credential_create\",\"cert_create\",\"environment_create\",\"env_node_create\",\"experience_task_create\",\"experience_group_create\"]'); +REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(6, "project", "qc", "QC", 0, 'QC can manage quality red line rules', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_list\"},{\"id\":\"codecc_rule_set_list\"},{\"id\":\"rule_create\"},{\"id\":\"quality_group_create\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"codecc_task_view-defect\"},{\"id\":\"codecc_task_view-report\"},{\"id\":\"codecc_task_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"codecc_task\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"repertory_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"repertory\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"rule_edit\"},{\"id\":\"rule_delete\"},{\"id\":\"rule_enable\"},{\"id\":\"rule_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"rule\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"quality_group_edit\"},{\"id\":\"quality_group_delete\"},{\"id\":\"quality_group_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"quality_group\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_list\",\"codecc_rule_set_list\",\"rule_create\",\"quality_group_create\"]'); REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(7, "project", "visitor", "Guest", 0, 'Guest can view the pipeline list', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"},{\"id\":\"project_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_list\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}],[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]}]', '[\"project_visit\",\"project_list\"]'); REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG(`ID`,`RESOURCE_TYPE`, `GROUP_CODE`, `GROUP_NAME`, `CREATE_MODE`, `DESCRIPTION`, `AUTHORIZATION_SCOPES`, `ACTIONS`) values(8, "pipeline", "manager", "Owner", 0, 'Pipeline owner can manage the permissions of the current pipeline', '[{\"system\":\"#system#\",\"actions\":[{\"id\":\"project_visit\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"project\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"}]]}]},{\"system\":\"#system#\",\"actions\":[{\"id\":\"pipeline_view\"},{\"id\":\"pipeline_edit\"},{\"id\":\"pipeline_delete\"},{\"id\":\"pipeline_execute\"},{\"id\":\"pipeline_list\"},{\"id\":\"pipeline_download\"},{\"id\":\"pipeline_share\"},{\"id\":\"pipeline_manage\"}],\"resources\":[{\"system\":\"#system#\",\"type\":\"pipeline\",\"paths\":[[{\"system\":\"#system#\",\"type\":\"project\",\"id\":\"#projectId#\",\"name\":\"#projectName#\"},{\"system\":\"#system#\",\"type\":\"pipeline\",\"id\":\"#resourceCode#\",\"name\":\"#resourceName#\"}]]}]}]', '[\"pipeline_view\",\"pipeline_edit\",\"pipeline_delete\",\"pipeline_execute\",\"pipeline_list\",\"pipeline_download\",\"pipeline_share\",\"pipeline_manage\"]'); From eda4e2679bb5213317582c46cefd9b2a3565317e Mon Sep 17 00:00:00 2001 From: yjieliang Date: Fri, 9 Jun 2023 17:43:05 +0800 Subject: [PATCH 051/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt index f3d90a1cf22..1b4a349422d 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/vo/GroupPermissionDetailVo.kt @@ -13,6 +13,5 @@ data class GroupPermissionDetailVo( @BkFieldI18n(convertName = "actionName") val name: String, @ApiModelProperty("关联资源") - @BkFieldI18n(reusePrefixFlag = false) val relatedResourceInfo: RelatedResourceInfo ) From 610ab0faea86835a02abc750a3358fcd8942e7da Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Fri, 9 Jun 2023 17:59:22 +0800 Subject: [PATCH 052/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/auth/service/RbacPermissionService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt index 9792b4c172c..7b0955db4fa 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionService.kt @@ -127,7 +127,7 @@ class RbacPermissionService constructor( ) } - @Suppress("ReturnCount") + @Suppress("ReturnCount", "ComplexMethod") override fun validateUserResourcePermissionByInstance( userId: String, action: String, From 77b19ca9b080519adf242de4b7627092ad892d43 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Fri, 9 Jun 2023 18:17:30 +0800 Subject: [PATCH 053/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/auth/api/user/UserAuthApplyResource.kt | 2 +- .../com/tencent/devops/auth/pojo/RelatedResourceInfo.kt | 2 -- .../devops/auth/service/RbacPermissionApplyService.kt | 5 ++++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt index 0dbf078763f..3ed454a6791 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthApplyResource.kt @@ -80,7 +80,7 @@ interface UserAuthApplyResource { @GET @Path("{groupId}/getGroupPermissionDetail") @ApiOperation("查询用户组权限详情") - @BkInterfaceI18n(keyPrefixNames = ["{data[*].actionId}", "{data[*].relatedResourceInfo.type}"]) + @BkInterfaceI18n(keyPrefixNames = ["{data[*].actionId}"]) fun getGroupPermissionDetail( @ApiParam(name = "用户名", required = true) @HeaderParam(AUTH_HEADER_USER_ID) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/RelatedResourceInfo.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/RelatedResourceInfo.kt index b27a0f5f0a5..41c8cbabd37 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/RelatedResourceInfo.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/pojo/RelatedResourceInfo.kt @@ -1,7 +1,6 @@ package com.tencent.devops.auth.pojo import com.tencent.bk.sdk.iam.dto.InstancesDTO -import com.tencent.devops.common.api.annotation.BkFieldI18n import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -10,7 +9,6 @@ data class RelatedResourceInfo( @ApiModelProperty("资源类型") val type: String, @ApiModelProperty("资源类型名") - @BkFieldI18n(keyPrefixName = "resourceType") val name: String, @ApiModelProperty("资源实例") val instances: InstancesDTO diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt index 0140570627f..3c806c88683 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/RbacPermissionApplyService.kt @@ -11,6 +11,7 @@ import com.tencent.bk.sdk.iam.service.v2.V2ManagerService import com.tencent.devops.auth.constant.AuthI18nConstants import com.tencent.devops.auth.constant.AuthI18nConstants.ACTION_NAME_SUFFIX import com.tencent.devops.auth.constant.AuthI18nConstants.AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX +import com.tencent.devops.auth.constant.AuthI18nConstants.RESOURCE_TYPE_NAME_SUFFIX import com.tencent.devops.auth.constant.AuthMessageCode import com.tencent.devops.auth.dao.AuthResourceGroupConfigDao import com.tencent.devops.auth.dao.AuthResourceGroupDao @@ -296,7 +297,9 @@ class RbacPermissionApplyService @Autowired constructor( buildRelatedResourceTypesDTO(instancesDTO = relatedResourceTypesDTO.condition[0].instances[0]) val relatedResourceInfo = RelatedResourceInfo( type = relatedResourceTypesDTO.type, - name = rbacCacheService.getResourceTypeInfo(relatedResourceTypesDTO.type).name, + name = I18nUtil.getCodeLanMessage( + relatedResourceTypesDTO.type + RESOURCE_TYPE_NAME_SUFFIX + ), instances = relatedResourceTypesDTO.condition[0].instances[0] ) GroupPermissionDetailVo( From 0f8e838620b93b3f3e6c9d354fa2c2fc0210b1c0 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 8 Jun 2023 21:33:08 +0800 Subject: [PATCH 054/166] =?UTF-8?q?feat=EF=BC=9A=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E9=97=AE=E9=A2=98=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20#8955=20=E5=A2=9E=E5=8A=A0task=E8=A1=A8post=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pipeline/record/BuildRecordContainer.kt | 3 +- .../pojo/pipeline/record/BuildRecordTask.kt | 3 ++ .../process/dao/record/BuildRecordTaskDao.kt | 27 ++++++++++++------ .../service/PipelineContainerService.kt | 4 ++- .../engine/service/PipelineRuntimeService.kt | 3 +- .../sql/1001_ci_process_ddl_mysql.sql | 1 + .../2020_ci_process-update_v2.0_mysql.sql | 28 +++++++++++++++++++ 7 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 support-files/sql/2003_v2.x/2020_ci_process-update_v2.0_mysql.sql diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordContainer.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordContainer.kt index cda8887e009..0e83caed429 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordContainer.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordContainer.kt @@ -134,7 +134,8 @@ data class BuildRecordContainer( taskSeq = index, status = buildStatus?.name, taskVar = mutableMapOf(), - timestamps = mapOf() + timestamps = mapOf(), + elementPostInfo = element.additionalOptions?.elementPostInfo ) ) } diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt index b5acb79c962..3a895351397 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt @@ -28,6 +28,7 @@ package com.tencent.devops.process.pojo.pipeline.record import com.tencent.devops.common.pipeline.enums.BuildRecordTimeStamp +import com.tencent.devops.common.pipeline.pojo.element.ElementPostInfo import com.tencent.devops.common.pipeline.pojo.time.BuildTimestampType import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -55,6 +56,8 @@ data class BuildRecordTask( val executeCount: Int, @ApiModelProperty("执行变量", required = true) var taskVar: MutableMap, + @ApiModelProperty("插件post信息", required = false) + val elementPostInfo: ElementPostInfo?, @ApiModelProperty("插件类型标识", required = true) val classType: String, @ApiModelProperty("市场插件标识", required = true) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt index 492601d95b4..59898dee274 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt @@ -31,6 +31,7 @@ import com.fasterxml.jackson.core.type.TypeReference import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.pipeline.enums.BuildRecordTimeStamp import com.tencent.devops.common.pipeline.enums.BuildStatus +import com.tencent.devops.common.pipeline.pojo.element.ElementPostInfo import com.tencent.devops.common.pipeline.pojo.time.BuildTimestampType import com.tencent.devops.model.process.tables.TPipelineBuildRecordTask import com.tencent.devops.model.process.tables.records.TPipelineBuildRecordTaskRecord @@ -39,7 +40,7 @@ import com.tencent.devops.process.pojo.KEY_TASK_ID import com.tencent.devops.process.pojo.pipeline.record.BuildRecordTask import org.jooq.Condition import org.jooq.DSLContext -import org.jooq.Record17 +import org.jooq.Record18 import org.jooq.RecordMapper import org.jooq.impl.DSL import org.jooq.util.mysql.MySQLDSL @@ -69,7 +70,8 @@ class BuildRecordTaskDao { STATUS, TASK_SEQ, ATOM_CODE, - TIMESTAMPS + TIMESTAMPS, + POST_INFO ).also { insert -> records.forEach { record -> insert.values( @@ -87,7 +89,8 @@ class BuildRecordTaskDao { record.status, record.taskSeq, record.atomCode, - JsonUtil.toJson(record.timestamps, false) + JsonUtil.toJson(record.timestamps, false), + record.elementPostInfo?.let { JsonUtil.toJson(it, false) } ) } }.onDuplicateKeyUpdate() @@ -200,7 +203,7 @@ class BuildRecordTaskDao { val result = dslContext.select( BUILD_ID, PROJECT_ID, PIPELINE_ID, RESOURCE_VERSION, STAGE_ID, CONTAINER_ID, TASK_ID, TASK_SEQ, EXECUTE_COUNT, TASK_VAR, CLASS_TYPE, ATOM_CODE, STATUS, ORIGIN_CLASS_TYPE, - START_TIME, END_TIME, TIMESTAMPS + START_TIME, END_TIME, TIMESTAMPS, POST_INFO ).from(this).join(max).on( TASK_ID.eq(max.field(KEY_TASK_ID, String::class.java)) .and(EXECUTE_COUNT.eq(max.field(KEY_EXECUTE_COUNT, Int::class.java))) @@ -227,7 +230,7 @@ class BuildRecordTaskDao { val result = dslContext.select( BUILD_ID, PROJECT_ID, PIPELINE_ID, RESOURCE_VERSION, STAGE_ID, CONTAINER_ID, TASK_ID, TASK_SEQ, EXECUTE_COUNT, TASK_VAR, CLASS_TYPE, ATOM_CODE, STATUS, ORIGIN_CLASS_TYPE, - START_TIME, END_TIME, TIMESTAMPS + START_TIME, END_TIME, TIMESTAMPS, POST_INFO ).from(this).where(conditions).orderBy(TASK_SEQ.asc()).fetch() return result.map { record -> generateBuildRecordTask(record) @@ -236,8 +239,8 @@ class BuildRecordTaskDao { } private fun TPipelineBuildRecordTask.generateBuildRecordTask( - record: Record17 + record: Record18 ) = BuildRecordTask( buildId = record[BUILD_ID], @@ -260,7 +263,10 @@ class BuildRecordTaskDao { endTime = record[END_TIME], timestamps = record[TIMESTAMPS]?.let { JsonUtil.to(it, object : TypeReference>() {}) - } ?: mapOf() + } ?: mapOf(), + elementPostInfo = record[POST_INFO]?.let { + JsonUtil.to(it, object : TypeReference() {}) + } ) fun getRecord( @@ -305,7 +311,10 @@ class BuildRecordTaskDao { endTime = endTime, timestamps = timestamps?.let { JsonUtil.to(it, object : TypeReference>() {}) - } ?: mapOf() + } ?: mapOf(), + elementPostInfo = postInfo?.let { + JsonUtil.to(it, object : TypeReference() {}) + } ) } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineContainerService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineContainerService.kt index 9e0b04819f2..2902addec50 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineContainerService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineContainerService.kt @@ -337,6 +337,7 @@ class PipelineContainerService @Autowired constructor( originClassType = atomElement.getClassType(), resourceVersion = resourceVersion, timestamps = mapOf(), + elementPostInfo = atomElement.additionalOptions?.elementPostInfo, // 对矩阵产生的插件特殊表示类型 taskVar = mutableMapOf( "@type" to MatrixStatusElement.classType, @@ -433,7 +434,8 @@ class PipelineContainerService @Autowired constructor( taskId = atomElement.id!!, classType = atomElement.getClassType(), atomCode = atomElement.getTaskAtom(), executeCount = context.executeCount, resourceVersion = context.resourceVersion, taskSeq = taskSeq, status = status.name, - taskVar = mutableMapOf(), timestamps = mapOf() + taskVar = mutableMapOf(), timestamps = mapOf(), + elementPostInfo = atomElement.additionalOptions?.elementPostInfo ) ) return@nextElement diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt index 624fadbc929..1e7cc6e8570 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRuntimeService.kt @@ -1129,7 +1129,8 @@ class PipelineRuntimeService @Autowired constructor( stageId = it.stageId, containerId = it.containerId, taskSeq = it.taskSeq, taskId = it.taskId, classType = it.taskType, atomCode = it.atomCode ?: it.taskAtom, executeCount = it.executeCount ?: 1, resourceVersion = resourceVersion, - taskVar = mutableMapOf(), timestamps = mapOf() + taskVar = mutableMapOf(), timestamps = mapOf(), + elementPostInfo = it.additionalOptions?.elementPostInfo ) ) } diff --git a/support-files/sql/1001_ci_process_ddl_mysql.sql b/support-files/sql/1001_ci_process_ddl_mysql.sql index 749a4785674..263b9fa264a 100644 --- a/support-files/sql/1001_ci_process_ddl_mysql.sql +++ b/support-files/sql/1001_ci_process_ddl_mysql.sql @@ -1159,6 +1159,7 @@ CREATE TABLE IF NOT EXISTS `T_PIPELINE_BUILD_RECORD_TASK` ( `EXECUTE_COUNT` int(11) NOT NULL DEFAULT '1' COMMENT '执行次数', `STATUS` varchar(32) DEFAULT NULL COMMENT '构建状态', `TASK_VAR` mediumtext NOT NULL COMMENT '当次执行的变量记录', + `POST_INFO` text DEFAULT NULL COMMENT '市场插件的POST关联信息', `CLASS_TYPE` varchar(64) NOT NULL DEFAULT '' COMMENT '项目ID', `ATOM_CODE` varchar(128) NOT NULL DEFAULT '' COMMENT '插件的唯一标识', `ORIGIN_CLASS_TYPE` varchar(64) DEFAULT NULL COMMENT '所在矩阵组ID', diff --git a/support-files/sql/2003_v2.x/2020_ci_process-update_v2.0_mysql.sql b/support-files/sql/2003_v2.x/2020_ci_process-update_v2.0_mysql.sql new file mode 100644 index 00000000000..2f083e64962 --- /dev/null +++ b/support-files/sql/2003_v2.x/2020_ci_process-update_v2.0_mysql.sql @@ -0,0 +1,28 @@ +USE devops_ci_process; +SET NAMES utf8mb4; + +DROP PROCEDURE IF EXISTS ci_process_schema_update; + +DELIMITER + +CREATE PROCEDURE ci_process_schema_update() +BEGIN + + DECLARE db VARCHAR(100); + SET AUTOCOMMIT = 0; + SELECT DATABASE() INTO db; + + IF NOT EXISTS(SELECT 1 + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'T_PIPELINE_BUILD_RECORD_TASK' + AND COLUMN_NAME = 'POST_INFO') THEN + ALTER TABLE `T_PIPELINE_BUILD_RECORD_TASK` + ADD COLUMN `POST_INFO` text DEFAULT NULL COMMENT '市场插件的POST关联信息'; + END IF; + + COMMIT; +END +DELIMITER ; +COMMIT; +CALL ci_process_schema_update(); From 676f7c8d8b53b56fe71d53d94edf5ef4a336b4f2 Mon Sep 17 00:00:00 2001 From: carlyin <449036249@qq.com> Date: Sun, 11 Jun 2023 19:53:31 +0800 Subject: [PATCH 055/166] =?UTF-8?q?feat=EF=BC=9A=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E9=97=AE=E9=A2=98=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20#8955?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pojo/element/ElementAdditionalOptions.kt | 14 ++-- .../engine/service/PipelineElementService.kt | 6 ++ .../service/PipelinePostElementService.kt | 48 ++++++++++---- .../service/record/BaseBuildRecordService.kt | 9 ++- .../record/PipelineRecordModelService.kt | 64 +++++++++++++++---- 5 files changed, 105 insertions(+), 36 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/ElementAdditionalOptions.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/ElementAdditionalOptions.kt index 7561207e858..e94f1061bff 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/ElementAdditionalOptions.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/ElementAdditionalOptions.kt @@ -41,9 +41,9 @@ data class ElementAdditionalOptions( @ApiModelProperty("是否出现跳过按钮(手动继续)", required = false) val manualSkip: Boolean? = null, // (continueWhenFailed = true && manualSkip = true) 出现跳过按钮(手动继续) @ApiModelProperty("是否失败时重试", required = false) - val retryWhenFailed: Boolean = false, + var retryWhenFailed: Boolean = false, @ApiModelProperty("重试计数", required = false) - val retryCount: Int = 0, + var retryCount: Int = 0, @ApiModelProperty("是否允许手动重试", required = false) val manualRetry: Boolean = true, // 自动重试一直失败后,界面出现重试按钮, 默认允许手动重试(为了兼容旧数据使用习惯) @ApiModelProperty("超时分钟", required = false) @@ -53,19 +53,19 @@ data class ElementAdditionalOptions( @JsonIgnore // 表示是否有修改,比如timeout. 注解 @JsonIgnore 表示本字段不会持久到数据库存储,只做临时的校验字段,不做任何保证 var change: Boolean = false, @ApiModelProperty("执行条件", required = false) - val runCondition: RunCondition?, + var runCondition: RunCondition?, @ApiModelProperty("是否配置前置暂停", required = false) var pauseBeforeExec: Boolean? = false, // 是否配置前置暂停 @ApiModelProperty("订阅暂停通知用户", required = false) - val subscriptionPauseUser: String? = "", // 订阅暂停通知用户 + var subscriptionPauseUser: String? = "", // 订阅暂停通知用户 @ApiModelProperty("", required = false) - val otherTask: String? = null, + var otherTask: String? = null, @ApiModelProperty("自定义变量", required = false) val customVariables: List? = null, @ApiModelProperty("自定义条件", required = false) - val customCondition: String? = "", + var customCondition: String? = "", @ApiModelProperty("插件post信息", required = false) - val elementPostInfo: ElementPostInfo? = null, + var elementPostInfo: ElementPostInfo? = null, @ApiModelProperty("是否设置自定义环境变量", required = false) val enableCustomEnv: Boolean? = false, // 是否设置自定义环境变量 @ApiModelProperty("自定义环境变量", required = false) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineElementService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineElementService.kt index cdbbd6ef262..2bd5fc306b4 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineElementService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineElementService.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.engine.service +import com.tencent.devops.common.api.util.Watcher import com.tencent.devops.common.api.util.timestamp import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.Model @@ -70,11 +71,14 @@ class PipelineElementService @Autowired constructor( startParamsMap: MutableMap? = null, handlePostFlag: Boolean = true ) { + val watcher = Watcher(id = "fillElementWhenNewBuild#$pipelineId") + watcher.start("getTemplateIdByPipeline") val templateId = if (model.instanceFromTemplate == true) { templateService.getTemplateIdByPipeline(projectId, pipelineId) } else { null } + watcher.start("getMatchRuleList") val ruleMatchList = getMatchRuleList(projectId, pipelineId, templateId) val qualityRuleFlag = ruleMatchList.isNotEmpty() var beforeElementSet: List? = null @@ -87,6 +91,7 @@ class PipelineElementService @Autowired constructor( elementRuleMap = triple.third } val qaSet = setOf(QualityGateInElement.classType, QualityGateOutElement.classType) + watcher.start("fillElement") model.stages.forEachIndexed { index, stage -> if (index == 0) { return@forEachIndexed @@ -170,6 +175,7 @@ class PipelineElementService @Autowired constructor( container.elements = finalElementList } } + watcher.stop() } fun getMatchRuleList(projectId: String, pipelineId: String, templateId: String?): List { diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt index 8651483aaa2..98f16af6311 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt @@ -203,19 +203,8 @@ class PipelinePostElementService @Autowired constructor( if (originAtomElement.name.length > 128) originAtomElement.name.substring(0, 128) else originAtomElement.name val postCondition = elementPostInfo.postCondition - var postAtomRunCondition = RunCondition.PRE_TASK_SUCCESS - when (postCondition) { - "failed()" -> { - postAtomRunCondition = RunCondition.PRE_TASK_FAILED_ONLY - } - "always()" -> { - postAtomRunCondition = RunCondition.PRE_TASK_FAILED_BUT_CANCEL - } - "canceledOrTimeOut()" -> { - postAtomRunCondition = RunCondition.PARENT_TASK_CANCELED_OR_TIMEOUT - } - } - val additionalOptions = ElementAdditionalOptions( + val postAtomRunCondition = getPostAtomRunCondition(postCondition) +/* val additionalOptions = ElementAdditionalOptions( enable = true, continueWhenFailed = true, retryWhenFailed = false, @@ -227,7 +216,20 @@ class PipelinePostElementService @Autowired constructor( otherTask = null, customCondition = null, elementPostInfo = elementPostInfo - ) + )*/ + val additionalOptions = originAtomElement.additionalOptions + additionalOptions?.let { + additionalOptions.enable = true + additionalOptions.continueWhenFailed = true + additionalOptions.retryWhenFailed = false + additionalOptions.runCondition = postAtomRunCondition + additionalOptions.pauseBeforeExec = null + additionalOptions.subscriptionPauseUser = null + additionalOptions.retryCount = 0 + additionalOptions.otherTask = null + additionalOptions.customCondition = null + additionalOptions.elementPostInfo = elementPostInfo + } // 生成post操作的element val postElementName = "$postPrompt$elementName" if (originAtomElement is MarketBuildAtomElement) { @@ -254,4 +256,22 @@ class PipelinePostElementService @Autowired constructor( finalElementList.add(marketBuildLessAtomElement) } } + + fun getPostAtomRunCondition(postCondition: String): RunCondition { + var postAtomRunCondition = RunCondition.PRE_TASK_SUCCESS + when (postCondition) { + "failed()" -> { + postAtomRunCondition = RunCondition.PRE_TASK_FAILED_ONLY + } + + "always()" -> { + postAtomRunCondition = RunCondition.PRE_TASK_FAILED_BUT_CANCEL + } + + "canceledOrTimeOut()" -> { + postAtomRunCondition = RunCondition.PARENT_TASK_CANCELED_OR_TIMEOUT + } + } + return postAtomRunCondition + } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt index 8515a153279..36a1d8f35ae 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt @@ -176,8 +176,13 @@ open class BaseBuildRecordService( return try { watcher.start("fillElementWhenNewBuild") val fullModel = JsonUtil.to(resourceStr, Model::class.java) - // 为model填充element - pipelineElementService.fillElementWhenNewBuild(fullModel, projectId, pipelineId) + // 为model填充质量红线element + pipelineElementService.fillElementWhenNewBuild( + model = fullModel, + projectId = projectId, + pipelineId = pipelineId, + handlePostFlag = false + ) val baseModelMap = JsonUtil.toMutableMap(fullModel) val mergeBuildRecordParam = MergeBuildRecordParam( projectId = projectId, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/record/PipelineRecordModelService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/record/PipelineRecordModelService.kt index 270b8e0d6c7..0ef88294d55 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/record/PipelineRecordModelService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/record/PipelineRecordModelService.kt @@ -27,16 +27,19 @@ package com.tencent.devops.process.service.record +import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.api.util.JsonUtil.deepCopy import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.container.Container import com.tencent.devops.common.pipeline.container.Stage import com.tencent.devops.common.pipeline.container.VMBuildContainer import com.tencent.devops.common.pipeline.pojo.element.Element +import com.tencent.devops.common.pipeline.pojo.element.ElementAdditionalOptions import com.tencent.devops.common.pipeline.utils.ModelUtils import com.tencent.devops.process.dao.record.BuildRecordContainerDao import com.tencent.devops.process.dao.record.BuildRecordStageDao import com.tencent.devops.process.dao.record.BuildRecordTaskDao +import com.tencent.devops.process.engine.service.PipelinePostElementService import com.tencent.devops.process.pojo.pipeline.record.BuildRecordContainer import com.tencent.devops.process.pojo.pipeline.record.BuildRecordTask import com.tencent.devops.process.pojo.pipeline.record.MergeBuildRecordParam @@ -49,6 +52,7 @@ class PipelineRecordModelService @Autowired constructor( private val buildRecordStageDao: BuildRecordStageDao, private val buildRecordContainerDao: BuildRecordContainerDao, private val buildRecordTaskDao: BuildRecordTaskDao, + private val pipelinePostElementService: PipelinePostElementService, private val dslContext: DSLContext ) { @@ -150,15 +154,21 @@ class PipelineRecordModelService @Autowired constructor( containerVarMap[Container::status.name] = stageRecordContainer.status ?: "" containerVarMap[Container::executeCount.name] = stageRecordContainer.executeCount containerVarMap[Container::containPostTaskFlag.name] = stageRecordContainer.containPostTaskFlag ?: false - handleContainerRecordTask(stageRecordTasks, containerId, containerVarMap) + val stageBaseMap = (pipelineBaseModelMap[Model::stages.name] as List>).first { + it[Stage::id.name] == stageId + } + val containerBaseMap = (stageBaseMap[Stage::containers.name] as List>).first { + it[Container::id.name] == containerId + } + val containerBaseModelMap = containerBaseMap.deepCopy>() + handleContainerRecordTask( + stageRecordTasks = stageRecordTasks, + containerId = containerId, + containerVarMap = containerVarMap, + containerBaseMap = containerBaseModelMap + ) val matrixGroupFlag = stageRecordContainer.matrixGroupFlag if (matrixGroupFlag == true) { - val stageBaseMap = (pipelineBaseModelMap[Model::stages.name] as List>).first { - it[Stage::id.name] == stageId - } - val containerBaseMap = (stageBaseMap[Stage::containers.name] as List>).first { - it[Container::id.name] == containerId - } // 过滤出矩阵分裂出的job数据 val matrixRecordContainers = stageRecordContainers.filter { it.matrixGroupId == containerId }.sortedBy { it.containerId.toInt() } @@ -167,7 +177,6 @@ class PipelineRecordModelService @Autowired constructor( // 生成矩阵job的变量模型 var matrixContainerVarMap = matrixRecordContainer.containerVar val matrixContainerId = matrixRecordContainer.containerId - val containerBaseModelMap = containerBaseMap.deepCopy>() matrixContainerVarMap[Container::id.name] = matrixContainerId matrixContainerVarMap[Container::status.name] = matrixRecordContainer.status ?: "" matrixContainerVarMap[Container::executeCount.name] = matrixRecordContainer.executeCount @@ -177,7 +186,8 @@ class PipelineRecordModelService @Autowired constructor( stageRecordTasks = stageRecordTasks, containerId = matrixContainerId, containerVarMap = matrixContainerVarMap, - containerBaseMap = containerBaseModelMap + containerBaseMap = containerBaseModelMap, + matrixTaskFlag = true ) containerBaseModelMap.remove(VMBuildContainer::matrixControlOption.name) containerBaseModelMap.remove(VMBuildContainer::groupContainers.name) @@ -199,7 +209,8 @@ class PipelineRecordModelService @Autowired constructor( stageRecordTasks: List, containerId: String, containerVarMap: MutableMap, - containerBaseMap: Map? = null + containerBaseMap: Map, + matrixTaskFlag: Boolean = false ) { // 过滤出job下的task变量数据 val containerRecordTasks = stageRecordTasks.filter { it.containerId == containerId }.sortedBy { it.taskSeq } @@ -210,10 +221,37 @@ class PipelineRecordModelService @Autowired constructor( taskVarMap[Element::id.name] = taskId taskVarMap[Element::status.name] = containerRecordTask.status ?: "" taskVarMap[Element::executeCount.name] = containerRecordTask.executeCount - containerBaseMap?.let { + val elementPostInfo = containerRecordTask.elementPostInfo + if (elementPostInfo != null) { + // 生成post类型task的变量模型 + val additionalOptions = ElementAdditionalOptions( + enable = true, + continueWhenFailed = true, + retryWhenFailed = false, + runCondition = pipelinePostElementService.getPostAtomRunCondition(elementPostInfo.postCondition), + pauseBeforeExec = null, + subscriptionPauseUser = null, + otherTask = null, + customCondition = null, + elementPostInfo = elementPostInfo + ) + val additionalOptionsMap = taskVarMap[Element::additionalOptions.name] as? MutableMap + val finalAdditionalOptionsMap = if (additionalOptionsMap != null) { + ModelUtils.generateBuildModelDetail(additionalOptionsMap, JsonUtil.toMutableMap(additionalOptions)) + } else { + JsonUtil.toMutableMap(additionalOptions) + } + taskVarMap[Element::additionalOptions.name] = finalAdditionalOptionsMap + val parentElementJobIndex = elementPostInfo.parentElementJobIndex + val taskBaseMap = + (containerBaseMap[Container::elements.name] as List>)[parentElementJobIndex] + taskVarMap = ModelUtils.generateBuildModelDetail(taskBaseMap.toMutableMap(), taskVarMap) + } + if (matrixTaskFlag && elementPostInfo == null) { // 生成矩阵task的变量模型 - val taskBaseMap = (it[Container::elements.name] as List>)[index].toMutableMap() - taskVarMap = ModelUtils.generateBuildModelDetail(taskBaseMap, taskVarMap) + val taskBaseMap = + (containerBaseMap[Container::elements.name] as List>)[index] + taskVarMap = ModelUtils.generateBuildModelDetail(taskBaseMap.toMutableMap(), taskVarMap) } tasks.add(taskVarMap) } From b0d0483a337b74f48614663ccaf73aba830f0a48 Mon Sep 17 00:00:00 2001 From: carlyin <449036249@qq.com> Date: Sun, 11 Jun 2023 20:17:17 +0800 Subject: [PATCH 056/166] =?UTF-8?q?pref:=E8=BF=9B=E5=85=A5=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E6=B5=81=E6=B0=B4=E7=BA=BF=E8=AF=A6=E6=83=85=E9=A1=B5?= =?UTF-8?q?=E8=80=97=E6=97=B6=E4=BC=98=E5=8C=96=20#8956?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/PipelinePostElementService.kt | 19 +++++-------------- .../record/PipelineRecordModelService.kt | 2 ++ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt index 98f16af6311..f212cf6cce7 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt @@ -204,19 +204,6 @@ class PipelinePostElementService @Autowired constructor( else originAtomElement.name val postCondition = elementPostInfo.postCondition val postAtomRunCondition = getPostAtomRunCondition(postCondition) -/* val additionalOptions = ElementAdditionalOptions( - enable = true, - continueWhenFailed = true, - retryWhenFailed = false, - runCondition = postAtomRunCondition, - pauseBeforeExec = null, - subscriptionPauseUser = null, - customVariables = originAtomElement.additionalOptions?.customVariables, - retryCount = 0, - otherTask = null, - customCondition = null, - elementPostInfo = elementPostInfo - )*/ val additionalOptions = originAtomElement.additionalOptions additionalOptions?.let { additionalOptions.enable = true @@ -231,7 +218,7 @@ class PipelinePostElementService @Autowired constructor( additionalOptions.elementPostInfo = elementPostInfo } // 生成post操作的element - val postElementName = "$postPrompt$elementName" + val postElementName = getPostElementName(elementName) if (originAtomElement is MarketBuildAtomElement) { val marketBuildAtomElement = MarketBuildAtomElement( name = postElementName, @@ -257,6 +244,10 @@ class PipelinePostElementService @Autowired constructor( } } + fun getPostElementName(elementName: String): String { + return "$postPrompt$elementName" + } + fun getPostAtomRunCondition(postCondition: String): RunCondition { var postAtomRunCondition = RunCondition.PRE_TASK_SUCCESS when (postCondition) { diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/record/PipelineRecordModelService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/record/PipelineRecordModelService.kt index 0ef88294d55..f5acf6a7fbd 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/record/PipelineRecordModelService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/record/PipelineRecordModelService.kt @@ -245,6 +245,8 @@ class PipelineRecordModelService @Autowired constructor( val parentElementJobIndex = elementPostInfo.parentElementJobIndex val taskBaseMap = (containerBaseMap[Container::elements.name] as List>)[parentElementJobIndex] + val taskName = taskBaseMap[Element::name.name]?.toString() ?: "" + taskVarMap[Element::name.name] = pipelinePostElementService.getPostElementName(taskName) taskVarMap = ModelUtils.generateBuildModelDetail(taskBaseMap.toMutableMap(), taskVarMap) } if (matrixTaskFlag && elementPostInfo == null) { From ef1ee316df7409737d5951ba181e7bafed72a1c5 Mon Sep 17 00:00:00 2001 From: carlyin <449036249@qq.com> Date: Mon, 12 Jun 2023 10:05:56 +0800 Subject: [PATCH 057/166] =?UTF-8?q?pref:=E8=BF=9B=E5=85=A5=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E6=B5=81=E6=B0=B4=E7=BA=BF=E8=AF=A6=E6=83=85=E9=A1=B5?= =?UTF-8?q?=E8=80=97=E6=97=B6=E4=BC=98=E5=8C=96=20#8956?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/engine/service/PipelinePostElementService.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt index f212cf6cce7..920c4502bf4 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelinePostElementService.kt @@ -32,7 +32,6 @@ import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.enums.BuildStatus import com.tencent.devops.common.pipeline.pojo.element.Element -import com.tencent.devops.common.pipeline.pojo.element.ElementAdditionalOptions import com.tencent.devops.common.pipeline.pojo.element.ElementBaseInfo import com.tencent.devops.common.pipeline.pojo.element.ElementPostInfo import com.tencent.devops.common.pipeline.pojo.element.RunCondition From 6f6a2d4f220430899d6bd87f27691564f932738d Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Mon, 12 Jun 2023 10:23:16 +0800 Subject: [PATCH 058/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/auth/service/migrate/MigrateIamApiService.kt | 2 +- .../devops/auth/service/migrate/RbacPermissionMigrateService.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateIamApiService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateIamApiService.kt index ab1b7d64410..16eb24a43a3 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateIamApiService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateIamApiService.kt @@ -166,7 +166,7 @@ class MigrateIamApiService { private fun getBody(operation: String, request: Request): String { OkhttpUtils.doHttp(request).use { response -> val responseContent = response.body!!.string() - logger.info("request ${request.url} response|$responseContent") + logger.info("request iam migrate api ${request.url} response|$responseContent") if (!response.isSuccessful) { logger.warn("Failed to request(${request.url}), code ${response.code}, content: $responseContent") throw RemoteServiceException(operation) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt index 0490b0a58d3..7ca61af2da0 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt @@ -405,7 +405,7 @@ class RbacPermissionMigrateService constructor( exception.defaultMessage } is CompletionException -> { - exception.cause?.message + exception.cause?.message ?: exception.message } else -> { exception.toString() From d796cf16d257d78515a0b5f2c45ff98b7ccc02f2 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 12 Jun 2023 10:36:09 +0800 Subject: [PATCH 059/166] =?UTF-8?q?feat=EF=BC=9A=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E9=97=AE=E9=A2=98=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20#8955=20=E8=A1=A5=E5=85=85websocket=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/engine/service/record/BaseBuildRecordService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt index 8515a153279..58af360dbaf 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt @@ -195,7 +195,7 @@ open class BaseBuildRecordService( modelFieldRecordMap = recordMap ) } catch (t: Throwable) { - PipelineBuildRecordService.logger.warn( + logger.warn( "RECORD|parse record($buildId)-recordMap(${JsonUtil.toJson(recordMap ?: "")})" + "-$executeCount with error: ", t ) From 85b86871e6228de93e853bb5d828461fb64b6dde Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Fri, 9 Jun 2023 15:18:34 +0800 Subject: [PATCH 060/166] =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BFLATEST=20STA?= =?UTF-8?q?TUS=20=E7=8A=B6=E6=80=81=E5=8F=96=E6=9C=80=E6=96=B0=E6=AC=A1?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E7=9A=84=E7=8A=B6=E6=80=81=20#8907?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/engine/dao/PipelineBuildSummaryDao.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineBuildSummaryDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineBuildSummaryDao.kt index d0ca424bca8..0119c9928e8 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineBuildSummaryDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineBuildSummaryDao.kt @@ -471,9 +471,15 @@ class PipelineBuildSummaryDao { dslContext.update(this) .let { if (executeCount == 1) { - // 只有首次才写入LATEST_BUILD_ID和LATEST_STATUS,重试不写入 + // 只有首次才写入LATEST_BUILD_ID it.set(LATEST_BUILD_ID, buildId).set(LATEST_STATUS, status.ordinal) - } else it + } else { + // 重试时只有最新的构建才能刷新LATEST_STATUS + it.set( + LATEST_STATUS, + DSL.`when`(LATEST_BUILD_ID.eq(buildId), status.ordinal).otherwise(LATEST_STATUS) + ) + } } .set(LATEST_TASK_COUNT, taskCount) .set(LATEST_START_USER, userId) From e78301246d5fe0c45d2c389eaa26f1ca4b7084aa Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Mon, 12 Jun 2023 11:01:31 +0800 Subject: [PATCH 061/166] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=9E=84=E5=BB=BA=E7=8E=AF=E5=A2=83=E7=9A=84=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E6=9C=BA=E5=88=97=E8=A1=A8=20#8947?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/apigw/v4/environment/ApigwEnvironmentResourceV4.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/environment/ApigwEnvironmentResourceV4.kt b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/environment/ApigwEnvironmentResourceV4.kt index 2c04282286e..5a4adb2dd1c 100644 --- a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/environment/ApigwEnvironmentResourceV4.kt +++ b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/environment/ApigwEnvironmentResourceV4.kt @@ -373,8 +373,8 @@ interface ApigwEnvironmentResourceV4 { @ApiParam("环境 hashId (envHashId和envName选填一项)", required = false) @QueryParam("envHashId") envHashId: String?, - @ApiParam("环境名称", required = false) - @QueryParam("envName (envHashId和envName选填一项)") + @ApiParam("环境名称 (envHashId和envName选填一项)", required = false) + @QueryParam("envName") envName: String? ): Result> } From 635444cd09645517f9548d0cbb37f4aeb8160864 Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Mon, 12 Jun 2023 11:11:34 +0800 Subject: [PATCH 062/166] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=9E=84=E5=BB=BA=E7=8E=AF=E5=A2=83=E7=9A=84=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E6=9C=BA=E5=88=97=E8=A1=A8=20#8947?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/environment/api/ServiceNodeResource.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/environment/api-environment/src/main/kotlin/com/tencent/devops/environment/api/ServiceNodeResource.kt b/src/backend/ci/core/environment/api-environment/src/main/kotlin/com/tencent/devops/environment/api/ServiceNodeResource.kt index b30fdfaec12..7913431effd 100644 --- a/src/backend/ci/core/environment/api-environment/src/main/kotlin/com/tencent/devops/environment/api/ServiceNodeResource.kt +++ b/src/backend/ci/core/environment/api-environment/src/main/kotlin/com/tencent/devops/environment/api/ServiceNodeResource.kt @@ -187,8 +187,8 @@ interface ServiceNodeResource { @ApiParam("环境 hashId (envHashId和envName选填一项)", required = false) @QueryParam("envHashId") envHashId: String?, - @ApiParam("环境名称", required = false) - @QueryParam("envName (envHashId和envName选填一项)") + @ApiParam("环境名称 (envHashId和envName选填一项)", required = false) + @QueryParam("envName") envName: String? ): Result> } From 8e814f6549f4ef99ea45f560c6ab625b7dc27b2b Mon Sep 17 00:00:00 2001 From: carlyin <449036249@qq.com> Date: Mon, 12 Jun 2023 11:39:04 +0800 Subject: [PATCH 063/166] =?UTF-8?q?pref:=E8=BF=9B=E5=85=A5=E5=A4=8D?= =?UTF-8?q?=E6=9D=82=E6=B5=81=E6=B0=B4=E7=BA=BF=E8=AF=A6=E6=83=85=E9=A1=B5?= =?UTF-8?q?=E8=80=97=E6=97=B6=E4=BC=98=E5=8C=96=20#8956?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/pojo/pipeline/record/BuildRecordTask.kt | 2 +- .../tencent/devops/process/dao/record/BuildRecordTaskDao.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt index 3a895351397..bf3b02c0870 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/record/BuildRecordTask.kt @@ -57,7 +57,7 @@ data class BuildRecordTask( @ApiModelProperty("执行变量", required = true) var taskVar: MutableMap, @ApiModelProperty("插件post信息", required = false) - val elementPostInfo: ElementPostInfo?, + val elementPostInfo: ElementPostInfo? = null, @ApiModelProperty("插件类型标识", required = true) val classType: String, @ApiModelProperty("市场插件标识", required = true) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt index 59898dee274..8e599a44f79 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/record/BuildRecordTaskDao.kt @@ -240,7 +240,8 @@ class BuildRecordTaskDao { private fun TPipelineBuildRecordTask.generateBuildRecordTask( record: Record18 + String, String, Int, Int, String, String, String, + String, String, LocalDateTime, LocalDateTime, String, String> ) = BuildRecordTask( buildId = record[BUILD_ID], From f400f89ecc53e3db57bde51894ccc987db8125fc Mon Sep 17 00:00:00 2001 From: stubenhuang Date: Mon, 12 Jun 2023 11:57:58 +0800 Subject: [PATCH 064/166] =?UTF-8?q?feat:=20JerseyConfig=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E5=AE=8C=E4=B9=8B=E5=90=8E=E7=AB=AF=E5=8F=A3=E6=89=8D?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E8=AE=BF=E9=97=AE=20#8946?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/common-web/src/main/resources/common-web.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties b/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties index dd48fa1b3cd..a72e4973c7e 100644 --- a/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties +++ b/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties @@ -31,3 +31,4 @@ server.servlet-path=/ server.undertow.accesslog.enabled=false server.undertow.accesslog.pattern='%h %I "%{i,X-DEVOPS-UID}" [%{time,yyyyMMddHHmmss.S}] "%r" %s %b "%{i,Referer}" "%{i,User-Agent}"' server.shutdown=graceful +spring.jersey.servlet.loadOnStartup=1 \ No newline at end of file From 58d8dc1ad80c410f1adae0b2f26362ac371cd8ec Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Mon, 12 Jun 2023 12:04:36 +0800 Subject: [PATCH 065/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/ci/boot-assembly/build.gradle.kts | 6 --- src/backend/ci/build.gradle.kts | 1 + .../src/main/kotlin/constants/Versions.kt | 1 + .../api/user/UserAuthPermissionResource.kt | 1 + .../tencent/devops/auth/AuthConfiguration.kt | 2 +- .../common/api/util/ReplacementUtilsTest.kt | 8 ++++ .../auth/BluekingV3AuthAutoConfiguration.kt | 6 +-- .../expression/utils/AntPathMatcher.java | 1 - .../expression/utils/CollectionUtils.java | 3 +- .../common/expression/utils/StringUtils.java | 3 +- .../sendmessage/richtext/RichtextMessage.kt | 1 + .../docker/client/BuildLessStartHandler.kt | 1 + .../notify/api/builds/BuildNotifyResource.kt | 1 - .../notify/command/impl/NotifySendCmd.kt | 3 +- .../service/template/TemplateFacadeService.kt | 2 +- .../project/service/ProjectTagService.kt | 2 +- .../service/impl/AbsProjectServiceImpl.kt | 5 +++ .../service/v2/QualityIndicatorService.kt | 6 ++- .../repository/service/scm/IGitService.kt | 2 +- .../common/impl/SampleStoreLogoServiceImpl.kt | 5 ++- .../atom/impl/AtomReleaseServiceImpl.kt | 39 +++++++++++++------ .../service/StreamPipelineBadgeService.kt | 1 - 22 files changed, 63 insertions(+), 37 deletions(-) diff --git a/src/backend/ci/boot-assembly/build.gradle.kts b/src/backend/ci/boot-assembly/build.gradle.kts index e8d847ed964..963d9ce13af 100644 --- a/src/backend/ci/boot-assembly/build.gradle.kts +++ b/src/backend/ci/boot-assembly/build.gradle.kts @@ -26,12 +26,6 @@ */ dependencies { - - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") - implementation("org.jetbrains.kotlin:kotlin-reflect") - testImplementation("junit:junit") - testImplementation("org.springframework.boot:spring-boot-starter-test") - implementation(project(":core:common:common-auth:common-auth-mock")) implementation(project(":core:common:common-auth:common-auth-blueking")) implementation(project(":core:common:common-auth:common-auth-v3")) diff --git a/src/backend/ci/build.gradle.kts b/src/backend/ci/build.gradle.kts index a447990558a..7bcef3f4ce2 100644 --- a/src/backend/ci/build.gradle.kts +++ b/src/backend/ci/build.gradle.kts @@ -58,6 +58,7 @@ allprojects { dependency("org.apache.pulsar:pulsar-client:${Versions.Pulsar}") dependency("com.github.oshi:oshi-core:${Versions.Oshi}") dependency("com.tencent.devops.leaf:leaf-boot-starter:${Versions.Leaf}") + dependency("com.github.xingePush:xinge:${Versions.Xinge}") dependency("org.reflections:reflections:${Versions.reflections}") dependency("org.dom4j:dom4j:${Versions.Dom4j}") dependency("org.apache.commons:commons-compress:${Versions.Compress}") diff --git a/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt b/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt index b854d5ce6b8..c07978a97c0 100644 --- a/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt +++ b/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt @@ -38,6 +38,7 @@ object Versions { const val Leaf = "1.0.2-RELEASE" const val p4 = "2021.1.2163843" const val YamlSchema = "1.0.49" + const val Xinge = "1.2.4.9" const val Pulsar = "2.7.2" const val reflections = "0.10.2" const val mockk = "1.12.2" diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthPermissionResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthPermissionResource.kt index 2e019692150..b331fba962d 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthPermissionResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/user/UserAuthPermissionResource.kt @@ -47,6 +47,7 @@ import javax.ws.rs.core.MediaType @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) interface UserAuthPermissionResource { + @POST @Path("/batch/validate") @ApiOperation("批量校验用户是否拥有某个资源实例的操作") diff --git a/src/backend/ci/core/auth/biz-auth-blueking/src/main/kotlin/com/tencent/devops/auth/AuthConfiguration.kt b/src/backend/ci/core/auth/biz-auth-blueking/src/main/kotlin/com/tencent/devops/auth/AuthConfiguration.kt index bc52a5e3bae..5c82f82a3bf 100644 --- a/src/backend/ci/core/auth/biz-auth-blueking/src/main/kotlin/com/tencent/devops/auth/AuthConfiguration.kt +++ b/src/backend/ci/core/auth/biz-auth-blueking/src/main/kotlin/com/tencent/devops/auth/AuthConfiguration.kt @@ -83,7 +83,7 @@ class AuthConfiguration { @Value("\${auth.url:}") val iamBaseUrl = "" - @Value("\${auth.appCode:}") + @Value("\${auth.iamSystem:}") val systemId = "" @Value("\${auth.appCode:}") diff --git a/src/backend/ci/core/common/common-api/src/test/kotlin/com/tencent/devops/common/api/util/ReplacementUtilsTest.kt b/src/backend/ci/core/common/common-api/src/test/kotlin/com/tencent/devops/common/api/util/ReplacementUtilsTest.kt index efb542e148f..bf69e8acd3d 100644 --- a/src/backend/ci/core/common/common-api/src/test/kotlin/com/tencent/devops/common/api/util/ReplacementUtilsTest.kt +++ b/src/backend/ci/core/common/common-api/src/test/kotlin/com/tencent/devops/common/api/util/ReplacementUtilsTest.kt @@ -37,6 +37,14 @@ class ReplacementUtilsTest { override fun getReplacement(key: String): String? = data[key] } + @Test + fun parseEnvNested() { + val data = HashMap() + data["Nested"] = "first" + data["first"] = "hello" + parseAndEquals(data = data, template = "\${\${Nested}}.html", expect = "hello.html") + } + @Test fun parseTwice() { val map = mutableMapOf() diff --git a/src/backend/ci/core/common/common-auth/common-auth-v3/src/main/kotlin/com/tencent/devops/common/auth/BluekingV3AuthAutoConfiguration.kt b/src/backend/ci/core/common/common-auth/common-auth-v3/src/main/kotlin/com/tencent/devops/common/auth/BluekingV3AuthAutoConfiguration.kt index 73c7ec143cc..55f015b2c4e 100644 --- a/src/backend/ci/core/common/common-auth/common-auth-v3/src/main/kotlin/com/tencent/devops/common/auth/BluekingV3AuthAutoConfiguration.kt +++ b/src/backend/ci/core/common/common-auth/common-auth-v3/src/main/kotlin/com/tencent/devops/common/auth/BluekingV3AuthAutoConfiguration.kt @@ -33,10 +33,10 @@ import com.tencent.bk.sdk.iam.service.impl.DefaultHttpClientServiceImpl import com.tencent.bk.sdk.iam.service.impl.GrantServiceImpl import com.tencent.bk.sdk.iam.service.impl.PolicyServiceImpl import com.tencent.bk.sdk.iam.service.impl.TokenServiceImpl +import com.tencent.devops.common.auth.api.BluekingV3AuthPermissionApi import com.tencent.devops.common.auth.api.BluekingV3AuthProjectApi -import com.tencent.devops.common.auth.api.BluekingV3ResourceApi import com.tencent.devops.common.auth.api.BluekingV3AuthTokenApi -import com.tencent.devops.common.auth.api.BluekingV3AuthPermissionApi +import com.tencent.devops.common.auth.api.BluekingV3ResourceApi import com.tencent.devops.common.auth.code.BluekingV3ArtifactoryAuthServiceCode import com.tencent.devops.common.auth.code.BluekingV3BcsAuthServiceCode import com.tencent.devops.common.auth.code.BluekingV3CodeAuthServiceCode @@ -70,7 +70,7 @@ class BluekingV3AuthAutoConfiguration { @Value("\${auth.url:}") val iamBaseUrl = "" - @Value("\${auth.appCode:}") + @Value("\${auth.iamSystem:}") val systemId = "" @Value("\${auth.appCode:}") diff --git a/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/AntPathMatcher.java b/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/AntPathMatcher.java index 3c22a720a48..005586111a1 100644 --- a/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/AntPathMatcher.java +++ b/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/AntPathMatcher.java @@ -23,7 +23,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; - import org.jetbrains.annotations.Nullable; /** diff --git a/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/CollectionUtils.java b/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/CollectionUtils.java index 1fc7a9fc0d3..2375627df15 100644 --- a/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/CollectionUtils.java +++ b/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/CollectionUtils.java @@ -16,9 +16,8 @@ package com.tencent.devops.common.expression.utils; -import org.jetbrains.annotations.Nullable; - import java.util.Collection; +import org.jetbrains.annotations.Nullable; @SuppressWarnings("all") public abstract class CollectionUtils { diff --git a/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/StringUtils.java b/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/StringUtils.java index d297dd68d41..c73ea13f467 100644 --- a/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/StringUtils.java +++ b/src/backend/ci/core/common/common-expression/src/main/java/com/tencent/devops/common/expression/utils/StringUtils.java @@ -16,12 +16,11 @@ package com.tencent.devops.common.expression.utils; -import org.jetbrains.annotations.Nullable; - import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.StringTokenizer; +import org.jetbrains.annotations.Nullable; @SuppressWarnings("all") public abstract class StringUtils { diff --git a/src/backend/ci/core/common/common-wechatwork/src/main/kotlin/com/tencent/devops/common/wechatwork/model/sendmessage/richtext/RichtextMessage.kt b/src/backend/ci/core/common/common-wechatwork/src/main/kotlin/com/tencent/devops/common/wechatwork/model/sendmessage/richtext/RichtextMessage.kt index 450f0280270..e5a5a0bf121 100644 --- a/src/backend/ci/core/common/common-wechatwork/src/main/kotlin/com/tencent/devops/common/wechatwork/model/sendmessage/richtext/RichtextMessage.kt +++ b/src/backend/ci/core/common/common-wechatwork/src/main/kotlin/com/tencent/devops/common/wechatwork/model/sendmessage/richtext/RichtextMessage.kt @@ -26,6 +26,7 @@ */ package com.tencent.devops.common.wechatwork.model.sendmessage.richtext + import com.fasterxml.jackson.annotation.JsonProperty import com.tencent.devops.common.wechatwork.model.sendmessage.Receiver diff --git a/src/backend/ci/core/dispatch-docker/biz-dispatch-docker/src/main/kotlin/com/tencent/devops/dispatch/docker/client/BuildLessStartHandler.kt b/src/backend/ci/core/dispatch-docker/biz-dispatch-docker/src/main/kotlin/com/tencent/devops/dispatch/docker/client/BuildLessStartHandler.kt index 1df44f9142c..c39b09f7ee5 100644 --- a/src/backend/ci/core/dispatch-docker/biz-dispatch-docker/src/main/kotlin/com/tencent/devops/dispatch/docker/client/BuildLessStartHandler.kt +++ b/src/backend/ci/core/dispatch-docker/biz-dispatch-docker/src/main/kotlin/com/tencent/devops/dispatch/docker/client/BuildLessStartHandler.kt @@ -63,6 +63,7 @@ class BuildLessStartHandler @Autowired constructor( ) : Handler() { private val logger = LoggerFactory.getLogger(BuildLessStartHandler::class.java) + @Suppress("NestedBlockDepth") override fun handlerRequest(handlerContext: BuildLessStartHandlerContext) { with(handlerContext) { val buildLessStartInfo = BuildLessStartInfo( diff --git a/src/backend/ci/core/notify/api-notify/src/main/kotlin/com/tencent/devops/notify/api/builds/BuildNotifyResource.kt b/src/backend/ci/core/notify/api-notify/src/main/kotlin/com/tencent/devops/notify/api/builds/BuildNotifyResource.kt index 0bb6d84e5c1..ea4420d1d05 100644 --- a/src/backend/ci/core/notify/api-notify/src/main/kotlin/com/tencent/devops/notify/api/builds/BuildNotifyResource.kt +++ b/src/backend/ci/core/notify/api-notify/src/main/kotlin/com/tencent/devops/notify/api/builds/BuildNotifyResource.kt @@ -63,7 +63,6 @@ interface BuildNotifyResource { fun sendRtxNotify( @ApiParam(value = "RTX信息内容", required = true) message: RtxNotifyMessage - ): Result @ApiOperation("发送电子邮件通知") diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/notify/command/impl/NotifySendCmd.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/notify/command/impl/NotifySendCmd.kt index 1b7dacb0637..c9c0e4c1d13 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/notify/command/impl/NotifySendCmd.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/notify/command/impl/NotifySendCmd.kt @@ -4,12 +4,11 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.client.Client import com.tencent.devops.notify.api.service.ServiceNotifyMessageTemplateResource import com.tencent.devops.notify.pojo.SendNotifyMessageTemplateRequest -import com.tencent.devops.process.notify.command.NotifyCmd import com.tencent.devops.process.notify.command.BuildNotifyContext +import com.tencent.devops.process.notify.command.NotifyCmd import com.tencent.devops.process.pojo.PipelineNotifyTemplateEnum import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service -import java.lang.IllegalArgumentException @Service class NotifySendCmd @Autowired constructor( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt index 1abda49f153..e806b2fdf20 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt @@ -1063,7 +1063,7 @@ class TemplateFacadeService @Autowired constructor( ?: throw NotFoundException( I18nUtil.getCodeLanMessage( messageCode = ERROR_TEMPLATE_NOT_EXISTS, - language = userId + language = I18nUtil.getLanguage(userId) )) val template: Model = objectMapper.readValue( templateDao.getTemplate(dslContext = dslContext, version = templatePipelineRecord.version).template diff --git a/src/backend/ci/core/project/biz-project/src/main/kotlin/com/tencent/devops/project/service/ProjectTagService.kt b/src/backend/ci/core/project/biz-project/src/main/kotlin/com/tencent/devops/project/service/ProjectTagService.kt index 7c49b75a0d0..1d0369ea20f 100644 --- a/src/backend/ci/core/project/biz-project/src/main/kotlin/com/tencent/devops/project/service/ProjectTagService.kt +++ b/src/backend/ci/core/project/biz-project/src/main/kotlin/com/tencent/devops/project/service/ProjectTagService.kt @@ -126,7 +126,7 @@ class ProjectTagService @Autowired constructor( fun updateTagByProject(projectTagUpdateDTO: ProjectTagUpdateDTO): Result { logger.info("updateTagByProject: $projectTagUpdateDTO") checkRouteTag(projectTagUpdateDTO.routerTag) - checkProject(projectTagUpdateDTO.projectCodeList) + // checkProject(projectTagUpdateDTO.projectCodeList) projectTagDao.updateProjectTags( dslContext = dslContext, englishNames = projectTagUpdateDTO.projectCodeList!!, diff --git a/src/backend/ci/core/project/biz-project/src/main/kotlin/com/tencent/devops/project/service/impl/AbsProjectServiceImpl.kt b/src/backend/ci/core/project/biz-project/src/main/kotlin/com/tencent/devops/project/service/impl/AbsProjectServiceImpl.kt index 08d86efd78c..a5eaf18595d 100644 --- a/src/backend/ci/core/project/biz-project/src/main/kotlin/com/tencent/devops/project/service/impl/AbsProjectServiceImpl.kt +++ b/src/backend/ci/core/project/biz-project/src/main/kotlin/com/tencent/devops/project/service/impl/AbsProjectServiceImpl.kt @@ -847,6 +847,11 @@ abstract class AbsProjectServiceImpl @Autowired constructor( accessToken: String? ): Result { logger.info("Update the logo of project : englishName = $englishName") + val verify = validatePermission(englishName, userId, AuthPermission.EDIT) + if (!verify) { + logger.info("$englishName| $userId| ${AuthPermission.EDIT} validatePermission fail") + throw PermissionForbiddenException(I18nUtil.getCodeLanMessage(ProjectMessageCode.PEM_CHECK_FAIL)) + } val projectRecord = projectDao.getByEnglishName(dslContext, englishName) if (projectRecord != null) { var logoFile: File? = null diff --git a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt index b50ac3deb2f..6acf1ba6b1d 100644 --- a/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt +++ b/src/backend/ci/core/quality/biz-quality/src/main/kotlin/com/tencent/devops/quality/service/v2/QualityIndicatorService.kt @@ -337,7 +337,11 @@ class QualityIndicatorService @Autowired constructor( if (indicatorDao.create(userId, indicatorUpdate, dslContext) > 0) { return Msg(0, I18nUtil.getCodeLanMessage(BK_CREATE_SUCCESS), true) } - return Msg(-1, I18nUtil.getCodeLanMessage(messageCode = BK_CREATE_FAIL, language = userId), false) + return Msg( + -1, + I18nUtil.getCodeLanMessage(messageCode = BK_CREATE_FAIL, language = I18nUtil.getLanguage(userId)), + false + ) } fun userDelete(userId: String, id: Long): Boolean { diff --git a/src/backend/ci/core/repository/biz-repository/src/main/kotlin/com/tencent/devops/repository/service/scm/IGitService.kt b/src/backend/ci/core/repository/biz-repository/src/main/kotlin/com/tencent/devops/repository/service/scm/IGitService.kt index 4d368561c20..3937859d8fa 100644 --- a/src/backend/ci/core/repository/biz-repository/src/main/kotlin/com/tencent/devops/repository/service/scm/IGitService.kt +++ b/src/backend/ci/core/repository/biz-repository/src/main/kotlin/com/tencent/devops/repository/service/scm/IGitService.kt @@ -170,7 +170,7 @@ interface IGitService { repoName: String, mrId: Long, tokenType: - TokenTypeEnum, + TokenTypeEnum, token: String, repoUrl: String? = null ): GitMrInfo diff --git a/src/backend/ci/core/store/biz-store-sample/src/main/kotlin/com/tencent/devops/store/service/common/impl/SampleStoreLogoServiceImpl.kt b/src/backend/ci/core/store/biz-store-sample/src/main/kotlin/com/tencent/devops/store/service/common/impl/SampleStoreLogoServiceImpl.kt index c3a325538fc..40c63a9addd 100644 --- a/src/backend/ci/core/store/biz-store-sample/src/main/kotlin/com/tencent/devops/store/service/common/impl/SampleStoreLogoServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store-sample/src/main/kotlin/com/tencent/devops/store/service/common/impl/SampleStoreLogoServiceImpl.kt @@ -31,9 +31,10 @@ import com.tencent.devops.artifactory.api.service.ServiceFileResource import com.tencent.devops.artifactory.pojo.enums.FileChannelTypeEnum import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.service.utils.CommonUtils +import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.store.utils.StoreUtils -import org.springframework.stereotype.Service import java.io.File +import org.springframework.stereotype.Service @Service class SampleStoreLogoServiceImpl : StoreLogoServiceImpl() { @@ -46,7 +47,7 @@ class SampleStoreLogoServiceImpl : StoreLogoServiceImpl() { file = file, fileChannelType = FileChannelTypeEnum.WEB_SHOW.name, logo = true, - language = userId + language = I18nUtil.getLanguage(userId) ).data // 开源版如果logoUrl的域名和ci域名一样,则logoUrl无需带上域名,防止域名变更影响图片显示(logoUrl会存db) return Result(if (logoUrl != null) StoreUtils.removeUrlHost(logoUrl) else logoUrl) diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt index ba244cd7763..8a1bac50978 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt @@ -192,8 +192,9 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ if (codeCount > 0) { // 抛出错误提示 return I18nUtil.generateResponseDataObject( - CommonMessageCode.PARAMETER_IS_EXIST, - arrayOf(atomCode) + messageCode = CommonMessageCode.PARAMETER_IS_EXIST, + params = arrayOf(atomCode), + language = I18nUtil.getLanguage(I18nUtil.getRequestUserId()) ) } val atomName = marketAtomCreateRequest.name @@ -202,8 +203,9 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ if (nameCount > 0) { // 抛出错误提示 return I18nUtil.generateResponseDataObject( - CommonMessageCode.PARAMETER_IS_EXIST, - arrayOf(atomName) + messageCode = CommonMessageCode.PARAMETER_IS_EXIST, + params = arrayOf(atomName), + language = I18nUtil.getLanguage(I18nUtil.getRequestUserId()) ) } return null @@ -309,7 +311,11 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ // 判断插件是不是首次创建版本 val atomCount = atomDao.countByCode(dslContext, atomCode) if (atomCount < 1) { - return I18nUtil.generateResponseDataObject(CommonMessageCode.PARAMETER_IS_INVALID, arrayOf(atomCode)) + return I18nUtil.generateResponseDataObject( + messageCode = CommonMessageCode.PARAMETER_IS_INVALID, + params = arrayOf(atomCode), + language = I18nUtil.getLanguage(userId) + ) } val atomRecord = atomDao.getMaxVersionAtomByCode(dslContext, atomCode)!! val releaseType = marketAtomUpdateRequest.releaseType @@ -331,8 +337,9 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ ) if (getAtomConfResult.errorCode != "0") { return I18nUtil.generateResponseDataObject( - getAtomConfResult.errorCode, - getAtomConfResult.errorParams + messageCode = getAtomConfResult.errorCode, + params = getAtomConfResult.errorParams, + language = I18nUtil.getLanguage(userId) ) } val taskJsonMap = getAtomConfResult.taskDataMap @@ -426,13 +433,16 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ logger.info("quality.json not found , skip...") } else if (getAtomQualityResult.errorCode != "0") { return I18nUtil.generateResponseDataObject( - getAtomQualityResult.errorCode, - getAtomQualityResult.errorParams + messageCode = getAtomQualityResult.errorCode, + params = getAtomQualityResult.errorParams, + language = I18nUtil.getLanguage(userId) ) } val atomEnvRequests = getAtomConfResult.atomEnvRequests ?: return I18nUtil.generateResponseDataObject( - StoreMessageCode.USER_REPOSITORY_TASK_JSON_FIELD_IS_NULL, arrayOf(KEY_EXECUTION) + messageCode = StoreMessageCode.USER_REPOSITORY_TASK_JSON_FIELD_IS_NULL, + params = arrayOf(KEY_EXECUTION), + language = I18nUtil.getLanguage(userId) ) val propsMap = mutableMapOf() propsMap[KEY_INPUT_GROUPS] = taskDataMap[KEY_INPUT_GROUPS] @@ -938,7 +948,11 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ logger.info("getProcessInfo userId is $userId,atomId is $atomId") val record = marketAtomDao.getAtomRecordById(dslContext, atomId) return if (null == record) { - I18nUtil.generateResponseDataObject(CommonMessageCode.PARAMETER_IS_INVALID, arrayOf(atomId)) + I18nUtil.generateResponseDataObject( + messageCode = CommonMessageCode.PARAMETER_IS_INVALID, + params = arrayOf(atomId), + language = I18nUtil.getLanguage(userId) + ) } else { val atomCode = record.atomCode // 判断用户是否有查询权限 @@ -1031,7 +1045,8 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ ?: return I18nUtil.generateResponseDataObject( messageCode = CommonMessageCode.PARAMETER_IS_INVALID, params = arrayOf(atomId), - data = false + data = false, + language = I18nUtil.getLanguage(userId) ) val atomCode = atomRecord.atomCode // 查看当前版本之前的版本是否有已发布的,如果有已发布的版本则只是普通的升级操作而不需要审核 diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineBadgeService.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineBadgeService.kt index c7aaeb9d026..fe3403a620d 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineBadgeService.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineBadgeService.kt @@ -36,7 +36,6 @@ import org.jooq.DSLContext import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Service -import java.lang.RuntimeException import java.net.URLDecoder @Service From c69b93f6dd6bd930f7937fa723c22d4579696021 Mon Sep 17 00:00:00 2001 From: stubenhuang Date: Mon, 12 Jun 2023 12:13:33 +0800 Subject: [PATCH 066/166] =?UTF-8?q?feat:=20JerseyConfig=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E5=AE=8C=E4=B9=8B=E5=90=8E=E7=AB=AF=E5=8F=A3=E6=89=8D?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E8=AE=BF=E9=97=AE=20#8946?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common-web/src/main/resources/common-web.properties | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties b/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties index a72e4973c7e..bc9b8e35b1d 100644 --- a/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties +++ b/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties @@ -31,4 +31,6 @@ server.servlet-path=/ server.undertow.accesslog.enabled=false server.undertow.accesslog.pattern='%h %I "%{i,X-DEVOPS-UID}" [%{time,yyyyMMddHHmmss.S}] "%r" %s %b "%{i,Referer}" "%{i,User-Agent}"' server.shutdown=graceful -spring.jersey.servlet.loadOnStartup=1 \ No newline at end of file +spring.jersey.servlet.loadOnStartup=1 +spring.mvc.servlet.load-on-startup=1 +spring.webservices.servlet.load-on-startup=1 From b33546509410f51fcfc70693ddf4f962e68a83f0 Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Mon, 12 Jun 2023 12:20:06 +0800 Subject: [PATCH 067/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/common/api/util/ReplacementUtilsTest.kt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/backend/ci/core/common/common-api/src/test/kotlin/com/tencent/devops/common/api/util/ReplacementUtilsTest.kt b/src/backend/ci/core/common/common-api/src/test/kotlin/com/tencent/devops/common/api/util/ReplacementUtilsTest.kt index bf69e8acd3d..efb542e148f 100644 --- a/src/backend/ci/core/common/common-api/src/test/kotlin/com/tencent/devops/common/api/util/ReplacementUtilsTest.kt +++ b/src/backend/ci/core/common/common-api/src/test/kotlin/com/tencent/devops/common/api/util/ReplacementUtilsTest.kt @@ -37,14 +37,6 @@ class ReplacementUtilsTest { override fun getReplacement(key: String): String? = data[key] } - @Test - fun parseEnvNested() { - val data = HashMap() - data["Nested"] = "first" - data["first"] = "hello" - parseAndEquals(data = data, template = "\${\${Nested}}.html", expect = "hello.html") - } - @Test fun parseTwice() { val map = mutableMapOf() From e356d448a39c6c812f15784860ccd8df56f8fab9 Mon Sep 17 00:00:00 2001 From: stubenhuang Date: Mon, 12 Jun 2023 14:46:41 +0800 Subject: [PATCH 068/166] =?UTF-8?q?feat:=20JerseyConfig=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E5=AE=8C=E4=B9=8B=E5=90=8E=E7=AB=AF=E5=8F=A3=E6=89=8D?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E8=AE=BF=E9=97=AE=20#8946?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/common-web/src/main/resources/common-web.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties b/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties index bc9b8e35b1d..18219b1ebac 100644 --- a/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties +++ b/src/backend/ci/core/common/common-web/src/main/resources/common-web.properties @@ -31,6 +31,6 @@ server.servlet-path=/ server.undertow.accesslog.enabled=false server.undertow.accesslog.pattern='%h %I "%{i,X-DEVOPS-UID}" [%{time,yyyyMMddHHmmss.S}] "%r" %s %b "%{i,Referer}" "%{i,User-Agent}"' server.shutdown=graceful -spring.jersey.servlet.loadOnStartup=1 +spring.jersey.servlet.load-on-startup=1 spring.mvc.servlet.load-on-startup=1 spring.webservices.servlet.load-on-startup=1 From 852ab7edef9cddcbcc5bb8626a7fbbb89133f0e8 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Mon, 12 Jun 2023 14:51:11 +0800 Subject: [PATCH 069/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/cron/AuthCronManager.kt | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt index b159d70a10c..1b1bb83cb82 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt @@ -158,10 +158,12 @@ class AuthCronManager @Autowired constructor( ) authActionI18nMap[it.action] = actionName } - authActionDao.updateActionName( - dslContext = dslContext, - authActionI18nMap = authActionI18nMap - ) + if (authActionI18nMap.isNotEmpty()) { + authActionDao.updateActionName( + dslContext = dslContext, + authActionI18nMap = authActionI18nMap + ) + } page ++ } while (actionRecordResult.size == PageUtil.DEFAULT_PAGE_SIZE) logger.info("init auth Action I18n end") @@ -199,10 +201,12 @@ class AuthCronManager @Autowired constructor( it.updateUser = SYSTEM authResourceTypes.add(it) } - authResourceTypeDao.batchUpdateAuthResourceType( - dslContext = dslContext, - authActionResourceTypes = authResourceTypes - ) + if (authResourceTypes.isNotEmpty()) { + authResourceTypeDao.batchUpdateAuthResourceType( + dslContext = dslContext, + authActionResourceTypes = authResourceTypes + ) + } page++ } while (resourceTypeResult.size == PageUtil.DEFAULT_PAGE_SIZE) logger.info("init auth resource type I18n end") @@ -241,10 +245,12 @@ class AuthCronManager @Autowired constructor( it.updateTime = LocalDateTime.now() authAuthResourceGroupConfigs.add(it) } - authResourceGroupConfigDao.batchUpdateAuthResourceGroupConfig( - dslContext, - authAuthResourceGroupConfigs - ) + if (authAuthResourceGroupConfigs.isNotEmpty()) { + authResourceGroupConfigDao.batchUpdateAuthResourceGroupConfig( + dslContext, + authAuthResourceGroupConfigs + ) + } page++ } while (resourceGroupConfigResult.size == PageUtil.DEFAULT_PAGE) logger.info("init auth resource group config I18n end") From babc51d39752c5fa913ae60e9459cff30d9c2253 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Mon, 12 Jun 2023 14:54:44 +0800 Subject: [PATCH 070/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql b/support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql index 0de71002283..f3887a6c4dc 100644 --- a/support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql +++ b/support-files/sql/2003_v2.x/2020_ci_notify-update_v2.0_mysql.sql @@ -42,7 +42,7 @@ SELECT DATABASE() INTO db; FROM information_schema.statistics WHERE TABLE_SCHEMA = db AND TABLE_NAME = 'T_COMMON_NOTIFY_MESSAGE_TEMPLATE' - AND INDEX_NAME = '`idx_code`') THEN + AND INDEX_NAME = 'idx_code') THEN ALTER TABLE T_COMMON_NOTIFY_MESSAGE_TEMPLATE DROP INDEX `idx_code`; END IF; From 08b5737ef8478099add0f488ffd0070ec0206f6e Mon Sep 17 00:00:00 2001 From: yjieliang Date: Mon, 12 Jun 2023 15:30:33 +0800 Subject: [PATCH 071/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/cron/AuthCronManager.kt | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt index 1b1bb83cb82..e43888b1066 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt @@ -156,7 +156,9 @@ class AuthCronManager @Autowired constructor( messageCode = "${it.action}.actionName", language = commonConfig.devopsDefaultLocaleLanguage ) - authActionI18nMap[it.action] = actionName + if (actionName.isNotBlank()) { + authActionI18nMap[it.action] = actionName + } } if (authActionI18nMap.isNotEmpty()) { authActionDao.updateActionName( @@ -189,17 +191,25 @@ class AuthCronManager @Autowired constructor( pageSize = PageUtil.DEFAULT_PAGE_SIZE ) resourceTypeResult.forEach { - it.name = MessageUtil.getMessageByLocale( + val name = MessageUtil.getMessageByLocale( messageCode = it.resourceType + RESOURCE_TYPE_NAME_SUFFIX, language = commonConfig.devopsDefaultLocaleLanguage ) - it.desc = MessageUtil.getMessageByLocale( + val desc = MessageUtil.getMessageByLocale( messageCode = it.resourceType + RESOURCE_TYPE_DESC_SUFFIX, language = commonConfig.devopsDefaultLocaleLanguage ) - it.updateTime = LocalDateTime.now() - it.updateUser = SYSTEM - authResourceTypes.add(it) + if (name.isNotBlank() || desc.isNotBlank()) { + if (name.isNotBlank()) { + it.name = name + } + if (desc.isNotBlank()) { + it.desc = desc + } + it.updateTime = LocalDateTime.now() + it.updateUser = SYSTEM + authResourceTypes.add(it) + } } if (authResourceTypes.isNotEmpty()) { authResourceTypeDao.batchUpdateAuthResourceType( @@ -232,18 +242,26 @@ class AuthCronManager @Autowired constructor( pageSize = PageUtil.DEFAULT_PAGE_SIZE ) resourceGroupConfigResult.forEach { - it.groupName = MessageUtil.getMessageByLocale( + val groupName = MessageUtil.getMessageByLocale( messageCode = "${it.resourceType}.${it.groupCode}" + AUTH_RESOURCE_GROUP_CONFIG_GROUP_NAME_SUFFIX, language = commonConfig.devopsDefaultLocaleLanguage ) - it.description = MessageUtil.getMessageByLocale( + val description = MessageUtil.getMessageByLocale( messageCode = "${it.resourceType}.${it.groupCode}" + AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX, language = commonConfig.devopsDefaultLocaleLanguage ) - it.updateTime = LocalDateTime.now() - authAuthResourceGroupConfigs.add(it) + if (groupName.isNotBlank() || description.isNotBlank()) { + if (groupName.isNotBlank()) { + it.groupName = groupName + } + if (description.isNotBlank()) { + it.description = description + } + it.updateTime = LocalDateTime.now() + authAuthResourceGroupConfigs.add(it) + } } if (authAuthResourceGroupConfigs.isNotEmpty()) { authResourceGroupConfigDao.batchUpdateAuthResourceGroupConfig( From 80b990706bb71d4de0b96dc20368a213f02a63e1 Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Mon, 12 Jun 2023 16:56:42 +0800 Subject: [PATCH 072/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/service/migrate/AbMigratePolicyService.kt | 4 ++-- .../devops/auth/service/migrate/MigrateResourceService.kt | 4 ++-- .../devops/auth/service/migrate/MigrateV0PolicyService.kt | 2 +- .../devops/auth/service/migrate/MigrateV3PolicyService.kt | 2 +- .../auth/service/migrate/RbacPermissionMigrateService.kt | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt index 8981b902926..ce0b4265241 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/AbMigratePolicyService.kt @@ -62,10 +62,10 @@ import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.auth.api.pojo.DefaultGroupType import com.tencent.devops.common.auth.utils.RbacAuthUtils import com.tencent.devops.common.web.utils.I18nUtil -import java.time.LocalDateTime -import java.util.concurrent.TimeUnit import org.jooq.DSLContext import org.slf4j.LoggerFactory +import java.time.LocalDateTime +import java.util.concurrent.TimeUnit @Suppress("LongParameterList", "TooManyFunctions") abstract class AbMigratePolicyService( diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateResourceService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateResourceService.kt index 86ef3350a38..2b95c4ed787 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateResourceService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateResourceService.kt @@ -51,12 +51,12 @@ import com.tencent.devops.common.auth.api.AuthTokenApi import com.tencent.devops.common.auth.code.ProjectAuthServiceCode import com.tencent.devops.common.auth.utils.RbacAuthUtils import com.tencent.devops.common.service.trace.TraceTag -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Executors import org.jooq.DSLContext import org.slf4j.LoggerFactory import org.slf4j.MDC import org.springframework.beans.factory.annotation.Autowired +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executors /** * 将资源迁移到权限中心 diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt index 278052c08b8..4b14c670a8a 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV0PolicyService.kt @@ -48,10 +48,10 @@ import com.tencent.devops.auth.service.RbacCacheService import com.tencent.devops.auth.service.iam.PermissionService import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType -import java.util.concurrent.TimeUnit import org.apache.commons.lang3.RandomUtils import org.jooq.DSLContext import org.slf4j.LoggerFactory +import java.util.concurrent.TimeUnit @Suppress("LongParameterList", "NestedBlockDepth", "TooManyFunctions") class MigrateV0PolicyService constructor( diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt index fac3fa3558a..a656c69b194 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/MigrateV3PolicyService.kt @@ -49,9 +49,9 @@ import com.tencent.devops.auth.service.RbacCacheService import com.tencent.devops.auth.service.iam.PermissionService import com.tencent.devops.common.api.util.DateTimeUtil import com.tencent.devops.common.auth.api.AuthResourceType -import java.util.Calendar import org.jooq.DSLContext import org.slf4j.LoggerFactory +import java.util.Calendar /** * v3权限策略迁移到rbac diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt index 7ca61af2da0..24c4333bb59 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/migrate/RbacPermissionMigrateService.kt @@ -50,11 +50,11 @@ import com.tencent.devops.project.api.service.ServiceProjectApprovalResource import com.tencent.devops.project.api.service.ServiceProjectResource import com.tencent.devops.project.api.service.ServiceProjectTagResource import com.tencent.devops.project.pojo.ProjectVO -import java.util.concurrent.CompletionException import org.jooq.DSLContext import org.slf4j.LoggerFactory import org.slf4j.MDC import org.springframework.beans.factory.annotation.Value +import java.util.concurrent.CompletionException import java.util.concurrent.Executors /** From 59bd6944f56a5f3adfe79717a53866ca49c30d85 Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Mon, 12 Jun 2023 17:10:19 +0800 Subject: [PATCH 073/166] =?UTF-8?q?feat:=20=E8=93=9D=E7=9B=BE=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E6=9D=83=E9=99=90=E4=B8=AD=E5=BF=83RBAC=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20#8941?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/api/callback/OpenAuthResourceCallBackResource.kt | 2 +- .../auth/api/callback/ServiceAuthResourceCallBackResource.kt | 2 +- .../devops/auth/service/PermissionGradeManagerService.kt | 2 +- .../com/tencent/devops/auth/dao/AuthResourceGroupDao.kt | 2 +- .../com/tencent/devops/common/auth/api/RbacAuthTokenApi.kt | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/callback/OpenAuthResourceCallBackResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/callback/OpenAuthResourceCallBackResource.kt index f11ff59bd9b..69c9c10cb7c 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/callback/OpenAuthResourceCallBackResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/callback/OpenAuthResourceCallBackResource.kt @@ -33,10 +33,10 @@ import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam import javax.ws.rs.Consumes +import javax.ws.rs.HeaderParam import javax.ws.rs.POST import javax.ws.rs.Path import javax.ws.rs.Produces -import javax.ws.rs.HeaderParam import javax.ws.rs.core.MediaType @Api(tags = ["AUTH_RESOURCE_CALLBACK"], description = "权限-资源-回调接口") diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/callback/ServiceAuthResourceCallBackResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/callback/ServiceAuthResourceCallBackResource.kt index 60d23f7d882..78e09961297 100644 --- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/callback/ServiceAuthResourceCallBackResource.kt +++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/callback/ServiceAuthResourceCallBackResource.kt @@ -33,10 +33,10 @@ import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam import javax.ws.rs.Consumes +import javax.ws.rs.HeaderParam import javax.ws.rs.POST import javax.ws.rs.Path import javax.ws.rs.Produces -import javax.ws.rs.HeaderParam import javax.ws.rs.core.MediaType @Api(tags = ["AUTH_RESOURCE_CALLBACK"], description = "权限-资源-回调接口") diff --git a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt index e69fbe15297..c9a15b49587 100644 --- a/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt +++ b/src/backend/ci/core/auth/biz-auth-rbac/src/main/kotlin/com/tencent/devops/auth/service/PermissionGradeManagerService.kt @@ -78,11 +78,11 @@ import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.project.api.service.ServiceProjectApprovalResource import com.tencent.devops.project.pojo.enums.ProjectApproveStatus import com.tencent.devops.project.pojo.enums.ProjectAuthSecrecyStatus -import java.util.Arrays import org.jooq.DSLContext import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value +import java.util.Arrays @Suppress("LongParameterList", "TooManyFunctions") class PermissionGradeManagerService @Autowired constructor( diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt index adaac2facf6..ac8c5cc21e6 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/dao/AuthResourceGroupDao.kt @@ -30,10 +30,10 @@ package com.tencent.devops.auth.dao import com.tencent.devops.model.auth.tables.TAuthResourceGroup import com.tencent.devops.model.auth.tables.records.TAuthResourceGroupRecord -import java.time.LocalDateTime import org.jooq.DSLContext import org.jooq.Result import org.springframework.stereotype.Repository +import java.time.LocalDateTime @Repository @Suppress("LongParameterList", "TooManyFunctions") diff --git a/src/backend/ci/core/common/common-auth/common-auth-rbac/src/main/kotlin/com/tencent/devops/common/auth/api/RbacAuthTokenApi.kt b/src/backend/ci/core/common/common-auth/common-auth-rbac/src/main/kotlin/com/tencent/devops/common/auth/api/RbacAuthTokenApi.kt index 518c652621c..516fe34bdbe 100644 --- a/src/backend/ci/core/common/common-auth/common-auth-rbac/src/main/kotlin/com/tencent/devops/common/auth/api/RbacAuthTokenApi.kt +++ b/src/backend/ci/core/common/common-auth/common-auth-rbac/src/main/kotlin/com/tencent/devops/common/auth/api/RbacAuthTokenApi.kt @@ -30,10 +30,10 @@ package com.tencent.devops.common.auth.api import com.tencent.bk.sdk.iam.service.impl.TokenServiceImpl import com.tencent.devops.common.auth.code.AuthServiceCode import com.tencent.devops.common.redis.RedisOperation -import java.nio.charset.Charset -import java.util.Base64 import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value +import java.nio.charset.Charset +import java.util.Base64 class RbacAuthTokenApi constructor( private val redisOperation: RedisOperation, From 0875cfd68eaedc15cd4eb14316fe871a9baa9942 Mon Sep 17 00:00:00 2001 From: carlyin <449036249@qq.com> Date: Mon, 12 Jun 2023 18:22:36 +0800 Subject: [PATCH 074/166] =?UTF-8?q?feat:=E8=93=9D=E7=9B=BE=E5=86=85?= =?UTF-8?q?=E7=BD=AE=E6=8F=92=E4=BB=B6=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=20#8900?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/ci/.gitignore | 1 + .../kotlin/plugins/task-i18n-load.gradle.kts | 6 +- .../biz-artifactory-sample/build.gradle.kts | 2 +- .../SampleArchiveAtomToBkRepoServiceImpl.kt | 44 +++++++++++++ .../impl/ArchiveAtomToBkRepoServiceImpl.kt | 11 +--- .../atom/ServiceMarketAtomArchiveResource.kt | 26 ++++---- .../pojo/atom/MarketAtomCreateRequest.kt | 5 +- .../atom/impl/SampleAtomReleaseServiceImpl.kt | 5 -- .../ServiceMarketAtomArchiveResourceImpl.kt | 8 +-- .../atom/impl/AtomReleaseServiceImpl.kt | 65 ++++++++++++------- .../atom/impl/MarketAtomArchiveServiceImpl.kt | 12 ++-- .../atom/impl/MarketAtomCommonServiceImpl.kt | 12 ++-- .../atom/impl/MarketAtomServiceImpl.kt | 9 ++- .../service/atom/impl/OpAtomServiceImpl.kt | 6 +- .../impl/StoreIndexManageServiceImpl.kt | 2 +- 15 files changed, 139 insertions(+), 75 deletions(-) create mode 100644 src/backend/ci/core/artifactory/biz-artifactory-sample/src/main/kotlin/com/tencent/devops/artifactory/service/SampleArchiveAtomToBkRepoServiceImpl.kt diff --git a/src/backend/ci/.gitignore b/src/backend/ci/.gitignore index e7fd0a014da..d858712732c 100644 --- a/src/backend/ci/.gitignore +++ b/src/backend/ci/.gitignore @@ -16,3 +16,4 @@ build.yml .temp .codecc *.log.gz +i18n/ diff --git a/src/backend/ci/buildSrc/src/main/kotlin/plugins/task-i18n-load.gradle.kts b/src/backend/ci/buildSrc/src/main/kotlin/plugins/task-i18n-load.gradle.kts index f89a0cd5fec..aae50b4e6c6 100644 --- a/src/backend/ci/buildSrc/src/main/kotlin/plugins/task-i18n-load.gradle.kts +++ b/src/backend/ci/buildSrc/src/main/kotlin/plugins/task-i18n-load.gradle.kts @@ -28,7 +28,11 @@ import java.io.FileInputStream import java.io.FileOutputStream import java.util.Properties -val i18nPath = joinPath(rootDir.absolutePath.replace("/src/backend/ci", ""), "support-files", "i18n") +val i18nPath = joinPath( + rootDir.absolutePath.replace("${File.separator}src${File.separator}backend${File.separator}ci", ""), + "support-files", + "i18n" +) println("rootDir is: $rootDir, i18nPath is: $i18nPath, projectName is: ${project.name}") if (File(i18nPath).isDirectory) { println("i18n load register , Path is $i18nPath") diff --git a/src/backend/ci/core/artifactory/biz-artifactory-sample/build.gradle.kts b/src/backend/ci/core/artifactory/biz-artifactory-sample/build.gradle.kts index 422cf2fe3fb..85185578b92 100644 --- a/src/backend/ci/core/artifactory/biz-artifactory-sample/build.gradle.kts +++ b/src/backend/ci/core/artifactory/biz-artifactory-sample/build.gradle.kts @@ -27,5 +27,5 @@ dependencies { api(project(":core:artifactory:api-artifactory-sample")) - api(project(":core:artifactory:biz-artifactory")) + api(project(":core:artifactory:biz-artifactory-store")) } diff --git a/src/backend/ci/core/artifactory/biz-artifactory-sample/src/main/kotlin/com/tencent/devops/artifactory/service/SampleArchiveAtomToBkRepoServiceImpl.kt b/src/backend/ci/core/artifactory/biz-artifactory-sample/src/main/kotlin/com/tencent/devops/artifactory/service/SampleArchiveAtomToBkRepoServiceImpl.kt new file mode 100644 index 00000000000..efb30d7c1d5 --- /dev/null +++ b/src/backend/ci/core/artifactory/biz-artifactory-sample/src/main/kotlin/com/tencent/devops/artifactory/service/SampleArchiveAtomToBkRepoServiceImpl.kt @@ -0,0 +1,44 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * 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.devops.artifactory.service + +import com.tencent.devops.artifactory.constant.BKREPO_STORE_PROJECT_ID +import com.tencent.devops.artifactory.constant.REALM_BK_REPO +import com.tencent.devops.artifactory.constant.REPO_NAME_PLUGIN +import com.tencent.devops.artifactory.service.impl.ArchiveAtomToBkRepoServiceImpl +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.stereotype.Service + +@Service +@ConditionalOnProperty(prefix = "artifactory", name = ["realm"], havingValue = REALM_BK_REPO) +class SampleArchiveAtomToBkRepoServiceImpl : ArchiveAtomToBkRepoServiceImpl() { + + override fun deleteAtom(userId: String, projectCode: String, atomCode: String) { + bkRepoClient.delete(userId, BKREPO_STORE_PROJECT_ID, REPO_NAME_PLUGIN, "$projectCode/$atomCode") + } +} diff --git a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomToBkRepoServiceImpl.kt b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomToBkRepoServiceImpl.kt index 847065554b9..8d936015453 100644 --- a/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomToBkRepoServiceImpl.kt +++ b/src/backend/ci/core/artifactory/biz-artifactory-store/src/main/kotlin/com/tencent/devops/artifactory/service/impl/ArchiveAtomToBkRepoServiceImpl.kt @@ -4,7 +4,6 @@ import com.tencent.devops.artifactory.constant.BKREPO_DEFAULT_USER import com.tencent.devops.artifactory.constant.BKREPO_STORE_PROJECT_ID import com.tencent.devops.artifactory.constant.BK_CI_ATOM_DIR import com.tencent.devops.artifactory.constant.BK_CI_PLUGIN_FE_DIR -import com.tencent.devops.artifactory.constant.REALM_BK_REPO import com.tencent.devops.artifactory.constant.REPO_NAME_PLUGIN import com.tencent.devops.artifactory.constant.REPO_NAME_STATIC import com.tencent.devops.artifactory.util.DefaultPathUtils @@ -12,15 +11,11 @@ import com.tencent.devops.common.api.constant.STATIC import com.tencent.devops.common.api.exception.RemoteServiceException import org.glassfish.jersey.media.multipart.FormDataContentDisposition import org.slf4j.LoggerFactory -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty -import org.springframework.stereotype.Service import java.io.File import java.io.InputStream import javax.ws.rs.NotFoundException -@Service -@ConditionalOnProperty(prefix = "artifactory", name = ["realm"], havingValue = REALM_BK_REPO) -class ArchiveAtomToBkRepoServiceImpl : ArchiveAtomServiceImpl() { +abstract class ArchiveAtomToBkRepoServiceImpl : ArchiveAtomServiceImpl() { override fun getAtomArchiveBasePath(): String { return System.getProperty("java.io.tmpdir") @@ -104,10 +99,6 @@ class ArchiveAtomToBkRepoServiceImpl : ArchiveAtomServiceImpl() { } } - override fun deleteAtom(userId: String, projectCode: String, atomCode: String) { - bkRepoClient.delete(userId, BKREPO_STORE_PROJECT_ID, REPO_NAME_PLUGIN, "$projectCode/$atomCode") - } - override fun clearServerTmpFile(projectCode: String, atomCode: String, version: String) { val atomArchivePath = buildAtomArchivePath(projectCode, atomCode, version) val frontendDir = buildAtomFrontendPath(atomCode, version) diff --git a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/api/atom/ServiceMarketAtomArchiveResource.kt b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/api/atom/ServiceMarketAtomArchiveResource.kt index 5a72e50ef3c..ec79ec39631 100644 --- a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/api/atom/ServiceMarketAtomArchiveResource.kt +++ b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/api/atom/ServiceMarketAtomArchiveResource.kt @@ -52,20 +52,20 @@ interface ServiceMarketAtomArchiveResource { @ApiOperation("校验用户上传的插件包是否合法") @GET - @Path("/users/{userId}/projects/{projectCode}/atoms/{atomCode}/versions/{version}/package/verify") + @Path("/users/{userId}/atoms/{atomCode}/versions/{version}/package/verify") fun verifyAtomPackageByUserId( @ApiParam("用户ID", required = true) @PathParam("userId") userId: String, - @ApiParam("项目代码", required = true) - @PathParam("projectCode") - projectCode: String, @ApiParam("插件代码", required = true) @PathParam("atomCode") atomCode: String, @ApiParam("版本号", required = true) @PathParam("version") version: String, + @ApiParam("项目代码", required = true) + @QueryParam("projectCode") + projectCode: String, @ApiParam("发布类型", required = false) @QueryParam("releaseType") releaseType: ReleaseTypeEnum?, @@ -76,38 +76,38 @@ interface ServiceMarketAtomArchiveResource { @ApiOperation("校验用户上传的插件包中的taskJson是否正确") @GET - @Path("/users/{userId}/projects/{projectCode}/atoms/{atomCode}/versions/{version}/json/verify") + @Path("/users/{userId}/atoms/{atomCode}/versions/{version}/json/verify") fun verifyAtomTaskJson( @ApiParam("用户ID", required = true) @PathParam("userId") userId: String, - @ApiParam("项目代码", required = true) - @PathParam("projectCode") - projectCode: String, @ApiParam("插件代码", required = true) @PathParam("atomCode") atomCode: String, @ApiParam("版本号", required = true) @PathParam("version") - version: String + version: String, + @ApiParam("项目代码", required = true) + @QueryParam("projectCode") + projectCode: String ): Result @ApiOperation("校验插件发布类型是否合法") @GET - @Path("/users/{userId}/projects/{projectCode}/atoms/{atomCode}/versions/{version}/releaseType/verify") + @Path("/users/{userId}/atoms/{atomCode}/versions/{version}/releaseType/verify") fun validateReleaseType( @ApiParam("用户ID", required = true) @PathParam("userId") userId: String, - @ApiParam("项目代码", required = true) - @PathParam("projectCode") - projectCode: String, @ApiParam("插件代码", required = true) @PathParam("atomCode") atomCode: String, @ApiParam("版本号", required = true) @PathParam("version") version: String, + @ApiParam("项目代码", required = true) + @QueryParam("projectCode") + projectCode: String, @ApiParam("插件字段校验确认标识", required = false) @QueryParam("fieldCheckConfirmFlag") fieldCheckConfirmFlag: Boolean? diff --git a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/MarketAtomCreateRequest.kt b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/MarketAtomCreateRequest.kt index 33072fec424..8434671fbd1 100644 --- a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/MarketAtomCreateRequest.kt +++ b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/pojo/atom/MarketAtomCreateRequest.kt @@ -31,6 +31,7 @@ import com.tencent.devops.common.api.enums.FrontendTypeEnum import com.tencent.devops.common.web.annotation.BkField import com.tencent.devops.common.web.constant.BkStyleEnum import com.tencent.devops.repository.pojo.enums.VisibilityLevelEnum +import com.tencent.devops.store.pojo.common.enums.PackageSourceTypeEnum import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -57,5 +58,7 @@ data class MarketAtomCreateRequest( @field:BkField(patternStyle = BkStyleEnum.NOTE_STYLE, required = false) val privateReason: String? = null, @ApiModelProperty(value = "前端UI渲染方式", required = true) - val frontendType: FrontendTypeEnum = FrontendTypeEnum.NORMAL + val frontendType: FrontendTypeEnum = FrontendTypeEnum.NORMAL, + @ApiModelProperty(value = "插件包发布方式", required = false) + val packageSourceType: PackageSourceTypeEnum? = null ) diff --git a/src/backend/ci/core/store/biz-store-sample/src/main/kotlin/com/tencent/devops/store/service/atom/impl/SampleAtomReleaseServiceImpl.kt b/src/backend/ci/core/store/biz-store-sample/src/main/kotlin/com/tencent/devops/store/service/atom/impl/SampleAtomReleaseServiceImpl.kt index 80b7b711710..02e237e5900 100644 --- a/src/backend/ci/core/store/biz-store-sample/src/main/kotlin/com/tencent/devops/store/service/atom/impl/SampleAtomReleaseServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store-sample/src/main/kotlin/com/tencent/devops/store/service/atom/impl/SampleAtomReleaseServiceImpl.kt @@ -46,7 +46,6 @@ import com.tencent.devops.store.constant.StoreMessageCode import com.tencent.devops.store.pojo.atom.AtomReleaseRequest import com.tencent.devops.store.pojo.atom.MarketAtomCreateRequest import com.tencent.devops.store.pojo.atom.MarketAtomUpdateRequest -import com.tencent.devops.store.pojo.common.enums.PackageSourceTypeEnum import com.tencent.devops.store.pojo.atom.enums.AtomStatusEnum import com.tencent.devops.store.pojo.common.ReleaseProcessItem import com.tencent.devops.store.pojo.common.enums.StoreTypeEnum @@ -68,10 +67,6 @@ class SampleAtomReleaseServiceImpl : SampleAtomReleaseService, AtomReleaseServic return Result(data = null) } - override fun getAtomPackageSourceType(): PackageSourceTypeEnum { - return PackageSourceTypeEnum.UPLOAD - } - override fun getFileStr( projectCode: String, atomCode: String, diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomArchiveResourceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomArchiveResourceImpl.kt index 0df551ccd05..2de9d6cf530 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomArchiveResourceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomArchiveResourceImpl.kt @@ -43,9 +43,9 @@ class ServiceMarketAtomArchiveResourceImpl @Autowired constructor( override fun verifyAtomPackageByUserId( userId: String, - projectCode: String, atomCode: String, version: String, + projectCode: String, releaseType: ReleaseTypeEnum?, os: String? ): Result { @@ -61,18 +61,18 @@ class ServiceMarketAtomArchiveResourceImpl @Autowired constructor( override fun verifyAtomTaskJson( userId: String, - projectCode: String, atomCode: String, - version: String + version: String, + projectCode: String, ): Result { return marketAtomArchiveService.verifyAtomTaskJson(userId, projectCode, atomCode, version) } override fun validateReleaseType( userId: String, - projectCode: String, atomCode: String, version: String, + projectCode: String, fieldCheckConfirmFlag: Boolean? ): Result { return marketAtomArchiveService.validateReleaseType( diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt index de6a97157d4..87f081a6900 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt @@ -193,8 +193,8 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ if (codeCount > 0) { // 抛出错误提示 return I18nUtil.generateResponseDataObject( - CommonMessageCode.PARAMETER_IS_EXIST, - arrayOf(atomCode) + messageCode = CommonMessageCode.PARAMETER_IS_EXIST, + params = arrayOf(atomCode) ) } val atomName = marketAtomCreateRequest.name @@ -203,8 +203,8 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ if (nameCount > 0) { // 抛出错误提示 return I18nUtil.generateResponseDataObject( - CommonMessageCode.PARAMETER_IS_EXIST, - arrayOf(atomName) + messageCode = CommonMessageCode.PARAMETER_IS_EXIST, + params = arrayOf(atomName) ) } return null @@ -296,7 +296,13 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ atomCode: String ): Result?> - abstract fun getAtomPackageSourceType(): PackageSourceTypeEnum + fun getAtomPackageSourceType(repositoryHashId: String?): PackageSourceTypeEnum { + return if (repositoryHashId.isNullOrBlank()) { + PackageSourceTypeEnum.UPLOAD + } else { + PackageSourceTypeEnum.REPO + } + } @Suppress("UNCHECKED_CAST") @BkTimed(extraTags = ["publish", "updateMarketAtom"], value = "store_publish_pipeline_atom") @@ -307,15 +313,19 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ ): Result { logger.info("updateMarketAtom userId is :$userId,marketAtomUpdateRequest is :$marketAtomUpdateRequest") val atomCode = marketAtomUpdateRequest.atomCode - val atomPackageSourceType = getAtomPackageSourceType() - logger.info("updateMarketAtom atomPackageSourceType is :$atomPackageSourceType") val version = marketAtomUpdateRequest.version // 判断插件是不是首次创建版本 val atomCount = atomDao.countByCode(dslContext, atomCode) if (atomCount < 1) { - return I18nUtil.generateResponseDataObject(CommonMessageCode.PARAMETER_IS_INVALID, arrayOf(atomCode)) + return I18nUtil.generateResponseDataObject( + messageCode = CommonMessageCode.PARAMETER_IS_INVALID, + params = arrayOf(atomCode), + language = I18nUtil.getLanguage(userId) + ) } val atomRecord = atomDao.getMaxVersionAtomByCode(dslContext, atomCode)!! + val atomPackageSourceType = getAtomPackageSourceType(atomRecord.repositoryHashId) + logger.info("updateMarketAtom atomPackageSourceType is :$atomPackageSourceType") val releaseType = marketAtomUpdateRequest.releaseType // 历史大版本下的小版本更新发布类型支持用户自定义分支,其他发布类型只支持master分支发布 val branch = if (marketAtomUpdateRequest.branch.isNullOrBlank() || @@ -335,8 +345,9 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ ) if (getAtomConfResult.errorCode != "0") { return I18nUtil.generateResponseDataObject( - getAtomConfResult.errorCode, - getAtomConfResult.errorParams + messageCode = getAtomConfResult.errorCode, + params = getAtomConfResult.errorParams, + language = I18nUtil.getLanguage(userId) ) } val taskJsonMap = getAtomConfResult.taskDataMap @@ -430,13 +441,16 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ logger.info("quality.json not found , skip...") } else if (getAtomQualityResult.errorCode != "0") { return I18nUtil.generateResponseDataObject( - getAtomQualityResult.errorCode, - getAtomQualityResult.errorParams + messageCode = getAtomQualityResult.errorCode, + params = getAtomQualityResult.errorParams, + language = I18nUtil.getLanguage(userId) ) } val atomEnvRequests = getAtomConfResult.atomEnvRequests ?: return I18nUtil.generateResponseDataObject( - StoreMessageCode.USER_REPOSITORY_TASK_JSON_FIELD_IS_NULL, arrayOf(KEY_EXECUTION) + messageCode = StoreMessageCode.USER_REPOSITORY_TASK_JSON_FIELD_IS_NULL, + params = arrayOf(KEY_EXECUTION), + language = I18nUtil.getLanguage(userId) ) val packagePath = executionInfoMap[KEY_PACKAGE_PATH] as? String @@ -480,7 +494,8 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ props = props, releaseType = releaseType.releaseType.toByte(), marketAtomUpdateRequest = convertUpdateRequest, - atomEnvRequests = atomEnvRequests + atomEnvRequests = atomEnvRequests, + repositoryHashId = atomRecord.repositoryHashId ) } else { // 升级插件 @@ -562,7 +577,8 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ props: String, releaseType: Byte, marketAtomUpdateRequest: MarketAtomUpdateRequest, - atomEnvRequests: List + atomEnvRequests: List, + repositoryHashId: String? ) { marketAtomDao.updateMarketAtom( dslContext = context, @@ -580,7 +596,7 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ releaseType = releaseType, versionContent = marketAtomUpdateRequest.versionContent ) - val atomPackageSourceType = getAtomPackageSourceType() + val atomPackageSourceType = getAtomPackageSourceType(repositoryHashId) if (atomPackageSourceType != PackageSourceTypeEnum.UPLOAD) { if (releaseType == ReleaseTypeEnum.CANCEL_RE_RELEASE.releaseType.toByte()) { marketAtomEnvInfoDao.deleteAtomEnvInfoById(context, atomId) @@ -602,11 +618,11 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ dslContext = dslContext, storeCode = atomCode, storeType = StoreTypeEnum.ATOM.type.toByte() - ) + ) ?: "" try { // 获取插件error.json文件内容 val errorJsonStr = getFileStr( - projectCode = projectCode!!, + projectCode = projectCode, atomCode = atomCode, atomVersion = atomVersion, fileName = ERROR_JSON_NAME, @@ -636,7 +652,7 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ projectCode = projectCode, errorCodes = errorCodes, fileDir = "$atomCode/$atomVersion", - i18nDir = StoreUtils.getStoreI18nDir(atomLanguage, getAtomPackageSourceType()), + i18nDir = StoreUtils.getStoreI18nDir(atomLanguage, getAtomPackageSourceType(repositoryHashId)), keyPrefix = "${StoreTypeEnum.ATOM.name}.$atomCode.$atomVersion", repositoryHashId = repositoryHashId ) @@ -929,7 +945,7 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ atomRecord = atomRecord, atomRequest = marketAtomUpdateRequest ) - val atomPackageSourceType = getAtomPackageSourceType() + val atomPackageSourceType = getAtomPackageSourceType(atomRecord.repositoryHashId) if (atomPackageSourceType != PackageSourceTypeEnum.UPLOAD) { marketAtomEnvInfoDao.addMarketAtomEnvInfo(context, atomId, atomEnvRequests) } @@ -951,7 +967,11 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ logger.info("getProcessInfo userId is $userId,atomId is $atomId") val record = marketAtomDao.getAtomRecordById(dslContext, atomId) return if (null == record) { - I18nUtil.generateResponseDataObject(CommonMessageCode.PARAMETER_IS_INVALID, arrayOf(atomId)) + I18nUtil.generateResponseDataObject( + messageCode = CommonMessageCode.PARAMETER_IS_INVALID, + params = arrayOf(atomId), + language = I18nUtil.getLanguage(userId) + ) } else { val atomCode = record.atomCode // 判断用户是否有查询权限 @@ -1044,7 +1064,8 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ ?: return I18nUtil.generateResponseDataObject( messageCode = CommonMessageCode.PARAMETER_IS_INVALID, params = arrayOf(atomId), - data = false + data = false, + language = I18nUtil.getLanguage(userId) ) val atomCode = atomRecord.atomCode // 查看当前版本之前的版本是否有已发布的,如果有已发布的版本则只是普通的升级操作而不需要审核 diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt index f9a6dcf6c32..01b1603f647 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt @@ -33,7 +33,6 @@ import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.client.Client -import com.tencent.devops.common.pipeline.pojo.element.market.MarketBuildLessAtomElement import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.store.dao.atom.AtomDao import com.tencent.devops.store.dao.atom.MarketAtomDao @@ -108,6 +107,7 @@ class MarketAtomArchiveServiceImpl : MarketAtomArchiveService { releaseType: ReleaseTypeEnum?, os: String? ): Result { + logger.info("verifyAtomPackageByUserId params[$userId|$projectCode|$atomCode|$version|$releaseType|$os]") val atomCount = atomDao.countByCode(dslContext, atomCode) if (atomCount < 0) { return I18nUtil.generateResponseDataObject( @@ -136,11 +136,11 @@ class MarketAtomArchiveServiceImpl : MarketAtomArchiveService { if (null != releaseType) { val osList = JsonUtil.getObjectMapper().readValue(os, ArrayList::class.java) as ArrayList val validateAtomVersionResult = marketAtomCommonService.validateAtomVersion( - atomRecord = atomRecord, - releaseType = releaseType, - osList = osList, - version = version - ) + atomRecord = atomRecord, + releaseType = releaseType, + osList = osList, + version = version + ) logger.info("validateAtomVersionResult is :$validateAtomVersionResult") if (validateAtomVersionResult.isNotOk()) { return validateAtomVersionResult diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomCommonServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomCommonServiceImpl.kt index 61c68cd5eea..1bc6edeb962 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomCommonServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomCommonServiceImpl.kt @@ -415,7 +415,7 @@ class MarketAtomCommonServiceImpl : MarketAtomCommonService { ) } val target = osExecutionInfoMap[KEY_TARGET] as? String - if (target.isNullOrBlank()) { + if (target == null) { // 执行入口为空则校验失败 throw ErrorCodeException( errorCode = StoreMessageCode.USER_REPOSITORY_TASK_JSON_FIELD_IS_NULL, @@ -438,7 +438,7 @@ class MarketAtomCommonServiceImpl : MarketAtomCommonService { pkgRepoPath = getPkgRepoPath(pkgLocalPath, projectCode, atomCode, version), language = language, minVersion = executionInfoMap[KEY_MINIMUM_VERSION] as? String, - target = osExecutionInfoMap[KEY_TARGET] as String, + target = target, shaContent = null, preCmd = JsonUtil.toJson(osExecutionInfoMap[KEY_DEMANDS] ?: ""), atomPostInfo = atomPostInfo, @@ -461,7 +461,7 @@ class MarketAtomCommonServiceImpl : MarketAtomCommonService { } } else { val target = executionInfoMap[KEY_TARGET] as? String - if (target.isNullOrBlank()) { + if (target == null) { // 执行入口为空则校验失败 throw ErrorCodeException( errorCode = StoreMessageCode.USER_REPOSITORY_TASK_JSON_FIELD_IS_NULL, @@ -475,7 +475,7 @@ class MarketAtomCommonServiceImpl : MarketAtomCommonService { pkgRepoPath = getPkgRepoPath(pkgLocalPath, projectCode, atomCode, version), language = language, minVersion = executionInfoMap[KEY_MINIMUM_VERSION] as? String, - target = executionInfoMap[KEY_TARGET] as String, + target = target, shaContent = null, preCmd = JsonUtil.toJson(executionInfoMap[KEY_DEMANDS] ?: ""), atomPostInfo = atomPostInfo, @@ -555,12 +555,12 @@ class MarketAtomCommonServiceImpl : MarketAtomCommonService { dslContext = dslContext, storeCode = atomCode, storeType = StoreTypeEnum.ATOM.type.toByte() - ) + ) ?: "" val atomRunInfo = AtomRunInfo( atomCode = atomCode, atomName = atom.name, version = atom.version, - initProjectCode = initProjectCode!!, + initProjectCode = initProjectCode, jobType = if (jobType == null) null else JobTypeEnum.valueOf(jobType), buildLessRunFlag = atom.buildLessRunFlag, inputTypeInfos = generateInputTypeInfos(atom.props) diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomServiceImpl.kt index e14cd9aff6e..9f2c70bae6c 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomServiceImpl.kt @@ -1058,10 +1058,13 @@ abstract class MarketAtomServiceImpl @Autowired constructor() : MarketAtomServic ) } // 删除仓库插件包文件 - val initProjectCode = - storeProjectRelDao.getInitProjectCodeByStoreCode(dslContext, atomCode, StoreTypeEnum.ATOM.type.toByte()) + val initProjectCode = storeProjectRelDao.getInitProjectCodeByStoreCode( + dslContext = dslContext, + storeCode = atomCode, + storeType = StoreTypeEnum.ATOM.type.toByte() + ) ?: "" val deleteAtomFileResult = - client.get(ServiceArchiveAtomResource::class).deleteAtomFile(userId, initProjectCode!!, atomCode) + client.get(ServiceArchiveAtomResource::class).deleteAtomFile(userId, initProjectCode, atomCode) if (deleteAtomFileResult.isNotOk()) { return deleteAtomFileResult } diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt index a8c80ffb9ac..fb9ef7f6f6f 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/OpAtomServiceImpl.kt @@ -70,6 +70,7 @@ import com.tencent.devops.store.pojo.common.PASS import com.tencent.devops.store.pojo.common.REJECT import com.tencent.devops.store.pojo.common.TASK_JSON_NAME import com.tencent.devops.store.pojo.common.enums.AuditTypeEnum +import com.tencent.devops.store.pojo.common.enums.PackageSourceTypeEnum import com.tencent.devops.store.pojo.common.enums.ReleaseTypeEnum import com.tencent.devops.store.pojo.common.enums.StoreTypeEnum import com.tencent.devops.store.service.atom.AtomNotifyService @@ -409,7 +410,8 @@ class OpAtomServiceImpl @Autowired constructor( atomCode = atomCode, name = releaseInfo.name, language = releaseInfo.language, - frontendType = releaseInfo.configInfo.frontendType + frontendType = releaseInfo.configInfo.frontendType, + packageSourceType = PackageSourceTypeEnum.UPLOAD ) ) if (addMarketAtomResult.isNotOk()) { @@ -430,7 +432,7 @@ class OpAtomServiceImpl @Autowired constructor( val relativePath = logoUrlAnalysisResult.data val logoFile = File( "$atomPath${File.separator}file" + - "${File.separator}${relativePath?.removePrefix(File.separator)}" + "${File.separator}${relativePath?.removePrefix(File.separator)}" ) if (logoFile.exists()) { val result = storeLogoService.uploadStoreLogo( diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/common/impl/StoreIndexManageServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/common/impl/StoreIndexManageServiceImpl.kt index 169c7225e8a..19ab69fee1e 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/common/impl/StoreIndexManageServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/common/impl/StoreIndexManageServiceImpl.kt @@ -152,7 +152,7 @@ class StoreIndexManageServiceImpl @Autowired constructor( dslContext = dslContext, storeCode = atomCode, storeType = StoreTypeEnum.ATOM.type.toByte() - )!! + ) ?: "" val pipelineBuildInfo = client.get(ServiceBuildResource::class).getPipelineLatestBuildByIds( initProjectCode, listOf(pipelineId) From d0f791a6737cf216355e849eeafba4ba51b45cb7 Mon Sep 17 00:00:00 2001 From: yjieliang Date: Mon, 12 Jun 2023 18:31:28 +0800 Subject: [PATCH 075/166] =?UTF-8?q?feat:auth=E5=BE=AE=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=95=B0=E6=8D=AE=E9=9C=80?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96=20#8898?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/auth/cron/AuthCronManager.kt | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt index e43888b1066..872cd10fd0e 100644 --- a/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt +++ b/src/backend/ci/core/auth/biz-auth/src/main/kotlin/com/tencent/devops/auth/cron/AuthCronManager.kt @@ -199,17 +199,15 @@ class AuthCronManager @Autowired constructor( messageCode = it.resourceType + RESOURCE_TYPE_DESC_SUFFIX, language = commonConfig.devopsDefaultLocaleLanguage ) - if (name.isNotBlank() || desc.isNotBlank()) { - if (name.isNotBlank()) { - it.name = name - } - if (desc.isNotBlank()) { - it.desc = desc - } - it.updateTime = LocalDateTime.now() - it.updateUser = SYSTEM - authResourceTypes.add(it) + if (name.isNotBlank()) { + it.name = name } + if (desc.isNotBlank()) { + it.desc = desc + } + it.updateTime = LocalDateTime.now() + it.updateUser = SYSTEM + authResourceTypes.add(it) } if (authResourceTypes.isNotEmpty()) { authResourceTypeDao.batchUpdateAuthResourceType( @@ -252,16 +250,14 @@ class AuthCronManager @Autowired constructor( AUTH_RESOURCE_GROUP_CONFIG_DESCRIPTION_SUFFIX, language = commonConfig.devopsDefaultLocaleLanguage ) - if (groupName.isNotBlank() || description.isNotBlank()) { - if (groupName.isNotBlank()) { - it.groupName = groupName - } - if (description.isNotBlank()) { - it.description = description - } - it.updateTime = LocalDateTime.now() - authAuthResourceGroupConfigs.add(it) + if (groupName.isNotBlank()) { + it.groupName = groupName + } + if (description.isNotBlank()) { + it.description = description } + it.updateTime = LocalDateTime.now() + authAuthResourceGroupConfigs.add(it) } if (authAuthResourceGroupConfigs.isNotEmpty()) { authResourceGroupConfigDao.batchUpdateAuthResourceGroupConfig( From 667d9a7d450d817564f60c7250fa6e3c73f6e374 Mon Sep 17 00:00:00 2001 From: carlyin <449036249@qq.com> Date: Mon, 12 Jun 2023 20:18:17 +0800 Subject: [PATCH 076/166] =?UTF-8?q?feat:=E8=93=9D=E7=9B=BE=E5=86=85?= =?UTF-8?q?=E7=BD=AE=E6=8F=92=E4=BB=B6=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=20#8900?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/service/atom/impl/AtomReleaseServiceImpl.kt | 3 ++- .../service/atom/impl/MarketAtomArchiveServiceImpl.kt | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt index 87f081a6900..0ee6a3dd6c3 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomReleaseServiceImpl.kt @@ -36,6 +36,7 @@ import com.tencent.devops.common.api.constant.KEY_REPOSITORY_HASH_ID import com.tencent.devops.common.api.constant.MASTER import com.tencent.devops.common.api.constant.SECURITY import com.tencent.devops.common.api.constant.TEST +import com.tencent.devops.common.api.enums.FrontendTypeEnum import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.api.util.JsonSchemaUtil @@ -464,7 +465,7 @@ abstract class AtomReleaseServiceImpl @Autowired constructor() : AtomReleaseServ } val propsMap = mutableMapOf() val inputDataMap = taskDataMap[KEY_INPUT] as? Map - if (packagePath.isNullOrBlank()) { + if (convertUpdateRequest.frontendType == FrontendTypeEnum.HISTORY) { inputDataMap?.let { propsMap.putAll(inputDataMap) } } else { propsMap[KEY_INPUT_GROUPS] = taskDataMap[KEY_INPUT_GROUPS] diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt index 01b1603f647..71fadcdc2a1 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt @@ -29,6 +29,7 @@ package com.tencent.devops.store.service.atom.impl import com.tencent.devops.artifactory.api.ServiceArchiveAtomResource import com.tencent.devops.common.api.constant.CommonMessageCode +import com.tencent.devops.common.api.enums.FrontendTypeEnum import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.api.util.JsonUtil @@ -39,14 +40,17 @@ import com.tencent.devops.store.dao.atom.MarketAtomDao import com.tencent.devops.store.dao.atom.MarketAtomEnvInfoDao import com.tencent.devops.store.dao.atom.MarketAtomVersionLogDao import com.tencent.devops.store.dao.common.StoreMemberDao +import com.tencent.devops.store.pojo.atom.AtomConfigInfo import com.tencent.devops.store.pojo.atom.AtomPkgInfoUpdateRequest import com.tencent.devops.store.pojo.atom.GetAtomConfigResult +import com.tencent.devops.store.pojo.atom.ReleaseInfo import com.tencent.devops.store.pojo.common.KEY_CONFIG import com.tencent.devops.store.pojo.common.KEY_EXECUTION import com.tencent.devops.store.pojo.common.KEY_INPUT import com.tencent.devops.store.pojo.common.KEY_INPUT_GROUPS import com.tencent.devops.store.pojo.common.KEY_OUTPUT import com.tencent.devops.store.pojo.common.KEY_PACKAGE_PATH +import com.tencent.devops.store.pojo.common.KEY_RELEASE_INFO import com.tencent.devops.store.pojo.common.TASK_JSON_NAME import com.tencent.devops.store.pojo.common.enums.ReleaseTypeEnum import com.tencent.devops.store.pojo.common.enums.StoreTypeEnum @@ -229,9 +233,11 @@ class MarketAtomArchiveServiceImpl : MarketAtomArchiveService { val taskDataMap = atomPkgInfoUpdateRequest.taskDataMap val executionInfoMap = taskDataMap[KEY_EXECUTION] as Map val propsMap = mutableMapOf() - val packagePath = executionInfoMap[KEY_PACKAGE_PATH] as? String + val releaseInfoMap = taskDataMap[KEY_RELEASE_INFO] as? Map + val configInfoMap = releaseInfoMap?.get(ReleaseInfo::configInfo.name) as? Map + val frontendType = configInfoMap?.get(AtomConfigInfo::frontendType.name) as? String val inputDataMap = taskDataMap[KEY_INPUT] as? Map - if (packagePath.isNullOrBlank()) { + if (frontendType == FrontendTypeEnum.HISTORY.name) { inputDataMap?.let { propsMap.putAll(inputDataMap) } } else { propsMap[KEY_INPUT_GROUPS] = taskDataMap[KEY_INPUT_GROUPS] From 6cfa4f2c867cd86843ebe34d9620868b6941196b Mon Sep 17 00:00:00 2001 From: carlyin <449036249@qq.com> Date: Mon, 12 Jun 2023 20:30:57 +0800 Subject: [PATCH 077/166] =?UTF-8?q?feat:=E8=93=9D=E7=9B=BE=E5=86=85?= =?UTF-8?q?=E7=BD=AE=E6=8F=92=E4=BB=B6=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=20#8900?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../atom/ServiceMarketAtomArchiveResourceImpl.kt | 9 +++++++-- .../service/atom/impl/MarketAtomArchiveServiceImpl.kt | 3 +-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomArchiveResourceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomArchiveResourceImpl.kt index 2de9d6cf530..0719a4ecdc8 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomArchiveResourceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomArchiveResourceImpl.kt @@ -63,9 +63,14 @@ class ServiceMarketAtomArchiveResourceImpl @Autowired constructor( userId: String, atomCode: String, version: String, - projectCode: String, + projectCode: String ): Result { - return marketAtomArchiveService.verifyAtomTaskJson(userId, projectCode, atomCode, version) + return marketAtomArchiveService.verifyAtomTaskJson( + userId = userId, + projectCode = projectCode, + atomCode = atomCode, + version = version + ) } override fun validateReleaseType( diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt index 71fadcdc2a1..cabc8f5e9fa 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomArchiveServiceImpl.kt @@ -49,7 +49,6 @@ import com.tencent.devops.store.pojo.common.KEY_EXECUTION import com.tencent.devops.store.pojo.common.KEY_INPUT import com.tencent.devops.store.pojo.common.KEY_INPUT_GROUPS import com.tencent.devops.store.pojo.common.KEY_OUTPUT -import com.tencent.devops.store.pojo.common.KEY_PACKAGE_PATH import com.tencent.devops.store.pojo.common.KEY_RELEASE_INFO import com.tencent.devops.store.pojo.common.TASK_JSON_NAME import com.tencent.devops.store.pojo.common.enums.ReleaseTypeEnum @@ -234,7 +233,7 @@ class MarketAtomArchiveServiceImpl : MarketAtomArchiveService { val executionInfoMap = taskDataMap[KEY_EXECUTION] as Map val propsMap = mutableMapOf() val releaseInfoMap = taskDataMap[KEY_RELEASE_INFO] as? Map - val configInfoMap = releaseInfoMap?.get(ReleaseInfo::configInfo.name) as? Map + val configInfoMap = releaseInfoMap?.get(ReleaseInfo::configInfo.name) as? Map val frontendType = configInfoMap?.get(AtomConfigInfo::frontendType.name) as? String val inputDataMap = taskDataMap[KEY_INPUT] as? Map if (frontendType == FrontendTypeEnum.HISTORY.name) { From 827934fdf0570115ecaa4e0ee5eb2d7390b7c826 Mon Sep 17 00:00:00 2001 From: lockiechen Date: Mon, 12 Jun 2023 21:06:55 +0800 Subject: [PATCH 078/166] =?UTF-8?q?feat=EF=BC=9A=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E9=97=AE=E9=A2=98=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20issue=20#8955?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bk-pipeline/dist/bk-pipeline.min.js | 2 +- src/frontend/bk-pipeline/src/AtomList.vue | 23 +- src/frontend/bk-pipeline/src/Job.vue | 4 + .../src/components/ExecPipeline.vue | 4 + .../src/components/Outputs/OutputQrcode.vue | 74 ++++++ .../src/components/Outputs/index.vue | 212 +++++++++++------- .../src/components/StartParams.vue | 11 +- .../src/store/modules/atom/index.js | 2 +- src/frontend/locale/pipeline/en-US.json | 3 +- src/frontend/locale/pipeline/zh-CN.json | 4 +- 10 files changed, 246 insertions(+), 93 deletions(-) create mode 100644 src/frontend/devops-pipeline/src/components/Outputs/OutputQrcode.vue diff --git a/src/frontend/bk-pipeline/dist/bk-pipeline.min.js b/src/frontend/bk-pipeline/dist/bk-pipeline.min.js index a5276be380b..113af917133 100644 --- a/src/frontend/bk-pipeline/dist/bk-pipeline.min.js +++ b/src/frontend/bk-pipeline/dist/bk-pipeline.min.js @@ -1,2 +1,2 @@ /*! For license information please see bk-pipeline.min.js.LICENSE.txt */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("vue")):"function"==typeof define&&define.amd?define(["vue"],e):"object"==typeof exports?exports.bkPipeline=e(require("vue")):t.bkPipeline=e(t.Vue)}(self,(t=>(()=>{var e={8467:()=>{!function(){const t='';document.body?document.body.insertAdjacentHTML("afterbegin",t):document.addEventListener("DOMContentLoaded",(function(){document.body.insertAdjacentHTML("afterbegin",t)}))}()},8383:function(t,e){!function(t){"use strict";function e(){e=function(){return t};var t={},n=Object.prototype,i=n.hasOwnProperty,o=Object.defineProperty||function(t,e,n){t[e]=n.value},r="function"==typeof Symbol?Symbol:{},a=r.iterator||"@@iterator",s=r.asyncIterator||"@@asyncIterator",c=r.toStringTag||"@@toStringTag";function l(t,e,n){return Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{l({},"")}catch(t){l=function(t,e,n){return t[e]=n}}function p(t,e,n,i){var r=e&&e.prototype instanceof f?e:f,a=Object.create(r.prototype),s=new S(i||[]);return o(a,"_invoke",{value:k(t,n,s)}),a}function d(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(t){return{type:"throw",arg:t}}}t.wrap=p;var u={};function f(){}function m(){}function h(){}var b={};l(b,a,(function(){return this}));var g=Object.getPrototypeOf,v=g&&g(g(C([])));v&&v!==n&&i.call(v,a)&&(b=v);var y=h.prototype=f.prototype=Object.create(b);function x(t){["next","throw","return"].forEach((function(e){l(t,e,(function(t){return this._invoke(e,t)}))}))}function w(t,e){function n(o,r,a,s){var c=d(t[o],t,r);if("throw"!==c.type){var l=c.arg,p=l.value;return p&&"object"==typeof p&&i.call(p,"__await")?e.resolve(p.__await).then((function(t){n("next",t,a,s)}),(function(t){n("throw",t,a,s)})):e.resolve(p).then((function(t){l.value=t,a(l)}),(function(t){return n("throw",t,a,s)}))}s(c.arg)}var r;o(this,"_invoke",{value:function(t,i){function o(){return new e((function(e,o){n(t,i,e,o)}))}return r=r?r.then(o,o):o()}})}function k(t,e,n){var i="suspendedStart";return function(o,r){if("executing"===i)throw new Error("Generator is already running");if("completed"===i){if("throw"===o)throw r;return{value:void 0,done:!0}}for(n.method=o,n.arg=r;;){var a=n.delegate;if(a){var s=E(a,n);if(s){if(s===u)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if("suspendedStart"===i)throw i="completed",n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);i="executing";var c=d(t,e,n);if("normal"===c.type){if(i=n.done?"completed":"suspendedYield",c.arg===u)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(i="completed",n.method="throw",n.arg=c.arg)}}}function E(t,e){var n=t.iterator[e.method];if(void 0===n){if(e.delegate=null,"throw"===e.method){if(t.iterator.return&&(e.method="return",e.arg=void 0,E(t,e),"throw"===e.method))return u;e.method="throw",e.arg=new TypeError("The iterator does not provide a 'throw' method")}return u}var i=d(n,t.iterator,e.arg);if("throw"===i.type)return e.method="throw",e.arg=i.arg,e.delegate=null,u;var o=i.arg;return o?o.done?(e[t.resultName]=o.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=void 0),e.delegate=null,u):o:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,u)}function T(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function I(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function S(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(T,this),this.reset(!0)}function C(t){if(t){var e=t[a];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,o=function e(){for(;++n=0;--o){var r=this.tryEntries[o],a=r.completion;if("root"===r.tryLoc)return n("end");if(r.tryLoc<=this.prev){var s=i.call(r,"catchLoc"),c=i.call(r,"finallyLoc");if(s&&c){if(this.prev=0;--n){var o=this.tryEntries[n];if(o.tryLoc<=this.prev&&i.call(o,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),I(n),u}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var i=n.completion;if("throw"===i.type){var o=i.arg;I(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:C(t),resultName:e,nextLoc:n},"next"===this.method&&(this.arg=void 0),u}},t}function n(t,e,n,i,o,r,a){try{var s=t[r](a),c=s.value}catch(t){return void n(t)}s.done?e(c):Promise.resolve(c).then(i,o)}var i=0;var o={name:"bk-checkbox",mixins:[{methods:{dispatch:function(t,e,n){for(var i=this.$parent||this.$root,o=i.$options.name;i&&(!o||o!==t);)(i=i.$parent)&&(o=i.$options.name);i&&i.$emit.apply(i,[e].concat(n))}}}],inject:{handleRemoveItem:{default:null},handleAddItem:{default:null}},props:{value:{type:[String,Number,Boolean],default:void 0},checked:{type:Boolean,default:void 0},trueValue:{type:[String,Number,Boolean],default:!0},falseValue:{type:[String,Number,Boolean],default:!1},label:{type:[String,Number]},name:{type:String,default:function(){return"bk-checkbox_".concat(i++)}},disabled:Boolean,indeterminate:Boolean,extCls:{type:String,default:""},beforeChange:Function},data:function(){return{parent:null,localValue:void 0}},computed:{selected:function(){return this.localValue===this.localTrueValue},parentValue:function(){return this.parent?this.parent.localValue:null},localTrueValue:function(){return this.parent?void 0===this.label&&void 0===this.value?this.trueValue:void 0!==this.value?this.value:this.label:void 0===this.label?this.trueValue:this.label}},watch:{value:function(t){this.setLocalValue(t)},checked:function(){this.setLocalValue()},parentValue:function(){this.setLocalValue()}},created:function(){this.handleAddItem&&"function"==typeof this.handleAddItem&&this.handleAddItem(this),this.init()},destroyed:function(){this.handleRemoveItem&&"function"==typeof this.handleRemoveItem&&this.handleRemoveItem(this)},methods:{getValue:function(){return this.selected?{isChecked:!0,value:this.localTrueValue}:{isChecked:!1,value:this.falseValue}},init:function(){for(var t=this.$parent;t&&!t.isCheckboxGroup&&"bk-checkbox-group"!==!t.$options.name;)t=t.$parent;this.parent=t,this.setLocalValue()},setLocalValue:function(t){if(void 0===t)if(this.parent){var e=this.localTrueValue,n=this.parent.localValue.includes(e);this.localValue=n?e:this.falseValue}else void 0!==this.checked?this.localValue=this.checked?this.localTrueValue:this.falseValue:void 0===this.value?this.localValue=this.falseValue:this.localValue=this.value;else this.localValue=t},handleClick:function(){var t=this;return function(t){return function(){var e=this,i=arguments;return new Promise((function(o,r){var a=t.apply(e,i);function s(t){n(a,o,r,s,c,"next",t)}function c(t){n(a,o,r,s,c,"throw",t)}s(void 0)}))}}(e().mark((function n(){var i,o,r;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!t.disabled){e.next=2;break}return e.abrupt("return",!1);case 2:if("function"!=typeof t.beforeChange){e.next=8;break}return e.next=5,t.beforeChange();case 5:if(!1!==e.sent){e.next=8;break}return e.abrupt("return");case 8:i=t.localValue,o=t.indeterminate?t.localTrueValue:i===t.localTrueValue?t.falseValue:t.localTrueValue,t.localValue=o,t.$emit("input",o,t.localTrueValue),t.$emit("change",o,i,t.localTrueValue),t.dispatch("bk-form-item","form-change"),t.parent&&(r=void 0===t.localTrueValue?o:t.localTrueValue,t.parent.handleChange(t.selected,r));case 15:case"end":return e.stop()}}),n)})))()}}};function r(t,e,n,i,o,r,a,s,c,l){"boolean"!=typeof a&&(c=s,s=a,a=!1);var p,d="function"==typeof n?n.options:n;if(t&&t.render&&(d.render=t.render,d.staticRenderFns=t.staticRenderFns,d._compiled=!0,o&&(d.functional=!0)),i&&(d._scopeId=i),r?(p=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),e&&e.call(this,c(t)),t&&t._registeredComponents&&t._registeredComponents.add(r)},d._ssrRegister=p):e&&(p=a?function(){e.call(this,l(this.$root.$options.shadowRoot))}:function(t){e.call(this,s(t))}),p)if(d.functional){var u=d.render;d.render=function(t,e){return p.call(e),u(t,e)}}else{var f=d.beforeCreate;d.beforeCreate=f?[].concat(f,p):[p]}return n}var a=r({render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("label",{staticClass:"bk-form-checkbox",class:[{"is-disabled":t.disabled,"is-indeterminate":t.indeterminate,"is-checked":t.selected},t.extCls],on:{click:t.handleClick,keydown:function(e){return!("button"in e)&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:(e.preventDefault(),t.handleClick(e))}}},[n("span",{staticClass:"bk-checkbox",attrs:{tabindex:!t.disabled&&0}}),n("input",{attrs:{type:"hidden",name:t.name},domProps:{value:void 0===t.label?t.localValue:t.label}}),t.$slots.default?n("span",{staticClass:"bk-checkbox-text"},[t._t("default")],2):t._e()])},staticRenderFns:[]},undefined,o,undefined,!1,undefined,!1,void 0,void 0,void 0),s=function(t){if(null==t)throw TypeError("Can't call method on "+t);return t},c={}.hasOwnProperty,l=function(t,e){return c.call(t,e)},p={}.toString,d=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==function(t){return p.call(t).slice(8,-1)}(t)?t.split(""):Object(t)},u=function(t){return d(s(t))},f=Math.ceil,m=Math.floor,h=function(t){return isNaN(t=+t)?0:(t>0?m:f)(t)},b=Math.min,g=Math.max,v=Math.min;function y(t,e){return t(e={exports:{}},e.exports),e.exports}var x,w,k=y((function(t){var e=t.exports={version:"2.6.12"};"number"==typeof __e&&(__e=e)})),E=(k.version,y((function(t){var e=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=e)}))),T=y((function(t){var e="__core-js_shared__",n=E[e]||(E[e]={});(t.exports=function(t,e){return n[t]||(n[t]=void 0!==e?e:{})})("versions",[]).push({version:k.version,mode:"pure",copyright:"© 2020 Denis Pushkarev (zloirock.ru)"})})),I=0,S=Math.random(),C=T("keys"),O=(w=!1,function(t,e,n){var i,o,r=u(t),a=(o=r.length)>0?b(h(o),9007199254740991):0,s=function(t,e){return(t=h(t))<0?g(t+e,0):v(t,e)}(n,a);if(w&&e!=e){for(;a>s;)if((i=r[s++])!=i)return!0}else for(;a>s;s++)if((w||s in r)&&r[s]===e)return w||s||0;return!w&&-1}),A=C[x="IE_PROTO"]||(C[x]=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++I+S).toString(36))}(x)),_="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),L=Object.keys||function(t){return function(t,e){var n,i=u(t),o=0,r=[];for(n in i)n!=A&&l(i,n)&&r.push(n);for(;e.length>o;)l(i,n=e[o++])&&(~O(r,n)||r.push(n));return r}(t,_)},M=function(t,e,n){if(function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!")}(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,i){return t.call(e,n,i)};case 3:return function(n,i,o){return t.call(e,n,i,o)}}return function(){return t.apply(e,arguments)}},N=function(t){return"object"==typeof t?null!==t:"function"==typeof t},R=function(t){if(!N(t))throw TypeError(t+" is not an object!");return t},D=function(t){try{return!!t()}catch(t){return!0}},z=!D((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})),P=E.document,H=N(P)&&N(P.createElement),F=!z&&!D((function(){return 7!=Object.defineProperty((t="div",H?P.createElement(t):{}),"a",{get:function(){return 7}}).a;var t})),j=Object.defineProperty,B={f:z?Object.defineProperty:function(t,e,n){if(R(t),e=function(t,e){if(!N(t))return t;var n,i;if(e&&"function"==typeof(n=t.toString)&&!N(i=n.call(t)))return i;if("function"==typeof(n=t.valueOf)&&!N(i=n.call(t)))return i;if(!e&&"function"==typeof(n=t.toString)&&!N(i=n.call(t)))return i;throw TypeError("Can't convert object to primitive value")}(e,!0),R(n),F)try{return j(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},U=z?function(t,e,n){return B.f(t,e,function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}(1,n))}:function(t,e,n){return t[e]=n,t},V="prototype",Y=function(t,e,n){var i,o,r,a=t&Y.F,s=t&Y.G,c=t&Y.S,p=t&Y.P,d=t&Y.B,u=t&Y.W,f=s?k:k[e]||(k[e]={}),m=f[V],h=s?E:c?E[e]:(E[e]||{})[V];for(i in s&&(n=e),n)(o=!a&&h&&void 0!==h[i])&&l(f,i)||(r=o?h[i]:n[i],f[i]=s&&"function"!=typeof h[i]?n[i]:d&&o?M(r,E):u&&h[i]==r?function(t){var e=function(e,n,i){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(e);case 2:return new t(e,n)}return new t(e,n,i)}return t.apply(this,arguments)};return e[V]=t[V],e}(r):p&&"function"==typeof r?M(Function.call,r):r,p&&((f.virtual||(f.virtual={}))[i]=r,t&Y.R&&m&&!m[i]&&U(m,i,r)))};Y.F=1,Y.G=2,Y.S=4,Y.P=8,Y.B=16,Y.W=32,Y.U=64,Y.R=128;var W,$,G,X,q=Y;W="keys",$=function(){return function(t){return L(function(t){return Object(s(t))}(t))}},G=(k.Object||{})[W]||Object[W],(X={})[W]=$(),q(q.S+q.F*D((function(){G(1)})),"Object",X);var K,Z,Q=k.Object.keys;(K=a).install=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=K.props||{};Q(e).forEach((function(t){n.hasOwnProperty(t)&&("function"==typeof n[t]||n[t]instanceof Array?n[t]={type:n[t],default:e[t]}:n[t].default=e[t])})),K.name=e.namespace?K.name.replace("bk",e.namespace):K.name,t.component(K.name,K),"function"==typeof Z&&Z(t,e)},t.default=a,Object.defineProperty(t,"__esModule",{value:!0})}(e)},1409:function(t,e,n){!function(t,e){"use strict";function i(t){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i(t)}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function r(t,e){for(var n=0;n>>0||(H.test(n)?16:10))}:z;C(C.G+C.F*(parseInt!=F),{parseInt:F});var j=p.parseInt,B={}.toString,U=function(t){return B.call(t).slice(8,-1)},V=Array.isArray||function(t){return"Array"==U(t)};C(C.S,"Array",{isArray:V});var Y,W,$,G,X,q,K=p.Array.isArray,Z=function(t){return Object(O(t))},Q=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==U(t)?t.split(""):Object(t)},J=function(t){return Q(O(t))},tt=Math.ceil,et=Math.floor,nt=function(t){return isNaN(t=+t)?0:(t>0?et:tt)(t)},it=Math.min,ot=Math.max,rt=Math.min,at=c((function(t){var e="__core-js_shared__",n=l[e]||(l[e]={});(t.exports=function(t,e){return n[t]||(n[t]=void 0!==e?e:{})})("versions",[]).push({version:p.version,mode:"pure",copyright:"© 2020 Denis Pushkarev (zloirock.ru)"})})),st=0,ct=Math.random(),lt=at("keys"),pt=(q=!1,function(t,e,n){var i,o,r=J(t),a=(o=r.length)>0?it(nt(o),9007199254740991):0,s=function(t,e){return(t=nt(t))<0?ot(t+e,0):rt(t,e)}(n,a);if(q&&e!=e){for(;a>s;)if((i=r[s++])!=i)return!0}else for(;a>s;s++)if((q||s in r)&&r[s]===e)return q||s||0;return!q&&-1}),dt=lt[X="IE_PROTO"]||(lt[X]=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++st+ct).toString(36))}(X)),ut="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),ft=Object.keys||function(t){return function(t,e){var n,i=J(t),o=0,r=[];for(n in i)n!=dt&&T(i,n)&&r.push(n);for(;e.length>o;)T(i,n=e[o++])&&(~pt(r,n)||r.push(n));return r}(t,ut)};Y="keys",W=function(){return function(t){return ft(Z(t))}},$=(p.Object||{})[Y]||Object[Y],(G={})[Y]=W(),C(C.S+C.F*h((function(){$(1)})),"Object",G);var mt=p.Object.keys,ht={f:Object.getOwnPropertySymbols},bt={f:{}.propertyIsEnumerable},gt=Object.assign,vt=!gt||h((function(){var t={},e={},n=Symbol(),i="abcdefghijklmnopqrst";return t[n]=7,i.split("").forEach((function(t){e[t]=t})),7!=gt({},t)[n]||Object.keys(gt({},e)).join("")!=i}))?function(t,e){for(var n=Z(t),i=arguments.length,o=1,r=ht.f,a=bt.f;i>o;)for(var s,c=Q(arguments[o++]),l=r?ft(c).concat(r(c)):ft(c),p=l.length,d=0;p>d;)s=l[d++],b&&!a.call(c,s)||(n[s]=c[s]);return n}:gt;C(C.S+C.F,"Object",{assign:vt});var yt=p.Object.assign,xt=l.parseFloat,wt=D.trim,kt=1/xt(A+"-0")!=-1/0?function(t){var e=wt(String(t),3),n=xt(e);return 0===n&&"-"==e.charAt(0)?-0:n}:xt;C(C.G+C.F*(parseFloat!=kt),{parseFloat:kt});for(var Et=p.parseFloat,Tt="undefined"!=typeof window&&"undefined"!=typeof document,It=["Edge","Trident","Firefox"],St=0,Ct=0;Ct=0){St=1;break}var Ot=Tt&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),St))}};function At(t){return t&&"[object Function]"==={}.toString.call(t)}function _t(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function Lt(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function Mt(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=_t(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:Mt(Lt(t))}var Nt=Tt&&!(!window.MSInputMethodContext||!document.documentMode),Rt=Tt&&/MSIE 10/.test(navigator.userAgent);function Dt(t){return 11===t?Nt:10===t?Rt:Nt||Rt}function zt(t){if(!t)return document.documentElement;for(var e=Dt(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===_t(n,"position")?zt(n):n:t?t.ownerDocument.documentElement:document.documentElement}function Pt(t){return null!==t.parentNode?Pt(t.parentNode):t}function Ht(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var a,s,c=r.commonAncestorContainer;if(t!==c&&e!==c||i.contains(o))return"BODY"===(s=(a=c).nodeName)||"HTML"!==s&&zt(a.firstElementChild)!==a?zt(c):c;var l=Pt(t);return l.host?Ht(l.host,e):Ht(t,Pt(e).host)}function Ft(t){var e="top"===(arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top")?"scrollTop":"scrollLeft",n=t.nodeName;if("BODY"===n||"HTML"===n){var i=t.ownerDocument.documentElement;return(t.ownerDocument.scrollingElement||i)[e]}return t[e]}function jt(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=Ft(e,"top"),o=Ft(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function Bt(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return Et(t["border".concat(n,"Width")],10)+Et(t["border".concat(i,"Width")],10)}function Ut(t,e,n,i){return Math.max(e["offset".concat(t)],e["scroll".concat(t)],n["client".concat(t)],n["offset".concat(t)],n["scroll".concat(t)],Dt(10)?j(n["offset".concat(t)])+j(i["margin".concat("Height"===t?"Top":"Left")])+j(i["margin".concat("Height"===t?"Bottom":"Right")]):0)}function Vt(t){var e=t.body,n=t.documentElement,i=Dt(10)&&getComputedStyle(n);return{height:Ut("Height",e,n,i),width:Ut("Width",e,n,i)}}var Yt=yt||function(t){for(var e=1;e2&&void 0!==arguments[2]&&arguments[2],i=Dt(10),o="HTML"===e.nodeName,r=$t(t),a=$t(e),s=Mt(t),c=_t(e),l=Et(c.borderTopWidth,10),p=Et(c.borderLeftWidth,10);n&&o&&(a.top=Math.max(a.top,0),a.left=Math.max(a.left,0));var d=Wt({top:r.top-a.top-l,left:r.left-a.left-p,width:r.width,height:r.height});if(d.marginTop=0,d.marginLeft=0,!i&&o){var u=Et(c.marginTop,10),f=Et(c.marginLeft,10);d.top-=l-u,d.bottom-=l-u,d.left-=p-f,d.right-=p-f,d.marginTop=u,d.marginLeft=f}return(i&&!n?e.contains(s):e===s&&"BODY"!==s.nodeName)&&(d=jt(d,e)),d}function Xt(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=Gt(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),a=e?0:Ft(n),s=e?0:Ft(n,"left");return Wt({top:a-i.top+i.marginTop,left:s-i.left+i.marginLeft,width:o,height:r})}function qt(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===_t(t,"position"))return!0;var n=Lt(t);return!!n&&qt(n)}function Kt(t){if(!t||!t.parentElement||Dt())return document.documentElement;for(var e=t.parentElement;e&&"none"===_t(e,"transform");)e=e.parentElement;return e||document.documentElement}function Zt(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},a=o?Kt(t):Ht(t,e);if("viewport"===i)r=Xt(a,o);else{var s;"scrollParent"===i?"BODY"===(s=Mt(Lt(e))).nodeName&&(s=t.ownerDocument.documentElement):s="window"===i?t.ownerDocument.documentElement:i;var c=Gt(s,a,o);if("HTML"!==s.nodeName||qt(a))r=c;else{var l=Vt(t.ownerDocument),p=l.height,d=l.width;r.top+=c.top-c.marginTop,r.bottom=p+c.top,r.left+=c.left-c.marginLeft,r.right=d+c.left}}var u="number"==typeof(n=n||0);return r.left+=u?n:n.left||0,r.top+=u?n:n.top||0,r.right-=u?n:n.right||0,r.bottom-=u?n:n.bottom||0,r}function Qt(t){return t.width*t.height}function Jt(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var a=Zt(n,i,r,o),s={top:{width:a.width,height:e.top-a.top},right:{width:a.right-e.right,height:a.height},bottom:{width:a.width,height:a.bottom-e.bottom},left:{width:e.left-a.left,height:a.height}},c=mt(s).map((function(t){return Yt({key:t},s[t],{area:Qt(s[t])})})).sort((function(t,e){return e.area-t.area})),l=c.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),p=l.length>0?l[0].key:c[0].key,d=t.split("-")[1];return p+(d?"-".concat(d):"")}function te(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;return Gt(n,i?Kt(e):Ht(e,n),i)}function ee(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=Et(e.marginTop||0)+Et(e.marginBottom||0),i=Et(e.marginLeft||0)+Et(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function ne(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function ie(t,e,n){n=n.split("-")[0];var i=ee(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),a=r?"top":"left",s=r?"left":"top",c=r?"height":"width",l=r?"width":"height";return o[a]=e[a]+e[c]/2-i[c]/2,o[s]=n===s?e[s]-i[l]:e[ne(s)],o}function oe(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function re(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===n}));var i=oe(t,(function(t){return t[e]===n}));return t.indexOf(i)}(t,"name",n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&At(n)&&(e.offsets.popper=Wt(e.offsets.popper),e.offsets.reference=Wt(e.offsets.reference),e=n(e,t))})),e}function ae(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=te(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=Jt(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=ie(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=re(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function se(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function ce(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i1&&void 0!==arguments[1]&&arguments[1],n=xe.indexOf(t),i=xe.slice(n+1).concat(xe.slice(0,n));return e?i.reverse():i}var ke="flip",Ee="clockwise",Te="counterclockwise";function Ie(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),a=t.split(/(\+|\-)/).map((function(t){return t.trim()})),s=a.indexOf(oe(a,(function(t){return-1!==t.search(/,|\s/)})));a[s]&&-1===a[s].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var c=/\s*,\s*|\s+/,l=-1!==s?[a.slice(0,s).concat([a[s].split(c)[0]]),[a[s].split(c)[1]].concat(a.slice(s+1))]:[a];return(l=l.map((function(t,i){var o=(1===i?!r:r)?"height":"width",a=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,a=!0,t):a?(t[t.length-1]+=e,a=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],a=o[2];return r?0===a.indexOf("%")?Wt("%p"===a?n:i)[e]/100*r:"vh"===a||"vw"===a?("vh"===a?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r:r:t}(t,o,e,n)}))}))).forEach((function(t,e){t.forEach((function(n,i){he(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}var Se={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,r=o.reference,s=o.popper,c=-1!==["bottom","top"].indexOf(n),l=c?"left":"top",p=c?"width":"height",d={start:a({},l,r[l]),end:a({},l,r[l]+r[p]-s[p])};t.offsets.popper=Yt({},s,d[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n,i=e.offset,o=t.placement,r=t.offsets,a=r.popper,s=r.reference,c=o.split("-")[0];return n=he(+i)?[+i,0]:Ie(i,a,s,c),"left"===c?(a.top+=n[0],a.left-=n[1]):"right"===c?(a.top+=n[0],a.left+=n[1]):"top"===c?(a.left+=n[0],a.top-=n[1]):"bottom"===c&&(a.left+=n[0],a.top+=n[1]),t.popper=a,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||zt(t.instance.popper);t.instance.reference===n&&(n=zt(n));var i=ce("transform"),o=t.instance.popper.style,r=o.top,s=o.left,c=o[i];o.top="",o.left="",o[i]="";var l=Zt(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=r,o.left=s,o[i]=c,e.boundaries=l;var p=e.priority,d=t.offsets.popper,u={primary:function(t){var n=d[t];return d[t]l[t]&&!e.escapeWithReference&&(i=Math.min(d[n],l[t]-("right"===t?d.width:d.height))),a({},n,i)}};return p.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";d=Yt({},d,u[e](t))})),t.offsets.popper=d,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(o),s=a?"right":"bottom",c=a?"left":"top",l=a?"width":"height";return n[s]r(i[s])&&(t.offsets.popper[c]=r(i[s])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!ve(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],r=t.offsets,s=r.popper,c=r.reference,l=-1!==["left","right"].indexOf(o),p=l?"height":"width",d=l?"Top":"Left",u=d.toLowerCase(),f=l?"left":"top",m=l?"bottom":"right",h=ee(i)[p];c[m]-hs[m]&&(t.offsets.popper[u]+=c[u]+h-s[m]),t.offsets.popper=Wt(t.offsets.popper);var b=c[u]+c[p]/2-h/2,g=_t(t.instance.popper),v=Et(g["margin".concat(d)],10),y=Et(g["border".concat(d,"Width")],10),x=b-t.offsets.popper[u]-v-y;return x=Math.max(Math.min(s[p]-h,x),0),t.arrowElement=i,t.offsets.arrow=(a(n={},u,Math.round(x)),a(n,f,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(se(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=Zt(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=ne(i),r=t.placement.split("-")[1]||"",a=[];switch(e.behavior){case ke:a=[i,o];break;case Ee:a=we(i);break;case Te:a=we(i,!0);break;default:a=e.behavior}return a.forEach((function(s,c){if(i!==s||a.length===c+1)return t;i=t.placement.split("-")[0],o=ne(i);var l=t.offsets.popper,p=t.offsets.reference,d=Math.floor,u="left"===i&&d(l.right)>d(p.left)||"right"===i&&d(l.left)d(p.top)||"bottom"===i&&d(l.top)d(n.right),h=d(l.top)d(n.bottom),g="left"===i&&f||"right"===i&&m||"top"===i&&h||"bottom"===i&&b,v=-1!==["top","bottom"].indexOf(i),y=!!e.flipVariations&&(v&&"start"===r&&f||v&&"end"===r&&m||!v&&"start"===r&&h||!v&&"end"===r&&b),x=!!e.flipVariationsByContent&&(v&&"start"===r&&m||v&&"end"===r&&f||!v&&"start"===r&&b||!v&&"end"===r&&h),w=y||x;(u||g||w)&&(t.flipped=!0,(u||g)&&(i=a[c+1]),w&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=Yt({},t.offsets.popper,ie(t.instance.popper,t.offsets.reference,t.placement)),t=re(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,a=-1!==["left","right"].indexOf(n),s=-1===["top","left"].indexOf(n);return o[a?"left":"top"]=r[n]-(s?o[a?"width":"height"]:0),t.placement=ne(e),t.offsets.popper=Wt(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!ve(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=oe(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottomn.right||e.top>n.bottom||e.right2&&void 0!==arguments[2]?arguments[2]:{};o(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=Ot(this.update.bind(this)),this.options=Yt({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},mt(Yt({},t.Defaults.modifiers,r.modifiers)).forEach((function(e){i.options.modifiers[e]=Yt({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})})),this.modifiers=mt(this.options.modifiers).map((function(t){return Yt({name:t},i.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&At(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)})),this.update();var a=this.options.eventsEnabled;a&&this.enableEventListeners(),this.state.eventsEnabled=a}return e=t,(n=[{key:"update",value:function(){return ae.call(this)}},{key:"destroy",value:function(){return le.call(this)}},{key:"enableEventListeners",value:function(){return fe.call(this)}},{key:"disableEventListeners",value:function(){return me.call(this)}}])&&r(e.prototype,n),i&&r(e,i),Object.defineProperty(e,"prototype",{writable:!1}),t;var e,n,i}();function Oe(){return Oe=yt||function(t){for(var e=1;e-1}function gn(t){return t instanceof Element}function vn(t){return!(!t||!un(t,"isVirtual"))||gn(t)}function yn(t,e){return"function"==typeof t?t.apply(null,e):t}function xn(t,e){t.filter((function(t){return"flip"===t.name}))[0].enabled=e}function wn(){return document.createElement("div")}function kn(t,e){t.forEach((function(t){t&&(t.style.transitionDuration="".concat(e,"ms"))}))}function En(t,e){t.forEach((function(t){t&&t.setAttribute("data-state",e)}))}function Tn(t,e){var n=Oe({},e,{content:yn(e.content,[t])},e.ignoreAttributes?{}:function(t){return pn.reduce((function(e,n){var i=(t.getAttribute("data-tippy-".concat(n))||"").trim();if(!i)return e;if("content"===n)e[n]=i;else try{e[n]=JSON.parse(i)}catch(t){e[n]=i}return e}),{})}(t));return(n.arrow||Me)&&(n.animateFill=!1),n}function In(t,e){mt(t).forEach((function(t){if(!un(e,t))throw new Error("[tippy]: `".concat(t,"` is not a valid option"))}))}function Sn(t,e){t.innerHTML=gn(e)?e.innerHTML:e}function Cn(t,e){gn(e.content)?(Sn(t,""),t.appendChild(e.content)):"function"!=typeof e.content&&(t[e.allowHTML?"innerHTML":"textContent"]=e.content)}function On(t){return{tooltip:t.querySelector(Je),backdrop:t.querySelector(en),content:t.querySelector(tn),arrow:t.querySelector(nn)||t.querySelector(on)}}function An(t){t.setAttribute("data-inertia","")}function _n(t){var e=wn();return"round"===t?(e.className=Ze,Sn(e,'')):e.className=Ke,e}function Ln(){var t=wn();return t.className=qe,t.setAttribute("data-state","hidden"),t}function Mn(t,e){t.setAttribute("tabindex","-1"),e.setAttribute("data-interactive","")}function Nn(t,e,n){var i=Me&&void 0!==document.body.style.webkitTransition?"webkitTransitionEnd":"transitionend";t[e+"EventListener"](i,n)}function Rn(t){var e=t.getAttribute(Ue);return e?e.split("-")[0]:""}function Dn(t,e,n){n.split(" ").forEach((function(n){t.classList[e](n+"-theme")}))}function zn(t,e,n){var i=e[n],o=j(i);"number"==typeof i?t.style[n]=i+"px":isNaN(o)?t.style[n]=i:t.style[n]=o+"px"}function Pn(t,e){var n=wn();n.className=$e+(e.extCls?" ".concat(e.extCls):""),n.id="tippy-".concat(t),n.style.zIndex=""+e.zIndex,n.style.position="absolute",n.style.top="0",n.style.left="0",e.role&&n.setAttribute("role",e.role);var i=wn();i.className=Ge,zn(i,e,"maxWidth"),zn(i,e,"width"),i.setAttribute("data-size",e.size),i.setAttribute("data-animation",e.animation),i.setAttribute("data-state","hidden"),Dn(i,"add",e.theme);var o=wn();return o.className=Xe,o.setAttribute("data-state","hidden"),e.interactive&&Mn(n,i),e.arrow&&i.appendChild(_n(e.arrowType)),e.animateFill&&(i.appendChild(Ln()),i.setAttribute("data-animatefill","")),e.inertia&&An(i),Cn(o,e),i.appendChild(o),n.appendChild(i),n}function Hn(t,e,n){var i=On(t),o=i.tooltip,r=i.content,a=i.backdrop,s=i.arrow;t.style.zIndex=""+n.zIndex,o.setAttribute("data-size",n.size),o.setAttribute("data-animation",n.animation),o.style.maxWidth=n.maxWidth+("number"==typeof n.maxWidth?"px":""),n.role?t.setAttribute("role",n.role):t.removeAttribute("role"),e.content!==n.content&&Cn(r,n),!e.animateFill&&n.animateFill?(o.appendChild(Ln()),o.setAttribute("data-animatefill","")):e.animateFill&&!n.animateFill&&(o.removeChild(a),o.removeAttribute("data-animatefill")),!e.arrow&&n.arrow?o.appendChild(_n(n.arrowType)):e.arrow&&!n.arrow&&o.removeChild(s),e.arrow&&n.arrow&&e.arrowType!==n.arrowType&&o.replaceChild(_n(n.arrowType),s),!e.interactive&&n.interactive?Mn(t,o):e.interactive&&!n.interactive&&function(t,e){t.removeAttribute("tabindex"),e.removeAttribute("data-interactive")}(t,o),!e.inertia&&n.inertia?An(o):e.inertia&&!n.inertia&&function(t){t.removeAttribute("data-inertia")}(o),e.theme!==n.theme&&(Dn(o,"remove",e.theme),Dn(o,"add",n.theme))}var Fn=1,jn=[];function Bn(t,e){var n,i,o,r,a,s=Tn(t,e);if(!s.multiple&&t._tippy)return null;var c,l,p,d,u,f=!1,m=!1,h=!1,b=!1,g=[],v=mn(F,s.interactiveDebounce),y=Fn++,x=Pn(y,s),w=On(x),k={id:y,reference:t,popper:x,popperChildren:w,popperInstance:null,props:s,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},clearDelayTimeouts:Z,set:Q,setContent:function(t){Q({content:t})},show:J,hide:tt,enable:function(){k.state.isEnabled=!0},disable:function(){k.state.isEnabled=!1},destroy:function(e){if(!k.state.isDestroyed){m=!0,k.state.isMounted&&tt(0),z(),delete t._tippy;var n=k.props.target;n&&e&&gn(t)&&He(t.querySelectorAll(n)).forEach((function(t){t._tippy&&t._tippy.destroy()})),k.popperInstance&&k.popperInstance.destroy(),m=!1,k.state.isDestroyed=!0}}};return t._tippy=k,x._tippy=k,D(),s.lazy||$(),s.showOnInit&&X(),!s.a11y||s.target||(!gn(u=I())||Pe.call(u,"a[href],area[href],button,details,input,textarea,select,iframe,[tabindex]")&&!u.hasAttribute("disabled"))||I().setAttribute("tabindex","0"),x.addEventListener("mouseenter",(function(t){k.props.interactive&&k.state.isVisible&&"mouseenter"===n&&X(t,!0)})),x.addEventListener("mouseleave",(function(){k.props.interactive&&"mouseenter"===n&&document.addEventListener("mousemove",v)})),k;function E(){document.removeEventListener("mousemove",P)}function T(){document.body.removeEventListener("mouseleave",q),document.removeEventListener("mousemove",v),jn=jn.filter((function(t){return t!==v}))}function I(){return k.props.triggerTarget||t}function S(){document.addEventListener("click",K,!0)}function C(){document.removeEventListener("click",K,!0)}function O(){return[k.popperChildren.tooltip,k.popperChildren.backdrop,k.popperChildren.content]}function A(){var t=k.props.followCursor;return t&&"focus"!==n||rn&&"initial"===t}function _(){kn([x],Le?0:k.props.updateDuration),function t(){k.popperInstance.scheduleUpdate(),k.state.isMounted?requestAnimationFrame(t):kn([x],0)}()}function L(t,e){N(t,(function(){!k.state.isVisible&&x.parentNode&&x.parentNode.contains(x)&&e()}))}function M(t,e){N(t,e)}function N(t,e){var n=k.popperChildren.tooltip;function i(t){t.target===n&&(Nn(n,"remove",i),e())}if(0===t)return e();Nn(n,"remove",p),Nn(n,"add",i),p=i}function R(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];I().addEventListener(t,e,n),g.push({eventType:t,handler:e,options:n})}function D(){k.props.touchHold&&!k.props.target&&(R("touchstart",H,Be),R("touchend",j,Be)),k.props.trigger.trim().split(" ").forEach((function(t){if("manual"!==t)if(k.props.target)switch(t){case"mouseenter":R("mouseover",U),R("mouseout",V);break;case"focus":R("focusin",U),R("focusout",V);break;case"click":R(t,U)}else switch(R(t,H),t){case"mouseenter":R("mouseleave",j);break;case"focus":R(Le?"focusout":"blur",B)}}))}function z(){g.forEach((function(t){var e=t.eventType,n=t.handler,i=t.options;I().removeEventListener(e,n,i)})),g=[]}function P(e){var n=i=e,o=n.clientX,r=n.clientY;if(d){var a=je(e.target,(function(e){return e===t})),s=t.getBoundingClientRect(),c=k.props.followCursor,l="horizontal"===c,p="vertical"===c,u=bn(["top","bottom"],Rn(x)),f=x.getAttribute(Ue),m=!!f&&!!f.split("-")[1],h=u?x.offsetWidth:x.offsetHeight,b=h/2,g=u?0:m?h:b,v=u?m?h:b:0;!a&&k.props.interactive||(k.popperInstance.reference=Oe({},k.popperInstance.reference,{clientWidth:0,clientHeight:0,getBoundingClientRect:function(){return{width:u?h:0,height:u?0:h,top:(l?s.top:r)-g,bottom:(l?s.bottom:r)+g,left:(p?s.left:o)-v,right:(p?s.right:o)+v}}}),k.popperInstance.update()),"initial"===c&&k.state.isVisible&&E()}}function H(t){k.state.isEnabled&&!Y(t)&&(k.state.isVisible||(n=t.type,t instanceof MouseEvent&&(i=t,jn.forEach((function(e){return e(t)})))),"click"===t.type&&!1!==k.props.hideOnClick&&k.state.isVisible?q():X(t))}function F(e){var n=Fe(e.target,Qe)===x,i=je(e.target,(function(e){return e===t}));n||i||function(t,e,n,i){if(!t)return!0;var o=n.clientX,r=n.clientY,a=i.interactiveBorder,s=i.distance,c=e.top-r>("top"===t?a+s:a),l=r-e.bottom>("bottom"===t?a+s:a),p=e.left-o>("left"===t?a+s:a),d=o-e.right>("right"===t?a+s:a);return c||l||p||d}(Rn(x),x.getBoundingClientRect(),e,k.props)&&(T(),q())}function j(t){if(!Y(t))return k.props.interactive?(document.body.addEventListener("mouseleave",q),document.addEventListener("mousemove",v),void jn.push(v)):void q()}function B(t){t.target===I()&&(k.props.interactive&&t.relatedTarget&&x.contains(t.relatedTarget)||q())}function U(t){Fe(t.target,k.props.target)&&X(t)}function V(t){Fe(t.target,k.props.target)&&q()}function Y(t){var e="ontouchstart"in window,n=bn(t.type,"touch"),i=k.props.touchHold;return e&&rn&&i&&!n||rn&&!i&&n}function W(){!b&&l&&(b=!0,function(t){t.offsetHeight}(x),l())}function $(){var e=k.props.popperOptions,n=k.popperChildren,i=n.tooltip,o=n.arrow,r=hn(e,"preventOverflow");function a(t){k.props.flip&&!k.props.flipOnUpdate&&(t.flipped&&(k.popperInstance.options.placement=t.placement),xn(k.popperInstance.modifiers,!1)),i.setAttribute(Ue,t.placement),!1!==t.attributes[Ve]?i.setAttribute(Ve,""):i.removeAttribute(Ve),c&&c!==t.placement&&h&&(i.style.transition="none",requestAnimationFrame((function(){i.style.transition=""}))),c=t.placement,h=k.state.isVisible;var e=Rn(x),n=i.style;n.top=n.bottom=n.left=n.right="",n[e]=-(k.props.distance-10)+"px";var o=r&&void 0!==r.padding?r.padding:4,a="number"==typeof o,s=Oe({top:a?o:o.top,bottom:a?o:o.bottom,left:a?o:o.left,right:a?o:o.right},!a&&o);s[e]=a?o+k.props.distance:(o[e]||0)+k.props.distance,k.popperInstance.modifiers.filter((function(t){return"preventOverflow"===t.name}))[0].padding=s,d=s}var s=Oe({eventsEnabled:!1,placement:k.props.placement},e,{modifiers:Oe({},e?e.modifiers:{},{preventOverflow:Oe({boundariesElement:k.props.boundary,padding:4},r),arrow:Oe({element:o,enabled:!!o},hn(e,"arrow")),flip:Oe({enabled:k.props.flip,padding:k.props.distance+4,behavior:k.props.flipBehavior},hn(e,"flip")),offset:Oe({offset:k.props.offset},hn(e,"offset"))}),onCreate:function(t){a(t),W(),e&&e.onCreate&&e.onCreate(t)},onUpdate:function(t){a(t),W(),e&&e.onUpdate&&e.onUpdate(t)}});k.popperInstance=new Ce(t,x,s)}function G(){b=!1;var e=A();k.popperInstance?(xn(k.popperInstance.modifiers,k.props.flip),e||(k.popperInstance.reference=t,k.popperInstance.enableEventListeners()),k.popperInstance.scheduleUpdate()):($(),e||k.popperInstance.enableEventListeners());var n=k.props.appendTo,i="parent"===n?t.parentNode:yn(n,[t]);i.contains(x)||(i.appendChild(x),k.props.onMount(k),k.state.isMounted=!0)}function X(t,n){if(Z(),!k.state.isVisible){if(k.props.target)return function(t){if(t){var n=Fe(t.target,k.props.target);n&&!n._tippy&&Bn(n,Oe({},k.props,{content:yn(e.content,[n]),appendTo:e.appendTo,target:"",showOnInit:!0}))}}(t);if(f=!0,t&&!n&&k.props.onTrigger(k,t),k.props.wait)return k.props.wait(k,t);A()&&!k.state.isMounted&&(k.popperInstance||$(),document.addEventListener("mousemove",P)),S();var i=fn(k.props.delay,0,Re.delay);i?o=setTimeout((function(){J()}),i):J()}}function q(){if(Z(),!k.state.isVisible)return E();f=!1;var t=fn(k.props.delay,1,Re.delay);t?r=setTimeout((function(){k.state.isVisible&&tt()}),t):a=requestAnimationFrame((function(){tt()}))}function K(t){if(!k.props.interactive||!x.contains(t.target)){if(I().contains(t.target)){if(rn)return;if(k.state.isVisible&&bn(k.props.trigger,"click"))return}!0===k.props.hideOnClick&&(Z(),tt())}}function Z(){clearTimeout(o),clearTimeout(r),cancelAnimationFrame(a)}function Q(e){In(e=e||{},Re),z();var n=k.props,o=Tn(t,Oe({},k.props,e,{ignoreAttributes:!0}));o.ignoreAttributes=un(e,"ignoreAttributes")?e.ignoreAttributes||!1:n.ignoreAttributes,k.props=o,D(),T(),v=mn(F,o.interactiveDebounce),Hn(x,n,o),k.popperChildren=On(x),k.popperInstance&&(De.some((function(t){return un(e,t)&&e[t]!==n[t]}))?(k.popperInstance.destroy(),$(),k.state.isVisible&&k.popperInstance.enableEventListeners(),k.props.followCursor&&i&&P(i)):k.popperInstance.update())}function J(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:fn(k.props.duration,0,Re.duration[1]);if(!k.state.isDestroyed&&k.state.isEnabled&&(!rn||k.props.touch)&&!I().hasAttribute("disabled")&&!1!==k.props.onShow(k)){S(),x.style.visibility="visible",k.state.isVisible=!0,k.props.interactive&&I().classList.add(We);var e=O();kn(e.concat(x),0),l=function(){if(k.state.isVisible){var n=A();n&&i?P(i):n||k.popperInstance.update(),k.popperChildren.backdrop&&(k.popperChildren.content.style.transitionDelay=Math.round(t/12)+"ms"),k.props.sticky&&_(),kn([x],k.props.updateDuration),kn(e,t),En(e,"visible"),M(t,(function(){k.props.aria&&I().setAttribute("aria-".concat(k.props.aria),x.id),k.props.onShown(k),k.state.isShown=!0}))}},G()}}function tt(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:fn(k.props.duration,1,Re.duration[1]);if(!k.state.isDestroyed&&(k.state.isEnabled||m)&&(!1!==k.props.onHide(k)||m)){C(),x.style.visibility="hidden",k.state.isVisible=!1,k.state.isShown=!1,h=!1,k.props.interactive&&I().classList.remove(We);var e=O();kn(e,t),En(e,"hidden"),L(t,(function(){f||E(),k.props.aria&&I().removeAttribute("aria-".concat(k.props.aria)),k.popperInstance.disableEventListeners(),k.popperInstance.options.placement=k.props.placement,x.parentNode.removeChild(x),k.props.onHidden(k),k.state.isMounted=!1}))}}}var Un=!1;function Vn(t,e){In(e||{},Re),Un||(document.addEventListener("touchstart",an,Be),window.addEventListener("blur",ln),Un=!0);var n,i=Oe({},Re,e);n=t,"[object Object]"==={}.toString.call(n)&&!n.addEventListener&&function(t){var e={isVirtual:!0,attributes:t.attributes||{},contains:function(){},setAttribute:function(e,n){t.attributes[e]=n},getAttribute:function(e){return t.attributes[e]},removeAttribute:function(e){delete t.attributes[e]},hasAttribute:function(e){return e in t.attributes},addEventListener:function(){},removeEventListener:function(){},classList:{classNames:{},add:function(e){t.classList.classNames[e]=!0},remove:function(e){delete t.classList.classNames[e]},contains:function(e){return e in t.classList.classNames}}};for(var n in e)t[n]=e[n]}(t);var o=function(t){if(vn(t))return[t];if(t instanceof NodeList)return He(t);if(K(t))return t;try{return He(document.querySelectorAll(t))}catch(t){return[]}}(t).reduce((function(t,e){var n=e&&Bn(e,i);return n&&t.push(n),t}),[]);return vn(t)?o[0]:o}Vn.version="4.3.4",Vn.defaults=Re,Vn.setDefaults=function(t){mt(t).forEach((function(e){Re[e]=t[e]}))},Vn.hideAll=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.exclude,n=t.duration;He(document.querySelectorAll(Qe)).forEach((function(t){var i=t._tippy;if(i){var o=!1;e&&(o=dn(e)?i.reference===e:t===e.popper),o||i.hide(n)}}))},Vn.group=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.delay,i=void 0===n?t[0].props.delay:n,o=e.duration,r=void 0===o?0:o,a=!1;function s(t){a=t,d()}function c(e){e._originalProps.onShow(e),t.forEach((function(t){t.set({duration:r}),t.state.isVisible&&t.hide()})),s(!0)}function l(t){t._originalProps.onHide(t),s(!1)}function p(t){t._originalProps.onShown(t),t.set({duration:t._originalProps.duration})}function d(){t.forEach((function(t){t.set({onShow:c,onShown:p,onHide:l,delay:a?[0,K(i)?i[1]:i]:i,duration:a?r:t._originalProps.duration})}))}t.forEach((function(t){t._originalProps?t.set(t._originalProps):t._originalProps=Oe({},t.props)})),d()},Ae&&setTimeout((function(){He(document.querySelectorAll("[data-tippy]")).forEach((function(t){var e=t.getAttribute("data-tippy");e&&Vn(t,{content:e})}))}));var Yn={duration:0,arrow:!0,size:"small",trigger:"mouseenter focus",theme:"dark",interactive:!0,boundary:"window",content:"",allowHTML:!0,extCls:""},Wn=["auto-start","auto","auto-end","top-start","top","top-end","right-start","right","right-end","bottom-end","bottom","bottom-start","left-end","left","left-start"],$n=function(t,n){var o=n.value,r=function(t){for(var e=1;e>>0||(P.test(n)?16:10))}:D;S(S.G+S.F*(parseInt!=H),{parseInt:H});var F=l.parseInt,j={}.toString,B=function(t){return j.call(t).slice(8,-1)},U=Array.isArray||function(t){return"Array"==B(t)};S(S.S,"Array",{isArray:U});var V,Y,W,$,G,X,q=l.Array.isArray,K=function(t){return Object(C(t))},Z=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==B(t)?t.split(""):Object(t)},Q=function(t){return Z(C(t))},J=Math.ceil,tt=Math.floor,et=function(t){return isNaN(t=+t)?0:(t>0?tt:J)(t)},nt=Math.min,it=Math.max,ot=Math.min,rt=s((function(t){var e="__core-js_shared__",n=c[e]||(c[e]={});(t.exports=function(t,e){return n[t]||(n[t]=void 0!==e?e:{})})("versions",[]).push({version:l.version,mode:"pure",copyright:"© 2020 Denis Pushkarev (zloirock.ru)"})})),at=0,st=Math.random(),ct=rt("keys"),lt=(X=!1,function(t,e,n){var i,o,r=Q(t),a=(o=r.length)>0?nt(et(o),9007199254740991):0,s=function(t,e){return(t=et(t))<0?it(t+e,0):ot(t,e)}(n,a);if(X&&e!=e){for(;a>s;)if((i=r[s++])!=i)return!0}else for(;a>s;s++)if((X||s in r)&&r[s]===e)return X||s||0;return!X&&-1}),pt=ct[G="IE_PROTO"]||(ct[G]=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++at+st).toString(36))}(G)),dt="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),ut=Object.keys||function(t){return function(t,e){var n,i=Q(t),o=0,r=[];for(n in i)n!=pt&&E(i,n)&&r.push(n);for(;e.length>o;)E(i,n=e[o++])&&(~lt(r,n)||r.push(n));return r}(t,dt)};V="keys",Y=function(){return function(t){return ut(K(t))}},W=(l.Object||{})[V]||Object[V],($={})[V]=Y(),S(S.S+S.F*m((function(){W(1)})),"Object",$);var ft=l.Object.keys,mt={f:Object.getOwnPropertySymbols},ht={f:{}.propertyIsEnumerable},bt=Object.assign,gt=!bt||m((function(){var t={},e={},n=Symbol(),i="abcdefghijklmnopqrst";return t[n]=7,i.split("").forEach((function(t){e[t]=t})),7!=bt({},t)[n]||Object.keys(bt({},e)).join("")!=i}))?function(t,e){for(var n=K(t),i=arguments.length,o=1,r=mt.f,a=ht.f;i>o;)for(var s,c=Z(arguments[o++]),l=r?ut(c).concat(r(c)):ut(c),p=l.length,d=0;p>d;)s=l[d++],h&&!a.call(c,s)||(n[s]=c[s]);return n}:bt;S(S.S+S.F,"Object",{assign:gt});var vt=l.Object.assign,yt=c.parseFloat,xt=R.trim,wt=1/yt(O+"-0")!=-1/0?function(t){var e=xt(String(t),3),n=yt(e);return 0===n&&"-"==e.charAt(0)?-0:n}:yt;S(S.G+S.F*(parseFloat!=wt),{parseFloat:wt});for(var kt=l.parseFloat,Et="undefined"!=typeof window&&"undefined"!=typeof document,Tt=["Edge","Trident","Firefox"],It=0,St=0;St=0){It=1;break}var Ct=Et&&window.Promise?function(t){var e=!1;return function(){e||(e=!0,window.Promise.resolve().then((function(){e=!1,t()})))}}:function(t){var e=!1;return function(){e||(e=!0,setTimeout((function(){e=!1,t()}),It))}};function Ot(t){return t&&"[object Function]"==={}.toString.call(t)}function At(t,e){if(1!==t.nodeType)return[];var n=t.ownerDocument.defaultView.getComputedStyle(t,null);return e?n[e]:n}function _t(t){return"HTML"===t.nodeName?t:t.parentNode||t.host}function Lt(t){if(!t)return document.body;switch(t.nodeName){case"HTML":case"BODY":return t.ownerDocument.body;case"#document":return t.body}var e=At(t),n=e.overflow,i=e.overflowX,o=e.overflowY;return/(auto|scroll|overlay)/.test(n+o+i)?t:Lt(_t(t))}var Mt=Et&&!(!window.MSInputMethodContext||!document.documentMode),Nt=Et&&/MSIE 10/.test(navigator.userAgent);function Rt(t){return 11===t?Mt:10===t?Nt:Mt||Nt}function Dt(t){if(!t)return document.documentElement;for(var e=Rt(10)?document.body:null,n=t.offsetParent||null;n===e&&t.nextElementSibling;)n=(t=t.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&"BODY"!==i&&"HTML"!==i?-1!==["TH","TD","TABLE"].indexOf(n.nodeName)&&"static"===At(n,"position")?Dt(n):n:t?t.ownerDocument.documentElement:document.documentElement}function zt(t){return null!==t.parentNode?zt(t.parentNode):t}function Pt(t,e){if(!(t&&t.nodeType&&e&&e.nodeType))return document.documentElement;var n=t.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING,i=n?t:e,o=n?e:t,r=document.createRange();r.setStart(i,0),r.setEnd(o,0);var a,s,c=r.commonAncestorContainer;if(t!==c&&e!==c||i.contains(o))return"BODY"===(s=(a=c).nodeName)||"HTML"!==s&&Dt(a.firstElementChild)!==a?Dt(c):c;var l=zt(t);return l.host?Pt(l.host,e):Pt(t,zt(e).host)}function Ht(t){var e="top"===(arguments.length>1&&void 0!==arguments[1]?arguments[1]:"top")?"scrollTop":"scrollLeft",n=t.nodeName;if("BODY"===n||"HTML"===n){var i=t.ownerDocument.documentElement;return(t.ownerDocument.scrollingElement||i)[e]}return t[e]}function Ft(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=Ht(e,"top"),o=Ht(e,"left"),r=n?-1:1;return t.top+=i*r,t.bottom+=i*r,t.left+=o*r,t.right+=o*r,t}function jt(t,e){var n="x"===e?"Left":"Top",i="Left"===n?"Right":"Bottom";return kt(t["border".concat(n,"Width")],10)+kt(t["border".concat(i,"Width")],10)}function Bt(t,e,n,i){return Math.max(e["offset".concat(t)],e["scroll".concat(t)],n["client".concat(t)],n["offset".concat(t)],n["scroll".concat(t)],Rt(10)?F(n["offset".concat(t)])+F(i["margin".concat("Height"===t?"Top":"Left")])+F(i["margin".concat("Height"===t?"Bottom":"Right")]):0)}function Ut(t){var e=t.body,n=t.documentElement,i=Rt(10)&&getComputedStyle(n);return{height:Bt("Height",e,n,i),width:Bt("Width",e,n,i)}}var Vt=vt||function(t){for(var e=1;e2&&void 0!==arguments[2]&&arguments[2],i=Rt(10),o="HTML"===e.nodeName,r=Wt(t),a=Wt(e),s=Lt(t),c=At(e),l=kt(c.borderTopWidth,10),p=kt(c.borderLeftWidth,10);n&&o&&(a.top=Math.max(a.top,0),a.left=Math.max(a.left,0));var d=Yt({top:r.top-a.top-l,left:r.left-a.left-p,width:r.width,height:r.height});if(d.marginTop=0,d.marginLeft=0,!i&&o){var u=kt(c.marginTop,10),f=kt(c.marginLeft,10);d.top-=l-u,d.bottom-=l-u,d.left-=p-f,d.right-=p-f,d.marginTop=u,d.marginLeft=f}return(i&&!n?e.contains(s):e===s&&"BODY"!==s.nodeName)&&(d=Ft(d,e)),d}function Gt(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t.ownerDocument.documentElement,i=$t(t,n),o=Math.max(n.clientWidth,window.innerWidth||0),r=Math.max(n.clientHeight,window.innerHeight||0),a=e?0:Ht(n),s=e?0:Ht(n,"left");return Yt({top:a-i.top+i.marginTop,left:s-i.left+i.marginLeft,width:o,height:r})}function Xt(t){var e=t.nodeName;if("BODY"===e||"HTML"===e)return!1;if("fixed"===At(t,"position"))return!0;var n=_t(t);return!!n&&Xt(n)}function qt(t){if(!t||!t.parentElement||Rt())return document.documentElement;for(var e=t.parentElement;e&&"none"===At(e,"transform");)e=e.parentElement;return e||document.documentElement}function Kt(t,e,n,i){var o=arguments.length>4&&void 0!==arguments[4]&&arguments[4],r={top:0,left:0},a=o?qt(t):Pt(t,e);if("viewport"===i)r=Gt(a,o);else{var s;"scrollParent"===i?"BODY"===(s=Lt(_t(e))).nodeName&&(s=t.ownerDocument.documentElement):s="window"===i?t.ownerDocument.documentElement:i;var c=$t(s,a,o);if("HTML"!==s.nodeName||Xt(a))r=c;else{var l=Ut(t.ownerDocument),p=l.height,d=l.width;r.top+=c.top-c.marginTop,r.bottom=p+c.top,r.left+=c.left-c.marginLeft,r.right=d+c.left}}var u="number"==typeof(n=n||0);return r.left+=u?n:n.left||0,r.top+=u?n:n.top||0,r.right-=u?n:n.right||0,r.bottom-=u?n:n.bottom||0,r}function Zt(t){return t.width*t.height}function Qt(t,e,n,i,o){var r=arguments.length>5&&void 0!==arguments[5]?arguments[5]:0;if(-1===t.indexOf("auto"))return t;var a=Kt(n,i,r,o),s={top:{width:a.width,height:e.top-a.top},right:{width:a.right-e.right,height:a.height},bottom:{width:a.width,height:a.bottom-e.bottom},left:{width:e.left-a.left,height:a.height}},c=ft(s).map((function(t){return Vt({key:t},s[t],{area:Zt(s[t])})})).sort((function(t,e){return e.area-t.area})),l=c.filter((function(t){var e=t.width,i=t.height;return e>=n.clientWidth&&i>=n.clientHeight})),p=l.length>0?l[0].key:c[0].key,d=t.split("-")[1];return p+(d?"-".concat(d):"")}function Jt(t,e,n){var i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;return $t(n,i?qt(e):Pt(e,n),i)}function te(t){var e=t.ownerDocument.defaultView.getComputedStyle(t),n=kt(e.marginTop||0)+kt(e.marginBottom||0),i=kt(e.marginLeft||0)+kt(e.marginRight||0);return{width:t.offsetWidth+i,height:t.offsetHeight+n}}function ee(t){var e={left:"right",right:"left",bottom:"top",top:"bottom"};return t.replace(/left|right|bottom|top/g,(function(t){return e[t]}))}function ne(t,e,n){n=n.split("-")[0];var i=te(t),o={width:i.width,height:i.height},r=-1!==["right","left"].indexOf(n),a=r?"top":"left",s=r?"left":"top",c=r?"height":"width",l=r?"width":"height";return o[a]=e[a]+e[c]/2-i[c]/2,o[s]=n===s?e[s]-i[l]:e[ee(s)],o}function ie(t,e){return Array.prototype.find?t.find(e):t.filter(e)[0]}function oe(t,e,n){return(void 0===n?t:t.slice(0,function(t,e,n){if(Array.prototype.findIndex)return t.findIndex((function(t){return t[e]===n}));var i=ie(t,(function(t){return t[e]===n}));return t.indexOf(i)}(t,"name",n))).forEach((function(t){t.function&&console.warn("`modifier.function` is deprecated, use `modifier.fn`!");var n=t.function||t.fn;t.enabled&&Ot(n)&&(e.offsets.popper=Yt(e.offsets.popper),e.offsets.reference=Yt(e.offsets.reference),e=n(e,t))})),e}function re(){if(!this.state.isDestroyed){var t={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};t.offsets.reference=Jt(this.state,this.popper,this.reference,this.options.positionFixed),t.placement=Qt(this.options.placement,t.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),t.originalPlacement=t.placement,t.positionFixed=this.options.positionFixed,t.offsets.popper=ne(this.popper,t.offsets.reference,t.placement),t.offsets.popper.position=this.options.positionFixed?"fixed":"absolute",t=oe(this.modifiers,t),this.state.isCreated?this.options.onUpdate(t):(this.state.isCreated=!0,this.options.onCreate(t))}}function ae(t,e){return t.some((function(t){var n=t.name;return t.enabled&&n===e}))}function se(t){for(var e=[!1,"ms","Webkit","Moz","O"],n=t.charAt(0).toUpperCase()+t.slice(1),i=0;i1&&void 0!==arguments[1]&&arguments[1],n=ye.indexOf(t),i=ye.slice(n+1).concat(ye.slice(0,n));return e?i.reverse():i}var we="flip",ke="clockwise",Ee="counterclockwise";function Te(t,e,n,i){var o=[0,0],r=-1!==["right","left"].indexOf(i),a=t.split(/(\+|\-)/).map((function(t){return t.trim()})),s=a.indexOf(ie(a,(function(t){return-1!==t.search(/,|\s/)})));a[s]&&-1===a[s].indexOf(",")&&console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");var c=/\s*,\s*|\s+/,l=-1!==s?[a.slice(0,s).concat([a[s].split(c)[0]]),[a[s].split(c)[1]].concat(a.slice(s+1))]:[a];return(l=l.map((function(t,i){var o=(1===i?!r:r)?"height":"width",a=!1;return t.reduce((function(t,e){return""===t[t.length-1]&&-1!==["+","-"].indexOf(e)?(t[t.length-1]=e,a=!0,t):a?(t[t.length-1]+=e,a=!1,t):t.concat(e)}),[]).map((function(t){return function(t,e,n,i){var o=t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+o[1],a=o[2];return r?0===a.indexOf("%")?Yt("%p"===a?n:i)[e]/100*r:"vh"===a||"vw"===a?("vh"===a?Math.max(document.documentElement.clientHeight,window.innerHeight||0):Math.max(document.documentElement.clientWidth,window.innerWidth||0))/100*r:r:t}(t,o,e,n)}))}))).forEach((function(t,e){t.forEach((function(n,i){me(n)&&(o[e]+=n*("-"===t[i-1]?-1:1))}))})),o}var Ie={placement:"bottom",positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(t){var e=t.placement,n=e.split("-")[0],i=e.split("-")[1];if(i){var o=t.offsets,a=o.reference,s=o.popper,c=-1!==["bottom","top"].indexOf(n),l=c?"left":"top",p=c?"width":"height",d={start:r({},l,a[l]),end:r({},l,a[l]+a[p]-s[p])};t.offsets.popper=Vt({},s,d[i])}return t}},offset:{order:200,enabled:!0,fn:function(t,e){var n,i=e.offset,o=t.placement,r=t.offsets,a=r.popper,s=r.reference,c=o.split("-")[0];return n=me(+i)?[+i,0]:Te(i,a,s,c),"left"===c?(a.top+=n[0],a.left-=n[1]):"right"===c?(a.top+=n[0],a.left+=n[1]):"top"===c?(a.left+=n[0],a.top-=n[1]):"bottom"===c&&(a.left+=n[0],a.top+=n[1]),t.popper=a,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(t,e){var n=e.boundariesElement||Dt(t.instance.popper);t.instance.reference===n&&(n=Dt(n));var i=se("transform"),o=t.instance.popper.style,a=o.top,s=o.left,c=o[i];o.top="",o.left="",o[i]="";var l=Kt(t.instance.popper,t.instance.reference,e.padding,n,t.positionFixed);o.top=a,o.left=s,o[i]=c,e.boundaries=l;var p=e.priority,d=t.offsets.popper,u={primary:function(t){var n=d[t];return d[t]l[t]&&!e.escapeWithReference&&(i=Math.min(d[n],l[t]-("right"===t?d.width:d.height))),r({},n,i)}};return p.forEach((function(t){var e=-1!==["left","top"].indexOf(t)?"primary":"secondary";d=Vt({},d,u[e](t))})),t.offsets.popper=d,t},priority:["left","right","top","bottom"],padding:5,boundariesElement:"scrollParent"},keepTogether:{order:400,enabled:!0,fn:function(t){var e=t.offsets,n=e.popper,i=e.reference,o=t.placement.split("-")[0],r=Math.floor,a=-1!==["top","bottom"].indexOf(o),s=a?"right":"bottom",c=a?"left":"top",l=a?"width":"height";return n[s]r(i[s])&&(t.offsets.popper[c]=r(i[s])),t}},arrow:{order:500,enabled:!0,fn:function(t,e){var n;if(!ge(t.instance.modifiers,"arrow","keepTogether"))return t;var i=e.element;if("string"==typeof i){if(!(i=t.instance.popper.querySelector(i)))return t}else if(!t.instance.popper.contains(i))return console.warn("WARNING: `arrow.element` must be child of its popper element!"),t;var o=t.placement.split("-")[0],a=t.offsets,s=a.popper,c=a.reference,l=-1!==["left","right"].indexOf(o),p=l?"height":"width",d=l?"Top":"Left",u=d.toLowerCase(),f=l?"left":"top",m=l?"bottom":"right",h=te(i)[p];c[m]-hs[m]&&(t.offsets.popper[u]+=c[u]+h-s[m]),t.offsets.popper=Yt(t.offsets.popper);var b=c[u]+c[p]/2-h/2,g=At(t.instance.popper),v=kt(g["margin".concat(d)],10),y=kt(g["border".concat(d,"Width")],10),x=b-t.offsets.popper[u]-v-y;return x=Math.max(Math.min(s[p]-h,x),0),t.arrowElement=i,t.offsets.arrow=(r(n={},u,Math.round(x)),r(n,f,""),n),t},element:"[x-arrow]"},flip:{order:600,enabled:!0,fn:function(t,e){if(ae(t.instance.modifiers,"inner"))return t;if(t.flipped&&t.placement===t.originalPlacement)return t;var n=Kt(t.instance.popper,t.instance.reference,e.padding,e.boundariesElement,t.positionFixed),i=t.placement.split("-")[0],o=ee(i),r=t.placement.split("-")[1]||"",a=[];switch(e.behavior){case we:a=[i,o];break;case ke:a=xe(i);break;case Ee:a=xe(i,!0);break;default:a=e.behavior}return a.forEach((function(s,c){if(i!==s||a.length===c+1)return t;i=t.placement.split("-")[0],o=ee(i);var l=t.offsets.popper,p=t.offsets.reference,d=Math.floor,u="left"===i&&d(l.right)>d(p.left)||"right"===i&&d(l.left)d(p.top)||"bottom"===i&&d(l.top)d(n.right),h=d(l.top)d(n.bottom),g="left"===i&&f||"right"===i&&m||"top"===i&&h||"bottom"===i&&b,v=-1!==["top","bottom"].indexOf(i),y=!!e.flipVariations&&(v&&"start"===r&&f||v&&"end"===r&&m||!v&&"start"===r&&h||!v&&"end"===r&&b),x=!!e.flipVariationsByContent&&(v&&"start"===r&&m||v&&"end"===r&&f||!v&&"start"===r&&b||!v&&"end"===r&&h),w=y||x;(u||g||w)&&(t.flipped=!0,(u||g)&&(i=a[c+1]),w&&(r=function(t){return"end"===t?"start":"start"===t?"end":t}(r)),t.placement=i+(r?"-"+r:""),t.offsets.popper=Vt({},t.offsets.popper,ne(t.instance.popper,t.offsets.reference,t.placement)),t=oe(t.instance.modifiers,t,"flip"))})),t},behavior:"flip",padding:5,boundariesElement:"viewport",flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(t){var e=t.placement,n=e.split("-")[0],i=t.offsets,o=i.popper,r=i.reference,a=-1!==["left","right"].indexOf(n),s=-1===["top","left"].indexOf(n);return o[a?"left":"top"]=r[n]-(s?o[a?"width":"height"]:0),t.placement=ee(e),t.offsets.popper=Yt(o),t}},hide:{order:800,enabled:!0,fn:function(t){if(!ge(t.instance.modifiers,"hide","preventOverflow"))return t;var e=t.offsets.reference,n=ie(t.instance.modifiers,(function(t){return"preventOverflow"===t.name})).boundaries;if(e.bottomn.right||e.top>n.bottom||e.right2&&void 0!==arguments[2]?arguments[2]:{};i(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(o.update)},this.update=Ct(this.update.bind(this)),this.options=Vt({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=e&&e.jquery?e[0]:e,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},ft(Vt({},t.Defaults.modifiers,r.modifiers)).forEach((function(e){o.options.modifiers[e]=Vt({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})})),this.modifiers=ft(this.options.modifiers).map((function(t){return Vt({name:t},o.options.modifiers[t])})).sort((function(t,e){return t.order-e.order})),this.modifiers.forEach((function(t){t.enabled&&Ot(t.onLoad)&&t.onLoad(o.reference,o.popper,o.options,t,o.state)})),this.update();var a=this.options.eventsEnabled;a&&this.enableEventListeners(),this.state.eventsEnabled=a}return e=t,(n=[{key:"update",value:function(){return re.call(this)}},{key:"destroy",value:function(){return ce.call(this)}},{key:"enableEventListeners",value:function(){return ue.call(this)}},{key:"disableEventListeners",value:function(){return fe.call(this)}}])&&o(e.prototype,n),r&&o(e,r),Object.defineProperty(e,"prototype",{writable:!1}),t;var e,n,r}();function Ce(){return Ce=vt||function(t){for(var e=1;e-1}function bn(t){return t instanceof Element}function gn(t){return!(!t||!dn(t,"isVirtual"))||bn(t)}function vn(t,e){return"function"==typeof t?t.apply(null,e):t}function yn(t,e){t.filter((function(t){return"flip"===t.name}))[0].enabled=e}function xn(){return document.createElement("div")}function wn(t,e){t.forEach((function(t){t&&(t.style.transitionDuration="".concat(e,"ms"))}))}function kn(t,e){t.forEach((function(t){t&&t.setAttribute("data-state",e)}))}function En(t,e){var n=Ce({},e,{content:vn(e.content,[t])},e.ignoreAttributes?{}:function(t){return ln.reduce((function(e,n){var i=(t.getAttribute("data-tippy-".concat(n))||"").trim();if(!i)return e;if("content"===n)e[n]=i;else try{e[n]=JSON.parse(i)}catch(t){e[n]=i}return e}),{})}(t));return(n.arrow||Le)&&(n.animateFill=!1),n}function Tn(t,e){ft(t).forEach((function(t){if(!dn(e,t))throw new Error("[tippy]: `".concat(t,"` is not a valid option"))}))}function In(t,e){t.innerHTML=bn(e)?e.innerHTML:e}function Sn(t,e){bn(e.content)?(In(t,""),t.appendChild(e.content)):"function"!=typeof e.content&&(t[e.allowHTML?"innerHTML":"textContent"]=e.content)}function Cn(t){return{tooltip:t.querySelector(Qe),backdrop:t.querySelector(tn),content:t.querySelector(Je),arrow:t.querySelector(en)||t.querySelector(nn)}}function On(t){t.setAttribute("data-inertia","")}function An(t){var e=xn();return"round"===t?(e.className=Ke,In(e,'')):e.className=qe,e}function _n(){var t=xn();return t.className=Xe,t.setAttribute("data-state","hidden"),t}function Ln(t,e){t.setAttribute("tabindex","-1"),e.setAttribute("data-interactive","")}function Mn(t,e,n){var i=Le&&void 0!==document.body.style.webkitTransition?"webkitTransitionEnd":"transitionend";t[e+"EventListener"](i,n)}function Nn(t){var e=t.getAttribute(Be);return e?e.split("-")[0]:""}function Rn(t,e,n){n.split(" ").forEach((function(n){t.classList[e](n+"-theme")}))}function Dn(t,e,n){var i=e[n],o=F(i);"number"==typeof i?t.style[n]=i+"px":isNaN(o)?t.style[n]=i:t.style[n]=o+"px"}function zn(t,e){var n=xn();n.className=We+(e.extCls?" ".concat(e.extCls):""),n.id="tippy-".concat(t),n.style.zIndex=""+e.zIndex,n.style.position="absolute",n.style.top="0",n.style.left="0",e.role&&n.setAttribute("role",e.role);var i=xn();i.className=$e,Dn(i,e,"maxWidth"),Dn(i,e,"width"),i.setAttribute("data-size",e.size),i.setAttribute("data-animation",e.animation),i.setAttribute("data-state","hidden"),Rn(i,"add",e.theme);var o=xn();return o.className=Ge,o.setAttribute("data-state","hidden"),e.interactive&&Ln(n,i),e.arrow&&i.appendChild(An(e.arrowType)),e.animateFill&&(i.appendChild(_n()),i.setAttribute("data-animatefill","")),e.inertia&&On(i),Sn(o,e),i.appendChild(o),n.appendChild(i),n}function Pn(t,e,n){var i=Cn(t),o=i.tooltip,r=i.content,a=i.backdrop,s=i.arrow;t.style.zIndex=""+n.zIndex,o.setAttribute("data-size",n.size),o.setAttribute("data-animation",n.animation),o.style.maxWidth=n.maxWidth+("number"==typeof n.maxWidth?"px":""),n.role?t.setAttribute("role",n.role):t.removeAttribute("role"),e.content!==n.content&&Sn(r,n),!e.animateFill&&n.animateFill?(o.appendChild(_n()),o.setAttribute("data-animatefill","")):e.animateFill&&!n.animateFill&&(o.removeChild(a),o.removeAttribute("data-animatefill")),!e.arrow&&n.arrow?o.appendChild(An(n.arrowType)):e.arrow&&!n.arrow&&o.removeChild(s),e.arrow&&n.arrow&&e.arrowType!==n.arrowType&&o.replaceChild(An(n.arrowType),s),!e.interactive&&n.interactive?Ln(t,o):e.interactive&&!n.interactive&&function(t,e){t.removeAttribute("tabindex"),e.removeAttribute("data-interactive")}(t,o),!e.inertia&&n.inertia?On(o):e.inertia&&!n.inertia&&function(t){t.removeAttribute("data-inertia")}(o),e.theme!==n.theme&&(Rn(o,"remove",e.theme),Rn(o,"add",n.theme))}var Hn=1,Fn=[];function jn(t,e){var n,i,o,r,a,s=En(t,e);if(!s.multiple&&t._tippy)return null;var c,l,p,d,u,f=!1,m=!1,h=!1,b=!1,g=[],v=fn(F,s.interactiveDebounce),y=Hn++,x=zn(y,s),w=Cn(x),k={id:y,reference:t,popper:x,popperChildren:w,popperInstance:null,props:s,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},clearDelayTimeouts:Z,set:Q,setContent:function(t){Q({content:t})},show:J,hide:tt,enable:function(){k.state.isEnabled=!0},disable:function(){k.state.isEnabled=!1},destroy:function(e){if(!k.state.isDestroyed){m=!0,k.state.isMounted&&tt(0),z(),delete t._tippy;var n=k.props.target;n&&e&&bn(t)&&Pe(t.querySelectorAll(n)).forEach((function(t){t._tippy&&t._tippy.destroy()})),k.popperInstance&&k.popperInstance.destroy(),m=!1,k.state.isDestroyed=!0}}};return t._tippy=k,x._tippy=k,D(),s.lazy||$(),s.showOnInit&&X(),!s.a11y||s.target||(!bn(u=I())||ze.call(u,"a[href],area[href],button,details,input,textarea,select,iframe,[tabindex]")&&!u.hasAttribute("disabled"))||I().setAttribute("tabindex","0"),x.addEventListener("mouseenter",(function(t){k.props.interactive&&k.state.isVisible&&"mouseenter"===n&&X(t,!0)})),x.addEventListener("mouseleave",(function(){k.props.interactive&&"mouseenter"===n&&document.addEventListener("mousemove",v)})),k;function E(){document.removeEventListener("mousemove",P)}function T(){document.body.removeEventListener("mouseleave",q),document.removeEventListener("mousemove",v),Fn=Fn.filter((function(t){return t!==v}))}function I(){return k.props.triggerTarget||t}function S(){document.addEventListener("click",K,!0)}function C(){document.removeEventListener("click",K,!0)}function O(){return[k.popperChildren.tooltip,k.popperChildren.backdrop,k.popperChildren.content]}function A(){var t=k.props.followCursor;return t&&"focus"!==n||on&&"initial"===t}function _(){wn([x],_e?0:k.props.updateDuration),function t(){k.popperInstance.scheduleUpdate(),k.state.isMounted?requestAnimationFrame(t):wn([x],0)}()}function L(t,e){N(t,(function(){!k.state.isVisible&&x.parentNode&&x.parentNode.contains(x)&&e()}))}function M(t,e){N(t,e)}function N(t,e){var n=k.popperChildren.tooltip;function i(t){t.target===n&&(Mn(n,"remove",i),e())}if(0===t)return e();Mn(n,"remove",p),Mn(n,"add",i),p=i}function R(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];I().addEventListener(t,e,n),g.push({eventType:t,handler:e,options:n})}function D(){k.props.touchHold&&!k.props.target&&(R("touchstart",H,je),R("touchend",j,je)),k.props.trigger.trim().split(" ").forEach((function(t){if("manual"!==t)if(k.props.target)switch(t){case"mouseenter":R("mouseover",U),R("mouseout",V);break;case"focus":R("focusin",U),R("focusout",V);break;case"click":R(t,U)}else switch(R(t,H),t){case"mouseenter":R("mouseleave",j);break;case"focus":R(_e?"focusout":"blur",B)}}))}function z(){g.forEach((function(t){var e=t.eventType,n=t.handler,i=t.options;I().removeEventListener(e,n,i)})),g=[]}function P(e){var n=i=e,o=n.clientX,r=n.clientY;if(d){var a=Fe(e.target,(function(e){return e===t})),s=t.getBoundingClientRect(),c=k.props.followCursor,l="horizontal"===c,p="vertical"===c,u=hn(["top","bottom"],Nn(x)),f=x.getAttribute(Be),m=!!f&&!!f.split("-")[1],h=u?x.offsetWidth:x.offsetHeight,b=h/2,g=u?0:m?h:b,v=u?m?h:b:0;!a&&k.props.interactive||(k.popperInstance.reference=Ce({},k.popperInstance.reference,{clientWidth:0,clientHeight:0,getBoundingClientRect:function(){return{width:u?h:0,height:u?0:h,top:(l?s.top:r)-g,bottom:(l?s.bottom:r)+g,left:(p?s.left:o)-v,right:(p?s.right:o)+v}}}),k.popperInstance.update()),"initial"===c&&k.state.isVisible&&E()}}function H(t){k.state.isEnabled&&!Y(t)&&(k.state.isVisible||(n=t.type,t instanceof MouseEvent&&(i=t,Fn.forEach((function(e){return e(t)})))),"click"===t.type&&!1!==k.props.hideOnClick&&k.state.isVisible?q():X(t))}function F(e){var n=He(e.target,Ze)===x,i=Fe(e.target,(function(e){return e===t}));n||i||function(t,e,n,i){if(!t)return!0;var o=n.clientX,r=n.clientY,a=i.interactiveBorder,s=i.distance,c=e.top-r>("top"===t?a+s:a),l=r-e.bottom>("bottom"===t?a+s:a),p=e.left-o>("left"===t?a+s:a),d=o-e.right>("right"===t?a+s:a);return c||l||p||d}(Nn(x),x.getBoundingClientRect(),e,k.props)&&(T(),q())}function j(t){if(!Y(t))return k.props.interactive?(document.body.addEventListener("mouseleave",q),document.addEventListener("mousemove",v),void Fn.push(v)):void q()}function B(t){t.target===I()&&(k.props.interactive&&t.relatedTarget&&x.contains(t.relatedTarget)||q())}function U(t){He(t.target,k.props.target)&&X(t)}function V(t){He(t.target,k.props.target)&&q()}function Y(t){var e="ontouchstart"in window,n=hn(t.type,"touch"),i=k.props.touchHold;return e&&on&&i&&!n||on&&!i&&n}function W(){!b&&l&&(b=!0,function(t){t.offsetHeight}(x),l())}function $(){var e=k.props.popperOptions,n=k.popperChildren,i=n.tooltip,o=n.arrow,r=mn(e,"preventOverflow");function a(t){k.props.flip&&!k.props.flipOnUpdate&&(t.flipped&&(k.popperInstance.options.placement=t.placement),yn(k.popperInstance.modifiers,!1)),i.setAttribute(Be,t.placement),!1!==t.attributes[Ue]?i.setAttribute(Ue,""):i.removeAttribute(Ue),c&&c!==t.placement&&h&&(i.style.transition="none",requestAnimationFrame((function(){i.style.transition=""}))),c=t.placement,h=k.state.isVisible;var e=Nn(x),n=i.style;n.top=n.bottom=n.left=n.right="",n[e]=-(k.props.distance-10)+"px";var o=r&&void 0!==r.padding?r.padding:4,a="number"==typeof o,s=Ce({top:a?o:o.top,bottom:a?o:o.bottom,left:a?o:o.left,right:a?o:o.right},!a&&o);s[e]=a?o+k.props.distance:(o[e]||0)+k.props.distance,k.popperInstance.modifiers.filter((function(t){return"preventOverflow"===t.name}))[0].padding=s,d=s}var s=Ce({eventsEnabled:!1,placement:k.props.placement},e,{modifiers:Ce({},e?e.modifiers:{},{preventOverflow:Ce({boundariesElement:k.props.boundary,padding:4},r),arrow:Ce({element:o,enabled:!!o},mn(e,"arrow")),flip:Ce({enabled:k.props.flip,padding:k.props.distance+4,behavior:k.props.flipBehavior},mn(e,"flip")),offset:Ce({offset:k.props.offset},mn(e,"offset"))}),onCreate:function(t){a(t),W(),e&&e.onCreate&&e.onCreate(t)},onUpdate:function(t){a(t),W(),e&&e.onUpdate&&e.onUpdate(t)}});k.popperInstance=new Se(t,x,s)}function G(){b=!1;var e=A();k.popperInstance?(yn(k.popperInstance.modifiers,k.props.flip),e||(k.popperInstance.reference=t,k.popperInstance.enableEventListeners()),k.popperInstance.scheduleUpdate()):($(),e||k.popperInstance.enableEventListeners());var n=k.props.appendTo,i="parent"===n?t.parentNode:vn(n,[t]);i.contains(x)||(i.appendChild(x),k.props.onMount(k),k.state.isMounted=!0)}function X(t,n){if(Z(),!k.state.isVisible){if(k.props.target)return function(t){if(t){var n=He(t.target,k.props.target);n&&!n._tippy&&jn(n,Ce({},k.props,{content:vn(e.content,[n]),appendTo:e.appendTo,target:"",showOnInit:!0}))}}(t);if(f=!0,t&&!n&&k.props.onTrigger(k,t),k.props.wait)return k.props.wait(k,t);A()&&!k.state.isMounted&&(k.popperInstance||$(),document.addEventListener("mousemove",P)),S();var i=un(k.props.delay,0,Ne.delay);i?o=setTimeout((function(){J()}),i):J()}}function q(){if(Z(),!k.state.isVisible)return E();f=!1;var t=un(k.props.delay,1,Ne.delay);t?r=setTimeout((function(){k.state.isVisible&&tt()}),t):a=requestAnimationFrame((function(){tt()}))}function K(t){if(!k.props.interactive||!x.contains(t.target)){if(I().contains(t.target)){if(on)return;if(k.state.isVisible&&hn(k.props.trigger,"click"))return}!0===k.props.hideOnClick&&(Z(),tt())}}function Z(){clearTimeout(o),clearTimeout(r),cancelAnimationFrame(a)}function Q(e){Tn(e=e||{},Ne),z();var n=k.props,o=En(t,Ce({},k.props,e,{ignoreAttributes:!0}));o.ignoreAttributes=dn(e,"ignoreAttributes")?e.ignoreAttributes||!1:n.ignoreAttributes,k.props=o,D(),T(),v=fn(F,o.interactiveDebounce),Pn(x,n,o),k.popperChildren=Cn(x),k.popperInstance&&(Re.some((function(t){return dn(e,t)&&e[t]!==n[t]}))?(k.popperInstance.destroy(),$(),k.state.isVisible&&k.popperInstance.enableEventListeners(),k.props.followCursor&&i&&P(i)):k.popperInstance.update())}function J(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:un(k.props.duration,0,Ne.duration[1]);if(!k.state.isDestroyed&&k.state.isEnabled&&(!on||k.props.touch)&&!I().hasAttribute("disabled")&&!1!==k.props.onShow(k)){S(),x.style.visibility="visible",k.state.isVisible=!0,k.props.interactive&&I().classList.add(Ye);var e=O();wn(e.concat(x),0),l=function(){if(k.state.isVisible){var n=A();n&&i?P(i):n||k.popperInstance.update(),k.popperChildren.backdrop&&(k.popperChildren.content.style.transitionDelay=Math.round(t/12)+"ms"),k.props.sticky&&_(),wn([x],k.props.updateDuration),wn(e,t),kn(e,"visible"),M(t,(function(){k.props.aria&&I().setAttribute("aria-".concat(k.props.aria),x.id),k.props.onShown(k),k.state.isShown=!0}))}},G()}}function tt(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:un(k.props.duration,1,Ne.duration[1]);if(!k.state.isDestroyed&&(k.state.isEnabled||m)&&(!1!==k.props.onHide(k)||m)){C(),x.style.visibility="hidden",k.state.isVisible=!1,k.state.isShown=!1,h=!1,k.props.interactive&&I().classList.remove(Ye);var e=O();wn(e,t),kn(e,"hidden"),L(t,(function(){f||E(),k.props.aria&&I().removeAttribute("aria-".concat(k.props.aria)),k.popperInstance.disableEventListeners(),k.popperInstance.options.placement=k.props.placement,x.parentNode.removeChild(x),k.props.onHidden(k),k.state.isMounted=!1}))}}}var Bn=!1;function Un(t,e){Tn(e||{},Ne),Bn||(document.addEventListener("touchstart",rn,je),window.addEventListener("blur",cn),Bn=!0);var n,i=Ce({},Ne,e);n=t,"[object Object]"==={}.toString.call(n)&&!n.addEventListener&&function(t){var e={isVirtual:!0,attributes:t.attributes||{},contains:function(){},setAttribute:function(e,n){t.attributes[e]=n},getAttribute:function(e){return t.attributes[e]},removeAttribute:function(e){delete t.attributes[e]},hasAttribute:function(e){return e in t.attributes},addEventListener:function(){},removeEventListener:function(){},classList:{classNames:{},add:function(e){t.classList.classNames[e]=!0},remove:function(e){delete t.classList.classNames[e]},contains:function(e){return e in t.classList.classNames}}};for(var n in e)t[n]=e[n]}(t);var o=function(t){if(gn(t))return[t];if(t instanceof NodeList)return Pe(t);if(q(t))return t;try{return Pe(document.querySelectorAll(t))}catch(t){return[]}}(t).reduce((function(t,e){var n=e&&jn(e,i);return n&&t.push(n),t}),[]);return gn(t)?o[0]:o}Un.version="4.3.4",Un.defaults=Ne,Un.setDefaults=function(t){ft(t).forEach((function(e){Ne[e]=t[e]}))},Un.hideAll=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.exclude,n=t.duration;Pe(document.querySelectorAll(Ze)).forEach((function(t){var i=t._tippy;if(i){var o=!1;e&&(o=pn(e)?i.reference===e:t===e.popper),o||i.hide(n)}}))},Un.group=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=e.delay,i=void 0===n?t[0].props.delay:n,o=e.duration,r=void 0===o?0:o,a=!1;function s(t){a=t,d()}function c(e){e._originalProps.onShow(e),t.forEach((function(t){t.set({duration:r}),t.state.isVisible&&t.hide()})),s(!0)}function l(t){t._originalProps.onHide(t),s(!1)}function p(t){t._originalProps.onShown(t),t.set({duration:t._originalProps.duration})}function d(){t.forEach((function(t){t.set({onShow:c,onShown:p,onHide:l,delay:a?[0,q(i)?i[1]:i]:i,duration:a?r:t._originalProps.duration})}))}t.forEach((function(t){t._originalProps?t.set(t._originalProps):t._originalProps=Ce({},t.props)})),d()},Oe&&setTimeout((function(){Pe(document.querySelectorAll("[data-tippy]")).forEach((function(t){var e=t.getAttribute("data-tippy");e&&Un(t,{content:e})}))}));S(S.S+S.F*!h,"Object",{defineProperty:x.f});var Vn,Yn=l.Object,Wn=function(t,e,n){return Yn.defineProperty(t,e,n)},$n=!1;!function(){if(!window.__bk_zIndex_manager){var t={nextZIndex:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"default";return"default"===e?t.zIndex++:e},nextTickIndex:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"default";return"default"===n?(t.zIndex+=e,t.zIndex):n}};Wn(t,"zIndex",{configurable:!0,get:function(){return $n||(Vn=Vn||(e.prototype.$BK_EL||{}).zIndex||2e3,$n=!0),Vn},set:function(t){Vn=t}}),window.__bk_zIndex_manager=t}}();var Gn=window.__bk_zIndex_manager,Xn={props:{zIndex:{type:[Number,String],default:"default"}},methods:{getLocalZIndex:function(t){return Gn.nextTickIndex(2,t)}}};S(S.S,"Number",{isNaN:function(t){return t!=t}});var qn=l.Number.isNaN;function Kn(){for(var t="",e=Math.floor(65536*(1+Math.random())).toString(16).substring(1),n=0;n<7;n++)t+=e;return t}window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame,window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame,function(){if(!window.__bk_pop_manager){var t="bk_pop_".concat((new Date).getTime()),e="bk_pop_mask_".concat((new Date).getTime()),n="bk_pop_key_".concat((new Date).getTime()),i=[],o={containerId:t,maskId:e,defaultKey:n,formatKey:function(t){return String(t).replace(/#/g,"_")},show:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{tplAction:"keepAll",zIndex:"",beforeHide:function(){},ignoreExistMask:!1,appendToBody:!1};t=null==t||qn(t)?this.defaultKey:t,t=this.formatKey(t);var i=Kn(),o=!1;if("onlyone"===n.tplAction&&this.clearByTpl(t),this.shouldAppendToBody(t))o=!0,this.showModalMask(n.zIndex),!n.appendToBody&&this.container.append(e);else{o=!1;var r=n.zIndex;this.showModalMask(r)}var a=n.beforeHide,s=n.zIndex,c=n.ignoreExistMask;return this.instances.push({uid:i,ins:e,tplName:t,beforeHide:a,zIndex:s,ignoreExistMask:c,isAppendToBody:o}),"".concat(i,"#").concat(t)},shouldAppendToBody:function(t){return this.instances.some((function(e){return e.tplName===t}))},hide:function(t,e){switch((e=e||{action:"hideUid"}).action){case"hideAll":this.clearAll();break;case"hideUid":this.clearByUid(t);break;case"hideSameTpl":this.clearByTpl(t);break;default:this.autoClear(t)}this.updateModalMaskIndex()},updateModalMaskIndex:function(){if(this.instances.length){var t=this.instances.slice(-1)[0],e=t.isAppendToBody?t.zIndex:t.zIndex-1;this.showModalMask(e)}else this.hideModalMask()},autoClear:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";t.indexOf("#")>0?this.clearByUid(t):this.clearByTpl()},clearByTpl:function(t){var e=this,n=t.split("#").slice(-1)[0];this.instances=this.instances.filter((function(t){return t.tplName!==n||(e.__hideInstance(t),!1)}))},clearByUid:function(t){var e=t.split("#"),n=e[0],i=e[1],o=this.instances.findIndex((function(t){return t.uid===n&&t.tplName===i}));o>=0?(this.__hideInstance(this.instances[o]),this.instances.splice(o,1)):console.warn("Can not find pop instance with index "+o)},clearAll:function(){var t=this;this.instances.forEach((function(e){return t.__hideInstance(e)})),this.instances=[]},showModalMask:function(t){this.dialogMask.setAttribute("style","z-index:".concat(t,";")),document.body.style.overflow="hidden",this.dialogMask.classList.remove("hide-active"),this.dialogMask.classList.add("show-active")},hideModalMask:function(){this.dialogMask.classList.remove("show-active"),this.dialogMask.classList.add("hide-active"),document.body.style.overflow=""},__hideInstance:function(t){"function"==typeof t.beforeHide?(t.beforeHide(),setTimeout((function(){t.isAppendToBody&&t.ins.remove()}))):t.isAppendToBody&&t.ins.remove()}};Wn(o,"container",{get:function(){var t=document.querySelector("[data-bkpop-container]");return t||((t=document.createElement("div")).setAttribute("id",this.containerId),t.setAttribute("data-bkpop-container","true"),document.body.append(t)),t}}),Wn(o,"dialogMask",{get:function(){var t=document.querySelector("[data-bkpop-mask]");return t||((t=document.createElement("div")).setAttribute("id",this.maskId),t.setAttribute("class","bk-dialog-mask"),t.setAttribute("data-bkpop-mask","true"),this.container.append(t)),t}}),Wn(o,"instances",{get:function(){return i},set:function(t){i=t}}),window.__bk_pop_manager=o,window.__bk_pop_manager.__container=o.container}}();var Zn=window.__bk_pop_manager,Qn={name:"bk-popover",mixins:[Xn],props:{placement:{type:String,default:"top"},content:{type:String,default:""},theme:{type:String,default:"dark"},interactive:{type:[Boolean,String],default:!0},arrow:{type:[Boolean,String],default:!0},arrowType:{type:String,default:"sharp"},boundary:{type:String,default:"window"},showOnInit:{type:Boolean,default:!1},arrowTransform:{type:String,default:""},trigger:{type:String,default:"mouseenter focus"},animation:{type:String,default:"shift-away"},distance:{type:Number,default:10},width:{type:[String,Number],default:"auto"},maxWidth:{type:[String,Number],default:"auto"},offset:{type:[Number,String],default:0},always:{type:Boolean,default:!1},followCursor:{type:[Boolean,String],default:!1},sticky:{type:[Boolean,String],default:!1},delay:{type:Number,default:100},size:{type:String,default:"small"},onShow:{type:Function,default:function(){}},onHide:{type:Function,default:function(){}},tippyOptions:{type:Object,default:function(){return{}}},extCls:{type:String,default:""},disabled:Boolean},data:function(){return{instance:null}},watch:{disabled:function(t){this.instance&&(t?this.instance.disable():this.instance.enable())},tippyOptions:function(t){this.instance&&this.instance.set(t)}},mounted:function(){var t=this,e=function(t){var e={};for(var n in t)Ne.hasOwnProperty(n)&&(e[n]=t[n]);return e}(a({},{appendTo:Zn.container},this.$props,this.tippyOptions)),n=e.onShow,i=e.onHide,o="number"==typeof e.zIndex?e.zIndex:null;e.onShow=function(e){e.set({zIndex:t.getLocalZIndex(o||t.zIndex)}),n&&n(e),t.$emit("show")},e.onHide=function(e){i&&i(e),t.$emit("hide")},e.content=this.$refs.html,this.always&&(e.showOnInit=!0,e.hideOnClick=!1,e.trigger="manual"),this.instance=Un(this.$refs.reference,e),this.disabled&&this.instance.disable()},updated:function(){this.instance.setContent(this.$refs.html),this.instance.popperInstance&&this.instance.popperInstance.update()},beforeDestroy:function(){this.instance.destroy()},methods:{showHandler:function(){this.instance.show()},hideHandler:function(){this.instance.hide()}}};function Jn(t,e,n,i,o,r,a,s,c,l){"boolean"!=typeof a&&(c=s,s=a,a=!1);var p,d="function"==typeof n?n.options:n;if(t&&t.render&&(d.render=t.render,d.staticRenderFns=t.staticRenderFns,d._compiled=!0,o&&(d.functional=!0)),i&&(d._scopeId=i),r?(p=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),e&&e.call(this,c(t)),t&&t._registeredComponents&&t._registeredComponents.add(r)},d._ssrRegister=p):e&&(p=a?function(){e.call(this,l(this.$root.$options.shadowRoot))}:function(t){e.call(this,s(t))}),p)if(d.functional){var u=d.render;d.render=function(t,e){return p.call(e),u(t,e)}}else{var f=d.beforeCreate;d.beforeCreate=f?[].concat(f,p):[p]}return n}var ti,ei,ni=Jn({render:function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"bk-tooltip"},[n("div",{ref:"html",staticClass:"bk-tooltip-content"},[t._t("content",[t._v(t._s(t.content))])],2),n("div",{ref:"reference",staticClass:"bk-tooltip-ref",attrs:{tabindex:"-1"}},[t._t("default")],2)])},staticRenderFns:[]},undefined,Qn,undefined,!1,undefined,!1,void 0,void 0,void 0);ei=function(t,e){t.prototype.$bkPopover=function(t,e){return Un(t,e)}},(ti=ni).install=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=ti.props||{};ft(e).forEach((function(t){n.hasOwnProperty(t)&&("function"==typeof n[t]||n[t]instanceof Array?n[t]={type:n[t],default:e[t]}:n[t].default=e[t])})),ti.name=e.namespace?ti.name.replace("bk",e.namespace):ti.name,t.component(ti.name,ti),"function"==typeof ei&&ei(t,e)},t.default=ni,Object.defineProperty(t,"__esModule",{value:!0})}(e,n(8976))},5768:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'.bk-form-checkbox{position:relative;display:inline-block;vertical-align:middle;font-size:0;line-height:18px;overflow:hidden;cursor:pointer}.bk-form-checkbox.is-indeterminate:not(.is-checked) .bk-checkbox{border-color:#3a84ff;background-color:#3a84ff;background-clip:content-box;position:relative}.bk-form-checkbox.is-indeterminate:not(.is-checked) .bk-checkbox:after{content:"";width:8px;height:2px;background:#fff;position:absolute;top:50%;left:50%;margin-left:-4px;border-radius:2px;margin-top:-1px;display:inline-block}.bk-form-checkbox.is-disabled{cursor:not-allowed}.bk-form-checkbox.is-disabled .bk-checkbox{border-color:#dcdee5;background-color:#fafbfd}.bk-form-checkbox.is-disabled.is-checked .bk-checkbox{border-color:#dcdee5;background-color:#dcdee5}.bk-form-checkbox.is-checked .bk-checkbox{border-color:#3a84ff;background-color:#3a84ff;background-clip:border-box}.bk-form-checkbox.is-checked .bk-checkbox:after{content:"";position:absolute;top:1px;left:4px;width:4px;height:8px;border:2px solid #fff;border-left:0;border-top:0;-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate(45deg) scaleY(1);transform:rotate(45deg) scaleY(1)}.bk-form-checkbox .bk-checkbox{position:relative;display:inline-block;vertical-align:middle;width:16px;height:16px;border:1px solid #979ba5;border-radius:2px}.bk-form-checkbox .bk-checkbox:focus{border-color:#3c96ff;outline:none}.bk-form-checkbox .bk-checkbox-text{display:inline-block;margin:0 0 0 6px;vertical-align:middle;font-size:14px;color:#63656e}',""]);const s=a},5861:(t,e,n)=>{"use strict";n.d(e,{Z:()=>v});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r),s=n(3626),c=n.n(s),l=new URL(n(5817),n.b),p=new URL(n(1365),n.b),d=new URL(n(8210),n.b),u=new URL(n(3385),n.b),f=a()(o()),m=c()(l,{hash:"#iconcool"}),h=c()(p),b=c()(d),g=c()(u,{hash:"?#iefix"});f.push([t.id,"body,html{margin:0;padding:0}*{-webkit-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:rgba(0,0,0,0)}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}::-ms-clear,::-ms-reveal{display:none}input[type=text]::-ms-clear{display:none}input[type=text]::-ms-reveal{display:none}input[type=search]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}@font-face{font-family:bk;src:url("+m+') format("svg"),url('+h+') format("truetype"),url('+b+') format("woff"),url('+g+') format("embedded-opentype");font-weight:400;font-style:normal}.bk-icon{font-family:bk !important;speak:none;font-style:normal;font-weight:400;-webkit-font-feature-settings:normal;font-feature-settings:normal;font-variant:normal;text-transform:none;line-height:1;text-align:center;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-angle-double-down:before{content:""}.icon-angle-double-left:before{content:""}.icon-angle-double-right:before{content:""}.icon-angle-double-up:before{content:""}.icon-angle-left:before{content:""}.icon-angle-down:before{content:""}.icon-angle-right:before{content:""}.icon-angle-up:before{content:""}.icon-apps-shape:before{content:""}.icon-apps:before{content:""}.icon-area-chart:before{content:""}.icon-arrows-down-circle-shape:before{content:""}.icon-arrows-down-circle:before{content:""}.icon-arrows-down-shape:before{content:""}.icon-arrows-down:before{content:""}.icon-arrows-left-circle-shape:before{content:""}.icon-arrows-left-circle:before{content:""}.icon-arrows-left-shape:before{content:""}.icon-arrows-left:before{content:""}.icon-arrows-m-down-shape:before{content:""}.icon-arrows-m-left-shape:before{content:""}.icon-arrows-m-right-shape:before{content:""}.icon-arrows-m-up-shape:before{content:""}.icon-arrows-right-circle-shape:before{content:""}.icon-arrows-right-circle:before{content:""}.icon-arrows-right-shape:before{content:""}.icon-arrows-right:before{content:""}.icon-arrows-up-circle-shape:before{content:""}.icon-arrows-up-circle:before{content:""}.icon-arrows-up-shape:before{content:""}.icon-arrows-up:before{content:""}.icon-back-shape:before{content:""}.icon-back:before{content:""}.icon-back2:before{content:""}.icon-bar-chart:before{content:""}.icon-bk:before{content:""}.icon-block-shape:before{content:""}.icon-calendar-shape:before{content:""}.icon-calendar:before{content:""}.icon-chain:before{content:""}.icon-check-1:before{content:""}.icon-check-circle-shape:before{content:""}.icon-check-circle:before{content:""}.icon-circle-2-1:before{content:""}.icon-circle-4-1:before{content:""}.icon-circle-shape:before{content:""}.icon-circle:before{content:""}.icon-clipboard-shape:before{content:""}.icon-clipboard:before{content:""}.icon-clock-shape:before{content:""}.icon-clock:before{content:""}.icon-close-circle-shape:before{content:""}.icon-close-circle:before{content:""}.icon-close:before{content:""}.icon-close3-shape:before{content:""}.icon-code:before{content:""}.icon-cog-shape:before{content:""}.icon-cog:before{content:""}.icon-cry-shape:before{content:""}.icon-cry:before{content:""}.icon-dashboard-2-shape:before{content:""}.icon-dashboard-2:before{content:""}.icon-dashboard-shape:before{content:""}.icon-dashboard:before{content:""}.icon-data-shape:before{content:""}.icon-data:before{content:""}.icon-data2-shape:before{content:""}.icon-data2:before{content:""}.icon-dedent:before{content:""}.icon-delete:before{content:""}.icon-dialogue-empty-shape:before{content:""}.icon-dialogue-empty:before{content:""}.icon-dialogue-shape:before{content:""}.icon-dialogue:before{content:""}.icon-dispirited-shape:before{content:""}.icon-dispirited:before{content:""}.icon-docker:before{content:""}.icon-down-shape:before{content:""}.icon-download:before{content:""}.icon-edit:before{content:""}.icon-edit2:before{content:""}.icon-ellipsis:before{content:""}.icon-email-shape:before{content:""}.icon-email:before{content:""}.icon-empty-shape:before{content:""}.icon-empty:before{content:""}.icon-end:before{content:""}.icon-exclamation-circle-shape:before{content:""}.icon-exclamation-circle:before{content:""}.icon-exclamation-triangle-shape:before{content:""}.icon-exclamation-triangle:before{content:""}.icon-exclamation:before{content:""}.icon-execute:before{content:""}.icon-eye-shape:before{content:""}.icon-eye-slash-shape:before{content:""}.icon-eye-slash:before{content:""}.icon-eye:before{content:""}.icon-file-plus-shape:before{content:""}.icon-file-plus:before{content:""}.icon-file-shape:before{content:""}.icon-file:before{content:""}.icon-folder-open-shape:before{content:""}.icon-folder-open:before{content:""}.icon-folder-plus-shape:before{content:""}.icon-folder-plus:before{content:""}.icon-folder-shape:before{content:""}.icon-folder:before{content:""}.icon-full-screen:before{content:""}.icon-heart-shape:before{content:""}.icon-heart:before{content:""}.icon-hide:before{content:""}.icon-home-shape:before{content:""}.icon-home:before{content:""}.icon-id-shape:before{content:""}.icon-id:before{content:""}.icon-image-shape:before{content:""}.icon-image:before{content:""}.icon-indent:before{content:""}.icon-info-circle-shape:before{content:""}.icon-info-circle:before{content:""}.icon-info:before{content:""}.icon-key:before{content:""}.icon-left-shape:before{content:""}.icon-line-chart:before{content:""}.icon-list:before{content:""}.icon-lock-shape:before{content:""}.icon-lock:before{content:""}.icon-minus-circle-shape:before{content:""}.icon-minus-circle:before{content:""}.icon-minus-square-shape:before{content:""}.icon-minus-square:before{content:""}.icon-minus:before{content:""}.icon-mobile-shape:before{content:""}.icon-mobile:before{content:""}.icon-monitors-cog:before{content:""}.icon-monitors:before{content:""}.icon-more:before{content:""}.icon-move:before{content:""}.icon-next-shape:before{content:""}.icon-next:before{content:""}.icon-order-shape:before{content:""}.icon-order:before{content:""}.icon-panel-permission:before{content:""}.icon-panel-shape:before{content:""}.icon-panel:before{content:""}.icon-panels:before{content:""}.icon-password-shape:before{content:""}.icon-password:before{content:""}.icon-pause:before{content:""}.icon-pc-shape:before{content:""}.icon-pc:before{content:""}.icon-pie-chart-shape:before{content:""}.icon-pie-chart:before{content:""}.icon-pipeline-shape:before{content:""}.icon-pipeline:before{content:""}.icon-play-circle-shape:before{content:""}.icon-play-shape:before{content:""}.icon-play:before{content:""}.icon-play2:before{content:""}.icon-play3:before{content:""}.icon-plus-circle-shape:before{content:""}.icon-plus-circle:before{content:""}.icon-plus-square-shape:before{content:""}.icon-plus-square:before{content:""}.icon-plus:before{content:""}.icon-project:before{content:""}.icon-qq-shape:before{content:""}.icon-qq:before{content:""}.icon-question-circle-shape:before{content:""}.icon-question-circle:before{content:""}.icon-question:before{content:""}.icon-refresh:before{content:""}.icon-right-shape:before{content:""}.icon-rtx:before{content:""}.icon-save-shape:before{content:""}.icon-save:before{content:""}.icon-script-file:before{content:""}.icon-script-files:before{content:""}.icon-search:before{content:""}.icon-sina-shape:before{content:""}.icon-sina:before{content:""}.icon-sitemap-shape:before{content:""}.icon-sitemap:before{content:""}.icon-smile-shape:before{content:""}.icon-smile:before{content:""}.icon-sort:before{content:""}.icon-star-shape:before{content:""}.icon-star:before{content:""}.icon-stop-shape:before{content:""}.icon-stop:before{content:""}.icon-tree-application-shape:before{content:""}.icon-tree-application:before{content:""}.icon-tree-group-shape:before{content:""}.icon-tree-group:before{content:""}.icon-tree-module-shape:before{content:""}.icon-tree-module:before{content:""}.icon-tree-process-shape:before{content:""}.icon-tree-process:before{content:""}.icon-un-full-screen:before{content:""}.icon-unlock-shape:before{content:""}.icon-unlock:before{content:""}.icon-up-shape:before{content:""}.icon-upload:before{content:""}.icon-user-shape:before{content:""}.icon-user:before{content:""}.icon-weixin-shape:before{content:""}.icon-weixin:before{content:""}.icon-work-manage:before{content:""}.icon-funnel:before{content:""}.icon-user-group:before{content:""}.icon-user-3:before{content:""}.icon-copy:before{content:""}.icon-batch-edit-line:before{content:""}.icon-refresh-line:before{content:""}.icon-close-line:before{content:""}.icon-1_up:before{content:""}.icon-arrows-right--line:before{content:""}.icon-arrows-left-line:before{content:""}.icon-arrows-down-line:before{content:""}.icon-arrows-up-line:before{content:""}.icon-angle-double-right-line:before{content:""}.icon-angle-double-down-line:before{content:""}.icon-angle-double-up-line:before{content:""}.icon-angle-double-left-line:before{content:""}.icon-angle-left-line:before{content:""}.icon-angle-right-line:before{content:""}.icon-angle-up-line:before{content:""}.icon-angle-down-line:before{content:""}.icon-check-line:before{content:""}.icon-close-line-2:before{content:""}.icon-edit-line:before{content:""}.icon-list-line:before{content:""}.icon-plus-line:before{content:""}.icon-angle-up-fill:before{content:""}.icon-angle-down-fill:before{content:""}.icon-grag-fill:before{content:""}.icon-template-fill-49:before{content:""}.icon-folder-fill:before{content:""}.icon-expand-line:before{content:""}.icon-shrink-line:before{content:""}.icon-minus-line:before{content:""}.icon-compressed-file:before{content:""}.icon-upload-cloud:before{content:""}.icon-text-file:before{content:""}.icon-filliscreen-line:before{content:""}.icon-left-turn-line:before{content:""}.icon-right-turn-line:before{content:""}.icon-enlarge-line:before{content:""}.icon-narrow-line:before{content:""}.icon-unfull-screen:before{content:""}.icon-image:before{content:""}.icon-image-fail:before{content:""}.icon-normalized:before{content:""}.icon-chinese:before{content:""}.icon-english:before{content:""}.icon-japanese:before{content:""}.transition-effect{-webkit-transition:all .2s linear;transition:all .2s linear}.bk-fade-in-linear-enter-active,.bk-fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.bk-fade-in-linear-enter,.bk-fade-in-linear-leave-active{opacity:0}.bk-fade-in-ease-enter-active,.bk-fade-in-ease-leave-active{-webkit-transition:opacity .2s cubic-bezier(0.55, 0, 0.1, 1);transition:opacity .2s cubic-bezier(0.55, 0, 0.1, 1)}.bk-fade-in-ease-enter,.bk-fade-in-ease-leave-active{opacity:0}.bk-slide-fade-right-enter-active,.bk-slide-fade-right-leave-active{-webkit-transition:opacity .2s linear,-webkit-transform .2s linear;transition:opacity .2s linear,-webkit-transform .2s linear;transition:transform .2s linear,opacity .2s linear;transition:transform .2s linear,opacity .2s linear,-webkit-transform .2s linear}.bk-slide-fade-right-enter{opacity:0;-webkit-transform:translate3d(20%, 0, 0);transform:translate3d(20%, 0, 0)}.bk-slide-fade-right-leave-active{opacity:0;-webkit-transform:translate3d(-20%, 0, 0);transform:translate3d(-20%, 0, 0)}.bk-slide-fade-left-enter-active,.bk-slide-fade-left-leave-active{-webkit-transition:opacity .2s linear,-webkit-transform .2s linear;transition:opacity .2s linear,-webkit-transform .2s linear;transition:transform .2s linear,opacity .2s linear;transition:transform .2s linear,opacity .2s linear,-webkit-transform .2s linear}.bk-slide-fade-left-enter{opacity:0;-webkit-transform:translate3d(-20%, 0, 0);transform:translate3d(-20%, 0, 0)}.bk-slide-fade-left-leave-active{opacity:0;-webkit-transform:translate3d(20%, 0, 0);transform:translate3d(20%, 0, 0)}.bk-slide-fade-up-enter-active,.bk-slide-fade-up-leave-active{-webkit-transition:opacity .2s linear,-webkit-transform .2s linear;transition:opacity .2s linear,-webkit-transform .2s linear;transition:transform .2s linear,opacity .2s linear;transition:transform .2s linear,opacity .2s linear,-webkit-transform .2s linear}.bk-slide-fade-up-enter{opacity:0;-webkit-transform:translate3d(0, 20%, 0);transform:translate3d(0, 20%, 0)}.bk-slide-fade-up-leave-active{opacity:0;-webkit-transform:translate3d(0, -20%, 0);transform:translate3d(0, -20%, 0)}.bk-slide-fade-down-enter-active,.bk-slide-fade-down-leave-active{-webkit-transition:opacity .2s linear,-webkit-transform .2s linear;transition:opacity .2s linear,-webkit-transform .2s linear;transition:transform .2s linear,opacity .2s linear;transition:transform .2s linear,opacity .2s linear,-webkit-transform .2s linear}.bk-slide-fade-down-enter{opacity:0;-webkit-transform:translate3d(0, -20%, 0);transform:translate3d(0, -20%, 0)}.bk-slide-fade-down-leave-active{opacity:0;-webkit-transform:translate3d(0, 20%, 0);transform:translate3d(0, 20%, 0)}.bk-zoom-enter,.bk-zoom-leave-to{-webkit-transform:scale(0);transform:scale(0)}.bk-zoom-enter-to,.bk-zoom-leave{-webkit-transform:scale(1);transform:scale(1)}.bk-zoom-enter-active,.bk-zoom-leave-active{-webkit-transition:all .2s;transition:all .2s}.bk-move-in-left-enter,.bk-move-in-left-leave-to{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);opacity:0}.bk-move-in-left-enter-to,.bk-move-in-left-leave{-webkit-transform:translateZ(0);transform:translateZ(0)}.bk-move-in-left-enter-active,.bk-move-in-left-leave-active{-webkit-transition:all .2s;transition:all .2s}.bk-move-in-right-enter,.bk-move-in-right-leave-to{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);opacity:0}.bk-move-in-right-enter-to,.bk-move-in-right-leave{-webkit-transform:translateZ(0);transform:translateZ(0)}.bk-move-in-right-enter-active,.bk-move-in-right-leave-active{-webkit-transition:all .2s;transition:all .2s}.bk-move-in-up-enter,.bk-move-in-up-leave-to{-webkit-transform:translate3d(0, -100%, 0);transform:translate3d(0, -100%, 0);opacity:0}.bk-move-in-up-enter-to,.bk-move-in-up-leave{-webkit-transform:translateZ(0);transform:translateZ(0)}.bk-move-in-up-enter-active,.bk-move-in-up-leave-active{-webkit-transition:all .2s;transition:all .2s}.bk-move-in-down-enter,.bk-move-in-down-leave-to{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);opacity:0}.bk-move-in-down-enter-to,.bk-move-in-down-leave{-webkit-transform:translateZ(0);transform:translateZ(0)}.bk-move-in-down-enter-active,.bk-move-in-down-leave-active{-webkit-transition:all .2s;transition:all .2s}.fade-enter-active,.fade-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.fade-enter,.fade-leave-active{opacity:0}.fade-show-enter-active,.fade-show-leave-active{-webkit-transition:opacity .2s linear,margin .2s linear;transition:opacity .2s linear,margin .2s linear}.fade-show-enter,.fade-show-leave-active{opacity:0;margin-top:-20px}.displacement-fade-show-enter-active,.displacement-fade-show-leave-active{-webkit-transition:opacity .2s linear,margin .2s linear;transition:opacity .2s linear,margin .2s linear}.displacement-fade-show-enter,.displacement-fade-show-leave-active{opacity:0;margin-top:-50px}.fade-center-enter-active,.fade-center-leave-active{-webkit-transition:opacity .2s linear,-webkit-transform .2s linear;transition:opacity .2s linear,-webkit-transform .2s linear;transition:opacity .2s linear,transform .2s linear;transition:opacity .2s linear,transform .2s linear,-webkit-transform .2s linear;-webkit-transform-origin:center center;transform-origin:center center}.fade-center-enter,.fade-center-leave-active{opacity:0;-webkit-transform:translate(50%, -50%) scale(0) !important;transform:translate(50%, -50%) scale(0) !important}.slide-enter-active .bk-sideslider-wrapper,.slide-leave-active .bk-sideslider-wrapper{-webkit-transform:translateX(0);transform:translateX(0);-webkit-transition:-webkit-transform .25s;transition:-webkit-transform .25s;transition:transform .25s;transition:transform .25s,-webkit-transform .25s}.slide-enter-active{-webkit-animation:slider-fade-in .25s;animation:slider-fade-in .25s}.slide-leave-active{animation:slider-fade-in .25s reverse}.slide-enter .bk-sideslider-wrapper.left,.slide-leave-to .bk-sideslider-wrapper.left{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transition:-webkit-transform .25s;transition:-webkit-transform .25s;transition:transform .25s;transition:transform .25s,-webkit-transform .25s}.slide-enter .bk-sideslider-wrapper.right,.slide-leave-to .bk-sideslider-wrapper.right{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transition:-webkit-transform .25s;transition:-webkit-transform .25s;transition:transform .25s;transition:transform .25s,-webkit-transform .25s}@-webkit-keyframes slider-fade-in{0%{opacity:0}to{opacity:1}}@keyframes slider-fade-in{0%{opacity:0}to{opacity:1}}.fade-leave-active,.slide-fade-enter-active{-webkit-transition:opacity .2s linear,-webkit-transform .2s linear;transition:opacity .2s linear,-webkit-transform .2s linear;transition:transform .2s linear,opacity .2s linear;transition:transform .2s linear,opacity .2s linear,-webkit-transform .2s linear}.slide-fade-enter{opacity:0;-webkit-transform:translateX(20%);transform:translateX(20%)}.slide-fade-leave-active{opacity:0;-webkit-transform:translateX(-20%);transform:translateX(-20%)}.toggle-slide-enter-active,.toggle-slide-leave-active{-webkit-transition:opacity .5s cubic-bezier(0.23, 1, 0.23, 1),-webkit-transform .3s cubic-bezier(0.23, 1, 0.23, 1);transition:opacity .5s cubic-bezier(0.23, 1, 0.23, 1),-webkit-transform .3s cubic-bezier(0.23, 1, 0.23, 1);transition:transform .3s cubic-bezier(0.23, 1, 0.23, 1),opacity .5s cubic-bezier(0.23, 1, 0.23, 1);transition:transform .3s cubic-bezier(0.23, 1, 0.23, 1),opacity .5s cubic-bezier(0.23, 1, 0.23, 1),-webkit-transform .3s cubic-bezier(0.23, 1, 0.23, 1);-webkit-transform-origin:center top;transform-origin:center top}.toggle-slide-enter,.toggle-slide-leave-active{-webkit-transform:translateZ(0) scaleY(0);transform:translateZ(0) scaleY(0);opacity:0}.toggle-slide2-enter-active,.toggle-slide2-leave-active{-webkit-transition:opacity .5s cubic-bezier(0.23, 1, 0.23, 1),-webkit-transform .3s cubic-bezier(0.23, 1, 0.23, 1);transition:opacity .5s cubic-bezier(0.23, 1, 0.23, 1),-webkit-transform .3s cubic-bezier(0.23, 1, 0.23, 1);transition:transform .3s cubic-bezier(0.23, 1, 0.23, 1),opacity .5s cubic-bezier(0.23, 1, 0.23, 1);transition:transform .3s cubic-bezier(0.23, 1, 0.23, 1),opacity .5s cubic-bezier(0.23, 1, 0.23, 1),-webkit-transform .3s cubic-bezier(0.23, 1, 0.23, 1);-webkit-transform-origin:center bottom;transform-origin:center bottom}.toggle-slide2-enter,.toggle-slide2-leave-active{-webkit-transform:translateZ(0) scaleY(0);transform:translateZ(0) scaleY(0);opacity:0}.fade-appear,.fade-enter-active,.fade-leave-active{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.fade-appear,.fade-enter-active{-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-play-state:running;animation-play-state:running}.fade-leave-active{-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-play-state:running;animation-play-state:running}.fade-appear,.fade-enter-active{opacity:0}.fade-appear,.fade-enter-active,.fade-leave-active{-webkit-animation-timing-function:linear;animation-timing-function:linear}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.ease-appear,.ease-enter-active,.ease-leave-active{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.ease-appear,.ease-enter-active{-webkit-animation-name:easeIn;animation-name:easeIn;-webkit-animation-play-state:running;animation-play-state:running}.ease-leave-active{-webkit-animation-name:easeOut;animation-name:easeOut;-webkit-animation-play-state:running;animation-play-state:running}.ease-appear,.ease-enter-active{opacity:0}.ease-appear,.ease-enter-active,.ease-leave-active{-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-duration:.2s;animation-duration:.2s}@-webkit-keyframes easeIn{0%{opacity:0;-webkit-transform:scale(0.9);transform:scale(0.9)}to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes easeIn{0%{opacity:0;-webkit-transform:scale(0.9);transform:scale(0.9)}to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes easeOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}to{opacity:0;-webkit-transform:scale(0.9);transform:scale(0.9)}}@keyframes easeOut{0%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}to{opacity:0;-webkit-transform:scale(0.9);transform:scale(0.9)}}.transition-drop-appear,.transition-drop-enter-active,.transition-drop-leave-active{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.transition-drop-appear,.transition-drop-enter-active{-webkit-animation-name:transitionDropIn;animation-name:transitionDropIn;-webkit-animation-play-state:running;animation-play-state:running}.transition-drop-leave-active{-webkit-animation-name:transitionDropOut;animation-name:transitionDropOut;-webkit-animation-play-state:running;animation-play-state:running}.transition-drop-appear,.transition-drop-enter-active{opacity:0}.transition-drop-appear,.transition-drop-enter-active,.transition-drop-leave-active{-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}@-webkit-keyframes transitionDropIn{0%{opacity:0;-webkit-transform:scaleY(0.8);transform:scaleY(0.8)}to{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}}@keyframes transitionDropIn{0%{opacity:0;-webkit-transform:scaleY(0.8);transform:scaleY(0.8)}to{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}}@-webkit-keyframes transitionDropOut{0%{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}to{opacity:0;-webkit-transform:scaleY(0.8);transform:scaleY(0.8)}}@keyframes transitionDropOut{0%{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}to{opacity:0;-webkit-transform:scaleY(0.8);transform:scaleY(0.8)}}.f10{font-size:10px !important}.f11{font-size:11px !important}.f12{font-size:12px !important}.f13{font-size:13px !important}.f14{font-size:14px !important}.f15{font-size:15px !important}.f16{font-size:16px !important}.f17{font-size:17px !important}.f18{font-size:18px !important}.f19{font-size:19px !important}.f20{font-size:20px !important}.f21{font-size:21px !important}.f22{font-size:22px !important}.f23{font-size:23px !important}.f24{font-size:24px !important}.f25{font-size:25px !important}.f26{font-size:26px !important}.f27{font-size:27px !important}.f28{font-size:28px !important}.f29{font-size:29px !important}.f30{font-size:30px !important}.f31{font-size:31px !important}.f32{font-size:32px !important}.f33{font-size:33px !important}.f34{font-size:34px !important}.f35{font-size:35px !important}.f36{font-size:36px !important}.f37{font-size:37px !important}.f38{font-size:38px !important}.f39{font-size:39px !important}.f40{font-size:40px !important}.m0{margin:0 !important}.m5{margin:5px !important}.m10{margin:10px !important}.m15{margin:15px !important}.m20{margin:20px !important}.m25{margin:25px !important}.m30{margin:30px !important}.m35{margin:35px !important}.m40{margin:40px !important}.m45{margin:45px !important}.m50{margin:50px !important}.mt0{margin-top:0 !important}.mt5{margin-top:5px !important}.mt10{margin-top:10px !important}.mt15{margin-top:15px !important}.mt20{margin-top:20px !important}.mt25{margin-top:25px !important}.mt30{margin-top:30px !important}.mt35{margin-top:35px !important}.mt40{margin-top:40px !important}.mt45{margin-top:45px !important}.mt50{margin-top:50px !important}.mb0{margin-bottom:0 !important}.mb5{margin-bottom:5px !important}.mb10{margin-bottom:10px !important}.mb15{margin-bottom:15px !important}.mb20{margin-bottom:20px !important}.mb25{margin-bottom:25px !important}.mb30{margin-bottom:30px !important}.mb35{margin-bottom:35px !important}.mb40{margin-bottom:40px !important}.mb45{margin-bottom:45px !important}.mb50{margin-bottom:50px !important}.ml0{margin-left:0 !important}.ml5{margin-left:5px !important}.ml10{margin-left:10px !important}.ml15{margin-left:15px !important}.ml20{margin-left:20px !important}.ml25{margin-left:25px !important}.ml30{margin-left:30px !important}.ml35{margin-left:35px !important}.ml40{margin-left:40px !important}.ml45{margin-left:45px !important}.ml50{margin-left:50px !important}.mr0{margin-right:0 !important}.mr5{margin-right:5px !important}.mr10{margin-right:10px !important}.mr15{margin-right:15px !important}.mr20{margin-right:20px !important}.mr25{margin-right:25px !important}.mr30{margin-right:30px !important}.mr35{margin-right:35px !important}.mr40{margin-right:40px !important}.mr45{margin-right:45px !important}.mr50{margin-right:50px !important}.p0{padding:0 !important}.p5{padding:5px !important}.p10{padding:10px !important}.p15{padding:15px !important}.p20{padding:20px !important}.p25{padding:25px !important}.p30{padding:30px !important}.p35{padding:35px !important}.p40{padding:40px !important}.p45{padding:45px !important}.p50{padding:50px !important}.pt0{padding-top:0 !important}.pt5{padding-top:5px !important}.pt10{padding-top:10px !important}.pt15{padding-top:15px !important}.pt20{padding-top:20px !important}.pt25{padding-top:25px !important}.pt30{padding-top:30px !important}.pt35{padding-top:35px !important}.pt40{padding-top:40px !important}.pt45{padding-top:45px !important}.pt50{padding-top:50px !important}.pb0{padding-bottom:0 !important}.pb5{padding-bottom:5px !important}.pb10{padding-bottom:10px !important}.pb15{padding-bottom:15px !important}.pb20{padding-bottom:20px !important}.pb25{padding-bottom:25px !important}.pb30{padding-bottom:30px !important}.pb35{padding-bottom:35px !important}.pb40{padding-bottom:40px !important}.pb45{padding-bottom:45px !important}.pb50{padding-bottom:50px !important}.pl0{padding-left:0 !important}.pl5{padding-left:5px !important}.pl10{padding-left:10px !important}.pl15{padding-left:15px !important}.pl20{padding-left:20px !important}.pl25{padding-left:25px !important}.pl30{padding-left:30px !important}.pl35{padding-left:35px !important}.pl40{padding-left:40px !important}.pl45{padding-left:45px !important}.pl50{padding-left:50px !important}.pr0{padding-right:0 !important}.pr5{padding-right:5px !important}.pr10{padding-right:10px !important}.pr15{padding-right:15px !important}.pr20{padding-right:20px !important}.pr25{padding-right:25px !important}.pr30{padding-right:30px !important}.pr35{padding-right:35px !important}.pr40{padding-right:40px !important}.pr45{padding-right:45px !important}.pr50{padding-right:50px !important}.bk-bg-default{background-color:#fafbfd}.bk-bg-primary{background-color:#3a84ff}.bk-bg-warning{background-color:#ff9c01}.bk-bg-danger{background-color:#ea3636}.bk-bg-success{background-color:#2dcb56}.bk-text-default{color:#63656e}.bk-text-primary{color:#3a84ff}.bk-text-warning{color:#ff9c01}.bk-text-danger{color:#ea3636}.bk-text-success{color:#2dcb56}.bk-text-main{color:#313238}.bk-text-minor{color:#979ba5}.bk-text-yahei{font-family:-apple-system,BlinkMacSystemFont,PingFang SC,Microsoft Yahei,Helvetica,Aria}.fb{font-weight:700 !important}.fn{font-weight:400 !important}.lh150{line-height:150% !important}.lh180{line-height:180% !important}.lh200{line-height:200% !important}.unl{text-decoration:underline !important}.no_unl{text-decoration:none !important}.tl{text-align:left !important}.tc{text-align:center !important}.tr{text-align:right !important}.bc{margin-left:auto !important;margin-right:auto !important}.fl{float:left !important}.fr{float:right !important}.cb{clear:both !important}.cl{clear:left !important}.cr{clear:right !important}.vm{vertical-align:middle !important}.pr{position:relative !important}.abs-right,.pa{position:absolute !important}.zoom{zoom:1}.hidden{visibility:hidden !important}.none{display:none !important}.h50{height:50px !important}.h80{height:80px !important}.h100{height:100px !important}.h200{height:200px !important}.h{height:100% !important}.bk-has-submenu{position:relative}.bk-has-submenu:hover .bk-submenu{display:block}.bk-has-submenu .bk-submenu{display:none;position:absolute;width:100%;left:0;right:0;padding:0}.bk-has-submenu .bk-submenu>li{display:block}',""]);const v=f},2979:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'.bk-tooltip,.bk-tooltip-ref{display:inline-block}.bk-tooltip-ref{position:relative;outline:0}.tippy-iOS{cursor:pointer !important;-webkit-tap-highlight-color:rgba(0,0,0,0)}.tippy-popper{-webkit-transition-timing-function:cubic-bezier(0.165, 0.84, 0.44, 1);transition-timing-function:cubic-bezier(0.165, 0.84, 0.44, 1);max-width:calc(100% - 8px);pointer-events:none;outline:0}.tippy-popper[x-placement^=top] .tippy-backdrop{border-radius:40% 40% 0 0}.tippy-popper[x-placement^=top] .tippy-roundarrow{bottom:-7px;bottom:-6.5px;-webkit-transform-origin:50% 0;transform-origin:50% 0;margin:0 3px}.tippy-popper[x-placement^=top] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.tippy-popper[x-placement^=top] .tippy-arrow{border-top:8px solid #333;border-right:8px solid rgba(0,0,0,0);border-left:8px solid rgba(0,0,0,0);bottom:-7px;margin:0 3px;-webkit-transform-origin:50% 0;transform-origin:50% 0}.tippy-popper[x-placement^=top] .tippy-backdrop{-webkit-transform-origin:0 25%;transform-origin:0 25%}.tippy-popper[x-placement^=top] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(1) translate(-50%, -55%);transform:scale(1) translate(-50%, -55%)}.tippy-popper[x-placement^=top] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(0.2) translate(-50%, -45%);transform:scale(0.2) translate(-50%, -45%);opacity:0}.tippy-popper[x-placement^=top] [data-animation=shift-toward][data-state=visible]{-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateY(-20px);transform:translateY(-20px)}.tippy-popper[x-placement^=top] [data-animation=perspective]{-webkit-transform-origin:bottom;transform-origin:bottom}.tippy-popper[x-placement^=top] [data-animation=perspective][data-state=visible]{-webkit-transform:perspective(700px) translateY(-10px) rotateX(0);transform:perspective(700px) translateY(-10px) rotateX(0)}.tippy-popper[x-placement^=top] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:perspective(700px) translateY(0) rotateX(60deg);transform:perspective(700px) translateY(0) rotateX(60deg)}.tippy-popper[x-placement^=top] [data-animation=fade][data-state=visible]{-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift-away][data-state=visible]{-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}.tippy-popper[x-placement^=top] [data-animation=scale]{-webkit-transform-origin:bottom;transform-origin:bottom}.tippy-popper[x-placement^=top] [data-animation=scale][data-state=visible]{-webkit-transform:translateY(-10px) scale(1);transform:translateY(-10px) scale(1)}.tippy-popper[x-placement^=top] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateY(-10px) scale(0.5);transform:translateY(-10px) scale(0.5)}.tippy-popper[x-placement^=top] [data-animation=slide-toggle]{-webkit-transform-origin:center bottom;transform-origin:center bottom}.tippy-popper[x-placement^=top] [data-animation=slide-toggle][data-state=visible]{-webkit-transform:scaleY(1);transform:scaleY(1);opacity:1}.tippy-popper[x-placement^=top] [data-animation=slide-toggle][data-state=hidden]{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.tippy-popper[x-placement^=bottom] .tippy-backdrop{border-radius:0 0 30% 30%}.tippy-popper[x-placement^=bottom] .tippy-roundarrow{top:-7px;-webkit-transform-origin:50% 100%;transform-origin:50% 100%;margin:0 3px}.tippy-popper[x-placement^=bottom] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(0);transform:rotate(0)}.tippy-popper[x-placement^=bottom] .tippy-arrow{border-bottom:8px solid #333;border-right:8px solid rgba(0,0,0,0);border-left:8px solid rgba(0,0,0,0);top:-7px;margin:0 3px;-webkit-transform-origin:50% 100%;transform-origin:50% 100%}.tippy-popper[x-placement^=bottom] .tippy-backdrop{-webkit-transform-origin:0 -50%;transform-origin:0 -50%}.tippy-popper[x-placement^=bottom] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(1) translate(-50%, -45%);transform:scale(1) translate(-50%, -45%)}.tippy-popper[x-placement^=bottom] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(0.2) translate(-50%);transform:scale(0.2) translate(-50%);opacity:0}.tippy-popper[x-placement^=bottom] [data-animation=shift-toward][data-state=visible]{-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateY(20px);transform:translateY(20px)}.tippy-popper[x-placement^=bottom] [data-animation=perspective]{-webkit-transform-origin:top;transform-origin:top}.tippy-popper[x-placement^=bottom] [data-animation=perspective][data-state=visible]{-webkit-transform:perspective(700px) translateY(10px) rotateX(0);transform:perspective(700px) translateY(10px) rotateX(0)}.tippy-popper[x-placement^=bottom] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:perspective(700px) translateY(0) rotateX(-60deg);transform:perspective(700px) translateY(0) rotateX(-60deg)}.tippy-popper[x-placement^=bottom] [data-animation=fade][data-state=visible]{-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift-away][data-state=visible]{-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}.tippy-popper[x-placement^=bottom] [data-animation=scale]{-webkit-transform-origin:top;transform-origin:top}.tippy-popper[x-placement^=bottom] [data-animation=scale][data-state=visible]{-webkit-transform:translateY(10px) scale(1);transform:translateY(10px) scale(1)}.tippy-popper[x-placement^=bottom] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateY(10px) scale(0.5);transform:translateY(10px) scale(0.5)}.tippy-popper[x-placement^=bottom] [data-animation=slide-toggle]{-webkit-transform-origin:center top;transform-origin:center top}.tippy-popper[x-placement^=bottom] [data-animation=slide-toggle][data-state=visible]{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}.tippy-popper[x-placement^=bottom] [data-animation=slide-toggle][data-state=hidden]{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.tippy-popper[x-placement^=left] .tippy-backdrop{border-radius:50% 0 0 50%}.tippy-popper[x-placement^=left] .tippy-roundarrow{right:-12px;-webkit-transform-origin:33.33333333% 50%;transform-origin:33.33333333% 50%;margin:3px 0}.tippy-popper[x-placement^=left] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(90deg);transform:rotate(90deg)}.tippy-popper[x-placement^=left] .tippy-arrow{border-left:8px solid #333;border-top:8px solid rgba(0,0,0,0);border-bottom:8px solid rgba(0,0,0,0);right:-7px;margin:3px 0;-webkit-transform-origin:0 50%;transform-origin:0 50%}.tippy-popper[x-placement^=left] .tippy-backdrop{-webkit-transform-origin:50% 0;transform-origin:50% 0}.tippy-popper[x-placement^=left] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(1) translate(-50%, -50%);transform:scale(1) translate(-50%, -50%)}.tippy-popper[x-placement^=left] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(0.2) translate(-75%, -50%);transform:scale(0.2) translate(-75%, -50%);opacity:0}.tippy-popper[x-placement^=left] [data-animation=shift-toward][data-state=visible]{-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateX(-20px);transform:translateX(-20px)}.tippy-popper[x-placement^=left] [data-animation=perspective]{-webkit-transform-origin:right;transform-origin:right}.tippy-popper[x-placement^=left] [data-animation=perspective][data-state=visible]{-webkit-transform:perspective(700px) translateX(-10px) rotateY(0);transform:perspective(700px) translateX(-10px) rotateY(0)}.tippy-popper[x-placement^=left] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:perspective(700px) translateX(0) rotateY(-60deg);transform:perspective(700px) translateX(0) rotateY(-60deg)}.tippy-popper[x-placement^=left] [data-animation=fade][data-state=visible]{-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift-away][data-state=visible]{-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateX(0);transform:translateX(0)}.tippy-popper[x-placement^=left] [data-animation=scale]{-webkit-transform-origin:right;transform-origin:right}.tippy-popper[x-placement^=left] [data-animation=scale][data-state=visible]{-webkit-transform:translateX(-10px) scale(1);transform:translateX(-10px) scale(1)}.tippy-popper[x-placement^=left] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateX(-10px) scale(0.5);transform:translateX(-10px) scale(0.5)}.tippy-popper[x-placement^=right] .tippy-backdrop{border-radius:0 50% 50% 0}.tippy-popper[x-placement^=right] .tippy-roundarrow{left:-12px;-webkit-transform-origin:66.66666666% 50%;transform-origin:66.66666666% 50%;margin:3px 0}.tippy-popper[x-placement^=right] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.tippy-popper[x-placement^=right] .tippy-arrow{border-right:8px solid #333;border-top:8px solid rgba(0,0,0,0);border-bottom:8px solid rgba(0,0,0,0);left:-7px;margin:3px 0;-webkit-transform-origin:100% 50%;transform-origin:100% 50%}.tippy-popper[x-placement^=right] .tippy-backdrop{-webkit-transform-origin:-50% 0;transform-origin:-50% 0}.tippy-popper[x-placement^=right] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(1) translate(-50%, -50%);transform:scale(1) translate(-50%, -50%)}.tippy-popper[x-placement^=right] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(0.2) translate(-25%, -50%);transform:scale(0.2) translate(-25%, -50%);opacity:0}.tippy-popper[x-placement^=right] [data-animation=shift-toward][data-state=visible]{-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateX(20px);transform:translateX(20px)}.tippy-popper[x-placement^=right] [data-animation=perspective]{-webkit-transform-origin:left;transform-origin:left}.tippy-popper[x-placement^=right] [data-animation=perspective][data-state=visible]{-webkit-transform:perspective(700px) translateX(10px) rotateY(0);transform:perspective(700px) translateX(10px) rotateY(0)}.tippy-popper[x-placement^=right] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:perspective(700px) translateX(0) rotateY(60deg);transform:perspective(700px) translateX(0) rotateY(60deg)}.tippy-popper[x-placement^=right] [data-animation=fade][data-state=visible]{-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift-away][data-state=visible]{-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateX(0);transform:translateX(0)}.tippy-popper[x-placement^=right] [data-animation=scale]{-webkit-transform-origin:left;transform-origin:left}.tippy-popper[x-placement^=right] [data-animation=scale][data-state=visible]{-webkit-transform:translateX(10px) scale(1);transform:translateX(10px) scale(1)}.tippy-popper[x-placement^=right] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateX(10px) scale(0.5);transform:translateX(10px) scale(0.5)}.tippy-tooltip{position:relative;color:#fff;border-radius:4px;font-size:.9rem;padding:.3rem .6rem;text-align:left;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:rgba(0,0,0,.8)}.tippy-tooltip[data-size=small]{padding:7px 14px;font-size:12px}.tippy-tooltip[data-size=large]{padding:.4rem .8rem;font-size:1rem}.tippy-tooltip[data-animatefill]{overflow:hidden;background-color:rgba(0,0,0,0)}.tippy-tooltip[data-interactive],.tippy-tooltip[data-interactive] .tippy-roundarrow path{pointer-events:auto}.tippy-tooltip[data-inertia][data-state=visible]{-webkit-transition-timing-function:cubic-bezier(0.54, 1.5, 0.38, 1.11);transition-timing-function:cubic-bezier(0.54, 1.5, 0.38, 1.11)}.tippy-tooltip[data-inertia][data-state=hidden]{-webkit-transition-timing-function:ease;transition-timing-function:ease}.tippy-arrow,.tippy-roundarrow{position:absolute;width:0;height:0}.tippy-roundarrow{width:18px;height:7px;fill:#333;pointer-events:none}.tippy-backdrop{position:absolute;background-color:#333;border-radius:50%;width:calc(110% + 2rem);left:50%;top:50%;z-index:-1;-webkit-transition:all cubic-bezier(0.46, 0.1, 0.52, 0.98);transition:all cubic-bezier(0.46, 0.1, 0.52, 0.98);-webkit-backface-visibility:hidden;backface-visibility:hidden}.tippy-backdrop:after{content:"";float:left;padding-top:100%}.tippy-backdrop+.tippy-content{-webkit-transition-property:opacity;transition-property:opacity}.tippy-backdrop+.tippy-content[data-state=visible]{opacity:1}.tippy-backdrop+.tippy-content[data-state=hidden]{opacity:0}.tippy-tooltip.light-theme{color:#26323d;-webkit-box-shadow:0 0 6px 0 #dcdee5;box-shadow:0 0 6px 0 #dcdee5;background-color:#fff}.tippy-tooltip.light-theme:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;border-radius:inherit;background:inherit}.tippy-tooltip.light-theme .tippy-arrow{z-index:-2;width:11px;height:11px;border:none !important;-webkit-box-shadow:inherit;box-shadow:inherit;background:inherit;-webkit-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.tippy-tooltip.light-theme[x-placement^=top] .tippy-arrow{bottom:-5px}.tippy-tooltip.light-theme[x-placement^=bottom] .tippy-arrow{top:-5px}.tippy-tooltip.light-theme[x-placement^=left] .tippy-arrow{right:-5px}.tippy-tooltip.light-theme[x-placement^=right] .tippy-arrow{left:-5px}.tippy-tooltip.light-theme .tippy-backdrop{background-color:#fff}.tippy-tooltip.light-theme .tippy-roundarrow{fill:#fff}.tippy-tooltip.light-theme[data-animatefill]{background-color:rgba(0,0,0,0)}.tippy-tooltip.light-border-theme{color:#26323d;-webkit-box-shadow:0 0 6px 0 #dcdee5;box-shadow:0 0 6px 0 #dcdee5;background-color:#fff;border:1px solid #dcdee5}.tippy-tooltip.light-border-theme:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;border-radius:inherit;background:inherit}.tippy-tooltip.light-border-theme .tippy-arrow{z-index:-2;width:11px;height:11px;border:1px solid #dcdee5;-webkit-box-shadow:inherit;box-shadow:inherit;background:inherit;-webkit-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.tippy-tooltip.light-border-theme[x-placement^=top] .tippy-arrow{bottom:-5px}.tippy-tooltip.light-border-theme[x-placement^=bottom] .tippy-arrow{top:-5px}.tippy-tooltip.light-border-theme[x-placement^=left] .tippy-arrow{right:-5px}.tippy-tooltip.light-border-theme[x-placement^=right] .tippy-arrow{left:-5px}.tippy-tooltip.light-border-theme .tippy-backdrop{background-color:#fff}.tippy-tooltip.light-border-theme .tippy-roundarrow{fill:#fff}.tippy-tooltip.light-border-theme[data-animatefill]{background-color:rgba(0,0,0,0)}',""]);const s=a},3545:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'.bk-tooltip,.bk-tooltip-ref{display:inline-block}.bk-tooltip-ref{position:relative;outline:0}.tippy-iOS{cursor:pointer !important;-webkit-tap-highlight-color:rgba(0,0,0,0)}.tippy-popper{-webkit-transition-timing-function:cubic-bezier(0.165, 0.84, 0.44, 1);transition-timing-function:cubic-bezier(0.165, 0.84, 0.44, 1);max-width:calc(100% - 8px);pointer-events:none;outline:0}.tippy-popper[x-placement^=top] .tippy-backdrop{border-radius:40% 40% 0 0}.tippy-popper[x-placement^=top] .tippy-roundarrow{bottom:-7px;bottom:-6.5px;-webkit-transform-origin:50% 0;transform-origin:50% 0;margin:0 3px}.tippy-popper[x-placement^=top] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.tippy-popper[x-placement^=top] .tippy-arrow{border-top:8px solid #333;border-right:8px solid rgba(0,0,0,0);border-left:8px solid rgba(0,0,0,0);bottom:-7px;margin:0 3px;-webkit-transform-origin:50% 0;transform-origin:50% 0}.tippy-popper[x-placement^=top] .tippy-backdrop{-webkit-transform-origin:0 25%;transform-origin:0 25%}.tippy-popper[x-placement^=top] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(1) translate(-50%, -55%);transform:scale(1) translate(-50%, -55%)}.tippy-popper[x-placement^=top] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(0.2) translate(-50%, -45%);transform:scale(0.2) translate(-50%, -45%);opacity:0}.tippy-popper[x-placement^=top] [data-animation=shift-toward][data-state=visible]{-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateY(-20px);transform:translateY(-20px)}.tippy-popper[x-placement^=top] [data-animation=perspective]{-webkit-transform-origin:bottom;transform-origin:bottom}.tippy-popper[x-placement^=top] [data-animation=perspective][data-state=visible]{-webkit-transform:perspective(700px) translateY(-10px) rotateX(0);transform:perspective(700px) translateY(-10px) rotateX(0)}.tippy-popper[x-placement^=top] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:perspective(700px) translateY(0) rotateX(60deg);transform:perspective(700px) translateY(0) rotateX(60deg)}.tippy-popper[x-placement^=top] [data-animation=fade][data-state=visible]{-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift-away][data-state=visible]{-webkit-transform:translateY(-10px);transform:translateY(-10px)}.tippy-popper[x-placement^=top] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}.tippy-popper[x-placement^=top] [data-animation=scale]{-webkit-transform-origin:bottom;transform-origin:bottom}.tippy-popper[x-placement^=top] [data-animation=scale][data-state=visible]{-webkit-transform:translateY(-10px) scale(1);transform:translateY(-10px) scale(1)}.tippy-popper[x-placement^=top] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateY(-10px) scale(0.5);transform:translateY(-10px) scale(0.5)}.tippy-popper[x-placement^=top] [data-animation=slide-toggle]{-webkit-transform-origin:center bottom;transform-origin:center bottom}.tippy-popper[x-placement^=top] [data-animation=slide-toggle][data-state=visible]{-webkit-transform:scaleY(1);transform:scaleY(1);opacity:1}.tippy-popper[x-placement^=top] [data-animation=slide-toggle][data-state=hidden]{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.tippy-popper[x-placement^=bottom] .tippy-backdrop{border-radius:0 0 30% 30%}.tippy-popper[x-placement^=bottom] .tippy-roundarrow{top:-7px;-webkit-transform-origin:50% 100%;transform-origin:50% 100%;margin:0 3px}.tippy-popper[x-placement^=bottom] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(0);transform:rotate(0)}.tippy-popper[x-placement^=bottom] .tippy-arrow{border-bottom:8px solid #333;border-right:8px solid rgba(0,0,0,0);border-left:8px solid rgba(0,0,0,0);top:-7px;margin:0 3px;-webkit-transform-origin:50% 100%;transform-origin:50% 100%}.tippy-popper[x-placement^=bottom] .tippy-backdrop{-webkit-transform-origin:0 -50%;transform-origin:0 -50%}.tippy-popper[x-placement^=bottom] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(1) translate(-50%, -45%);transform:scale(1) translate(-50%, -45%)}.tippy-popper[x-placement^=bottom] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(0.2) translate(-50%);transform:scale(0.2) translate(-50%);opacity:0}.tippy-popper[x-placement^=bottom] [data-animation=shift-toward][data-state=visible]{-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateY(20px);transform:translateY(20px)}.tippy-popper[x-placement^=bottom] [data-animation=perspective]{-webkit-transform-origin:top;transform-origin:top}.tippy-popper[x-placement^=bottom] [data-animation=perspective][data-state=visible]{-webkit-transform:perspective(700px) translateY(10px) rotateX(0);transform:perspective(700px) translateY(10px) rotateX(0)}.tippy-popper[x-placement^=bottom] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:perspective(700px) translateY(0) rotateX(-60deg);transform:perspective(700px) translateY(0) rotateX(-60deg)}.tippy-popper[x-placement^=bottom] [data-animation=fade][data-state=visible]{-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift-away][data-state=visible]{-webkit-transform:translateY(10px);transform:translateY(10px)}.tippy-popper[x-placement^=bottom] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateY(0);transform:translateY(0)}.tippy-popper[x-placement^=bottom] [data-animation=scale]{-webkit-transform-origin:top;transform-origin:top}.tippy-popper[x-placement^=bottom] [data-animation=scale][data-state=visible]{-webkit-transform:translateY(10px) scale(1);transform:translateY(10px) scale(1)}.tippy-popper[x-placement^=bottom] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateY(10px) scale(0.5);transform:translateY(10px) scale(0.5)}.tippy-popper[x-placement^=bottom] [data-animation=slide-toggle]{-webkit-transform-origin:center top;transform-origin:center top}.tippy-popper[x-placement^=bottom] [data-animation=slide-toggle][data-state=visible]{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1)}.tippy-popper[x-placement^=bottom] [data-animation=slide-toggle][data-state=hidden]{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.tippy-popper[x-placement^=left] .tippy-backdrop{border-radius:50% 0 0 50%}.tippy-popper[x-placement^=left] .tippy-roundarrow{right:-12px;-webkit-transform-origin:33.33333333% 50%;transform-origin:33.33333333% 50%;margin:3px 0}.tippy-popper[x-placement^=left] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(90deg);transform:rotate(90deg)}.tippy-popper[x-placement^=left] .tippy-arrow{border-left:8px solid #333;border-top:8px solid rgba(0,0,0,0);border-bottom:8px solid rgba(0,0,0,0);right:-7px;margin:3px 0;-webkit-transform-origin:0 50%;transform-origin:0 50%}.tippy-popper[x-placement^=left] .tippy-backdrop{-webkit-transform-origin:50% 0;transform-origin:50% 0}.tippy-popper[x-placement^=left] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(1) translate(-50%, -50%);transform:scale(1) translate(-50%, -50%)}.tippy-popper[x-placement^=left] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(0.2) translate(-75%, -50%);transform:scale(0.2) translate(-75%, -50%);opacity:0}.tippy-popper[x-placement^=left] [data-animation=shift-toward][data-state=visible]{-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateX(-20px);transform:translateX(-20px)}.tippy-popper[x-placement^=left] [data-animation=perspective]{-webkit-transform-origin:right;transform-origin:right}.tippy-popper[x-placement^=left] [data-animation=perspective][data-state=visible]{-webkit-transform:perspective(700px) translateX(-10px) rotateY(0);transform:perspective(700px) translateX(-10px) rotateY(0)}.tippy-popper[x-placement^=left] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:perspective(700px) translateX(0) rotateY(-60deg);transform:perspective(700px) translateX(0) rotateY(-60deg)}.tippy-popper[x-placement^=left] [data-animation=fade][data-state=visible]{-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift-away][data-state=visible]{-webkit-transform:translateX(-10px);transform:translateX(-10px)}.tippy-popper[x-placement^=left] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateX(0);transform:translateX(0)}.tippy-popper[x-placement^=left] [data-animation=scale]{-webkit-transform-origin:right;transform-origin:right}.tippy-popper[x-placement^=left] [data-animation=scale][data-state=visible]{-webkit-transform:translateX(-10px) scale(1);transform:translateX(-10px) scale(1)}.tippy-popper[x-placement^=left] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateX(-10px) scale(0.5);transform:translateX(-10px) scale(0.5)}.tippy-popper[x-placement^=right] .tippy-backdrop{border-radius:0 50% 50% 0}.tippy-popper[x-placement^=right] .tippy-roundarrow{left:-12px;-webkit-transform-origin:66.66666666% 50%;transform-origin:66.66666666% 50%;margin:3px 0}.tippy-popper[x-placement^=right] .tippy-roundarrow svg{position:absolute;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.tippy-popper[x-placement^=right] .tippy-arrow{border-right:8px solid #333;border-top:8px solid rgba(0,0,0,0);border-bottom:8px solid rgba(0,0,0,0);left:-7px;margin:3px 0;-webkit-transform-origin:100% 50%;transform-origin:100% 50%}.tippy-popper[x-placement^=right] .tippy-backdrop{-webkit-transform-origin:-50% 0;transform-origin:-50% 0}.tippy-popper[x-placement^=right] .tippy-backdrop[data-state=visible]{-webkit-transform:scale(1) translate(-50%, -50%);transform:scale(1) translate(-50%, -50%)}.tippy-popper[x-placement^=right] .tippy-backdrop[data-state=hidden]{-webkit-transform:scale(0.2) translate(-25%, -50%);transform:scale(0.2) translate(-25%, -50%);opacity:0}.tippy-popper[x-placement^=right] [data-animation=shift-toward][data-state=visible]{-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift-toward][data-state=hidden]{opacity:0;-webkit-transform:translateX(20px);transform:translateX(20px)}.tippy-popper[x-placement^=right] [data-animation=perspective]{-webkit-transform-origin:left;transform-origin:left}.tippy-popper[x-placement^=right] [data-animation=perspective][data-state=visible]{-webkit-transform:perspective(700px) translateX(10px) rotateY(0);transform:perspective(700px) translateX(10px) rotateY(0)}.tippy-popper[x-placement^=right] [data-animation=perspective][data-state=hidden]{opacity:0;-webkit-transform:perspective(700px) translateX(0) rotateY(60deg);transform:perspective(700px) translateX(0) rotateY(60deg)}.tippy-popper[x-placement^=right] [data-animation=fade][data-state=visible]{-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=fade][data-state=hidden]{opacity:0;-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift-away][data-state=visible]{-webkit-transform:translateX(10px);transform:translateX(10px)}.tippy-popper[x-placement^=right] [data-animation=shift-away][data-state=hidden]{opacity:0;-webkit-transform:translateX(0);transform:translateX(0)}.tippy-popper[x-placement^=right] [data-animation=scale]{-webkit-transform-origin:left;transform-origin:left}.tippy-popper[x-placement^=right] [data-animation=scale][data-state=visible]{-webkit-transform:translateX(10px) scale(1);transform:translateX(10px) scale(1)}.tippy-popper[x-placement^=right] [data-animation=scale][data-state=hidden]{opacity:0;-webkit-transform:translateX(10px) scale(0.5);transform:translateX(10px) scale(0.5)}.tippy-tooltip{position:relative;color:#fff;border-radius:4px;font-size:.9rem;padding:.3rem .6rem;text-align:left;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:rgba(0,0,0,.8)}.tippy-tooltip[data-size=small]{padding:7px 14px;font-size:12px}.tippy-tooltip[data-size=large]{padding:.4rem .8rem;font-size:1rem}.tippy-tooltip[data-animatefill]{overflow:hidden;background-color:rgba(0,0,0,0)}.tippy-tooltip[data-interactive],.tippy-tooltip[data-interactive] .tippy-roundarrow path{pointer-events:auto}.tippy-tooltip[data-inertia][data-state=visible]{-webkit-transition-timing-function:cubic-bezier(0.54, 1.5, 0.38, 1.11);transition-timing-function:cubic-bezier(0.54, 1.5, 0.38, 1.11)}.tippy-tooltip[data-inertia][data-state=hidden]{-webkit-transition-timing-function:ease;transition-timing-function:ease}.tippy-arrow,.tippy-roundarrow{position:absolute;width:0;height:0}.tippy-roundarrow{width:18px;height:7px;fill:#333;pointer-events:none}.tippy-backdrop{position:absolute;background-color:#333;border-radius:50%;width:calc(110% + 2rem);left:50%;top:50%;z-index:-1;-webkit-transition:all cubic-bezier(0.46, 0.1, 0.52, 0.98);transition:all cubic-bezier(0.46, 0.1, 0.52, 0.98);-webkit-backface-visibility:hidden;backface-visibility:hidden}.tippy-backdrop:after{content:"";float:left;padding-top:100%}.tippy-backdrop+.tippy-content{-webkit-transition-property:opacity;transition-property:opacity}.tippy-backdrop+.tippy-content[data-state=visible]{opacity:1}.tippy-backdrop+.tippy-content[data-state=hidden]{opacity:0}.tippy-tooltip.light-theme{color:#26323d;-webkit-box-shadow:0 0 6px 0 #dcdee5;box-shadow:0 0 6px 0 #dcdee5;background-color:#fff}.tippy-tooltip.light-theme:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;border-radius:inherit;background:inherit}.tippy-tooltip.light-theme .tippy-arrow{z-index:-2;width:11px;height:11px;border:none !important;-webkit-box-shadow:inherit;box-shadow:inherit;background:inherit;-webkit-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.tippy-tooltip.light-theme[x-placement^=top] .tippy-arrow{bottom:-5px}.tippy-tooltip.light-theme[x-placement^=bottom] .tippy-arrow{top:-5px}.tippy-tooltip.light-theme[x-placement^=left] .tippy-arrow{right:-5px}.tippy-tooltip.light-theme[x-placement^=right] .tippy-arrow{left:-5px}.tippy-tooltip.light-theme .tippy-backdrop{background-color:#fff}.tippy-tooltip.light-theme .tippy-roundarrow{fill:#fff}.tippy-tooltip.light-theme[data-animatefill]{background-color:rgba(0,0,0,0)}.tippy-tooltip.light-border-theme{color:#26323d;-webkit-box-shadow:0 0 6px 0 #dcdee5;box-shadow:0 0 6px 0 #dcdee5;background-color:#fff;border:1px solid #dcdee5}.tippy-tooltip.light-border-theme:before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;border-radius:inherit;background:inherit}.tippy-tooltip.light-border-theme .tippy-arrow{z-index:-2;width:11px;height:11px;border:1px solid #dcdee5;-webkit-box-shadow:inherit;box-shadow:inherit;background:inherit;-webkit-transform-origin:center center;transform-origin:center center;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.tippy-tooltip.light-border-theme[x-placement^=top] .tippy-arrow{bottom:-5px}.tippy-tooltip.light-border-theme[x-placement^=bottom] .tippy-arrow{top:-5px}.tippy-tooltip.light-border-theme[x-placement^=left] .tippy-arrow{right:-5px}.tippy-tooltip.light-border-theme[x-placement^=right] .tippy-arrow{left:-5px}.tippy-tooltip.light-border-theme .tippy-backdrop{background-color:#fff}.tippy-tooltip.light-border-theme .tippy-roundarrow{fill:#fff}.tippy-tooltip.light-border-theme[data-animatefill]{background-color:rgba(0,0,0,0)}',""]);const s=a},4800:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'/*!\n * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.\n *\n * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.\n *\n * A copy of the MIT License is included in this file.\n *\n *\n * Terms of the MIT License:\n * ---------------------------------------------------\n * 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:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * 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.\n *//*!\n * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.\n *\n * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.\n *\n * A copy of the MIT License is included in this file.\n *\n *\n * Terms of the MIT License:\n * ---------------------------------------------------\n * 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:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * 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.\n */@keyframes rotating{from{transform:rotate(0)}to{transform:rotate(359deg)}}.connect-line{position:absolute;width:58px;top:19px;stroke:#3c96ff;stroke-width:1;fill:none}.insert-tip{position:absolute;display:block;padding:0 10px;max-width:100px;height:24px;display:flex;align-items:center;border:1px solid #addaff;border-radius:22px;color:#3c96ff;font-size:10px;cursor:pointer;background-color:#fff;box-shadow:0px 2px 4px 0px rgba(60,150,255,.2)}.insert-tip.direction:after{content:"";position:absolute;height:6px;width:6px;background-color:#fff;transform:rotate(45deg);bottom:-4px;left:20px;border-right:1px solid #addaff;border-bottom:1px solid #addaff}.insert-tip .tip-icon{margin:0 5px 0 0;cursor:pointer;position:relative;display:block;width:8px;height:8px;transition:all .3s ease}.insert-tip .tip-icon:before,.insert-tip .tip-icon:after{content:"";position:absolute;left:3px;top:0px;height:8px;width:2px;background-color:#3c96ff}.insert-tip .tip-icon:after{transform:rotate(90deg)}.insert-tip>span{white-space:nowrap}.insert-tip:hover{background-color:#3c96ff;color:#fff;border-color:#3c96ff}.insert-tip:hover.direction:after{background-color:#3c96ff;border-right-color:#3c96ff;border-bottom-color:#3c96ff}.insert-tip:hover .tip-icon{position:relative;display:block;width:8px;height:8px;transition:all .3s ease}.insert-tip:hover .tip-icon:before,.insert-tip:hover .tip-icon:after{content:"";position:absolute;left:3px;top:0px;height:8px;width:2px;background-color:#fff}.insert-tip:hover .tip-icon:after{transform:rotate(90deg)}.pointer{cursor:pointer}span.skip-name{text-decoration:line-through;color:#c4cdd6}span.skip-name:hover{color:#c4cdd6}.spin-icon{display:inline-block;animation:loading .8s linear infinite}.add-plus-icon,.minus-icon{position:relative;display:block;width:18px;height:18px;border:1px solid #addaff;background-color:#fff;border-radius:50%;transition:all .3s ease}.add-plus-icon:before,.minus-icon:before,.add-plus-icon:after,.minus-icon:after{content:"";position:absolute;left:8px;top:5px;left:7px;top:4px;height:8px;width:2px;background-color:#3c96ff}.add-plus-icon:after,.minus-icon:after{transform:rotate(90deg)}.add-plus-icon.active,.active.minus-icon{border-color:#3c96ff;background-color:#3c96ff}.add-plus-icon.active:before,.active.minus-icon:before,.add-plus-icon.active:after,.active.minus-icon:after{background-color:#fff}.add-plus-icon:hover,.minus-icon:hover{border-color:#3c96ff;background-color:#3c96ff}.add-plus-icon:hover:before,.minus-icon:hover:before,.add-plus-icon:hover:after,.minus-icon:hover:after{background-color:#fff}.minus-icon:before{display:none}.un-exec-this-time{opacity:.5}.un-exec-this-time .un-exec-this-time{opacity:1}.readonly .stage-connector{background:#c3cdd7;color:#c3cdd7}.readonly .stage-connector:before{background:#c3cdd7}.readonly .connect-line.left,.readonly .connect-line.right{stroke:#c3cdd7}.readonly .connect-line.left:before,.readonly .connect-line.right:before{stroke:#c3cdd7}.readonly .connect-line.left:after,.readonly .connect-line.right:after{stroke:#c3cdd7;background-color:#c3cdd7}.readonly:after{background:#c3cdd7}.readonly .container-connect-triangle{color:#c3cdd7}.readonly .container-title{cursor:pointer;background-color:#63656e}.readonly .container-title:before,.readonly .container-title:after{border-top-color:#c3cdd7}.readonly .container-title>.container-name span{color:#fff}.editing .stage-connector{background:#3c96ff;color:#3c96ff}.editing .stage-connector:before{background:#3c96ff}.editing .connect-line.left,.editing .connect-line.right{stroke:#3c96ff}.editing .connect-line.left:before,.editing .connect-line.right:before{stroke:#3c96ff}.editing .connect-line.left:after,.editing .connect-line.right:after{stroke:#3c96ff;background-color:#3c96ff}.editing:after{background:#3c96ff}.editing:before{color:#3c96ff}.container-type{font-size:12px;margin-right:12px;font-style:normal}.container-type .devops-icon{font-size:18px}.container-type .devops-icon.icon-exclamation-triangle-shape{font-size:14px}.container-type .devops-icon.icon-exclamation-triangle-shape.is-danger{color:#ff5656}.container-type i{font-style:normal}.bk-pipeline .stage-status:not(.readonly){background-color:#3c96ff}.bk-pipeline .stage-status:not(.readonly).WARNING{background-color:#ffb400;color:#fff}.bk-pipeline .stage-status:not(.readonly).FAILED{background-color:#ff5656;color:#fff}.bk-pipeline .stage-status:not(.readonly).SUCCEED{background-color:#34d97b;color:#fff}.bk-pipeline .stage-status.CANCELED,.bk-pipeline .stage-status.REVIEW_ABORT,.bk-pipeline .stage-status.REVIEWING,.bk-pipeline .stage-name-status-icon.CANCELED,.bk-pipeline .stage-name-status-icon.REVIEW_ABORT,.bk-pipeline .stage-name-status-icon.REVIEWING{color:#ffb400}.bk-pipeline .stage-status.FAILED,.bk-pipeline .stage-status.QUALITY_CHECK_FAIL,.bk-pipeline .stage-status.HEARTBEAT_TIMEOUT,.bk-pipeline .stage-status.QUEUE_TIMEOUT,.bk-pipeline .stage-status.EXEC_TIMEOUT,.bk-pipeline .stage-name-status-icon.FAILED,.bk-pipeline .stage-name-status-icon.QUALITY_CHECK_FAIL,.bk-pipeline .stage-name-status-icon.HEARTBEAT_TIMEOUT,.bk-pipeline .stage-name-status-icon.QUEUE_TIMEOUT,.bk-pipeline .stage-name-status-icon.EXEC_TIMEOUT{color:#ff5656}.bk-pipeline .stage-status.SUCCEED,.bk-pipeline .stage-status.REVIEW_PROCESSED,.bk-pipeline .stage-name-status-icon.SUCCEED,.bk-pipeline .stage-name-status-icon.REVIEW_PROCESSED{color:#34d97b}.bk-pipeline .stage-status.PAUSE,.bk-pipeline .stage-name-status-icon.PAUSE{color:#63656e}.bk-pipeline .container-title .stage-status{color:#fff}.bk-pipeline .container-title.UNEXEC,.bk-pipeline .container-title.SKIP,.bk-pipeline .container-title.DISABLED{color:#fff;background-color:#63656e}.bk-pipeline .container-title.UNEXEC .fold-atom-icon,.bk-pipeline .container-title.SKIP .fold-atom-icon,.bk-pipeline .container-title.DISABLED .fold-atom-icon{color:#63656e}.bk-pipeline .container-title.QUEUE,.bk-pipeline .container-title.RUNNING,.bk-pipeline .container-title.REVIEWING,.bk-pipeline .container-title.PREPARE_ENV,.bk-pipeline .container-title.LOOP_WAITING,.bk-pipeline .container-title.DEPENDENT_WAITING,.bk-pipeline .container-title.CALL_WAITING{background-color:#459fff;color:#fff}.bk-pipeline .container-title.QUEUE .fold-atom-icon,.bk-pipeline .container-title.RUNNING .fold-atom-icon,.bk-pipeline .container-title.REVIEWING .fold-atom-icon,.bk-pipeline .container-title.PREPARE_ENV .fold-atom-icon,.bk-pipeline .container-title.LOOP_WAITING .fold-atom-icon,.bk-pipeline .container-title.DEPENDENT_WAITING .fold-atom-icon,.bk-pipeline .container-title.CALL_WAITING .fold-atom-icon{color:#459fff}.bk-pipeline .container-title.CANCELED,.bk-pipeline .container-title.REVIEW_ABORT,.bk-pipeline .container-title.TRY_FINALLY,.bk-pipeline .container-title.QUEUE_CACHE{background-color:#f6b026}.bk-pipeline .container-title.CANCELED span.skip-name,.bk-pipeline .container-title.REVIEW_ABORT span.skip-name,.bk-pipeline .container-title.TRY_FINALLY span.skip-name,.bk-pipeline .container-title.QUEUE_CACHE span.skip-name{color:#fff}.bk-pipeline .container-title.CANCELED .fold-atom-icon,.bk-pipeline .container-title.REVIEW_ABORT .fold-atom-icon,.bk-pipeline .container-title.TRY_FINALLY .fold-atom-icon,.bk-pipeline .container-title.QUEUE_CACHE .fold-atom-icon{color:#f6b026}.bk-pipeline .container-title.FAILED,.bk-pipeline .container-title.TERMINATE,.bk-pipeline .container-title.HEARTBEAT_TIMEOUT,.bk-pipeline .container-title.QUALITY_CHECK_FAIL,.bk-pipeline .container-title.QUEUE_TIMEOUT,.bk-pipeline .container-title.EXEC_TIMEOUT{color:#fff;background-color:#ff5656}.bk-pipeline .container-title.FAILED .fold-atom-icon,.bk-pipeline .container-title.TERMINATE .fold-atom-icon,.bk-pipeline .container-title.HEARTBEAT_TIMEOUT .fold-atom-icon,.bk-pipeline .container-title.QUALITY_CHECK_FAIL .fold-atom-icon,.bk-pipeline .container-title.QUEUE_TIMEOUT .fold-atom-icon,.bk-pipeline .container-title.EXEC_TIMEOUT .fold-atom-icon{color:#ff5656}.bk-pipeline .container-title.SUCCEED,.bk-pipeline .container-title.REVIEW_PROCESSED,.bk-pipeline .container-title.STAGE_SUCCESS{color:#fff;background-color:#34d97b}.bk-pipeline .container-title.SUCCEED .fold-atom-icon,.bk-pipeline .container-title.REVIEW_PROCESSED .fold-atom-icon,.bk-pipeline .container-title.STAGE_SUCCESS .fold-atom-icon{color:#34d97b}.bk-pipeline .container-title.PAUSE{color:#fff;background-color:#ff9801}.bk-pipeline .container-title.PAUSE .fold-atom-icon{color:#ff9801}.bk-pipeline .bk-pipeline-atom.UNEXEC,.bk-pipeline .bk-pipeline-atom.SKIP,.bk-pipeline .bk-pipeline-atom.DISABLED{color:#63656e}.bk-pipeline .bk-pipeline-atom.CANCELED,.bk-pipeline .bk-pipeline-atom.REVIEW_ABORT,.bk-pipeline .bk-pipeline-atom.REVIEWING{border-color:#ffb400}.bk-pipeline .bk-pipeline-atom.CANCELED:before,.bk-pipeline .bk-pipeline-atom.REVIEW_ABORT:before,.bk-pipeline .bk-pipeline-atom.REVIEWING:before{background-color:#ffb400}.bk-pipeline .bk-pipeline-atom.CANCELED:after,.bk-pipeline .bk-pipeline-atom.REVIEW_ABORT:after,.bk-pipeline .bk-pipeline-atom.REVIEWING:after{border-color:#ffb400}.bk-pipeline .bk-pipeline-atom.CANCELED .atom-icon,.bk-pipeline .bk-pipeline-atom.CANCELED .atom-execute-time,.bk-pipeline .bk-pipeline-atom.CANCELED .stage-check-icon,.bk-pipeline .bk-pipeline-atom.REVIEW_ABORT .atom-icon,.bk-pipeline .bk-pipeline-atom.REVIEW_ABORT .atom-execute-time,.bk-pipeline .bk-pipeline-atom.REVIEW_ABORT .stage-check-icon,.bk-pipeline .bk-pipeline-atom.REVIEWING .atom-icon,.bk-pipeline .bk-pipeline-atom.REVIEWING .atom-execute-time,.bk-pipeline .bk-pipeline-atom.REVIEWING .stage-check-icon{color:#ffb400}.bk-pipeline .bk-pipeline-atom.FAILED,.bk-pipeline .bk-pipeline-atom.TERMINATE,.bk-pipeline .bk-pipeline-atom.HEARTBEAT_TIMEOUT,.bk-pipeline .bk-pipeline-atom.QUALITY_CHECK_FAIL,.bk-pipeline .bk-pipeline-atom.QUEUE_TIMEOUT,.bk-pipeline .bk-pipeline-atom.EXEC_TIMEOUT{border-color:#ff5656}.bk-pipeline .bk-pipeline-atom.FAILED:before,.bk-pipeline .bk-pipeline-atom.TERMINATE:before,.bk-pipeline .bk-pipeline-atom.HEARTBEAT_TIMEOUT:before,.bk-pipeline .bk-pipeline-atom.QUALITY_CHECK_FAIL:before,.bk-pipeline .bk-pipeline-atom.QUEUE_TIMEOUT:before,.bk-pipeline .bk-pipeline-atom.EXEC_TIMEOUT:before{background-color:#ff5656}.bk-pipeline .bk-pipeline-atom.FAILED:after,.bk-pipeline .bk-pipeline-atom.TERMINATE:after,.bk-pipeline .bk-pipeline-atom.HEARTBEAT_TIMEOUT:after,.bk-pipeline .bk-pipeline-atom.QUALITY_CHECK_FAIL:after,.bk-pipeline .bk-pipeline-atom.QUEUE_TIMEOUT:after,.bk-pipeline .bk-pipeline-atom.EXEC_TIMEOUT:after{border-color:#ff5656}.bk-pipeline .bk-pipeline-atom.FAILED .atom-icon,.bk-pipeline .bk-pipeline-atom.FAILED .atom-execute-time,.bk-pipeline .bk-pipeline-atom.FAILED .stage-check-icon,.bk-pipeline .bk-pipeline-atom.TERMINATE .atom-icon,.bk-pipeline .bk-pipeline-atom.TERMINATE .atom-execute-time,.bk-pipeline .bk-pipeline-atom.TERMINATE .stage-check-icon,.bk-pipeline .bk-pipeline-atom.HEARTBEAT_TIMEOUT .atom-icon,.bk-pipeline .bk-pipeline-atom.HEARTBEAT_TIMEOUT .atom-execute-time,.bk-pipeline .bk-pipeline-atom.HEARTBEAT_TIMEOUT .stage-check-icon,.bk-pipeline .bk-pipeline-atom.QUALITY_CHECK_FAIL .atom-icon,.bk-pipeline .bk-pipeline-atom.QUALITY_CHECK_FAIL .atom-execute-time,.bk-pipeline .bk-pipeline-atom.QUALITY_CHECK_FAIL .stage-check-icon,.bk-pipeline .bk-pipeline-atom.QUEUE_TIMEOUT .atom-icon,.bk-pipeline .bk-pipeline-atom.QUEUE_TIMEOUT .atom-execute-time,.bk-pipeline .bk-pipeline-atom.QUEUE_TIMEOUT .stage-check-icon,.bk-pipeline .bk-pipeline-atom.EXEC_TIMEOUT .atom-icon,.bk-pipeline .bk-pipeline-atom.EXEC_TIMEOUT .atom-execute-time,.bk-pipeline .bk-pipeline-atom.EXEC_TIMEOUT .stage-check-icon{color:#ff5656}.bk-pipeline .bk-pipeline-atom.SUCCEED,.bk-pipeline .bk-pipeline-atom.REVIEW_PROCESSED{border-color:#34d97b}.bk-pipeline .bk-pipeline-atom.SUCCEED:before,.bk-pipeline .bk-pipeline-atom.REVIEW_PROCESSED:before{background-color:#34d97b}.bk-pipeline .bk-pipeline-atom.SUCCEED:after,.bk-pipeline .bk-pipeline-atom.REVIEW_PROCESSED:after{border-color:#34d97b}.bk-pipeline .bk-pipeline-atom.SUCCEED .atom-icon,.bk-pipeline .bk-pipeline-atom.SUCCEED .atom-execute-time,.bk-pipeline .bk-pipeline-atom.SUCCEED .stage-check-icon,.bk-pipeline .bk-pipeline-atom.REVIEW_PROCESSED .atom-icon,.bk-pipeline .bk-pipeline-atom.REVIEW_PROCESSED .atom-execute-time,.bk-pipeline .bk-pipeline-atom.REVIEW_PROCESSED .stage-check-icon{color:#34d97b}.bk-pipeline .bk-pipeline-atom.SUCCEED .stage-check-icon,.bk-pipeline .bk-pipeline-atom.REVIEW_PROCESSED .stage-check-icon{border-color:#34d97b}.bk-pipeline .bk-pipeline-atom.PAUSE{border-color:#ff9801;color:#ff9801}.bk-pipeline .bk-pipeline-atom.PAUSE:before{background-color:#ff9801}.bk-pipeline .bk-pipeline-atom.PAUSE:after{border-color:#ff9801}.bk-pipeline .bk-pipeline-atom.PAUSE .atom-icon,.bk-pipeline .bk-pipeline-atom.PAUSE .atom-execute-time{color:#63656e}.bk-pipeline .bk-pipeline-atom.template-compare-atom{border-color:#ff6e00}.bk-pipeline .bk-pipeline-atom.template-compare-atom:before{background-color:#ff6e00}.bk-pipeline .bk-pipeline-atom.template-compare-atom:after{border-color:#ff6e00}.bk-pipeline .bk-pipeline-atom.template-compare-atom:hover{border-color:#ffb400}.bk-pipeline .bk-pipeline-atom.quality-atom{background-color:rgba(0,0,0,0)}.bk-pipeline .bk-pipeline-atom.quality-atom.SUCCEED{border-color:#34d97b}.bk-pipeline .bk-pipeline-atom.quality-atom.SUCCEED .atom-title{color:#34d97b}.bk-pipeline .bk-pipeline-atom.quality-atom.SUCCEED .atom-title>i{border-color:#34d97b}.bk-pipeline .bk-pipeline-atom.quality-atom.REVIEWING{border-color:#ffb400}.bk-pipeline .bk-pipeline-atom.quality-atom.REVIEWING .atom-title{color:#ffb400}.bk-pipeline .bk-pipeline-atom.quality-atom.REVIEWING .atom-title>i{border-color:#ffb400}.bk-pipeline .bk-pipeline-atom.quality-atom.REVIEWING .atom-title>i:last-child{border-color:rgba(0,0,0,0)}.bk-pipeline .bk-pipeline-atom.quality-atom.FAILED{border-color:#ff5656}.bk-pipeline .bk-pipeline-atom.quality-atom.FAILED .atom-title{color:#ff5656}.bk-pipeline .bk-pipeline-atom.quality-atom.FAILED .atom-title>i{border-top:2px solid #ff5656}',""]);const s=a},8998:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'/*!\n * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.\n *\n * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.\n *\n * A copy of the MIT License is included in this file.\n *\n *\n * Terms of the MIT License:\n * ---------------------------------------------------\n * 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:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * 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.\n */@keyframes rotating{from{transform:rotate(0)}to{transform:rotate(359deg)}}.bk-pipeline .bk-pipeline-atom{cursor:pointer;position:relative;display:flex;flex-direction:row;align-items:center;height:42px;margin:0 0 11px 0;background-color:#fff;border-radius:2px;font-size:14px;transition:all .4s ease-in-out;z-index:2;border:1px solid #c4cdd6}.bk-pipeline .bk-pipeline-atom .active-atom-location-icon{position:absolute;color:#3c96ff;left:-30px}.bk-pipeline .bk-pipeline-atom.trigger-atom:before,.bk-pipeline .bk-pipeline-atom.trigger-atom:after{display:none}.bk-pipeline .bk-pipeline-atom:first-child:before{top:-16px}.bk-pipeline .bk-pipeline-atom:before{content:"";position:absolute;height:14px;width:2px;background:#c4cdd6;top:-12px;left:22px;z-index:1}.bk-pipeline .bk-pipeline-atom:after{content:"";position:absolute;height:4px;width:4px;border:2px solid #c4cdd6;border-radius:50%;background:#fff !important;top:-5px;left:19px;z-index:2}.bk-pipeline .bk-pipeline-atom.is-intercept{border-color:#ffb400}.bk-pipeline .bk-pipeline-atom.is-intercept:hover{border-color:#ffb400}.bk-pipeline .bk-pipeline-atom.is-error{border-color:#ff5656;color:#ff5656}.bk-pipeline .bk-pipeline-atom.is-error:hover .atom-invalid-icon{display:none}.bk-pipeline .bk-pipeline-atom.is-error .atom-invalid-icon{margin:0 12px}.bk-pipeline .bk-pipeline-atom:not(.readonly):hover{border-color:#3c96ff}.bk-pipeline .bk-pipeline-atom:not(.readonly):hover .atom-icon.skip-icon{color:#c4cdd6}.bk-pipeline .bk-pipeline-atom:not(.readonly):hover .atom-icon,.bk-pipeline .bk-pipeline-atom:not(.readonly):hover .atom-name{color:#3c96ff}.bk-pipeline .bk-pipeline-atom:not(.readonly):hover .add-plus-icon.close,.bk-pipeline .bk-pipeline-atom:not(.readonly):hover .copy{cursor:pointer;display:block}.bk-pipeline .bk-pipeline-atom .atom-icon{text-align:center;margin:0 14.5px;font-size:18px;width:18px;color:#63656e;fill:currentColor}.bk-pipeline .bk-pipeline-atom .atom-icon.skip-icon{color:#c4cdd6}.bk-pipeline .bk-pipeline-atom .atom-name span.skip-name{text-decoration:line-through;color:#c4cdd6}.bk-pipeline .bk-pipeline-atom .atom-name span.skip-name:hover{color:#c4cdd6}.bk-pipeline .bk-pipeline-atom .pause-button{margin-right:8px;color:#3c96ff}.bk-pipeline .bk-pipeline-atom .add-plus-icon.close{position:relative;display:block;width:16px;height:16px;border:1px solid #fff;background-color:#c4c6cd;border-radius:50%;transition:all .3s ease;display:none;margin-right:10px;border:none;transform:rotate(45deg)}.bk-pipeline .bk-pipeline-atom .add-plus-icon.close:before,.bk-pipeline .bk-pipeline-atom .add-plus-icon.close:after{content:"";position:absolute;left:7px;top:4px;left:6px;top:3px;height:8px;width:2px;background-color:#fff}.bk-pipeline .bk-pipeline-atom .add-plus-icon.close:after{transform:rotate(90deg)}.bk-pipeline .bk-pipeline-atom .add-plus-icon.close:hover{border-color:#ff5656;background-color:#ff5656}.bk-pipeline .bk-pipeline-atom .add-plus-icon.close:hover:before,.bk-pipeline .bk-pipeline-atom .add-plus-icon.close:hover:after{background-color:#fff}.bk-pipeline .bk-pipeline-atom .add-plus-icon.close:before,.bk-pipeline .bk-pipeline-atom .add-plus-icon.close:after{left:7px;top:4px}.bk-pipeline .bk-pipeline-atom .copy{display:none;margin-right:10px;color:#c4cdd6}.bk-pipeline .bk-pipeline-atom .copy:hover{color:#3c96ff}.bk-pipeline .bk-pipeline-atom>.atom-name{flex:1;color:#63656e;display:inline-block;max-width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:188px;margin-right:2px}.bk-pipeline .bk-pipeline-atom>.atom-name span:hover{color:#3c96ff}.bk-pipeline .bk-pipeline-atom .disabled{cursor:not-allowed;color:#c4cdd6}.bk-pipeline .bk-pipeline-atom .atom-execounter{color:#3c96ff;font-size:12px}.bk-pipeline .bk-pipeline-atom .atom-operate-area{margin:0 8px 0 0;color:#3c96ff;font-size:12px}.bk-pipeline .bk-pipeline-atom .atom-reviewing-tips[disabled]{cursor:not-allowed;color:#c3cdd7}.bk-pipeline .bk-pipeline-atom .atom-review-diasbled-tips{color:#c3cdd7;margin:0 8px 0 2px}.bk-pipeline .bk-pipeline-atom .atom-canskip-checkbox{margin-right:6px}.bk-pipeline .bk-pipeline-atom.quality-atom{display:flex;justify-content:center;border-color:rgba(0,0,0,0);height:24px;background:rgba(0,0,0,0);border-color:rgba(0,0,0,0) !important;font-size:12px}.bk-pipeline .bk-pipeline-atom.quality-atom:before{height:40px;z-index:8}.bk-pipeline .bk-pipeline-atom.quality-atom:after{display:none}.bk-pipeline .bk-pipeline-atom.quality-atom.last-quality-atom:before{height:22px}.bk-pipeline .bk-pipeline-atom.quality-atom .atom-title{display:flex;width:100%;align-items:center;justify-content:center;margin-left:22px}.bk-pipeline .bk-pipeline-atom.quality-atom .atom-title>span{border-radius:12px;font-weight:bold;border:1px solid #c4cdd6;padding:0 12px;margin:0 4px}.bk-pipeline .bk-pipeline-atom.quality-atom .atom-title>i{height:0;flex:1;border-top:2px dashed #c4cdd6}.bk-pipeline .bk-pipeline-atom.quality-atom .handler-list{position:absolute;right:0}.bk-pipeline .bk-pipeline-atom.quality-atom .handler-list span{color:#3c96ff;font-size:12px}.bk-pipeline .bk-pipeline-atom.quality-atom .handler-list span:first-child{margin-right:5px}.bk-pipeline .bk-pipeline-atom.quality-atom .executing-job{position:absolute;top:6px;right:42px}.bk-pipeline .bk-pipeline-atom.quality-atom .executing-job:before{display:inline-block;animation:rotating infinite .6s ease-in-out}.bk-pipeline .bk-pipeline-atom.quality-atom .disabled-review span{color:#c4cdd6;cursor:default}.bk-pipeline .bk-pipeline-atom.readonly{background-color:#fff}.bk-pipeline .bk-pipeline-atom.readonly .atom-name:hover span{color:#63656e}.bk-pipeline .bk-pipeline-atom.readonly .atom-name:hover .skip-name{text-decoration:line-through;color:#c4cdd6}.bk-pipeline .bk-pipeline-atom.readonly.quality-prev-atom:before{height:24px;top:-23px}',""]);const s=a},3300:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'/*!\n * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.\n *\n * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.\n *\n * A copy of the MIT License is included in this file.\n *\n *\n * Terms of the MIT License:\n * ---------------------------------------------------\n * 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:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * 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.\n */@keyframes rotating{from{transform:rotate(0)}to{transform:rotate(359deg)}}.container-atom-list{position:relative;z-index:3}.container-atom-list .sortable-ghost-atom{opacity:.5}.container-atom-list .sortable-chosen-atom{transform:scale(1)}.container-atom-list .add-atom-entry{position:absolute;bottom:-10px;left:111px;background-color:#fff;cursor:pointer;z-index:3}.container-atom-list .add-atom-entry .add-plus-icon{position:relative;display:block;width:18px;height:18px;border:1px solid #c4cdd6;background-color:#fff;border-radius:50%;transition:all .3s ease}.container-atom-list .add-atom-entry .add-plus-icon:before,.container-atom-list .add-atom-entry .add-plus-icon:after{content:"";position:absolute;left:8px;top:5px;left:7px;top:4px;height:8px;width:2px;background-color:#c4cdd6}.container-atom-list .add-atom-entry .add-plus-icon:after{transform:rotate(90deg)}.container-atom-list .add-atom-entry .add-plus-icon:hover{border-color:#3c96ff;background-color:#3c96ff}.container-atom-list .add-atom-entry .add-plus-icon:hover:before,.container-atom-list .add-atom-entry .add-plus-icon:hover:after{background-color:#fff}.container-atom-list .add-atom-entry.block-add-entry{display:flex;flex-direction:row;align-items:center;height:42px;margin:0 0 11px 0;background-color:#fff;border-radius:2px;font-size:14px;transition:all .4s ease-in-out;z-index:2;position:static;padding-right:12px;border-style:dashed;color:#ff5656;border-color:#ff5656;border-width:1px}.container-atom-list .add-atom-entry.block-add-entry .add-atom-label{flex:1;color:#dde4eb}.container-atom-list .add-atom-entry.block-add-entry .add-plus-icon{margin:12px 13px}.container-atom-list .add-atom-entry.block-add-entry:before,.container-atom-list .add-atom-entry.block-add-entry:after{display:none}.container-atom-list .add-atom-entry:hover{border-color:#3c96ff;color:#3c96ff}.container-atom-list .post-action-arrow{position:relativecd;display:flex;align-items:center;justify-content:center;position:absolute;height:14px;width:14px;border:1px solid #979ba5;color:#979ba5;border-radius:50%;background:#fff !important;top:-7px;left:17px;z-index:3;font-weight:bold}.container-atom-list .post-action-arrow .toggle-post-action-icon{display:block;transition:all .5s ease}.container-atom-list .post-action-arrow.post-action-arrow-show .toggle-post-action-icon{transform:rotate(180deg)}.container-atom-list .post-action-arrow::after{content:"";position:absolute;width:2px;height:6px;background-color:#979ba5;left:5px;top:-6px}.container-atom-list .post-action-arrow.FAILED{border-color:#ff5656;color:#ff5656}.container-atom-list .post-action-arrow.FAILED::after{background-color:#ff5656}.container-atom-list .post-action-arrow.CANCELED{border-color:#ffb400;color:#ffb400}.container-atom-list .post-action-arrow.CANCELED::after{background-color:#ffb400}.container-atom-list .post-action-arrow.SUCCEED{border-color:#34d97b;color:#34d97b}.container-atom-list .post-action-arrow.SUCCEED::after{background-color:#34d97b}.container-atom-list .post-action-arrow.RUNNING{border-color:#3c96ff;color:#3c96ff}.container-atom-list .post-action-arrow.RUNNING::after{background-color:#3c96ff}',""]);const s=a},6096:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'/*!\n * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.\n *\n * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.\n *\n * A copy of the MIT License is included in this file.\n *\n *\n * Terms of the MIT License:\n * ---------------------------------------------------\n * 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:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * 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.\n */@keyframes rotating{from{transform:rotate(0)}to{transform:rotate(359deg)}}.devops-stage-container .container-title{display:flex;height:42px;background:#33333f;cursor:pointer;color:#fff;font-size:14px;align-items:center;position:relative;margin:0 0 16px 0;z-index:3}.devops-stage-container .container-title>.container-name{display:inline-block;max-width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;padding:0 6px}.devops-stage-container .container-title .atom-canskip-checkbox{margin-right:6px}.devops-stage-container .container-title .atom-canskip-checkbox.is-disabled .bk-checkbox{background-color:rgba(0,0,0,0);border-color:#979ba4}.devops-stage-container .container-title input[type=checkbox]{border-radius:3px}.devops-stage-container .container-title .matrix-flag-icon{position:absolute;top:0px;font-size:16px}.devops-stage-container .container-title .fold-atom-icon{position:absolute;background:#fff;border-radius:50%;bottom:-10px;left:44%;transition:all .3s ease}.devops-stage-container .container-title .fold-atom-icon.open{transform:rotate(-180deg)}.devops-stage-container .container-title .fold-atom-icon.readonly{color:#63656e}.devops-stage-container .container-title .copyJob{display:none;margin-right:10px;color:#c4cdd6;cursor:pointer}.devops-stage-container .container-title .copyJob:hover{color:#3c96ff}.devops-stage-container .container-title .close{position:relative;display:block;width:16px;height:16px;border:1px solid #2e2e3a;background-color:#c4c6cd;border-radius:50%;transition:all .3s ease;border:none;display:none;margin-right:10px;transform:rotate(45deg);cursor:pointer}.devops-stage-container .container-title .close:before,.devops-stage-container .container-title .close:after{content:"";position:absolute;left:7px;top:4px;left:6px;top:3px;height:8px;width:2px;background-color:#2e2e3a}.devops-stage-container .container-title .close:after{transform:rotate(90deg)}.devops-stage-container .container-title .close:hover{border-color:#ff5656;background-color:#ff5656}.devops-stage-container .container-title .close:hover:before,.devops-stage-container .container-title .close:hover:after{background-color:#fff}.devops-stage-container .container-title .close:before,.devops-stage-container .container-title .close:after{left:7px;top:4px}.devops-stage-container .container-title .debug-btn{position:absolute;height:100%;right:0}.devops-stage-container .container-title .container-locate-icon{position:absolute;left:-30px;top:13px;color:#3c96ff}.devops-stage-container .container-title:hover .copyJob,.devops-stage-container .container-title:hover .close{display:block}.devops-stage-container .container-title:hover .hover-hide{display:none}',""]);const s=a},6399:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'/*!\n * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.\n *\n * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.\n *\n * A copy of the MIT License is included in this file.\n *\n *\n * Terms of the MIT License:\n * ---------------------------------------------------\n * 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:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * 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.\n */@keyframes rotating{from{transform:rotate(0)}to{transform:rotate(359deg)}}.bk-pipeline-matrix-group{border:1px solid #b5c0d5;padding:10px;background:#fff}.bk-pipeline-matrix-group .bk-pipeline-matrix-group-header{display:flex;align-items:center;cursor:pointer;justify-content:space-between;height:20px}.bk-pipeline-matrix-group .bk-pipeline-matrix-group-header .matrix-name{display:flex;align-items:center;font-size:14px;color:#222;min-width:0}.bk-pipeline-matrix-group .bk-pipeline-matrix-group-header .matrix-name .matrix-fold-icon{display:block;margin-right:10px;transition:all .3s ease;flex-shrink:0}.bk-pipeline-matrix-group .bk-pipeline-matrix-group-header .matrix-name .matrix-fold-icon.open{transform:rotate(-180deg)}.bk-pipeline-matrix-group .bk-pipeline-matrix-group-header .matrix-name>span{display:inline-block;max-width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bk-pipeline-matrix-group .bk-pipeline-matrix-group-header .matrix-status{color:#3c96ff;display:flex;align-items:center}.bk-pipeline-matrix-group .bk-pipeline-matrix-group-header .matrix-status .status-desc{font-size:12px;display:inline-block;max-width:110px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bk-pipeline-matrix-group .matrix-body{margin-top:12px}.bk-pipeline-matrix-group .matrix-body>div{margin-bottom:34px}',""]);const s=a},4944:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'/*!\n * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.\n *\n * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.\n *\n * A copy of the MIT License is included in this file.\n *\n *\n * Terms of the MIT License:\n * ---------------------------------------------------\n * 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:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * 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.\n */@keyframes rotating{from{transform:rotate(0)}to{transform:rotate(359deg)}}.pipeline-drag{cursor:grab,default}.pipeline-stage{position:relative;width:280px;border-radius:2px;padding:0;background:#f5f5f5;margin:0 80px 0 0}.pipeline-stage .pipeline-stage-entry{position:relative;cursor:pointer;display:flex;width:100%;height:50px;align-items:center;min-width:0;font-size:14px;background-color:#eff5ff;border:1px solid #d4e8ff;color:#3c96ff}.pipeline-stage .pipeline-stage-entry:hover{border-color:#1a6df3;background-color:#d1e2fd}.pipeline-stage .pipeline-stage-entry .check-in-icon,.pipeline-stage .pipeline-stage-entry .check-out-icon{position:absolute;left:-14px;top:11px}.pipeline-stage .pipeline-stage-entry .check-in-icon.check-out-icon,.pipeline-stage .pipeline-stage-entry .check-out-icon.check-out-icon{left:auto;right:-14px}.pipeline-stage .pipeline-stage-entry .stage-entry-name{flex:1;display:flex;align-items:center;justify-content:center;margin:0 80px;overflow:hidden}.pipeline-stage .pipeline-stage-entry .stage-entry-name .stage-title-name{display:inline-block;max-width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-left:6px}.pipeline-stage .pipeline-stage-entry .stage-single-retry{cursor:pointer;position:absolute;right:6%;color:#3c96ff}.pipeline-stage .pipeline-stage-entry .stage-entry-error-icon,.pipeline-stage .pipeline-stage-entry .check-total-stage{position:absolute;right:27px}.pipeline-stage .pipeline-stage-entry .stage-entry-error-icon.stage-entry-error-icon,.pipeline-stage .pipeline-stage-entry .check-total-stage.stage-entry-error-icon{top:16px;right:8px;color:#ff5656}.pipeline-stage .pipeline-stage-entry .stage-entry-btns{position:absolute;right:0;top:16px;display:none;width:80px;align-items:center;justify-content:flex-end;color:#fff;fill:#fff;z-index:2}.pipeline-stage .pipeline-stage-entry .stage-entry-btns .copy-stage:hover{color:#3c96ff}.pipeline-stage .pipeline-stage-entry .stage-entry-btns .close{position:relative;display:block;width:16px;height:16px;border:1px solid #2e2e3a;background-color:#fff;border-radius:50%;transition:all .3s ease;border:none;margin:0 10px 0 8px;transform:rotate(45deg);cursor:pointer}.pipeline-stage .pipeline-stage-entry .stage-entry-btns .close:before,.pipeline-stage .pipeline-stage-entry .stage-entry-btns .close:after{content:"";position:absolute;left:7px;top:4px;left:6px;top:3px;height:8px;width:2px;background-color:#2e2e3a}.pipeline-stage .pipeline-stage-entry .stage-entry-btns .close:after{transform:rotate(90deg)}.pipeline-stage .pipeline-stage-entry .stage-entry-btns .close:hover{border-color:#ff5656;background-color:#ff5656}.pipeline-stage .pipeline-stage-entry .stage-entry-btns .close:hover:before,.pipeline-stage .pipeline-stage-entry .stage-entry-btns .close:hover:after{background-color:#fff}.pipeline-stage .pipeline-stage-entry .stage-entry-btns .close:before,.pipeline-stage .pipeline-stage-entry .stage-entry-btns .close:after{left:7px;top:4px}.pipeline-stage.editable:not(.readonly) .pipeline-stage-entry:hover{color:#000;border-color:#1a6df3;background-color:#d1e2fd}.pipeline-stage.editable .pipeline-stage-entry:hover .stage-entry-btns{display:flex}.pipeline-stage.editable .pipeline-stage-entry:hover .stage-entry-error-icon{display:none}.pipeline-stage.readonly.SKIP .pipeline-stage-entry{color:#c3cdd7;fill:#c3cdd7}.pipeline-stage.readonly.RUNNING .pipeline-stage-entry{background-color:#eff5ff;border-color:#d4e8ff;color:#3c96ff}.pipeline-stage.readonly.REVIEWING .pipeline-stage-entry{background-color:#f3f3f3;border-color:#d0d8ea;color:#000}.pipeline-stage.readonly.FAILED .pipeline-stage-entry{border-color:#ffd4d4;background-color:#fff9f9;color:#000}.pipeline-stage.readonly.SUCCEED .pipeline-stage-entry{background-color:#f3fff6;border-color:#bbefc9;color:#000}.pipeline-stage.readonly .pipeline-stage-entry{background-color:#f3f3f3;border-color:#d0d8ea;color:#000}.pipeline-stage.readonly .pipeline-stage-entry .skip-icon{vertical-align:middle}.pipeline-stage .add-connector{stroke-dasharray:4,4;top:7px;left:10px}.pipeline-stage .append-stage{position:absolute;top:16px;right:-44px;z-index:3}.pipeline-stage .append-stage .add-plus-icon{box-shadow:0px 2px 4px 0px rgba(60,150,255,.2)}.pipeline-stage .append-stage .line-add{top:-46px;left:-16px}.pipeline-stage .append-stage .add-plus-connector{position:absolute;width:40px;height:2px;left:-26px;top:8px;background-color:#3c96ff}.pipeline-stage .add-menu{position:absolute;top:16px;left:-53px;cursor:pointer;z-index:3}.pipeline-stage .add-menu .add-plus-icon{box-shadow:0px 2px 4px 0px rgba(60,150,255,.2)}.pipeline-stage .add-menu .minus-icon{z-index:4}.pipeline-stage .add-menu .line-add{top:-46px;left:-16px}.pipeline-stage .add-menu .parallel-add{left:50px}.pipeline-stage:first-child .stage-connector{display:none}.pipeline-stage.is-final-stage .stage-connector{width:80px}.pipeline-stage .stage-connector{position:absolute;width:66px;height:2px;left:-80px;top:24px;color:#3c96ff;background-color:#3c96ff}.pipeline-stage .stage-connector:before{content:"";width:8px;height:8px;position:absolute;left:-4px;top:-3px;background-color:#3c96ff;border-radius:50%}.pipeline-stage .stage-connector .connector-angle{position:absolute;right:-3px;top:-6px}.pipeline-stage .insert-stage{position:absolute;display:block;width:160px;background-color:#fff;border:1px solid #dcdee5}.pipeline-stage .insert-stage .click-item{padding:0 15px;font-size:12px;line-height:32px}.pipeline-stage .insert-stage .click-item:hover,.pipeline-stage .insert-stage .click-item :hover{color:#3c96ff;background-color:#eaf3ff}.pipeline-stage .insert-stage .disabled-item{cursor:not-allowed;color:#c4cdd6}.pipeline-stage .insert-stage .disabled-item:hover,.pipeline-stage .insert-stage .disabled-item :hover{color:#c4cdd6;background-color:#fff}.stage-retry-dialog .bk-form-radio{display:block;margin-top:15px}.stage-retry-dialog .bk-form-radio .bk-radio-text{font-size:14px}',""]);const s=a},7849:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'/*!\n * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.\n *\n * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.\n *\n * A copy of the MIT License is included in this file.\n *\n *\n * Terms of the MIT License:\n * ---------------------------------------------------\n * 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:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * 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.\n */@keyframes rotating{from{transform:rotate(0)}to{transform:rotate(359deg)}}.stage-check-icon{border-radius:100px;border:1px solid #d0d8ea;display:flex;align-items:center;background:#fff;font-size:12px;z-index:3;color:#63656e}.stage-check-icon.reviewing{color:#3c96ff;border-color:#3c96ff}.stage-check-icon.quality-check{color:#34d97b;border-color:#34d97b}.stage-check-icon.quality-check-error,.stage-check-icon.review-error{color:#ff5656;border-color:#ff5656}.stage-check-icon .stage-check-txt{padding-right:10px}',""]);const s=a},2718:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'/*!\n * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.\n *\n * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.\n *\n * A copy of the MIT License is included in this file.\n *\n *\n * Terms of the MIT License:\n * ---------------------------------------------------\n * 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:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * 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.\n */@keyframes rotating{from{transform:rotate(0)}to{transform:rotate(359deg)}}.devops-stage-container{text-align:left;margin:16px 20px 24px 20px;position:relative}.devops-stage-container:not(.last-stage-container):after{content:"";width:6px;height:6px;position:absolute;right:-3px;top:19px;border-radius:50%}.devops-stage-container:not(.last-stage-container):after:not(.readonly){background:#3c96ff}.devops-stage-container .container-connect-triangle{position:absolute;color:#3c96ff;left:-9px;top:15.5px;z-index:2}.devops-stage-container .connect-line{position:absolute;top:1px;stroke:#3c96ff;stroke-width:1;fill:none;z-index:0}.devops-stage-container .connect-line.left{left:-54px}.devops-stage-container .connect-line.right{right:-46px}.devops-stage-container .connect-line.first-connect-line{height:76px;width:58px;top:-43px}.devops-stage-container .connect-line.first-connect-line.left{left:-63px}.devops-stage-container .connect-line.first-connect-line.right{left:auto;right:-55px}',""]);const s=a},6190:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,'/*!\n * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.\n *\n * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.\n *\n * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.\n *\n * A copy of the MIT License is included in this file.\n *\n *\n * Terms of the MIT License:\n * ---------------------------------------------------\n * 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:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * 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.\n */@keyframes rotating{from{transform:rotate(0)}to{transform:rotate(359deg)}}.stage-status{position:relative;text-align:center;overflow:hidden;font-size:14px;width:42px;height:42px;box-sizing:border-box}.stage-status>span{position:absolute;width:100%;height:100%;display:flex;align-items:center;justify-content:center;left:0;top:0;transition:all .3s cubic-bezier(1, 0.5, 0.8, 1)}.stage-status.matrix{width:20px;height:20px}.stage-status .status-logo{position:absolute;left:15px;top:15px}.stage-status .slide-top-enter,.stage-status .slide-top-leave-to{transform:translateY(42px)}.stage-status .slide-down-enter,.stage-status .slide-down-leave-to{transform:translateY(-42px)}.stage-status .slide-left-enter,.stage-status .slide-left-leave-to{transform:translateX(42px)}.stage-status .slide-right-enter,.stage-status .slide-right-leave-to{transform:translateX(-42px)}.stage-status.readonly{font-size:12px;font-weight:normal;background-color:rgba(0,0,0,0)}.stage-status.readonly.container{color:#fff}',""]);const s=a},812:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(8081),o=n.n(i),r=n(3645),a=n.n(r)()(o());a.push([t.id,".bk-pipeline{display:flex;padding-right:120px;width:fit-content;position:relative;align-items:flex-start}.bk-pipeline ul,.bk-pipeline li{margin:0;padding:0}.list-item{transition:transform .2s ease-out}.list-enter,.list-leave-to{opacity:0;transform:translateY(36px) scale(0, 1)}.list-leave-active{position:absolute !important}",""]);const s=a},3645:t=>{"use strict";t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var n="",i=void 0!==e[5];return e[4]&&(n+="@supports (".concat(e[4],") {")),e[2]&&(n+="@media ".concat(e[2]," {")),i&&(n+="@layer".concat(e[5].length>0?" ".concat(e[5]):""," {")),n+=t(e),i&&(n+="}"),e[2]&&(n+="}"),e[4]&&(n+="}"),n})).join("")},e.i=function(t,n,i,o,r){"string"==typeof t&&(t=[[null,t,void 0]]);var a={};if(i)for(var s=0;s0?" ".concat(p[5]):""," {").concat(p[1],"}")),p[5]=r),n&&(p[2]?(p[1]="@media ".concat(p[2]," {").concat(p[1],"}"),p[2]=n):p[2]=n),o&&(p[4]?(p[1]="@supports (".concat(p[4],") {").concat(p[1],"}"),p[4]=o):p[4]="".concat(o)),e.push(p))}},e}},3626:t=>{"use strict";t.exports=function(t,e){return e||(e={}),t?(t=String(t.__esModule?t.default:t),/^['"].*['"]$/.test(t)&&(t=t.slice(1,-1)),e.hash&&(t+=e.hash),/["'() \t\n]|(%20)/.test(t)||e.needQuotes?'"'.concat(t.replace(/"/g,'\\"').replace(/\n/g,"\\n"),'"'):t):t}},8081:t=>{"use strict";t.exports=function(t){return t[1]}},1474:(t,e,n)=>{"use strict";function i(t){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i(t)}function o(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function r(){return r=Object.assign||function(t){for(var e=1;e=0||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n])}return o}function c(t){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(t)}n.r(e),n.d(e,{MultiDrag:()=>ge,Sortable:()=>Ht,Swap:()=>ae,default:()=>xe});var l=c(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i),p=c(/Edge/i),d=c(/firefox/i),u=c(/safari/i)&&!c(/chrome/i)&&!c(/android/i),f=c(/iP(ad|od|hone)/i),m=c(/chrome/i)&&c(/android/i),h={capture:!1,passive:!1};function b(t,e,n){t.addEventListener(e,n,!l&&h)}function g(t,e,n){t.removeEventListener(e,n,!l&&h)}function v(t,e){if(e){if(">"===e[0]&&(e=e.substring(1)),t)try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return!1}return!1}}function y(t){return t.host&&t!==document&&t.host.nodeType?t.host:t.parentNode}function x(t,e,n,i){if(t){n=n||document;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&v(t,e):v(t,e))||i&&t===n)return t;if(t===n)break}while(t=y(t))}return null}var w,k=/\s+/g;function E(t,e,n){if(t&&e)if(t.classList)t.classList[n?"add":"remove"](e);else{var i=(" "+t.className+" ").replace(k," ").replace(" "+e+" "," ");t.className=(i+(n?" "+e:"")).replace(k," ")}}function T(t,e,n){var i=t&&t.style;if(i){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];e in i||-1!==e.indexOf("webkit")||(e="-webkit-"+e),i[e]=n+("string"==typeof n?"":"px")}}function I(t,e){var n="";if("string"==typeof t)n=t;else do{var i=T(t,"transform");i&&"none"!==i&&(n=i+" "+n)}while(!e&&(t=t.parentNode));var o=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return o&&new o(n)}function S(t,e,n){if(t){var i=t.getElementsByTagName(e),o=0,r=i.length;if(n)for(;o=r:o<=r))return i;if(i===C())break;i=R(i,!1)}return!1}function _(t,e,n){for(var i=0,o=0,r=t.children;o2&&void 0!==arguments[2]?arguments[2]:{},i=n.evt,o=s(n,["evt"]);Y.pluginEvent.bind(Ht)(t,e,a({dragEl:X,parentEl:q,ghostEl:K,rootEl:Z,nextEl:Q,lastDownEl:J,cloneEl:tt,cloneHidden:et,dragStarted:mt,putSortable:st,activeSortable:Ht.active,originalEvent:i,oldIndex:nt,oldDraggableIndex:ot,newIndex:it,newDraggableIndex:rt,hideGhostForTarget:Rt,unhideGhostForTarget:Dt,cloneNowHidden:function(){et=!0},cloneNowShown:function(){et=!1},dispatchSortableEvent:function(t){G({sortable:e,name:t,originalEvent:i})}},o))};function G(t){W(a({putSortable:st,cloneEl:tt,targetEl:X,rootEl:Z,oldIndex:nt,oldDraggableIndex:ot,newIndex:it,newDraggableIndex:rt},t))}var X,q,K,Z,Q,J,tt,et,nt,it,ot,rt,at,st,ct,lt,pt,dt,ut,ft,mt,ht,bt,gt,vt,yt=!1,xt=!1,wt=[],kt=!1,Et=!1,Tt=[],It=!1,St=[],Ct="undefined"!=typeof document,Ot=f,At=p||l?"cssFloat":"float",_t=Ct&&!m&&!f&&"draggable"in document.createElement("div"),Lt=function(){if(Ct){if(l)return!1;var t=document.createElement("x");return t.style.cssText="pointer-events:auto","auto"===t.style.pointerEvents}}(),Mt=function(t,e){var n=T(t),i=parseInt(n.width)-parseInt(n.paddingLeft)-parseInt(n.paddingRight)-parseInt(n.borderLeftWidth)-parseInt(n.borderRightWidth),o=_(t,0,e),r=_(t,1,e),a=o&&T(o),s=r&&T(r),c=a&&parseInt(a.marginLeft)+parseInt(a.marginRight)+O(o).width,l=s&&parseInt(s.marginLeft)+parseInt(s.marginRight)+O(r).width;if("flex"===n.display)return"column"===n.flexDirection||"column-reverse"===n.flexDirection?"vertical":"horizontal";if("grid"===n.display)return n.gridTemplateColumns.split(" ").length<=1?"vertical":"horizontal";if(o&&a.float&&"none"!==a.float){var p="left"===a.float?"left":"right";return!r||"both"!==s.clear&&s.clear!==p?"horizontal":"vertical"}return o&&("block"===a.display||"flex"===a.display||"table"===a.display||"grid"===a.display||c>=i&&"none"===n[At]||r&&"none"===n[At]&&c+l>i)?"vertical":"horizontal"},Nt=function(t){function e(t,n){return function(i,o,r,a){var s=i.options.group.name&&o.options.group.name&&i.options.group.name===o.options.group.name;if(null==t&&(n||s))return!0;if(null==t||!1===t)return!1;if(n&&"clone"===t)return t;if("function"==typeof t)return e(t(i,o,r,a),n)(i,o,r,a);var c=(n?i:o).options.group.name;return!0===t||"string"==typeof t&&t===c||t.join&&t.indexOf(c)>-1}}var n={},o=t.group;o&&"object"==i(o)||(o={name:o}),n.name=o.name,n.checkPull=e(o.pull,!0),n.checkPut=e(o.put),n.revertClone=o.revertClone,t.group=n},Rt=function(){!Lt&&K&&T(K,"display","none")},Dt=function(){!Lt&&K&&T(K,"display","")};Ct&&document.addEventListener("click",(function(t){if(xt)return t.preventDefault(),t.stopPropagation&&t.stopPropagation(),t.stopImmediatePropagation&&t.stopImmediatePropagation(),xt=!1,!1}),!0);var zt=function(t){if(X){t=t.touches?t.touches[0]:t;var e=(o=t.clientX,r=t.clientY,wt.some((function(t){if(!L(t)){var e=O(t),n=t[B].options.emptyInsertThreshold,i=o>=e.left-n&&o<=e.right+n,s=r>=e.top-n&&r<=e.bottom+n;return n&&i&&s?a=t:void 0}})),a);if(e){var n={};for(var i in t)t.hasOwnProperty(i)&&(n[i]=t[i]);n.target=n.rootEl=e,n.preventDefault=void 0,n.stopPropagation=void 0,e[B]._onDragOver(n)}}var o,r,a},Pt=function(t){X&&X.parentNode[B]._isOutsideThisEl(t.target)};function Ht(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=r({},e),t[B]=this;var n,i,o={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Mt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ht.supportPointer&&"PointerEvent"in window,emptyInsertThreshold:5};for(var s in Y.initializePlugins(this,t,o),o)!(s in e)&&(e[s]=o[s]);for(var c in Nt(e),this)"_"===c.charAt(0)&&"function"==typeof this[c]&&(this[c]=this[c].bind(this));this.nativeDraggable=!e.forceFallback&&_t,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?b(t,"pointerdown",this._onTapStart):(b(t,"mousedown",this._onTapStart),b(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(b(t,"dragover",this),b(t,"dragenter",this)),wt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),r(this,(i=[],{captureAnimationState:function(){i=[],this.options.animation&&[].slice.call(this.el.children).forEach((function(t){if("none"!==T(t,"display")&&t!==Ht.ghost){i.push({target:t,rect:O(t)});var e=a({},i[i.length-1].rect);if(t.thisAnimationDuration){var n=I(t,!0);n&&(e.top-=n.f,e.left-=n.e)}t.fromRect=e}}))},addAnimationState:function(t){i.push(t)},removeAnimationState:function(t){i.splice(function(t,e){for(var n in t)if(t.hasOwnProperty(n))for(var i in e)if(e.hasOwnProperty(i)&&e[i]===t[n][i])return Number(n);return-1}(i,{target:t}),1)},animateAll:function(t){var e=this;if(!this.options.animation)return clearTimeout(n),void("function"==typeof t&&t());var o=!1,r=0;i.forEach((function(t){var n=0,i=t.target,a=i.fromRect,s=O(i),c=i.prevFromRect,l=i.prevToRect,p=t.rect,d=I(i,!0);d&&(s.top-=d.f,s.left-=d.e),i.toRect=s,i.thisAnimationDuration&&D(c,s)&&!D(a,s)&&(p.top-s.top)/(p.left-s.left)==(a.top-s.top)/(a.left-s.left)&&(n=function(t,e,n,i){return Math.sqrt(Math.pow(e.top-t.top,2)+Math.pow(e.left-t.left,2))/Math.sqrt(Math.pow(e.top-n.top,2)+Math.pow(e.left-n.left,2))*i.animation}(p,c,l,e.options)),D(s,a)||(i.prevFromRect=a,i.prevToRect=s,n||(n=e.options.animation),e.animate(i,p,s,n)),n&&(o=!0,r=Math.max(r,n),clearTimeout(i.animationResetTimer),i.animationResetTimer=setTimeout((function(){i.animationTime=0,i.prevFromRect=null,i.fromRect=null,i.prevToRect=null,i.thisAnimationDuration=null}),n),i.thisAnimationDuration=n)})),clearTimeout(n),o?n=setTimeout((function(){"function"==typeof t&&t()}),r):"function"==typeof t&&t(),i=[]},animate:function(t,e,n,i){if(i){T(t,"transition",""),T(t,"transform","");var o=I(this.el),r=o&&o.a,a=o&&o.d,s=(e.left-n.left)/(r||1),c=(e.top-n.top)/(a||1);t.animatingX=!!s,t.animatingY=!!c,T(t,"transform","translate3d("+s+"px,"+c+"px,0)"),function(t){t.offsetWidth}(t),T(t,"transition","transform "+i+"ms"+(this.options.easing?" "+this.options.easing:"")),T(t,"transform","translate3d(0,0,0)"),"number"==typeof t.animated&&clearTimeout(t.animated),t.animated=setTimeout((function(){T(t,"transition",""),T(t,"transform",""),t.animated=!1,t.animatingX=!1,t.animatingY=!1}),i)}}}))}function Ft(t,e,n,i,o,r,a,s){var c,d,u=t[B],f=u.options.onMove;return!window.CustomEvent||l||p?(c=document.createEvent("Event")).initEvent("move",!0,!0):c=new CustomEvent("move",{bubbles:!0,cancelable:!0}),c.to=e,c.from=t,c.dragged=n,c.draggedRect=i,c.related=o||e,c.relatedRect=r||O(e),c.willInsertAfter=s,c.originalEvent=a,t.dispatchEvent(c),f&&(d=f.call(u,c,a)),d}function jt(t){t.draggable=!1}function Bt(){It=!1}function Ut(t){for(var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,i=0;n--;)i+=e.charCodeAt(n);return i.toString(36)}function Vt(t){return setTimeout(t,0)}function Yt(t){return clearTimeout(t)}Ht.prototype={constructor:Ht,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(ht=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,X):this.options.direction},_onTapStart:function(t){if(t.cancelable){var e=this,n=this.el,i=this.options,o=i.preventOnFilter,r=t.type,a=t.touches&&t.touches[0]||t.pointerType&&"touch"===t.pointerType&&t,s=(a||t).target,c=t.target.shadowRoot&&(t.path&&t.path[0]||t.composedPath&&t.composedPath()[0])||s,l=i.filter;if(function(t){St.length=0;for(var e=t.getElementsByTagName("input"),n=e.length;n--;){var i=e[n];i.checked&&St.push(i)}}(n),!X&&!(/mousedown|pointerdown/.test(r)&&0!==t.button||i.disabled||c.isContentEditable||(s=x(s,i.draggable,n,!1))&&s.animated||J===s)){if(nt=M(s),ot=M(s,i.draggable),"function"==typeof l){if(l.call(this,t,s,this))return G({sortable:e,rootEl:c,name:"filter",targetEl:s,toEl:n,fromEl:n}),$("filter",e,{evt:t}),void(o&&t.cancelable&&t.preventDefault())}else if(l&&(l=l.split(",").some((function(i){if(i=x(c,i.trim(),n,!1))return G({sortable:e,rootEl:i,name:"filter",targetEl:s,fromEl:n,toEl:n}),$("filter",e,{evt:t}),!0}))))return void(o&&t.cancelable&&t.preventDefault());i.handle&&!x(c,i.handle,n,!1)||this._prepareDragStart(t,a,s)}}},_prepareDragStart:function(t,e,n){var i,o=this,r=o.el,a=o.options,s=r.ownerDocument;if(n&&!X&&n.parentNode===r){var c=O(n);if(Z=r,q=(X=n).parentNode,Q=X.nextSibling,J=n,at=a.group,Ht.dragged=X,ct={target:X,clientX:(e||t).clientX,clientY:(e||t).clientY},ut=ct.clientX-c.left,ft=ct.clientY-c.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,X.style["will-change"]="all",i=function(){$("delayEnded",o,{evt:t}),Ht.eventCanceled?o._onDrop():(o._disableDelayedDragEvents(),!d&&o.nativeDraggable&&(X.draggable=!0),o._triggerDragStart(t,e),G({sortable:o,name:"choose",originalEvent:t}),E(X,a.chosenClass,!0))},a.ignore.split(",").forEach((function(t){S(X,t.trim(),jt)})),b(s,"dragover",zt),b(s,"mousemove",zt),b(s,"touchmove",zt),b(s,"mouseup",o._onDrop),b(s,"touchend",o._onDrop),b(s,"touchcancel",o._onDrop),d&&this.nativeDraggable&&(this.options.touchStartThreshold=4,X.draggable=!0),$("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(p||l))i();else{if(Ht.eventCanceled)return void this._onDrop();b(s,"mouseup",o._disableDelayedDrag),b(s,"touchend",o._disableDelayedDrag),b(s,"touchcancel",o._disableDelayedDrag),b(s,"mousemove",o._delayedDragTouchMoveHandler),b(s,"touchmove",o._delayedDragTouchMoveHandler),a.supportPointer&&b(s,"pointermove",o._delayedDragTouchMoveHandler),o._dragStartTimer=setTimeout(i,a.delay)}}},_delayedDragTouchMoveHandler:function(t){var e=t.touches?t.touches[0]:t;Math.max(Math.abs(e.clientX-this._lastX),Math.abs(e.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){X&&jt(X),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;g(t,"mouseup",this._disableDelayedDrag),g(t,"touchend",this._disableDelayedDrag),g(t,"touchcancel",this._disableDelayedDrag),g(t,"mousemove",this._delayedDragTouchMoveHandler),g(t,"touchmove",this._delayedDragTouchMoveHandler),g(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?b(document,"pointermove",this._onTouchMove):b(document,e?"touchmove":"mousemove",this._onTouchMove):(b(X,"dragend",this),b(Z,"dragstart",this._onDragStart));try{document.selection?Vt((function(){document.selection.empty()})):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){if(yt=!1,Z&&X){$("dragStarted",this,{evt:e}),this.nativeDraggable&&b(document,"dragover",Pt);var n=this.options;!t&&E(X,n.dragClass,!1),E(X,n.ghostClass,!0),Ht.active=this,t&&this._appendGhost(),G({sortable:this,name:"start",originalEvent:e})}else this._nulling()},_emulateDragOver:function(){if(lt){this._lastX=lt.clientX,this._lastY=lt.clientY,Rt();for(var t=document.elementFromPoint(lt.clientX,lt.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(lt.clientX,lt.clientY))!==e;)e=t;if(X.parentNode[B]._isOutsideThisEl(t),e)do{if(e[B]&&e[B]._onDragOver({clientX:lt.clientX,clientY:lt.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break;t=e}while(e=e.parentNode);Dt()}},_onTouchMove:function(t){if(ct){var e=this.options,n=e.fallbackTolerance,i=e.fallbackOffset,o=t.touches?t.touches[0]:t,r=K&&I(K,!0),a=K&&r&&r.a,s=K&&r&&r.d,c=Ot&&vt&&N(vt),l=(o.clientX-ct.clientX+i.x)/(a||1)+(c?c[0]-Tt[0]:0)/(a||1),p=(o.clientY-ct.clientY+i.y)/(s||1)+(c?c[1]-Tt[1]:0)/(s||1);if(!Ht.active&&!yt){if(n&&Math.max(Math.abs(o.clientX-this._lastX),Math.abs(o.clientY-this._lastY))i.right+10||t.clientX<=i.right&&t.clientY>i.bottom&&t.clientX>=i.left:t.clientX>i.right&&t.clientY>i.top||t.clientX<=i.right&&t.clientY>i.bottom+10}(t,o,this)&&!b.animated){if(b===X)return F(!1);if(b&&r===t.target&&(s=b),s&&(n=O(s)),!1!==Ft(Z,r,X,e,s,n,t,!!s))return H(),r.appendChild(X),q=r,j(),F(!0)}else if(s.parentNode===r){n=O(s);var g,v,y,w=X.parentNode!==r,k=!function(t,e,n){var i=n?t.left:t.top,o=n?t.right:t.bottom,r=n?t.width:t.height,a=n?e.left:e.top,s=n?e.right:e.bottom,c=n?e.width:e.height;return i===a||o===s||i+r/2===a+c/2}(X.animated&&X.toRect||e,s.animated&&s.toRect||n,o),I=o?"top":"left",S=A(s,"top","top")||A(X,"top","top"),C=S?S.scrollTop:void 0;if(ht!==s&&(v=n[I],kt=!1,Et=!k&&c.invertSwap||w),g=function(t,e,n,i,o,r,a,s){var c=i?t.clientY:t.clientX,l=i?n.height:n.width,p=i?n.top:n.left,d=i?n.bottom:n.right,u=!1;if(!a)if(s&>p+l*r/2:cd-gt)return-bt}else if(c>p+l*(1-o)/2&&cd-l*r/2)?c>p+l/2?1:-1:0}(t,s,n,o,k?1:c.swapThreshold,null==c.invertedSwapThreshold?c.swapThreshold:c.invertedSwapThreshold,Et,ht===s),0!==g){var _=M(X);do{_-=g,y=q.children[_]}while(y&&("none"===T(y,"display")||y===K))}if(0===g||y===s)return F(!1);ht=s,bt=g;var N=s.nextElementSibling,R=!1,D=Ft(Z,r,X,e,s,n,t,R=1===g);if(!1!==D)return 1!==D&&-1!==D||(R=1===D),It=!0,setTimeout(Bt,30),H(),R&&!N?r.appendChild(X):s.parentNode.insertBefore(X,R?N:s),S&&P(S,0,C-S.scrollTop),q=X.parentNode,void 0===v||Et||(gt=Math.abs(v-O(s)[I])),j(),F(!0)}if(r.contains(X))return F(!1)}return!1}function z(c,l){$(c,m,a({evt:t,isOwner:d,axis:o?"vertical":"horizontal",revert:i,dragRect:e,targetRect:n,canSort:u,fromSortable:f,target:s,completed:F,onMove:function(n,i){return Ft(Z,r,X,e,n,O(n),t,i)},changed:j},l))}function H(){z("dragOverAnimationCapture"),m.captureAnimationState(),m!==f&&f.captureAnimationState()}function F(e){return z("dragOverCompleted",{insertion:e}),e&&(d?p._hideClone():p._showClone(m),m!==f&&(E(X,st?st.options.ghostClass:p.options.ghostClass,!1),E(X,c.ghostClass,!0)),st!==m&&m!==Ht.active?st=m:m===Ht.active&&st&&(st=null),f===m&&(m._ignoreWhileAnimating=s),m.animateAll((function(){z("dragOverAnimationComplete"),m._ignoreWhileAnimating=null})),m!==f&&(f.animateAll(),f._ignoreWhileAnimating=null)),(s===X&&!X.animated||s===r&&!s.animated)&&(ht=null),c.dragoverBubble||t.rootEl||s===document||(X.parentNode[B]._isOutsideThisEl(t.target),!e&&zt(t)),!c.dragoverBubble&&t.stopPropagation&&t.stopPropagation(),h=!0}function j(){it=M(X),rt=M(X,c.draggable),G({sortable:m,name:"change",toEl:r,newIndex:it,newDraggableIndex:rt,originalEvent:t})}},_ignoreWhileAnimating:null,_offMoveEvents:function(){g(document,"mousemove",this._onTouchMove),g(document,"touchmove",this._onTouchMove),g(document,"pointermove",this._onTouchMove),g(document,"dragover",zt),g(document,"mousemove",zt),g(document,"touchmove",zt)},_offUpEvents:function(){var t=this.el.ownerDocument;g(t,"mouseup",this._onDrop),g(t,"touchend",this._onDrop),g(t,"pointerup",this._onDrop),g(t,"touchcancel",this._onDrop),g(document,"selectstart",this)},_onDrop:function(t){var e=this.el,n=this.options;it=M(X),rt=M(X,n.draggable),$("drop",this,{evt:t}),q=X&&X.parentNode,it=M(X),rt=M(X,n.draggable),Ht.eventCanceled||(yt=!1,Et=!1,kt=!1,clearInterval(this._loopId),clearTimeout(this._dragStartTimer),Yt(this.cloneId),Yt(this._dragStartId),this.nativeDraggable&&(g(document,"drop",this),g(e,"dragstart",this._onDragStart)),this._offMoveEvents(),this._offUpEvents(),u&&T(document.body,"user-select",""),T(X,"transform",""),t&&(mt&&(t.cancelable&&t.preventDefault(),!n.dropBubble&&t.stopPropagation()),K&&K.parentNode&&K.parentNode.removeChild(K),(Z===q||st&&"clone"!==st.lastPutMode)&&tt&&tt.parentNode&&tt.parentNode.removeChild(tt),X&&(this.nativeDraggable&&g(X,"dragend",this),jt(X),X.style["will-change"]="",mt&&!yt&&E(X,st?st.options.ghostClass:this.options.ghostClass,!1),E(X,this.options.chosenClass,!1),G({sortable:this,name:"unchoose",toEl:q,newIndex:null,newDraggableIndex:null,originalEvent:t}),Z!==q?(it>=0&&(G({rootEl:q,name:"add",toEl:q,fromEl:Z,originalEvent:t}),G({sortable:this,name:"remove",toEl:q,originalEvent:t}),G({rootEl:q,name:"sort",toEl:q,fromEl:Z,originalEvent:t}),G({sortable:this,name:"sort",toEl:q,originalEvent:t})),st&&st.save()):it!==nt&&it>=0&&(G({sortable:this,name:"update",toEl:q,originalEvent:t}),G({sortable:this,name:"sort",toEl:q,originalEvent:t})),Ht.active&&(null!=it&&-1!==it||(it=nt,rt=ot),G({sortable:this,name:"end",toEl:q,originalEvent:t}),this.save())))),this._nulling()},_nulling:function(){$("nulling",this),Z=X=q=K=Q=tt=J=et=ct=lt=mt=it=rt=nt=ot=ht=bt=st=at=Ht.dragged=Ht.ghost=Ht.clone=Ht.active=null,St.forEach((function(t){t.checked=!0})),St.length=pt=dt=0},handleEvent:function(t){switch(t.type){case"drop":case"dragend":this._onDrop(t);break;case"dragenter":case"dragover":X&&(this._onDragOver(t),function(t){t.dataTransfer&&(t.dataTransfer.dropEffect="move"),t.cancelable&&t.preventDefault()}(t));break;case"selectstart":t.preventDefault()}},toArray:function(){for(var t,e=[],n=this.el.children,i=0,o=n.length,r=this.options;i1&&(ue.forEach((function(t){i.addAnimationState({target:t,rect:he?O(t):o}),j(t),t.fromRect=o,e.removeAnimationState(t)})),he=!1,function(t,e){ue.forEach((function(n,i){var o=e.children[n.sortableIndex+(t?Number(i):0)];o?e.insertBefore(n,o):e.appendChild(n)}))}(!this.options.removeCloneOnHide,n))},dragOverCompleted:function(t){var e=t.sortable,n=t.isOwner,i=t.insertion,o=t.activeSortable,r=t.parentEl,a=t.putSortable,s=this.options;if(i){if(n&&o._hideClone(),me=!1,s.animation&&ue.length>1&&(he||!n&&!o.options.sort&&!a)){var c=O(le,!1,!0,!0);ue.forEach((function(t){t!==le&&(F(t,c),r.appendChild(t))})),he=!0}if(!n)if(he||ye(),ue.length>1){var l=de;o._showClone(e),o.options.animation&&!de&&l&&fe.forEach((function(t){o.addAnimationState({target:t,rect:pe}),t.fromRect=pe,t.thisAnimationDuration=null}))}else o._showClone(e)}},dragOverAnimationCapture:function(t){var e=t.dragRect,n=t.isOwner,i=t.activeSortable;if(ue.forEach((function(t){t.thisAnimationDuration=null})),i.options.animation&&!n&&i.multiDrag.isMultiDrag){pe=r({},e);var o=I(le,!0);pe.top-=o.f,pe.left-=o.e}},dragOverAnimationComplete:function(){he&&(he=!1,ye())},drop:function(t){var e=t.originalEvent,n=t.rootEl,i=t.parentEl,o=t.sortable,r=t.dispatchSortableEvent,a=t.oldIndex,s=t.putSortable,c=s||this.sortable;if(e){var l=this.options,p=i.children;if(!be)if(l.multiDragKey&&!this.multiDragKeyDown&&this._deselectMultiDrag(),E(le,l.selectedClass,!~ue.indexOf(le)),~ue.indexOf(le))ue.splice(ue.indexOf(le),1),se=null,W({sortable:o,rootEl:n,name:"deselect",targetEl:le,originalEvt:e});else{if(ue.push(le),W({sortable:o,rootEl:n,name:"select",targetEl:le,originalEvt:e}),e.shiftKey&&se&&o.el.contains(se)){var d,u,f=M(se),m=M(le);if(~f&&~m&&f!==m)for(m>f?(u=f,d=m):(u=m,d=f+1);u1){var h=O(le),b=M(le,":not(."+this.options.selectedClass+")");if(!me&&l.animation&&(le.thisAnimationDuration=null),c.captureAnimationState(),!me&&(l.animation&&(le.fromRect=h,ue.forEach((function(t){if(t.thisAnimationDuration=null,t!==le){var e=he?O(t):h;t.fromRect=e,c.addAnimationState({target:t,rect:e})}}))),ye(),ue.forEach((function(t){p[b]?i.insertBefore(t,p[b]):i.appendChild(t),b++})),a===M(le))){var g=!1;ue.forEach((function(t){t.sortableIndex===M(t)||(g=!0)})),g&&r("update")}ue.forEach((function(t){j(t)})),c.animateAll()}ce=c}(n===i||s&&"clone"!==s.lastPutMode)&&fe.forEach((function(t){t.parentNode&&t.parentNode.removeChild(t)}))}},nullingGlobal:function(){this.isMultiDrag=be=!1,fe.length=0},destroyGlobal:function(){this._deselectMultiDrag(),g(document,"pointerup",this._deselectMultiDrag),g(document,"mouseup",this._deselectMultiDrag),g(document,"touchend",this._deselectMultiDrag),g(document,"keydown",this._checkKeyDown),g(document,"keyup",this._checkKeyUp)},_deselectMultiDrag:function(t){if(!(void 0!==be&&be||ce!==this.sortable||t&&x(t.target,this.options.draggable,this.sortable.el,!1)||t&&0!==t.button))for(;ue.length;){var e=ue[0];E(e,this.options.selectedClass,!1),ue.shift(),W({sortable:this.sortable,rootEl:this.sortable.el,name:"deselect",targetEl:e,originalEvt:t})}},_checkKeyDown:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!0)},_checkKeyUp:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!1)}},r(t,{pluginName:"multiDrag",utils:{select:function(t){var e=t.parentNode[B];e&&e.options.multiDrag&&!~ue.indexOf(t)&&(ce&&ce!==e&&(ce.multiDrag._deselectMultiDrag(),ce=e),E(t,e.options.selectedClass,!0),ue.push(t))},deselect:function(t){var e=t.parentNode[B],n=ue.indexOf(t);e&&e.options.multiDrag&&~n&&(E(t,e.options.selectedClass,!1),ue.splice(n,1))}},eventProperties:function(){var t,e=this,n=[],i=[];return ue.forEach((function(t){var o;n.push({multiDragElement:t,index:t.sortableIndex}),o=he&&t!==le?-1:he?M(t,":not(."+e.options.selectedClass+")"):M(t),i.push({multiDragElement:t,index:o})})),{items:(t=ue,function(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e1&&(t=t.charAt(0).toUpperCase()+t.substr(1)),t}}})}function ve(t,e){fe.forEach((function(n,i){var o=e.children[n.sortableIndex+(t?Number(i):0)];o?e.insertBefore(n,o):e.appendChild(n)}))}function ye(){ue.forEach((function(t){t!==le&&t.parentNode&&t.parentNode.removeChild(t)}))}Ht.mount(new function(){function t(){for(var t in this.defaults={scroll:!0,scrollSensitivity:30,scrollSpeed:10,bubbleScroll:!0},this)"_"===t.charAt(0)&&"function"==typeof this[t]&&(this[t]=this[t].bind(this))}return t.prototype={dragStarted:function(t){var e=t.originalEvent;this.sortable.nativeDraggable?b(document,"dragover",this._handleAutoScroll):this.options.supportPointer?b(document,"pointermove",this._handleFallbackAutoScroll):e.touches?b(document,"touchmove",this._handleFallbackAutoScroll):b(document,"mousemove",this._handleFallbackAutoScroll)},dragOverCompleted:function(t){var e=t.originalEvent;this.options.dragOverBubble||e.rootEl||this._handleAutoScroll(e)},drop:function(){this.sortable.nativeDraggable?g(document,"dragover",this._handleAutoScroll):(g(document,"pointermove",this._handleFallbackAutoScroll),g(document,"touchmove",this._handleFallbackAutoScroll),g(document,"mousemove",this._handleFallbackAutoScroll)),te(),Jt(),clearTimeout(w),w=void 0},nulling:function(){qt=$t=Wt=Qt=Kt=Gt=Xt=null,Zt.length=0},_handleFallbackAutoScroll:function(t){this._handleAutoScroll(t,!0)},_handleAutoScroll:function(t,e){var n=this,i=(t.touches?t.touches[0]:t).clientX,o=(t.touches?t.touches[0]:t).clientY,r=document.elementFromPoint(i,o);if(qt=t,e||p||l||u){ne(t,this.options,r,e);var a=R(r,!0);!Qt||Kt&&i===Gt&&o===Xt||(Kt&&te(),Kt=setInterval((function(){var r=R(document.elementFromPoint(i,o),!0);r!==a&&(a=r,Jt()),ne(t,n.options,r,e)}),10),Gt=i,Xt=o)}else{if(!this.options.bubbleScroll||R(r,!0)===C())return void Jt();ne(t,this.options,R(r,!1),!1)}}},r(t,{pluginName:"scroll",initializeByDefault:!0})}),Ht.mount(re,oe);const xe=Ht},3379:t=>{"use strict";var e=[];function n(t){for(var n=-1,i=0;i{"use strict";var e={};t.exports=function(t,n){var i=function(t){if(void 0===e[t]){var n=document.querySelector(t);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(t){n=null}e[t]=n}return e[t]}(t);if(!i)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");i.appendChild(n)}},9216:t=>{"use strict";t.exports=function(t){var e=document.createElement("style");return t.setAttributes(e,t.attributes),t.insert(e,t.options),e}},3565:(t,e,n)=>{"use strict";t.exports=function(t){var e=n.nc;e&&t.setAttribute("nonce",e)}},7795:t=>{"use strict";t.exports=function(t){var e=t.insertStyleElement(t);return{update:function(n){!function(t,e,n){var i="";n.supports&&(i+="@supports (".concat(n.supports,") {")),n.media&&(i+="@media ".concat(n.media," {"));var o=void 0!==n.layer;o&&(i+="@layer".concat(n.layer.length>0?" ".concat(n.layer):""," {")),i+=n.css,o&&(i+="}"),n.media&&(i+="}"),n.supports&&(i+="}");var r=n.sourceMap;r&&"undefined"!=typeof btoa&&(i+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(r))))," */")),e.styleTagTransform(i,t,e.options)}(e,t,n)},remove:function(){!function(t){if(null===t.parentNode)return!1;t.parentNode.removeChild(t)}(e)}}}},4589:t=>{"use strict";t.exports=function(t,e){if(e.styleSheet)e.styleSheet.cssText=t;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(t))}}},9980:function(t,e,n){var i;"undefined"!=typeof self&&self,i=function(t){return function(t){var e={};function n(i){if(e[i])return e[i].exports;var o=e[i]={i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(i,o,function(e){return t[e]}.bind(null,o));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s="fb15")}({"01f9":function(t,e,n){"use strict";var i=n("2d00"),o=n("5ca1"),r=n("2aba"),a=n("32e9"),s=n("84f2"),c=n("41a0"),l=n("7f20"),p=n("38fd"),d=n("2b4c")("iterator"),u=!([].keys&&"next"in[].keys()),f="keys",m="values",h=function(){return this};t.exports=function(t,e,n,b,g,v,y){c(n,e,b);var x,w,k,E=function(t){if(!u&&t in C)return C[t];switch(t){case f:case m:return function(){return new n(this,t)}}return function(){return new n(this,t)}},T=e+" Iterator",I=g==m,S=!1,C=t.prototype,O=C[d]||C["@@iterator"]||g&&C[g],A=O||E(g),_=g?I?E("entries"):A:void 0,L="Array"==e&&C.entries||O;if(L&&(k=p(L.call(new t)))!==Object.prototype&&k.next&&(l(k,T,!0),i||"function"==typeof k[d]||a(k,d,h)),I&&O&&O.name!==m&&(S=!0,A=function(){return O.call(this)}),i&&!y||!u&&!S&&C[d]||a(C,d,A),s[e]=A,s[T]=h,g)if(x={values:I?A:E(m),keys:v?A:E(f),entries:_},y)for(w in x)w in C||r(C,w,x[w]);else o(o.P+o.F*(u||S),e,x);return x}},"02f4":function(t,e,n){var i=n("4588"),o=n("be13");t.exports=function(t){return function(e,n){var r,a,s=String(o(e)),c=i(n),l=s.length;return c<0||c>=l?t?"":void 0:(r=s.charCodeAt(c))<55296||r>56319||c+1===l||(a=s.charCodeAt(c+1))<56320||a>57343?t?s.charAt(c):r:t?s.slice(c,c+2):a-56320+(r-55296<<10)+65536}}},"0390":function(t,e,n){"use strict";var i=n("02f4")(!0);t.exports=function(t,e,n){return e+(n?i(t,e).length:1)}},"0bfb":function(t,e,n){"use strict";var i=n("cb7c");t.exports=function(){var t=i(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},"0d58":function(t,e,n){var i=n("ce10"),o=n("e11e");t.exports=Object.keys||function(t){return i(t,o)}},1495:function(t,e,n){var i=n("86cc"),o=n("cb7c"),r=n("0d58");t.exports=n("9e1e")?Object.defineProperties:function(t,e){o(t);for(var n,a=r(e),s=a.length,c=0;s>c;)i.f(t,n=a[c++],e[n]);return t}},"214f":function(t,e,n){"use strict";n("b0c5");var i=n("2aba"),o=n("32e9"),r=n("79e5"),a=n("be13"),s=n("2b4c"),c=n("520a"),l=s("species"),p=!r((function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$")})),d=function(){var t=/(?:)/,e=t.exec;t.exec=function(){return e.apply(this,arguments)};var n="ab".split(t);return 2===n.length&&"a"===n[0]&&"b"===n[1]}();t.exports=function(t,e,n){var u=s(t),f=!r((function(){var e={};return e[u]=function(){return 7},7!=""[t](e)})),m=f?!r((function(){var e=!1,n=/a/;return n.exec=function(){return e=!0,null},"split"===t&&(n.constructor={},n.constructor[l]=function(){return n}),n[u](""),!e})):void 0;if(!f||!m||"replace"===t&&!p||"split"===t&&!d){var h=/./[u],b=n(a,u,""[t],(function(t,e,n,i,o){return e.exec===c?f&&!o?{done:!0,value:h.call(e,n,i)}:{done:!0,value:t.call(n,e,i)}:{done:!1}})),g=b[0],v=b[1];i(String.prototype,t,g),o(RegExp.prototype,u,2==e?function(t,e){return v.call(t,this,e)}:function(t){return v.call(t,this)})}}},"230e":function(t,e,n){var i=n("d3f4"),o=n("7726").document,r=i(o)&&i(o.createElement);t.exports=function(t){return r?o.createElement(t):{}}},"23c6":function(t,e,n){var i=n("2d95"),o=n("2b4c")("toStringTag"),r="Arguments"==i(function(){return arguments}());t.exports=function(t){var e,n,a;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=function(t,e){try{return t[e]}catch(t){}}(e=Object(t),o))?n:r?i(e):"Object"==(a=i(e))&&"function"==typeof e.callee?"Arguments":a}},2621:function(t,e){e.f=Object.getOwnPropertySymbols},"2aba":function(t,e,n){var i=n("7726"),o=n("32e9"),r=n("69a8"),a=n("ca5a")("src"),s=n("fa5b"),c="toString",l=(""+s).split(c);n("8378").inspectSource=function(t){return s.call(t)},(t.exports=function(t,e,n,s){var c="function"==typeof n;c&&(r(n,"name")||o(n,"name",e)),t[e]!==n&&(c&&(r(n,a)||o(n,a,t[e]?""+t[e]:l.join(String(e)))),t===i?t[e]=n:s?t[e]?t[e]=n:o(t,e,n):(delete t[e],o(t,e,n)))})(Function.prototype,c,(function(){return"function"==typeof this&&this[a]||s.call(this)}))},"2aeb":function(t,e,n){var i=n("cb7c"),o=n("1495"),r=n("e11e"),a=n("613b")("IE_PROTO"),s=function(){},c="prototype",l=function(){var t,e=n("230e")("iframe"),i=r.length;for(e.style.display="none",n("fab2").appendChild(e),e.src="javascript:",(t=e.contentWindow.document).open(),t.write(" + + diff --git a/src/frontend/devops-pipeline/src/components/Outputs/index.vue b/src/frontend/devops-pipeline/src/components/Outputs/index.vue index d72d383f39f..5c095d18430 100644 --- a/src/frontend/devops-pipeline/src/components/Outputs/index.vue +++ b/src/frontend/devops-pipeline/src/components/Outputs/index.vue @@ -1,6 +1,17 @@
@@ -114,7 +132,7 @@ import CopyToCustomRepoDialog from '@/components/Outputs/CopyToCustomRepoDialog' import IframeReport from '@/components/Outputs/IframeReport' import ThirdPartyReport from '@/components/Outputs/ThirdPartyReport' - import qrcode from '@/components/devops/qrcode' + import OutputQrcode from '@/components/Outputs/OutputQrcode' import ExtMenu from '@/components/pipelineList/extMenu' import { extForFile, repoTypeMap, repoTypeNameMap } from '@/utils/pipelineConst' import { convertFileSize, convertTime } from '@/utils/util' @@ -125,12 +143,13 @@ Logo, ThirdPartyReport, IframeReport, - qrcode, ExtMenu, - CopyToCustomRepoDialog + CopyToCustomRepoDialog, + OutputQrcode }, data () { return { + keyWord: '', isCopyDialogShow: false, isCopying: false, currentTab: 'all', @@ -138,7 +157,8 @@ activeOutput: '', activeOutputDetail: null, hasPermission: false, - isLoading: false + isLoading: false, + asideCollpased: false } }, computed: { @@ -183,17 +203,19 @@ } ] : [] + let visibleOutputs = [ + ...this.outputs.filter((output) => !this.isThirdReport(output.reportType)), + ...thirdReportList + ] switch (this.currentTab) { case 'artifact': - return this.artifacts + visibleOutputs = this.artifacts + break case 'report': - return [...this.reports, ...thirdReportList] - default: - return [ - ...this.outputs.filter((output) => !this.isThirdReport(output.reportType)), - ...thirdReportList - ] + visibleOutputs = [...this.reports, ...thirdReportList] + break } + return visibleOutputs.filter(output => output.name.toLowerCase().includes(this.keyWord.toLowerCase())) }, isActiveThirdReport () { return this.isThirdReport(this.activeOutput?.reportType) @@ -301,12 +323,16 @@ 'requestExternalUrl', 'requestDownloadUrl' ]), + toggleCollapseAside () { + console.log(this.asideCollpased) + this.asideCollpased = !this.asideCollpased + }, async init () { const { projectId, pipelineId, buildNo: buildId } = this.$route.params try { this.isLoading = true - const [, res] = await Promise.all([ + const [hasPermission, res] = await Promise.all([ this.requestHasPermission(), this.requestOutputs({ projectId, @@ -325,7 +351,8 @@ ...item, id, icon, - isApp: ['ipafile', 'apkfile'].includes(icon) + isApp: ['ipafile', 'apkfile'].includes(icon), + downloadable: hasPermission && this.isArtifact(item.artifactoryType) && item.artifactoryType !== 'IMAGE' } }) } catch (err) { @@ -345,6 +372,7 @@ }) this.hasPermission = res + return res } catch (err) { const message = err.message ? err.message : err const theme = 'error' @@ -355,26 +383,6 @@ }) } }, - async getQrcodeUrl (params) { - try { - const external = await this.requestExternalUrl(params) - return external?.url - } catch (err) { - this.handleError(err, [ - { - actionId: this.$permissionActionMap.download, - resourceId: this.$permissionResourceMap.pipeline, - instanceId: [ - { - id: this.$route.params.pipelineId, - name: this.$route.params.pipelineId - } - ], - projectId: this.$route.params.projectId - } - ]) - } - }, async showDetail (output) { const { projectId } = this.$route.params try { @@ -382,12 +390,9 @@ const params = { projectId, type: output.artifactoryType, - path: `${output.fullPath}` + path: output.fullPath } - const [res, qrcodeUrl] = await Promise.all([ - this.requestFileInfo(params), - ...(output.isApp ? [this.getQrcodeUrl(params)] : []) - ]) + const res = await this.requestFileInfo(params) this.activeOutputDetail = { ...output, ...res, @@ -395,8 +400,7 @@ size: res.size > 0 ? convertFileSize(res.size, 'B') : '--', createdTime: convertTime(res.createdTime * 1000), modifiedTime: convertTime(res.modifiedTime * 1000), - icon: extForFile(res.name), - qrcodeUrl + icon: extForFile(res.name) } this.isLoading = false } catch (err) { @@ -453,12 +457,46 @@ } } .pipeline-exec-outputs-aside { - width: 295px; + position: relative; + width: 30vw; flex-shrink: 0; padding: 16px 11px; border-right: 1px solid #dcdee5; display: flex; flex-direction: column; + transition: all 0.3s; + + &.pipeline-exec-outputs-aside-collapse { + width: 0; + padding: 0; + .pipeline-exec-output-classify-tab { + display: none; + } + .aside-collapse-icon { + transform: rotate(180deg); + } + } + .collapse-handler { + position: absolute; + right: -16px; + top: 50%; + display: flex; + cursor: pointer; + align-items: center; + width: 16px; + height: 100px; + background: #DCDEE5; + border-radius: 0 4px 4px 0; + transform: translateY(-50px); + color: white; + font-size: 12px; + justify-content: center; + font-weight: 700; + z-index: 2; + .aside-collapse-icon { + transition: all 0.3s; + } + } .pipeline-exec-output-classify-tab { display: flex; align-items: center; @@ -493,6 +531,9 @@ } } } + .pipeline-exec-outputs-filter-input { + margin: 12px 0; + } .pipeline-exec-outputs-filter { position: relative; margin: 16px 0 21px 0; @@ -525,33 +566,44 @@ border-radius: 2px; font-size: 12px; margin-bottom: 10px; - > .devops-icon { - display: inline-block; + > .devops-icon, + .output-hover-icon { + display: inline-flex; font-size: 16px; margin-right: 4px; flex-shrink: 0; } + .output-hover-icon { + font-size: 12px; + display: none; + } > span { flex: 1; @include ellipsis(); } &.active, &:hover { - color: $primaryColor; - background: #f5f7fa; + color: $primaryColor; + background: #f5f7fa; + .output-hover-icon { + display: inline-flex; + } } } } } .pipeline-exec-outputs-section { flex: 1; - overflow: auto; + display: flex; + flex-direction: column; + overflow: hidden; .pipeline-exec-output-header { display: flex; align-items: center; height: 48px; background: #fafbfd; padding: 0 24px; + flex-shrink: 0; &-name { display: flex; align-items: center; @@ -571,6 +623,10 @@ margin-left: auto; } } + .pipeline-exec-output-artifact { + flex: 1; + overflow: auto; + } .pipeline-exec-output-block { padding: 16px 24px; .pipeline-exec-output-block-title { diff --git a/src/frontend/devops-pipeline/src/components/StartParams.vue b/src/frontend/devops-pipeline/src/components/StartParams.vue index d0c568072af..2691a532b12 100644 --- a/src/frontend/devops-pipeline/src/components/StartParams.vue +++ b/src/frontend/devops-pipeline/src/components/StartParams.vue @@ -14,7 +14,7 @@ /> -