From e53c49bb004508b2e5776559f5b9537b3d71093d Mon Sep 17 00:00:00 2001 From: jsonwan Date: Thu, 25 May 2023 15:18:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=84=9A=E6=9C=AC=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E6=95=8F=E6=84=9F=E5=8F=82=E6=95=B0=E5=AD=98=E5=82=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=9B=BD=E5=AF=86=20#2055?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 敏感参数场景支持国密实现 --- src/backend/build.gradle | 2 +- .../bk/job/common/encrypt/AESCryptor.java | 9 +- .../common/encrypt/CryptoConfigService.java | 92 +++++++ .../common/encrypt/CryptoScenarioEnum.java | 57 +++++ .../bk/job/common/encrypt/CryptorNames.java | 36 +++ .../bk/job/common/encrypt/EncryptConfig.java | 65 +++++ .../bk/job/common/encrypt/NoneCryptor.java | 19 +- .../encrypt/SymmetricCryptoService.java | 81 +++--- .../scenario/SensitiveParamService.java | 73 ++++++ ...encent.bk.sdk.gm.cryptor.SymmetricCryptor} | 0 .../job/backup/JobBackupBootApplication.java | 3 +- .../crontab/JobCrontabBootApplication.java | 3 +- .../execute/JobExecuteBootApplication.java | 3 +- .../StepInstanceDAOImplIntegrationTest.java | 4 +- .../src/test/resources/init_schema.sql | 39 +-- .../resources/init_step_instance_data.sql | 2 +- .../bk/job/execute/dao/StepInstanceDAO.java | 13 +- .../execute/dao/impl/StepInstanceDAOImpl.java | 146 +++++++---- .../executor/ScriptGseTaskStartCommand.java | 8 +- .../execute/service/TaskInstanceService.java | 7 +- .../service/impl/TaskInstanceServiceImpl.java | 4 +- .../job/manage/JobManageBootApplication.java | 3 +- .../src/test/resources/init_schema.sql | 35 +-- .../init_template_script_step_data.sql | 11 +- .../plan/impl/TaskPlanScriptStepDAOImpl.java | 197 +++++++++++---- .../impl/TaskTemplateScriptStepDAOImpl.java | 230 +++++++++++++----- ...job_execute_20230519-1000_V3.8.0_mysql.sql | 31 +++ ..._job_manage_20230519-1000_V3.8.0_mysql.sql | 38 +++ 28 files changed, 957 insertions(+), 254 deletions(-) create mode 100644 src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptoConfigService.java create mode 100644 src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptoScenarioEnum.java create mode 100644 src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptorNames.java create mode 100644 src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/EncryptConfig.java create mode 100644 src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/scenario/SensitiveParamService.java rename src/backend/commons/common/src/main/resources/META-INF/services/{com.tencent.bk.sdk.gm.cryptor.Cryptor => com.tencent.bk.sdk.gm.cryptor.SymmetricCryptor} (100%) create mode 100644 support-files/sql/job-execute/0023_job_execute_20230519-1000_V3.8.0_mysql.sql create mode 100644 support-files/sql/job-manage/0031_job_manage_20230519-1000_V3.8.0_mysql.sql diff --git a/src/backend/build.gradle b/src/backend/build.gradle index cd9c4d043d..52f1b41703 100644 --- a/src/backend/build.gradle +++ b/src/backend/build.gradle @@ -130,7 +130,7 @@ ext { set('jcommanderVersion', "1.71") set('kubernetesJavaClientVersion', "11.0.4") set('springCloudKubernetesVersion', "2.0.6") - set('gmJavaSDKVersion', "0.0.1") + set('gmJavaSDKVersion', "0.0.4") if (System.getProperty("bkjobVersion")) { set('bkjobVersion', System.getProperty("bkjobVersion")) println "bkjobVersion:" + bkjobVersion diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/AESCryptor.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/AESCryptor.java index a2ba337f02..797f56d895 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/AESCryptor.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/AESCryptor.java @@ -25,14 +25,15 @@ package com.tencent.bk.job.common.encrypt; import com.tencent.bk.job.common.util.crypto.AESUtils; -import com.tencent.bk.sdk.gm.annotation.CryptoPriority; -import com.tencent.bk.sdk.gm.cryptor.Cryptor; +import com.tencent.bk.sdk.gm.annotation.Cryptor; +import com.tencent.bk.sdk.gm.annotation.CryptorTypeEnum; +import com.tencent.bk.sdk.gm.cryptor.AbstractSymmetricCryptor; /** * 使用AES/CBC/PKCS5Padding的加密实现 */ -@CryptoPriority(name = "AES") -public class AESCryptor implements Cryptor { +@Cryptor(name = CryptorNames.AES, type = CryptorTypeEnum.SYMMETRIC) +public class AESCryptor extends AbstractSymmetricCryptor { @Override public byte[] encrypt(byte[] key, byte[] message) { try { diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptoConfigService.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptoConfigService.java new file mode 100644 index 0000000000..f4b559d2e3 --- /dev/null +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptoConfigService.java @@ -0,0 +1,92 @@ +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * 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.bk.job.common.encrypt; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; + +/** + * 加密配置服务 + */ +@SuppressWarnings("unused") +@Slf4j +@Service +public class CryptoConfigService { + + private final EncryptConfig encryptConfig; + private final Map scenarioAlgorithms; + + @Autowired + public CryptoConfigService(EncryptConfig encryptConfig) { + this.encryptConfig = encryptConfig; + this.scenarioAlgorithms = trimKeyValues(encryptConfig.getScenarioAlgorithms()); + } + + private Map trimKeyValues(Map map) { + if (map == null) { + return null; + } + Map resultMap = new HashMap<>(); + map.forEach((key, value) -> { + if (key != null) { + key = key.trim(); + } + if (value != null) { + value = value.trim(); + } + resultMap.put(key, value); + }); + return resultMap; + } + + /** + * 获取对称加密密钥 + * + * @return 对称加密密钥 + */ + public String getSymmetricPassword() { + return encryptConfig.getPassword(); + } + + /** + * 根据加密场景获取需要使用的加密算法 + * + * @param cryptoScenarioEnum 加密场景枚举值 + * @return 加密算法标识 + */ + public String getSymmetricAlgorithmByScenario(CryptoScenarioEnum cryptoScenarioEnum) { + if (cryptoScenarioEnum == null) { + return encryptConfig.getDefaultSymmetricAlgorithm(); + } + if (scenarioAlgorithms != null && scenarioAlgorithms.containsKey(cryptoScenarioEnum.getValue())) { + return scenarioAlgorithms.get(cryptoScenarioEnum.getValue()); + } + return encryptConfig.getDefaultSymmetricAlgorithm(); + } +} diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptoScenarioEnum.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptoScenarioEnum.java new file mode 100644 index 0000000000..91e468a227 --- /dev/null +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptoScenarioEnum.java @@ -0,0 +1,57 @@ +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * 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.bk.job.common.encrypt; + +/** + * 加密场景枚举值 + */ +public enum CryptoScenarioEnum { + // 脚本敏感参数 + SCRIPT_SENSITIVE_PARAM((byte) 0, "scriptSensitiveParam"), + // 密文变量 + CIPHER_VARIABLE((byte) 0, "cipherVariable"), + // DB账号的密码 + DATABASE_PASSWORD((byte) 0, "databasePassword"), + // 凭证信息 + CREDENTIAL((byte) 0, "credential"); + + // 加密类型:0为对称加密,1为非对称加密 + private final byte type; + // 场景标识 + private final String value; + + CryptoScenarioEnum(byte type, String value) { + this.type = type; + this.value = value; + } + + public String getValue() { + return value; + } + + public byte getType() { + return type; + } +} diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptorNames.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptorNames.java new file mode 100644 index 0000000000..2b2a1b97cc --- /dev/null +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/CryptorNames.java @@ -0,0 +1,36 @@ +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * 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.bk.job.common.encrypt; + +public class CryptorNames { + // 不加密 + public static final String NONE = "None"; + // 对称加密 + public static final String AES = "AES"; + public static final String SM4 = "SM4"; + // 非对称加密 + public static final String RSA = "RSA"; + public static final String SM2 = "SM2"; +} diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/EncryptConfig.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/EncryptConfig.java new file mode 100644 index 0000000000..2d99b66a4e --- /dev/null +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/EncryptConfig.java @@ -0,0 +1,65 @@ +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * 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.bk.job.common.encrypt; + +import com.tencent.bk.job.common.util.json.JsonUtils; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import javax.annotation.PostConstruct; +import java.util.Map; + +/** + * 加密配置 + *

+ * ignoreInvalidFields: true, 避免因为错误的配置导致微服务不可用(RefreshScopeHealthIndicator会对ConfigurationProperties + * 进行健康检查,如果配置有问题,会把微服务的状态设置为health=DOWN) + */ +@ConfigurationProperties(prefix = "job.encrypt", ignoreInvalidFields = true) +@ToString +@Getter +@Setter +@Slf4j +public class EncryptConfig { + + private String password; + + private String defaultSymmetricAlgorithm = CryptorNames.NONE; + + private String defaultAsymmetricAlgorithm = CryptorNames.RSA; + + /** + * 各个场景下使用的加密算法,不配置则使用默认算法 + */ + private Map scenarioAlgorithms; + + @PostConstruct + public void print() { + log.info("EncryptConfig init: {}", JsonUtils.toJson(this)); + } +} diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/NoneCryptor.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/NoneCryptor.java index a5f010792d..a70d470edb 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/NoneCryptor.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/NoneCryptor.java @@ -24,14 +24,15 @@ package com.tencent.bk.job.common.encrypt; -import com.tencent.bk.sdk.gm.annotation.CryptoPriority; -import com.tencent.bk.sdk.gm.cryptor.Cryptor; + +import com.tencent.bk.sdk.gm.annotation.Cryptor; +import com.tencent.bk.sdk.gm.cryptor.SymmetricCryptor; /** * 不做任何加密操作,直接返回明文的加密实现 */ -@CryptoPriority(name = "None") -public class NoneCryptor implements Cryptor { +@Cryptor(name = CryptorNames.NONE) +public class NoneCryptor implements SymmetricCryptor { @Override public byte[] encrypt(byte[] key, byte[] message) { return message; @@ -41,4 +42,14 @@ public byte[] encrypt(byte[] key, byte[] message) { public byte[] decrypt(byte[] key, byte[] encryptedMessage) { return encryptedMessage; } + + @Override + public String encrypt(String key, String message) { + return message; + } + + @Override + public String decrypt(String key, String base64EncodedEncryptedMessage) { + return base64EncodedEncryptedMessage; + } } diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/SymmetricCryptoService.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/SymmetricCryptoService.java index 9d662eb720..a281618c8d 100644 --- a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/SymmetricCryptoService.java +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/SymmetricCryptoService.java @@ -24,12 +24,11 @@ package com.tencent.bk.job.common.encrypt; -import com.google.common.base.Charsets; -import com.tencent.bk.job.common.util.Base64Util; -import com.tencent.bk.sdk.gm.cryptor.Cryptor; -import com.tencent.bk.sdk.gm.cryptor.CryptorFactory; +import com.tencent.bk.sdk.gm.cryptor.SymmetricCryptor; +import com.tencent.bk.sdk.gm.cryptor.SymmetricCryptorFactory; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.HashMap; @@ -43,64 +42,78 @@ @Service public class SymmetricCryptoService { - private final Map cryptorMap = new HashMap<>(); + private final CryptoConfigService cryptoConfigService; + private final Map cryptorMap = new HashMap<>(); - @Value("${job.encrypt.password:}") - private String encryptPassword; + @Autowired + public SymmetricCryptoService(CryptoConfigService cryptoConfigService) { + this.cryptoConfigService = cryptoConfigService; + } - @Value("${job.encrypt.default-symmetric-algorithm:None}") - private String defaultSymmetricAlgorithm; + /** + * 根据场景获取加密算法 + * + * @param cryptoScenarioEnum 加密场景 + * @return 使用的加密算法标识 + */ + public String getAlgorithmByScenario(CryptoScenarioEnum cryptoScenarioEnum) { + return cryptoConfigService.getSymmetricAlgorithmByScenario(cryptoScenarioEnum); + } /** - * 对明文信息加密,返回Base64编码的加密后的密文信息,使用默认加密算法 + * 对明文信息加密,返回Base64编码的加密后的密文信息 * - * @param message 要加密的明文信息 + * @param message 要加密的明文信息,不可为空 + * @param cryptoScenarioEnum 加密场景 * @return Base64编码的加密后的密文信息 */ - public String encryptToBase64Str(String message) { - return encryptToBase64Str(message, defaultSymmetricAlgorithm); + public String encryptToBase64Str(String message, CryptoScenarioEnum cryptoScenarioEnum) { + return encryptToBase64Str(message, cryptoConfigService.getSymmetricAlgorithmByScenario(cryptoScenarioEnum)); } /** - * 对明文信息加密,返回Base64编码的加密后的密文信息 + * 对明文信息加密,返回Base64编码的加密后的密文信息,明文为空则原样返回 * * @param message 要加密的明文信息 - * @param algorithm 加密算法 + * @param algorithm 加密算法,不可为空 * @return Base64编码的加密后的密文信息 */ public String encryptToBase64Str(String message, String algorithm) { - Cryptor cryptor = cryptorMap.computeIfAbsent(algorithm, CryptorFactory::getCryptor); - byte[] encryptedMessage = cryptor.encrypt( - encryptPassword.getBytes(Charsets.UTF_8), - message.getBytes(Charsets.UTF_8) - ); - return Base64Util.encodeContentToStr(encryptedMessage); + assert StringUtils.isNotEmpty(algorithm); + if (StringUtils.isEmpty(message)) { + return message; + } + SymmetricCryptor cryptor = cryptorMap.computeIfAbsent(algorithm, SymmetricCryptorFactory::getCryptor); + return cryptor.encrypt(cryptoConfigService.getSymmetricPassword(), message); } /** - * 对Base64编码的加密后的密文信息解密,返回解密后的明文,使用默认加密算法 + * 对Base64编码的加密后的密文信息解密,返回解密后的明文 * - * @param base64EncryptedMessage Base64编码的加密后的密文信息 + * @param base64EncryptedMessage Base64编码的加密后的密文信息,不可为空 + * @param cryptoScenarioEnum 加密场景 * @return 解密后的明文信息 */ - public String decrypt(String base64EncryptedMessage) { - return decrypt(base64EncryptedMessage, defaultSymmetricAlgorithm); + public String decrypt(String base64EncryptedMessage, CryptoScenarioEnum cryptoScenarioEnum) { + return decrypt(base64EncryptedMessage, cryptoConfigService.getSymmetricAlgorithmByScenario(cryptoScenarioEnum)); } /** - * 对Base64编码的加密后的密文信息解密,返回解密后的明文 + * 对Base64编码的加密后的密文信息解密,返回解密后的明文,密文为空则原样返回 * * @param base64EncryptedMessage Base64编码的加密后的密文信息 - * @param algorithm 加密算法 + * @param algorithm 加密算法,不可为空 * @return 解密后的明文信息 */ public String decrypt(String base64EncryptedMessage, String algorithm) { - Cryptor cryptor = cryptorMap.computeIfAbsent(algorithm, CryptorFactory::getCryptor); - byte[] rawEncryptedMessage = Base64Util.decodeContentToByte(base64EncryptedMessage); - byte[] decryptedMessage = cryptor.decrypt( - encryptPassword.getBytes(Charsets.UTF_8), - rawEncryptedMessage + assert StringUtils.isNotEmpty(algorithm); + if (StringUtils.isEmpty(base64EncryptedMessage)) { + return base64EncryptedMessage; + } + SymmetricCryptor cryptor = cryptorMap.computeIfAbsent(algorithm, SymmetricCryptorFactory::getCryptor); + return cryptor.decrypt( + cryptoConfigService.getSymmetricPassword(), + base64EncryptedMessage ); - return new String(decryptedMessage, Charsets.UTF_8); } } diff --git a/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/scenario/SensitiveParamService.java b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/scenario/SensitiveParamService.java new file mode 100644 index 0000000000..0db55c1744 --- /dev/null +++ b/src/backend/commons/common/src/main/java/com/tencent/bk/job/common/encrypt/scenario/SensitiveParamService.java @@ -0,0 +1,73 @@ +/* + * Tencent is pleased to support the open source community by making BK-JOB蓝鲸智云作业平台 available. + * + * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-JOB蓝鲸智云作业平台 is licensed under the MIT License. + * + * License for BK-JOB蓝鲸智云作业平台: + * -------------------------------------------------------------------- + * 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.bk.job.common.encrypt.scenario; + +import com.tencent.bk.job.common.encrypt.CryptoScenarioEnum; +import com.tencent.bk.job.common.encrypt.CryptorNames; +import com.tencent.bk.job.common.encrypt.SymmetricCryptoService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class SensitiveParamService { + + private final SymmetricCryptoService symmetricCryptoService; + + @Autowired + public SensitiveParamService(SymmetricCryptoService symmetricCryptoService) { + this.symmetricCryptoService = symmetricCryptoService; + } + + public String getSecureParamEncryptAlgorithm(Boolean secureParam) { + if (secureParam == null || !secureParam) { + return CryptorNames.NONE; + } + return symmetricCryptoService.getAlgorithmByScenario(CryptoScenarioEnum.SCRIPT_SENSITIVE_PARAM); + } + + public String encryptParamIfNeeded(boolean secureParam, String param) { + if (!secureParam) { + return param; + } + return symmetricCryptoService.encryptToBase64Str(param, CryptoScenarioEnum.SCRIPT_SENSITIVE_PARAM); + } + + public String encryptParamIfNeeded(boolean secureParam, String param, String encryptAlgorithm) { + if (!secureParam) { + return param; + } + return symmetricCryptoService.encryptToBase64Str(param, encryptAlgorithm); + } + + public String decryptParamIfNeeded(boolean secureParam, String encryptedParam, String algorithm) { + if (!secureParam) { + return encryptedParam; + } + return symmetricCryptoService.decrypt(encryptedParam, algorithm); + } + +} diff --git a/src/backend/commons/common/src/main/resources/META-INF/services/com.tencent.bk.sdk.gm.cryptor.Cryptor b/src/backend/commons/common/src/main/resources/META-INF/services/com.tencent.bk.sdk.gm.cryptor.SymmetricCryptor similarity index 100% rename from src/backend/commons/common/src/main/resources/META-INF/services/com.tencent.bk.sdk.gm.cryptor.Cryptor rename to src/backend/commons/common/src/main/resources/META-INF/services/com.tencent.bk.sdk.gm.cryptor.SymmetricCryptor diff --git a/src/backend/job-backup/boot-job-backup/src/main/java/com/tencent/bk/job/backup/JobBackupBootApplication.java b/src/backend/job-backup/boot-job-backup/src/main/java/com/tencent/bk/job/backup/JobBackupBootApplication.java index 55d0de443d..95854e87b4 100644 --- a/src/backend/job-backup/boot-job-backup/src/main/java/com/tencent/bk/job/backup/JobBackupBootApplication.java +++ b/src/backend/job-backup/boot-job-backup/src/main/java/com/tencent/bk/job/backup/JobBackupBootApplication.java @@ -25,6 +25,7 @@ package com.tencent.bk.job.backup; import com.tencent.bk.job.common.config.FeatureToggleConfig; +import com.tencent.bk.job.common.encrypt.EncryptConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; @@ -41,7 +42,7 @@ @EnableCaching @EnableFeignClients @EnableScheduling -@EnableConfigurationProperties({FeatureToggleConfig.class}) +@EnableConfigurationProperties({FeatureToggleConfig.class, EncryptConfig.class}) @DependsOn("applicationContextRegister") public class JobBackupBootApplication { public static void main(String[] args) { diff --git a/src/backend/job-crontab/boot-job-crontab/src/main/java/com/tencent/bk/job/crontab/JobCrontabBootApplication.java b/src/backend/job-crontab/boot-job-crontab/src/main/java/com/tencent/bk/job/crontab/JobCrontabBootApplication.java index 0d5ca00673..40f2a5c8a1 100644 --- a/src/backend/job-crontab/boot-job-crontab/src/main/java/com/tencent/bk/job/crontab/JobCrontabBootApplication.java +++ b/src/backend/job-crontab/boot-job-crontab/src/main/java/com/tencent/bk/job/crontab/JobCrontabBootApplication.java @@ -25,6 +25,7 @@ package com.tencent.bk.job.crontab; import com.tencent.bk.job.common.config.FeatureToggleConfig; +import com.tencent.bk.job.common.encrypt.EncryptConfig; import com.tencent.bk.job.crontab.config.JobQuartzProperties; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -37,7 +38,7 @@ */ @SpringBootApplication(scanBasePackages = "com.tencent.bk.job", exclude = {RedisAutoConfiguration.class}) @EnableFeignClients -@EnableConfigurationProperties({FeatureToggleConfig.class, JobQuartzProperties.class}) +@EnableConfigurationProperties({FeatureToggleConfig.class, JobQuartzProperties.class, EncryptConfig.class}) public class JobCrontabBootApplication { public static void main(String[] args) { diff --git a/src/backend/job-execute/boot-job-execute/src/main/java/com/tencent/bk/job/execute/JobExecuteBootApplication.java b/src/backend/job-execute/boot-job-execute/src/main/java/com/tencent/bk/job/execute/JobExecuteBootApplication.java index 065e9f81f5..de174d8311 100644 --- a/src/backend/job-execute/boot-job-execute/src/main/java/com/tencent/bk/job/execute/JobExecuteBootApplication.java +++ b/src/backend/job-execute/boot-job-execute/src/main/java/com/tencent/bk/job/execute/JobExecuteBootApplication.java @@ -25,6 +25,7 @@ package com.tencent.bk.job.execute; import com.tencent.bk.job.common.config.FeatureToggleConfig; +import com.tencent.bk.job.common.encrypt.EncryptConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; @@ -36,7 +37,7 @@ @SpringBootApplication(scanBasePackages = "com.tencent.bk.job", exclude = {RedisAutoConfiguration.class}) @EnableDiscoveryClient @EnableFeignClients -@EnableConfigurationProperties({FeatureToggleConfig.class}) +@EnableConfigurationProperties({FeatureToggleConfig.class, EncryptConfig.class}) public class JobExecuteBootApplication { public static void main(String[] args) { diff --git a/src/backend/job-execute/boot-job-execute/src/test/java/com/tencent/bk/job/execute/dao/impl/StepInstanceDAOImplIntegrationTest.java b/src/backend/job-execute/boot-job-execute/src/test/java/com/tencent/bk/job/execute/dao/impl/StepInstanceDAOImplIntegrationTest.java index c37a8dc8ef..1fac6bb006 100644 --- a/src/backend/job-execute/boot-job-execute/src/test/java/com/tencent/bk/job/execute/dao/impl/StepInstanceDAOImplIntegrationTest.java +++ b/src/backend/job-execute/boot-job-execute/src/test/java/com/tencent/bk/job/execute/dao/impl/StepInstanceDAOImplIntegrationTest.java @@ -365,7 +365,7 @@ public void testAddFileStepInstance() { assertThat(savedStepInstance.getFileSourceList().get(0).getServers().getIpList()).isNotEmpty(); assertThat(savedStepInstance.getFileSourceList().get(0).getServers().getIpList()) .containsOnly(new HostDTO(1L, - "10.10.10.10")); + "10.10.10.10")); assertThat(savedStepInstance.getFileSourceList().get(0).getFiles()).isNotEmpty(); assertThat(savedStepInstance.getFileSourceList().get(0).getFiles().get(0).getFilePath()) .isEqualTo("/tmp/1.log"); @@ -427,7 +427,7 @@ public void testAddConfirmStepInstance() { @Test void testUpdateResolvedScriptParam() { - stepInstanceDAO.updateResolvedScriptParam(1L, "resolved_var"); + stepInstanceDAO.updateResolvedScriptParam(1L, true, "resolved_var"); ScriptStepInstanceDTO updatedStepInstance = stepInstanceDAO.getScriptStepInstance(1L); assertThat(updatedStepInstance).isNotNull(); diff --git a/src/backend/job-execute/boot-job-execute/src/test/resources/init_schema.sql b/src/backend/job-execute/boot-job-execute/src/test/resources/init_schema.sql index babd26a3f5..66b4aa3dbf 100644 --- a/src/backend/job-execute/boot-job-execute/src/test/resources/init_schema.sql +++ b/src/backend/job-execute/boot-job-execute/src/test/resources/init_schema.sql @@ -89,25 +89,26 @@ CREATE TABLE IF NOT EXISTS `step_instance` CREATE TABLE IF NOT EXISTS `step_instance_script` ( - `step_instance_id` bigint(20) NOT NULL, - `script_content` mediumtext, - `script_type` tinyint(4) DEFAULT NULL, - `script_param` text, - `resolved_script_param` text, - `execution_timeout` int(11) DEFAULT NULL, - `system_account_id` bigint(20) DEFAULT NULL, - `system_account` varchar(256) DEFAULT NULL, - `db_account_id` bigint(20) DEFAULT NULL, - `db_type` tinyint(4) DEFAULT NULL, - `db_account` varchar(256) DEFAULT NULL, - `db_password` varchar(512) DEFAULT NULL, - `db_port` int(5) DEFAULT NULL, - `row_create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `row_update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `script_source` tinyint(4) DEFAULT 1, - `script_id` varchar(32) DEFAULT NULL, - `script_version_id` bigint(20) DEFAULT NULL, - `is_secure_param` tinyint(1) DEFAULT 0, + `step_instance_id` bigint(20) NOT NULL, + `script_content` mediumtext, + `script_type` tinyint(4) DEFAULT NULL, + `script_param` text, + `resolved_script_param` text, + `execution_timeout` int(11) DEFAULT NULL, + `system_account_id` bigint(20) DEFAULT NULL, + `system_account` varchar(256) DEFAULT NULL, + `db_account_id` bigint(20) DEFAULT NULL, + `db_type` tinyint(4) DEFAULT NULL, + `db_account` varchar(256) DEFAULT NULL, + `db_password` varchar(512) DEFAULT NULL, + `db_port` int(5) DEFAULT NULL, + `row_create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `row_update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `script_source` tinyint(4) DEFAULT 1, + `script_id` varchar(32) DEFAULT NULL, + `script_version_id` bigint(20) DEFAULT NULL, + `is_secure_param` tinyint(1) DEFAULT 0, + `secure_param_encrypt_algorithm` VARCHAR(32) NOT NULL DEFAULT 'None', PRIMARY KEY (`step_instance_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; diff --git a/src/backend/job-execute/boot-job-execute/src/test/resources/init_step_instance_data.sql b/src/backend/job-execute/boot-job-execute/src/test/resources/init_step_instance_data.sql index 962cc07651..dc0fa70f9e 100644 --- a/src/backend/job-execute/boot-job-execute/src/test/resources/init_step_instance_data.sql +++ b/src/backend/job-execute/boot-job-execute/src/test/resources/init_step_instance_data.sql @@ -41,7 +41,7 @@ create_time,step_num,step_order) values (4,2,3,-1,'fast_execute_task_name',1,'{" insert into job_execute.step_instance_script(step_instance_id,script_content,script_type,script_param,resolved_script_param,execution_timeout,system_account_id,system_account, -db_account_id,db_type,db_account,db_password,db_port,script_source,script_id,script_version_id) values (1,'script_content',1,'${var1}','var1',1000,1,'root',11,1,'root','db_password',3306,1,NULL,NULL); +db_account_id,db_type,db_account,db_password,db_port,script_source,script_id,script_version_id,secure_param_encrypt_algorithm) values (1,'script_content',1,'${var1}','var1',1000,1,'root',11,1,'root','db_password',3306,1,NULL,NULL,'None'); insert into job_execute.step_instance_file(step_instance_id,file_source,resolved_file_source,file_target_path,file_target_name,resolved_file_target_path,file_upload_speed_limit,file_download_speed_limit, file_duplicate_handle,not_exist_path_handler,execution_timeout,system_account_id,system_account) values (2,'[{"files":[{ "filePath":"/${log_dir}/1.log" }],"localUpload":false}]', diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/StepInstanceDAO.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/StepInstanceDAO.java index 88a7a2970b..d3878c35bb 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/StepInstanceDAO.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/StepInstanceDAO.java @@ -114,15 +114,16 @@ void updateStepExecutionInfo(long stepInstanceId, RunStatusEnum status, Long sta * 更新解析之后的脚本参数 * * @param stepInstanceId 步骤实例ID + * @param isSecureParam 是否为敏感参数 * @param resolvedScriptParam 解析之后的脚本参数 */ - void updateResolvedScriptParam(long stepInstanceId, String resolvedScriptParam); + void updateResolvedScriptParam(long stepInstanceId, boolean isSecureParam, String resolvedScriptParam); /** * 更新变量解析之后的源文件 * * @param stepInstanceId 步骤实例ID - * @param resolvedFileSources + * @param resolvedFileSources 解析后的源文件信息 */ void updateResolvedSourceFile(long stepInstanceId, List resolvedFileSources); @@ -175,16 +176,16 @@ List> listFastPushFileSource(Long appId, DuplicateHandlerEnu /** * 根据taskInstanceId获取一个stepInstanceId,用于快速脚本/文件任务 * - * @param taskInstanceId - * @return + * @param taskInstanceId 作业实例ID + * @return 步骤实例ID */ Long getStepInstanceId(long taskInstanceId); /** * 根据stepInstanceId获取脚本类型 * - * @param stepInstanceId - * @return + * @param stepInstanceId 步骤实例ID + * @return 脚本类型 */ Byte getScriptTypeByStepInstanceId(long stepInstanceId); diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/impl/StepInstanceDAOImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/impl/StepInstanceDAOImpl.java index c81d934784..155ead567e 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/impl/StepInstanceDAOImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/dao/impl/StepInstanceDAOImpl.java @@ -27,6 +27,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.tencent.bk.job.common.constant.DuplicateHandlerEnum; import com.tencent.bk.job.common.constant.NotExistPathHandlerEnum; +import com.tencent.bk.job.common.encrypt.scenario.SensitiveParamService; import com.tencent.bk.job.common.util.Utils; import com.tencent.bk.job.common.util.json.JsonUtils; import com.tencent.bk.job.execute.common.constants.RunStatusEnum; @@ -98,37 +99,56 @@ public class StepInstanceDAOImpl implements StepInstanceDAO { }; private final DSLContext CTX; + private final SensitiveParamService sensitiveParamService; @Autowired - public StepInstanceDAOImpl(@Qualifier("job-execute-dsl-context") DSLContext CTX) { + public StepInstanceDAOImpl(@Qualifier("job-execute-dsl-context") DSLContext CTX, + SensitiveParamService sensitiveParamService) { this.CTX = CTX; + this.sensitiveParamService = sensitiveParamService; } @Override public Long addStepInstanceBase(StepInstanceBaseDTO stepInstance) { StepInstance t = StepInstance.STEP_INSTANCE; - Record record = CTX.insertInto(t, t.STEP_ID, t.TASK_INSTANCE_ID, t.APP_ID, t.NAME, t.TYPE, - t.OPERATOR, t.STATUS, t.EXECUTE_COUNT, t.START_TIME, t.END_TIME, t.TOTAL_TIME, - t.TARGET_SERVERS, t.CREATE_TIME, t.IGNORE_ERROR, t.STEP_NUM, - t.STEP_ORDER, t.BATCH) - .values(stepInstance.getStepId(), - stepInstance.getTaskInstanceId(), - stepInstance.getAppId(), - stepInstance.getName(), - JooqDataTypeUtil.toByte(stepInstance.getExecuteType()), - stepInstance.getOperator(), - stepInstance.getStatus().getValue().byteValue(), - stepInstance.getExecuteCount(), - stepInstance.getStartTime(), - stepInstance.getEndTime(), - stepInstance.getTotalTime(), - stepInstance.getTargetServers() == null ? null : JsonUtils.toJson(stepInstance.getTargetServers()), - stepInstance.getCreateTime(), - stepInstance.isIgnoreError() ? Byte.valueOf("1") : Byte.valueOf("0"), - stepInstance.getStepNum(), - stepInstance.getStepOrder(), - (short) stepInstance.getBatch()) - .returning(t.ID).fetchOne(); + Record record = CTX.insertInto(t, + t.STEP_ID, + t.TASK_INSTANCE_ID, + t.APP_ID, + t.NAME, + t.TYPE, + t.OPERATOR, + t.STATUS, + t.EXECUTE_COUNT, + t.START_TIME, + t.END_TIME, + t.TOTAL_TIME, + t.TARGET_SERVERS, + t.CREATE_TIME, + t.IGNORE_ERROR, + t.STEP_NUM, + t.STEP_ORDER, + t.BATCH + ).values( + stepInstance.getStepId(), + stepInstance.getTaskInstanceId(), + stepInstance.getAppId(), + stepInstance.getName(), + JooqDataTypeUtil.toByte(stepInstance.getExecuteType()), + stepInstance.getOperator(), + stepInstance.getStatus().getValue().byteValue(), + stepInstance.getExecuteCount(), + stepInstance.getStartTime(), + stepInstance.getEndTime(), + stepInstance.getTotalTime(), + stepInstance.getTargetServers() == null ? null : JsonUtils.toJson(stepInstance.getTargetServers()), + stepInstance.getCreateTime(), + stepInstance.isIgnoreError() ? Byte.valueOf("1") : Byte.valueOf("0"), + stepInstance.getStepNum(), + stepInstance.getStepOrder(), + (short) stepInstance.getBatch() + ).returning(t.ID).fetchOne(); + assert record != null; return record.getValue(t.ID); } @@ -143,12 +163,14 @@ public void addScriptStepInstance(StepInstanceDTO stepInstance) { CTX.insertInto(t, t.STEP_INSTANCE_ID, t.SCRIPT_CONTENT, t.SCRIPT_TYPE, t.SCRIPT_PARAM, t.RESOLVED_SCRIPT_PARAM, t.EXECUTION_TIMEOUT, t.SYSTEM_ACCOUNT_ID, t.SYSTEM_ACCOUNT, t.DB_ACCOUNT_ID, t.DB_TYPE, t.DB_ACCOUNT, t.DB_PASSWORD, t.DB_PORT, t.SCRIPT_SOURCE, t.SCRIPT_ID, t.SCRIPT_VERSION_ID, - t.IS_SECURE_PARAM) + t.IS_SECURE_PARAM, t.SECURE_PARAM_ENCRYPT_ALGORITHM) .values(stepInstance.getId(), stepInstance.getScriptContent(), JooqDataTypeUtil.toByte(stepInstance.getScriptType()), - stepInstance.getScriptParam(), - stepInstance.getResolvedScriptParam(), + sensitiveParamService.encryptParamIfNeeded( + stepInstance.isSecureParam(), stepInstance.getScriptParam()), + sensitiveParamService.encryptParamIfNeeded( + stepInstance.isSecureParam(), stepInstance.getResolvedScriptParam()), stepInstance.getTimeout(), stepInstance.getAccountId(), stepInstance.getAccount(), @@ -161,7 +183,8 @@ public void addScriptStepInstance(StepInstanceDTO stepInstance) { stepInstance.getScriptId(), stepInstance.getScriptVersionId(), stepInstance.isSecureParam() ? JooqDataTypeUtil.toByte(1) : - JooqDataTypeUtil.toByte(0) + JooqDataTypeUtil.toByte(0), + sensitiveParamService.getSecureParamEncryptAlgorithm(stepInstance.isSecureParam()) ).execute(); } @@ -206,7 +229,7 @@ public ScriptStepInstanceDTO getScriptStepInstance(long stepInstanceId) { Record record = CTX.select(t.STEP_INSTANCE_ID, t.SCRIPT_CONTENT, t.SCRIPT_TYPE, t.SCRIPT_PARAM, t.RESOLVED_SCRIPT_PARAM, t.EXECUTION_TIMEOUT, t.SYSTEM_ACCOUNT_ID, t.SYSTEM_ACCOUNT, t.DB_ACCOUNT_ID, t.DB_ACCOUNT, t.DB_TYPE, t.DB_PASSWORD, t.DB_PORT, t.SCRIPT_SOURCE, t.SCRIPT_ID, - t.SCRIPT_VERSION_ID, t.IS_SECURE_PARAM + t.SCRIPT_VERSION_ID, t.IS_SECURE_PARAM, t.SECURE_PARAM_ENCRYPT_ALGORITHM ).from(t) .where(t.STEP_INSTANCE_ID.eq(stepInstanceId)).fetchOne(); return extractScriptInfo(record); @@ -221,8 +244,22 @@ private ScriptStepInstanceDTO extractScriptInfo(Record record) { stepInstance.setStepInstanceId(record.get(t.STEP_INSTANCE_ID)); stepInstance.setScriptContent(record.get(t.SCRIPT_CONTENT)); stepInstance.setScriptType(JooqDataTypeUtil.toInteger(record.get(t.SCRIPT_TYPE))); - stepInstance.setScriptParam(record.get(t.SCRIPT_PARAM)); - stepInstance.setResolvedScriptParam(record.get(t.RESOLVED_SCRIPT_PARAM)); + stepInstance.setSecureParam(record.get(t.IS_SECURE_PARAM).intValue() == 1); + String secureParamEncryptAlgorithm = record.get(t.SECURE_PARAM_ENCRYPT_ALGORITHM); + String encryptedScriptParam = record.get(t.SCRIPT_PARAM); + String scriptParam = sensitiveParamService.decryptParamIfNeeded( + stepInstance.isSecureParam(), + encryptedScriptParam, + secureParamEncryptAlgorithm + ); + stepInstance.setScriptParam(scriptParam); + String encryptedResolvedScriptParam = record.get(t.RESOLVED_SCRIPT_PARAM); + String resolvedScriptParam = sensitiveParamService.decryptParamIfNeeded( + stepInstance.isSecureParam(), + encryptedResolvedScriptParam, + secureParamEncryptAlgorithm + ); + stepInstance.setResolvedScriptParam(resolvedScriptParam); stepInstance.setTimeout(record.get(t.EXECUTION_TIMEOUT)); stepInstance.setAccountId(record.get(t.SYSTEM_ACCOUNT_ID)); stepInstance.setAccount(record.get(t.SYSTEM_ACCOUNT)); @@ -231,7 +268,6 @@ private ScriptStepInstanceDTO extractScriptInfo(Record record) { stepInstance.setDbAccount(record.get(t.DB_ACCOUNT)); stepInstance.setDbPass(record.get(t.DB_PASSWORD)); stepInstance.setDbPort(record.get(t.DB_PORT)); - stepInstance.setSecureParam(record.get(t.IS_SECURE_PARAM).intValue() == 1); Byte scriptSource = record.get(t.SCRIPT_SOURCE); if (scriptSource == null) { stepInstance.setScriptSource(1); @@ -505,10 +541,20 @@ private UpdateSetMoreStep buildBasicUpdateSetMoreStep(RunSta } @Override - public void updateResolvedScriptParam(long stepInstanceId, String resolvedScriptParam) { + public void updateResolvedScriptParam(long stepInstanceId, boolean isSecureParam, String resolvedScriptParam) { StepInstanceScript t = StepInstanceScript.STEP_INSTANCE_SCRIPT; - CTX.update(t).set(t.RESOLVED_SCRIPT_PARAM, resolvedScriptParam) + Result> records = CTX.select(t.SECURE_PARAM_ENCRYPT_ALGORITHM).from(t) .where(t.STEP_INSTANCE_ID.eq(stepInstanceId)) + .fetch(); + if (records.isEmpty()) { + log.warn("Cannot find encryptAlgorithm by stepInstanceId={}", stepInstanceId); + return; + } + String encryptAlgorithm = records.get(0).get(t.SECURE_PARAM_ENCRYPT_ALGORITHM); + CTX.update(t) + .set(t.RESOLVED_SCRIPT_PARAM, sensitiveParamService.encryptParamIfNeeded( + isSecureParam, resolvedScriptParam, encryptAlgorithm + )).where(t.STEP_INSTANCE_ID.eq(stepInstanceId)) .execute(); } @@ -587,18 +633,24 @@ public Byte getScriptTypeByStepInstanceId(long stepInstanceId) { } public Integer countStepInstanceByConditions(Collection conditions) { - return CTX.selectCount().from(T_STEP_INSTANCE) - .where(conditions).fetchOne().value1(); + Record1 record = CTX.selectCount().from(T_STEP_INSTANCE) + .where(conditions).fetchOne(); + assert record != null; + return record.value1(); } public Integer countStepInstanceScriptByConditions(Collection conditions) { - return CTX.selectCount().from(TABLE_STEP_INSTANCE_SCRIPT) - .where(conditions).fetchOne().value1(); + Record1 record = CTX.selectCount().from(TABLE_STEP_INSTANCE_SCRIPT) + .where(conditions).fetchOne(); + assert record != null; + return record.value1(); } public Integer countStepInstanceFileByConditions(Collection conditions) { - return CTX.selectCount().from(TABLE_STEP_INSTANCE_FILE) - .where(conditions).fetchOne().value1(); + Record1 record = CTX.selectCount().from(TABLE_STEP_INSTANCE_FILE) + .where(conditions).fetchOne(); + assert record != null; + return record.value1(); } @Override @@ -686,9 +738,8 @@ private List genStepInstanceFileConditions(Collection stepInsta } else { conditions.add(TABLE_STEP_INSTANCE_FILE.FILE_DUPLICATE_HANDLE.isNotNull()); } - } else { - // fileDupliateHandle与fileDupliateHandleNull同时为null表示FILE_DUPLICATE_HANDLE字段不作任何筛选 } + // fileDupliateHandle与fileDupliateHandleNull同时为null表示FILE_DUPLICATE_HANDLE字段不作任何筛选 } if (notExistPathHandler != null) { conditions.add(TABLE_STEP_INSTANCE_FILE.NOT_EXIST_PATH_HANDLER.eq(UByte.valueOf(notExistPathHandler.getValue()))); @@ -699,9 +750,8 @@ private List genStepInstanceFileConditions(Collection stepInsta } else { conditions.add(TABLE_STEP_INSTANCE_FILE.NOT_EXIST_PATH_HANDLER.isNotNull()); } - } else { - // notExistPathHandler与notExistPathHandlerNull同时为null表示NOT_EXIST_PATH_HANDLER字段不作任何筛选 } + // notExistPathHandler与notExistPathHandlerNull同时为null表示NOT_EXIST_PATH_HANDLER字段不作任何筛选 } return conditions; } @@ -722,9 +772,8 @@ private List genConditions(Long appId, DuplicateHandlerEnum fileDupli } else { conditions.add(TABLE_STEP_INSTANCE_FILE.FILE_DUPLICATE_HANDLE.isNotNull()); } - } else { - // fileDupliateHandle与fileDupliateHandleNull同时为null表示FILE_DUPLICATE_HANDLE字段不作任何筛选 } + // fileDupliateHandle与fileDupliateHandleNull同时为null表示FILE_DUPLICATE_HANDLE字段不作任何筛选 } if (notExistPathHandler != null) { conditions.add(TABLE_STEP_INSTANCE_FILE.NOT_EXIST_PATH_HANDLER.eq(UByte.valueOf(notExistPathHandler.getValue()))); @@ -735,9 +784,8 @@ private List genConditions(Long appId, DuplicateHandlerEnum fileDupli } else { conditions.add(TABLE_STEP_INSTANCE_FILE.NOT_EXIST_PATH_HANDLER.isNotNull()); } - } else { - // notExistPathHandler与notExistPathHandlerNull同时为null表示NOT_EXIST_PATH_HANDLER字段不作任何筛选 } + // notExistPathHandler与notExistPathHandlerNull同时为null表示NOT_EXIST_PATH_HANDLER字段不作任何筛选 } if (runStatus != null) { conditions.add(T_STEP_INSTANCE.STATUS.eq(runStatus.getValue().byteValue())); @@ -767,9 +815,7 @@ public List> listFastPushFileSource(Long appId, DuplicateHan try { Result> records = query.fetch(); List> resultList = new ArrayList<>(); - records.forEach(record -> { - resultList.add(convertStringToFileSourceDTO((String) record.get(0))); - }); + records.forEach(record -> resultList.add(convertStringToFileSourceDTO((String) record.get(0)))); return resultList; } catch (Exception e) { String msg = MessageFormatter.format( diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/engine/executor/ScriptGseTaskStartCommand.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/engine/executor/ScriptGseTaskStartCommand.java index 75bc3d56b4..257032c8be 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/engine/executor/ScriptGseTaskStartCommand.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/engine/executor/ScriptGseTaskStartCommand.java @@ -246,7 +246,11 @@ private String resolveScriptParamVariables(String scriptParam) { private void updateResolvedScriptParamIfNecessary(String originParam, String resolvedScriptParam) { // 只有存在变量解析之后才需要update if (!resolvedScriptParam.equals(originParam)) { - taskInstanceService.updateResolvedScriptParam(stepInstance.getId(), resolvedScriptParam); + taskInstanceService.updateResolvedScriptParam( + stepInstance.getId(), + stepInstance.isSecureParam(), + resolvedScriptParam + ); } } @@ -391,6 +395,7 @@ private String escapeSingleQuote(String value) { return value.replaceAll("'", "'\\\\''"); } + @SuppressWarnings({"StringBufferReplaceableByString", "StringBufferMayBeStringBuilder"}) private String buildWrapperScriptWithConstParamOnly(String declareFileName, String userScriptFileName) { StringBuffer sb = new StringBuffer(1024); sb.append("#!/bin/bash\n"); @@ -605,6 +610,7 @@ private String buildOutputVarsOnExitFunction(TaskVariablesAnalyzeResult taskVari return sb.toString(); } + @SuppressWarnings("StringBufferReplaceableByString") private String buildGetJobParamsScript(String varOutputFileName) { StringBuilder sb = new StringBuilder(1024); sb.append("#!/bin/bash\n"); diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/TaskInstanceService.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/TaskInstanceService.java index 7acb09ae69..f839db670a 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/TaskInstanceService.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/TaskInstanceService.java @@ -59,7 +59,7 @@ public interface TaskInstanceService { * 获取作业实例详情-包含步骤信息和全局变量信息 * * @param taskInstanceId 作业实例 ID - * @return + * @return 作业实例 */ TaskInstanceDTO getTaskInstanceDetail(long taskInstanceId); @@ -166,15 +166,16 @@ void updateStepExecutionInfo(long stepInstanceId, RunStatusEnum status, * 更新解析之后的脚本参数 * * @param stepInstanceId 步骤实例ID + * @param isSecureParam 是否为敏感参数 * @param resolvedScriptParam 解析之后的脚本参数 */ - void updateResolvedScriptParam(long stepInstanceId, String resolvedScriptParam); + void updateResolvedScriptParam(long stepInstanceId, boolean isSecureParam, String resolvedScriptParam); /** * 更新变量解析之后的源文件 * * @param stepInstanceId 步骤实例ID - * @param resolvedFileSources + * @param resolvedFileSources 解析后的源文件信息 */ void updateResolvedSourceFile(long stepInstanceId, List resolvedFileSources); diff --git a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/TaskInstanceServiceImpl.java b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/TaskInstanceServiceImpl.java index c7b203cf61..10d722b0f2 100644 --- a/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/TaskInstanceServiceImpl.java +++ b/src/backend/job-execute/service-job-execute/src/main/java/com/tencent/bk/job/execute/service/impl/TaskInstanceServiceImpl.java @@ -245,8 +245,8 @@ public void updateStepExecutionInfo(long stepInstanceId, RunStatusEnum status, L } @Override - public void updateResolvedScriptParam(long stepInstanceId, String resolvedScriptParam) { - stepInstanceDAO.updateResolvedScriptParam(stepInstanceId, resolvedScriptParam); + public void updateResolvedScriptParam(long stepInstanceId, boolean isSecureParam, String resolvedScriptParam) { + stepInstanceDAO.updateResolvedScriptParam(stepInstanceId, isSecureParam, resolvedScriptParam); } @Override diff --git a/src/backend/job-manage/boot-job-manage/src/main/java/com/tencent/bk/job/manage/JobManageBootApplication.java b/src/backend/job-manage/boot-job-manage/src/main/java/com/tencent/bk/job/manage/JobManageBootApplication.java index 08f4a2e0ce..74555f652e 100644 --- a/src/backend/job-manage/boot-job-manage/src/main/java/com/tencent/bk/job/manage/JobManageBootApplication.java +++ b/src/backend/job-manage/boot-job-manage/src/main/java/com/tencent/bk/job/manage/JobManageBootApplication.java @@ -25,6 +25,7 @@ package com.tencent.bk.job.manage; import com.tencent.bk.job.common.config.FeatureToggleConfig; +import com.tencent.bk.job.common.encrypt.EncryptConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; @@ -34,7 +35,7 @@ import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication(scanBasePackages = "com.tencent.bk.job", exclude = {RedisAutoConfiguration.class}) -@EnableConfigurationProperties({FeatureToggleConfig.class}) +@EnableConfigurationProperties({FeatureToggleConfig.class, EncryptConfig.class}) @EnableCaching @EnableFeignClients @EnableScheduling diff --git a/src/backend/job-manage/boot-job-manage/src/test/resources/init_schema.sql b/src/backend/job-manage/boot-job-manage/src/test/resources/init_schema.sql index e6922c900c..2c08aaa27a 100644 --- a/src/backend/job-manage/boot-job-manage/src/test/resources/init_schema.sql +++ b/src/backend/job-manage/boot-job-manage/src/test/resources/init_schema.sql @@ -428,23 +428,24 @@ CREATE TABLE `task_template_step_file_list` -- ---------------------------- CREATE TABLE `task_template_step_script` ( - `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, - `row_create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - `row_update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `template_id` BIGINT(20) UNSIGNED NOT NULL, - `step_id` BIGINT(20) UNSIGNED NOT NULL, - `script_type` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0', - `script_id` CHAR(32) NOT NULL, - `script_version_id` BIGINT(20) UNSIGNED NOT NULL, - `content` LONGTEXT NULL, - `language` TINYINT(5) UNSIGNED NOT NULL, - `script_param` VARCHAR(512) NULL, - `script_timeout` BIGINT(20) UNSIGNED NOT NULL, - `execute_account` BIGINT(20) NOT NULL, - `destination_host_list` LONGTEXT NULL, - `is_secure_param` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0', - `is_latest_version` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1', - `ignore_error` TINYINT(1) UNSIGNED NOT NULL, + `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, + `row_create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + `row_update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `template_id` BIGINT(20) UNSIGNED NOT NULL, + `step_id` BIGINT(20) UNSIGNED NOT NULL, + `script_type` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0', + `script_id` CHAR(32) NOT NULL, + `script_version_id` BIGINT(20) UNSIGNED NOT NULL, + `content` LONGTEXT NULL, + `language` TINYINT(5) UNSIGNED NOT NULL, + `script_param` VARCHAR(512) NULL, + `script_timeout` BIGINT(20) UNSIGNED NOT NULL, + `execute_account` BIGINT(20) NOT NULL, + `destination_host_list` LONGTEXT NULL, + `is_secure_param` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0', + `is_latest_version` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1', + `ignore_error` TINYINT(1) UNSIGNED NOT NULL, + `secure_param_encrypt_algorithm` VARCHAR(32) NOT NULL DEFAULT 'None', PRIMARY KEY (`id`), UNIQUE KEY (`step_id`) USING BTREE, KEY (`script_id`) USING BTREE, diff --git a/src/backend/job-manage/boot-job-manage/src/test/resources/template/init_template_script_step_data.sql b/src/backend/job-manage/boot-job-manage/src/test/resources/template/init_template_script_step_data.sql index 1550a888bb..023bba6d03 100644 --- a/src/backend/job-manage/boot-job-manage/src/test/resources/template/init_template_script_step_data.sql +++ b/src/backend/job-manage/boot-job-manage/src/test/resources/template/init_template_script_step_data.sql @@ -26,8 +26,9 @@ USE `job_manage`; TRUNCATE TABLE `task_template_step_script`; INSERT INTO `task_template_step_script` (id, template_id, step_id, script_type, script_id, script_version_id, content, language, script_param, script_timeout, execute_account, - destination_host_list, is_secure_param, status, ignore_error) -VALUES (1, 100000, 1000, 1, '1000', 1000, null, 1, 'a=a', 600, 1, null, 0, 1, 0), - (2, 100000, 2000, 2, '2000', 2000, 'this is a sample content', 1, null, 600, 2, null, 1, 0, 1), - (3, 100000, 3000, 1, '3000', 3000, null, 1, 'c=c', 600, 3, null, 1, 1, 0), - (4, 200000, 4000, 1, '1000', 1000, null, 1, 'a=a', 600, 1, null, 0, 0, 0); + destination_host_list, is_secure_param, status, ignore_error, + secure_param_encrypt_algorithm) +VALUES (1, 100000, 1000, 1, '1000', 1000, null, 1, 'a=a', 600, 1, null, 0, 1, 0, 'None'), + (2, 100000, 2000, 2, '2000', 2000, 'this is a sample content', 1, null, 600, 2, null, 1, 0, 1, 'None'), + (3, 100000, 3000, 1, '3000', 3000, null, 1, 'c=c', 600, 3, null, 1, 1, 0, 'None'), + (4, 200000, 4000, 1, '1000', 1000, null, 1, 'a=a', 600, 1, null, 0, 0, 0, 'None'); diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/plan/impl/TaskPlanScriptStepDAOImpl.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/plan/impl/TaskPlanScriptStepDAOImpl.java index b3ca3d7235..8428ee7388 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/plan/impl/TaskPlanScriptStepDAOImpl.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/plan/impl/TaskPlanScriptStepDAOImpl.java @@ -25,10 +25,10 @@ package com.tencent.bk.job.manage.dao.plan.impl; import com.tencent.bk.job.common.constant.ErrorCode; +import com.tencent.bk.job.common.encrypt.scenario.SensitiveParamService; import com.tencent.bk.job.common.exception.InternalException; +import com.tencent.bk.job.manage.common.consts.script.ScriptTypeEnum; import com.tencent.bk.job.manage.common.consts.task.TaskScriptSourceEnum; -import com.tencent.bk.job.manage.common.consts.task.TaskTypeEnum; -import com.tencent.bk.job.manage.common.util.DbRecordMapper; import com.tencent.bk.job.manage.common.util.JooqDataTypeUtil; import com.tencent.bk.job.manage.dao.TaskScriptStepDAO; import com.tencent.bk.job.manage.model.dto.task.TaskScriptStepDTO; @@ -37,7 +37,8 @@ import org.apache.commons.lang3.StringUtils; import org.jooq.Condition; import org.jooq.DSLContext; -import org.jooq.Record15; +import org.jooq.Record1; +import org.jooq.Record16; import org.jooq.Result; import org.jooq.generated.tables.TaskPlan; import org.jooq.generated.tables.TaskPlanStep; @@ -68,11 +69,44 @@ public class TaskPlanScriptStepDAOImpl implements TaskScriptStepDAO { private static final TaskPlanStep tableTTStep = TaskPlanStep.TASK_PLAN_STEP; private static final TaskPlanStepScript tableTTStepScript = TaskPlanStepScript.TASK_PLAN_STEP_SCRIPT; - private DSLContext context; + private final DSLContext context; + private final SensitiveParamService sensitiveParamService; @Autowired - public TaskPlanScriptStepDAOImpl(@Qualifier("job-manage-dsl-context") DSLContext context) { + public TaskPlanScriptStepDAOImpl(@Qualifier("job-manage-dsl-context") DSLContext context, + SensitiveParamService sensitiveParamService) { this.context = context; + this.sensitiveParamService = sensitiveParamService; + } + + private TaskScriptStepDTO convertRecordToTaskScriptStep(Record16 record) { + if (record == null) { + return null; + } + TaskScriptStepDTO taskScriptStep = new TaskScriptStepDTO(); + taskScriptStep.setId(record.get(TABLE.ID).longValue()); + taskScriptStep.setPlanId((record.get(TABLE.PLAN_ID)).longValue()); + taskScriptStep.setStepId((record.get(TABLE.STEP_ID)).longValue()); + taskScriptStep.setScriptSource(TaskScriptSourceEnum.valueOf((record.get(TABLE.SCRIPT_TYPE)).intValue())); + taskScriptStep.setScriptId(record.get(TABLE.SCRIPT_ID)); + if (record.get(TABLE.SCRIPT_VERSION_ID) != null) { + taskScriptStep.setScriptVersionId((record.get(TABLE.SCRIPT_VERSION_ID)).longValue()); + } + taskScriptStep.setContent(record.get(TABLE.CONTENT)); + taskScriptStep.setLanguage(ScriptTypeEnum.valueOf((record.get(TABLE.LANGUAGE)).intValue())); + taskScriptStep.setTimeout((record.get(TABLE.SCRIPT_TIMEOUT)).longValue()); + taskScriptStep.setAccount((record.get(TABLE.EXECUTE_ACCOUNT)).longValue()); + taskScriptStep.setExecuteTarget(TaskTargetDTO.fromJsonString(record.get(TABLE.DESTINATION_HOST_LIST))); + taskScriptStep.setSecureParam((record.get(TABLE.IS_SECURE_PARAM)).intValue() == 1); + String encryptedScriptParam = record.get(TABLE.SCRIPT_PARAM); + String algorithm = record.get(TABLE.SECURE_PARAM_ENCRYPT_ALGORITHM); + taskScriptStep.setScriptParam(sensitiveParamService.decryptParamIfNeeded( + taskScriptStep.getSecureParam(), encryptedScriptParam, algorithm + )); + taskScriptStep.setStatus((record.get(TABLE.STATUS)).intValue()); + taskScriptStep.setIgnoreError((record.get(TABLE.IGNORE_ERROR)).intValue() == 1); + return taskScriptStep; } @Override @@ -80,20 +114,33 @@ public List listScriptStepByParentId(long parentId) { List conditions = new ArrayList<>(); conditions.add(TABLE.PLAN_ID.eq(ULong.valueOf(parentId))); Result< - Record15> result = + Record16> result = context - .select(TABLE.ID, TABLE.PLAN_ID, TABLE.STEP_ID, TABLE.SCRIPT_TYPE, TABLE.SCRIPT_ID, - TABLE.SCRIPT_VERSION_ID, TABLE.CONTENT, TABLE.LANGUAGE, TABLE.SCRIPT_PARAM, - TABLE.SCRIPT_TIMEOUT, TABLE.EXECUTE_ACCOUNT, TABLE.DESTINATION_HOST_LIST, - TABLE.IS_SECURE_PARAM, TABLE.STATUS, TABLE.IGNORE_ERROR) - .from(TABLE).where(conditions).fetch(); + .select( + TABLE.ID, + TABLE.PLAN_ID, + TABLE.STEP_ID, + TABLE.SCRIPT_TYPE, + TABLE.SCRIPT_ID, + TABLE.SCRIPT_VERSION_ID, + TABLE.CONTENT, + TABLE.LANGUAGE, + TABLE.SCRIPT_PARAM, + TABLE.SCRIPT_TIMEOUT, + TABLE.EXECUTE_ACCOUNT, + TABLE.DESTINATION_HOST_LIST, + TABLE.IS_SECURE_PARAM, + TABLE.STATUS, + TABLE.IGNORE_ERROR, + TABLE.SECURE_PARAM_ENCRYPT_ALGORITHM + ).from(TABLE).where(conditions).fetch(); List taskScriptStepList = new ArrayList<>(); - if (result != null && result.size() >= 1) { + if (result.size() >= 1) { result.map(record -> taskScriptStepList - .add(DbRecordMapper.convertRecordToTaskScriptStep(record, TaskTypeEnum.PLAN))); + .add(convertRecordToTaskScriptStep(record))); } return taskScriptStepList; } @@ -103,20 +150,35 @@ public Map listScriptStepByIds(List stepIdList) { List conditions = new ArrayList<>(); conditions.add(TABLE.STEP_ID.in(stepIdList.stream().map(ULong::valueOf).collect(Collectors.toList()))); Result< - Record15> result = + Record16> result = context - .select(TABLE.ID, TABLE.PLAN_ID, TABLE.STEP_ID, TABLE.SCRIPT_TYPE, TABLE.SCRIPT_ID, - TABLE.SCRIPT_VERSION_ID, TABLE.CONTENT, TABLE.LANGUAGE, TABLE.SCRIPT_PARAM, - TABLE.SCRIPT_TIMEOUT, TABLE.EXECUTE_ACCOUNT, TABLE.DESTINATION_HOST_LIST, - TABLE.IS_SECURE_PARAM, TABLE.STATUS, TABLE.IGNORE_ERROR) - .from(TABLE).where(conditions).fetch(); + .select( + TABLE.ID, + TABLE.PLAN_ID, + TABLE.STEP_ID, + TABLE.SCRIPT_TYPE, + TABLE.SCRIPT_ID, + TABLE.SCRIPT_VERSION_ID, + TABLE.CONTENT, + TABLE.LANGUAGE, + TABLE.SCRIPT_PARAM, + TABLE.SCRIPT_TIMEOUT, + TABLE.EXECUTE_ACCOUNT, + TABLE.DESTINATION_HOST_LIST, + TABLE.IS_SECURE_PARAM, + TABLE.STATUS, + TABLE.IGNORE_ERROR, + TABLE.SECURE_PARAM_ENCRYPT_ALGORITHM + ).from(TABLE).where(conditions).fetch(); Map taskScriptStepMap = new HashMap<>(stepIdList.size()); - if (result != null && result.size() >= 1) { - result.map(record -> taskScriptStepMap.put(record.get(TABLE.STEP_ID).longValue(), - DbRecordMapper.convertRecordToTaskScriptStep(record, TaskTypeEnum.PLAN))); + if (result.size() >= 1) { + result.map(record -> taskScriptStepMap.put( + record.get(TABLE.STEP_ID).longValue(), + convertRecordToTaskScriptStep(record)) + ); } return taskScriptStepMap; } @@ -125,13 +187,27 @@ public Map listScriptStepByIds(List stepIdList) { public TaskScriptStepDTO getScriptStepById(long stepId) { List conditions = new ArrayList<>(); conditions.add(TABLE.STEP_ID.eq(ULong.valueOf(stepId))); - Record15 record = context.select(TABLE.ID, TABLE.PLAN_ID, TABLE.STEP_ID, TABLE.SCRIPT_TYPE, TABLE.SCRIPT_ID, - TABLE.SCRIPT_VERSION_ID, TABLE.CONTENT, TABLE.LANGUAGE, TABLE.SCRIPT_PARAM, TABLE.SCRIPT_TIMEOUT, - TABLE.EXECUTE_ACCOUNT, TABLE.DESTINATION_HOST_LIST, TABLE.IS_SECURE_PARAM, TABLE.STATUS, - TABLE.IGNORE_ERROR).from(TABLE).where(conditions).fetchOne(); + Record16 record = context.select( + TABLE.ID, + TABLE.PLAN_ID, + TABLE.STEP_ID, + TABLE.SCRIPT_TYPE, + TABLE.SCRIPT_ID, + TABLE.SCRIPT_VERSION_ID, + TABLE.CONTENT, + TABLE.LANGUAGE, + TABLE.SCRIPT_PARAM, + TABLE.SCRIPT_TIMEOUT, + TABLE.EXECUTE_ACCOUNT, + TABLE.DESTINATION_HOST_LIST, + TABLE.IS_SECURE_PARAM, + TABLE.STATUS, + TABLE.IGNORE_ERROR, + TABLE.SECURE_PARAM_ENCRYPT_ALGORITHM + ).from(TABLE).where(conditions).fetchOne(); if (record != null) { - return DbRecordMapper.convertRecordToTaskScriptStep(record, TaskTypeEnum.PLAN); + return convertRecordToTaskScriptStep(record); } else { return null; } @@ -149,17 +225,40 @@ public long insertScriptStep(TaskScriptStepDTO scriptStep) { ignoreError = UByte.valueOf(1); } TaskPlanStepScriptRecord record = context.insertInto(TABLE) - .columns(TABLE.PLAN_ID, TABLE.STEP_ID, TABLE.SCRIPT_TYPE, TABLE.SCRIPT_ID, TABLE.SCRIPT_VERSION_ID, - TABLE.CONTENT, TABLE.LANGUAGE, TABLE.SCRIPT_PARAM, TABLE.SCRIPT_TIMEOUT, TABLE.EXECUTE_ACCOUNT, - TABLE.DESTINATION_HOST_LIST, TABLE.IS_SECURE_PARAM, TABLE.STATUS, TABLE.IGNORE_ERROR) - .values(ULong.valueOf(scriptStep.getPlanId()), ULong.valueOf(scriptStep.getStepId()), - UByte.valueOf(scriptStep.getScriptSource().getType()), scriptStep.getScriptId(), + .columns( + TABLE.PLAN_ID, + TABLE.STEP_ID, + TABLE.SCRIPT_TYPE, + TABLE.SCRIPT_ID, + TABLE.SCRIPT_VERSION_ID, + TABLE.CONTENT, + TABLE.LANGUAGE, + TABLE.SCRIPT_PARAM, + TABLE.SCRIPT_TIMEOUT, + TABLE.EXECUTE_ACCOUNT, + TABLE.DESTINATION_HOST_LIST, + TABLE.IS_SECURE_PARAM, + TABLE.STATUS, + TABLE.IGNORE_ERROR, + TABLE.SECURE_PARAM_ENCRYPT_ALGORITHM + ).values( + ULong.valueOf(scriptStep.getPlanId()), + ULong.valueOf(scriptStep.getStepId()), + UByte.valueOf(scriptStep.getScriptSource().getType()), + scriptStep.getScriptId(), scriptStep.getScriptVersionId() == null ? null : ULong.valueOf(scriptStep.getScriptVersionId()), - scriptStep.getContent(), UByte.valueOf(scriptStep.getLanguage().getValue()), - scriptStep.getScriptParam(), ULong.valueOf(scriptStep.getTimeout()), - ULong.valueOf(scriptStep.getAccount()), scriptStep.getExecuteTarget().toJsonString(), isSecureParam, - status, ignoreError) - .returning(TABLE.ID).fetchOne(); + scriptStep.getContent(), + UByte.valueOf(scriptStep.getLanguage().getValue()), + sensitiveParamService.encryptParamIfNeeded(scriptStep.getSecureParam(), scriptStep.getScriptParam()), + ULong.valueOf(scriptStep.getTimeout()), + ULong.valueOf(scriptStep.getAccount()), + scriptStep.getExecuteTarget().toJsonString(), + isSecureParam, + status, + ignoreError, + sensitiveParamService.getSecureParamEncryptAlgorithm(scriptStep.getSecureParam()) + ).returning(TABLE.ID).fetchOne(); + assert record != null; return record.getId().longValue(); } @@ -189,10 +288,12 @@ public int countScriptSteps(Long appId, TaskScriptSourceEnum scriptSource) { if (scriptSource != null) { conditions.add(tableTTStepScript.SCRIPT_TYPE.eq(UByte.valueOf(scriptSource.getType()))); } - return context.selectCount().from(tableTTStepScript) + Record1 record = context.selectCount().from(tableTTStepScript) .join(tableTTStep).on(tableTTStep.ID.eq(tableTTStepScript.STEP_ID)) .join(tableTaskPlan).on(tableTTStep.PLAN_ID.eq(tableTaskPlan.ID)) - .where(conditions).fetchOne().value1(); + .where(conditions).fetchOne(); + assert record != null; + return record.value1(); } @Override @@ -204,10 +305,12 @@ public int countScriptCitedByStepsByScriptIds(Long appId, List scriptIdL if (scriptIdList != null) { conditions.add(tableTTStepScript.SCRIPT_ID.in(scriptIdList)); } - return context.select(DSL.countDistinct(tableTTStepScript.SCRIPT_ID)).from(tableTTStepScript) + Record1 record = context.select(DSL.countDistinct(tableTTStepScript.SCRIPT_ID)).from(tableTTStepScript) .join(tableTTStep).on(tableTTStep.ID.eq(tableTTStepScript.STEP_ID)) .join(tableTaskPlan).on(tableTTStep.PLAN_ID.eq(tableTaskPlan.ID)) - .where(conditions).fetchOne().value1(); + .where(conditions).fetchOne(); + assert record != null; + return record.value1(); } @Override @@ -219,10 +322,12 @@ public int countScriptStepsByScriptIds(Long appId, List scriptIdList) { if (scriptIdList != null) { conditions.add(tableTTStepScript.SCRIPT_ID.in(scriptIdList)); } - return context.selectCount().from(tableTTStepScript) + Record1 record = context.selectCount().from(tableTTStepScript) .join(tableTTStep).on(tableTTStep.ID.eq(tableTTStepScript.STEP_ID)) .join(tableTaskPlan).on(tableTTStep.PLAN_ID.eq(tableTaskPlan.ID)) - .where(conditions).fetchOne().value1(); + .where(conditions).fetchOne(); + assert record != null; + return record.value1(); } @Override diff --git a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/template/impl/TaskTemplateScriptStepDAOImpl.java b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/template/impl/TaskTemplateScriptStepDAOImpl.java index cbb82c8aa3..827a440d5a 100644 --- a/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/template/impl/TaskTemplateScriptStepDAOImpl.java +++ b/src/backend/job-manage/service-job-manage/src/main/java/com/tencent/bk/job/manage/dao/template/impl/TaskTemplateScriptStepDAOImpl.java @@ -24,9 +24,9 @@ package com.tencent.bk.job.manage.dao.template.impl; +import com.tencent.bk.job.common.encrypt.scenario.SensitiveParamService; +import com.tencent.bk.job.manage.common.consts.script.ScriptTypeEnum; import com.tencent.bk.job.manage.common.consts.task.TaskScriptSourceEnum; -import com.tencent.bk.job.manage.common.consts.task.TaskTypeEnum; -import com.tencent.bk.job.manage.common.util.DbRecordMapper; import com.tencent.bk.job.manage.common.util.JooqDataTypeUtil; import com.tencent.bk.job.manage.dao.TaskScriptStepDAO; import com.tencent.bk.job.manage.model.dto.task.TaskScriptStepDTO; @@ -35,7 +35,8 @@ import org.apache.commons.lang3.StringUtils; import org.jooq.Condition; import org.jooq.DSLContext; -import org.jooq.Record15; +import org.jooq.Record1; +import org.jooq.Record16; import org.jooq.Record3; import org.jooq.Result; import org.jooq.generated.tables.TaskTemplate; @@ -68,11 +69,44 @@ public class TaskTemplateScriptStepDAOImpl implements TaskScriptStepDAO { private static final TaskTemplateStep tableTTStep = TaskTemplateStep.TASK_TEMPLATE_STEP; private static final TaskTemplateStepScript tableTTStepScript = TaskTemplateStepScript.TASK_TEMPLATE_STEP_SCRIPT; - private DSLContext context; + private final DSLContext context; + private final SensitiveParamService sensitiveParamService; @Autowired - public TaskTemplateScriptStepDAOImpl(@Qualifier("job-manage-dsl-context") DSLContext context) { + public TaskTemplateScriptStepDAOImpl(@Qualifier("job-manage-dsl-context") DSLContext context, + SensitiveParamService sensitiveParamService) { this.context = context; + this.sensitiveParamService = sensitiveParamService; + } + + private TaskScriptStepDTO convertRecordToTaskScriptStep(Record16 record) { + if (record == null) { + return null; + } + TaskScriptStepDTO taskScriptStep = new TaskScriptStepDTO(); + taskScriptStep.setId(record.get(TABLE.ID).longValue()); + taskScriptStep.setTemplateId((record.get(TABLE.TEMPLATE_ID)).longValue()); + taskScriptStep.setStepId((record.get(TABLE.STEP_ID)).longValue()); + taskScriptStep.setScriptSource(TaskScriptSourceEnum.valueOf((record.get(TABLE.SCRIPT_TYPE)).intValue())); + taskScriptStep.setScriptId(record.get(TABLE.SCRIPT_ID)); + if (record.get(TABLE.SCRIPT_VERSION_ID) != null) { + taskScriptStep.setScriptVersionId((record.get(TABLE.SCRIPT_VERSION_ID)).longValue()); + } + taskScriptStep.setContent(record.get(TABLE.CONTENT)); + taskScriptStep.setLanguage(ScriptTypeEnum.valueOf((record.get(TABLE.LANGUAGE)).intValue())); + taskScriptStep.setTimeout((record.get(TABLE.SCRIPT_TIMEOUT)).longValue()); + taskScriptStep.setAccount((record.get(TABLE.EXECUTE_ACCOUNT)).longValue()); + taskScriptStep.setExecuteTarget(TaskTargetDTO.fromJsonString(record.get(TABLE.DESTINATION_HOST_LIST))); + taskScriptStep.setSecureParam((record.get(TABLE.IS_SECURE_PARAM)).intValue() == 1); + String encryptedScriptParam = record.get(TABLE.SCRIPT_PARAM); + String algorithm = record.get(TABLE.SECURE_PARAM_ENCRYPT_ALGORITHM); + taskScriptStep.setScriptParam(sensitiveParamService.decryptParamIfNeeded( + taskScriptStep.getSecureParam(), encryptedScriptParam, algorithm + )); + taskScriptStep.setStatus((record.get(TABLE.STATUS)).intValue()); + taskScriptStep.setIgnoreError((record.get(TABLE.IGNORE_ERROR)).intValue() == 1); + return taskScriptStep; } @Override @@ -80,20 +114,34 @@ public List listScriptStepByParentId(long parentId) { List conditions = new ArrayList<>(); conditions.add(TABLE.TEMPLATE_ID.eq(ULong.valueOf(parentId))); Result< - Record15> result = + Record16> result = context - .select(TABLE.ID, TABLE.TEMPLATE_ID, TABLE.STEP_ID, TABLE.SCRIPT_TYPE, TABLE.SCRIPT_ID, - TABLE.SCRIPT_VERSION_ID, TABLE.CONTENT, TABLE.LANGUAGE, TABLE.SCRIPT_PARAM, - TABLE.SCRIPT_TIMEOUT, TABLE.EXECUTE_ACCOUNT, TABLE.DESTINATION_HOST_LIST, - TABLE.IS_SECURE_PARAM, TABLE.STATUS, TABLE.IGNORE_ERROR) - .from(TABLE).where(conditions).fetch(); + .select( + TABLE.ID, + TABLE.TEMPLATE_ID, + TABLE.STEP_ID, + TABLE.SCRIPT_TYPE, + TABLE.SCRIPT_ID, + TABLE.SCRIPT_VERSION_ID, + TABLE.CONTENT, + TABLE.LANGUAGE, + TABLE.SCRIPT_PARAM, + TABLE.SCRIPT_TIMEOUT, + TABLE.EXECUTE_ACCOUNT, + TABLE.DESTINATION_HOST_LIST, + TABLE.IS_SECURE_PARAM, + TABLE.STATUS, + TABLE.IGNORE_ERROR, + TABLE.SECURE_PARAM_ENCRYPT_ALGORITHM + ).from(TABLE).where(conditions).fetch(); List taskScriptStepList = new ArrayList<>(); - if (result != null && result.size() >= 1) { - result.map(record -> taskScriptStepList - .add(DbRecordMapper.convertRecordToTaskScriptStep(record, TaskTypeEnum.TEMPLATE))); + if (result.size() >= 1) { + result.map(record -> + taskScriptStepList.add(convertRecordToTaskScriptStep(record)) + ); } return taskScriptStepList; } @@ -103,20 +151,35 @@ public Map listScriptStepByIds(List stepIdList) { List conditions = new ArrayList<>(); conditions.add(TABLE.STEP_ID.in(stepIdList.stream().map(ULong::valueOf).collect(Collectors.toList()))); Result< - Record15> result = + Record16> result = context - .select(TABLE.ID, TABLE.TEMPLATE_ID, TABLE.STEP_ID, TABLE.SCRIPT_TYPE, TABLE.SCRIPT_ID, - TABLE.SCRIPT_VERSION_ID, TABLE.CONTENT, TABLE.LANGUAGE, TABLE.SCRIPT_PARAM, - TABLE.SCRIPT_TIMEOUT, TABLE.EXECUTE_ACCOUNT, TABLE.DESTINATION_HOST_LIST, - TABLE.IS_SECURE_PARAM, TABLE.STATUS, TABLE.IGNORE_ERROR) - .from(TABLE).where(conditions).fetch(); + .select( + TABLE.ID, + TABLE.TEMPLATE_ID, + TABLE.STEP_ID, + TABLE.SCRIPT_TYPE, + TABLE.SCRIPT_ID, + TABLE.SCRIPT_VERSION_ID, + TABLE.CONTENT, + TABLE.LANGUAGE, + TABLE.SCRIPT_PARAM, + TABLE.SCRIPT_TIMEOUT, + TABLE.EXECUTE_ACCOUNT, + TABLE.DESTINATION_HOST_LIST, + TABLE.IS_SECURE_PARAM, + TABLE.STATUS, + TABLE.IGNORE_ERROR, + TABLE.SECURE_PARAM_ENCRYPT_ALGORITHM + ).from(TABLE).where(conditions).fetch(); Map taskScriptStepMap = new HashMap<>(stepIdList.size()); - if (result != null && result.size() >= 1) { - result.map(record -> taskScriptStepMap.put(record.get(TABLE.STEP_ID).longValue(), - DbRecordMapper.convertRecordToTaskScriptStep(record, TaskTypeEnum.TEMPLATE))); + if (result.size() >= 1) { + result.map(record -> taskScriptStepMap.put( + record.get(TABLE.STEP_ID).longValue(), + convertRecordToTaskScriptStep(record) + )); } return taskScriptStepMap; } @@ -125,13 +188,27 @@ public Map listScriptStepByIds(List stepIdList) { public TaskScriptStepDTO getScriptStepById(long stepId) { List conditions = new ArrayList<>(); conditions.add(TABLE.STEP_ID.eq(ULong.valueOf(stepId))); - Record15 record = context.select(TABLE.ID, TABLE.TEMPLATE_ID, TABLE.STEP_ID, TABLE.SCRIPT_TYPE, - TABLE.SCRIPT_ID, TABLE.SCRIPT_VERSION_ID, TABLE.CONTENT, TABLE.LANGUAGE, TABLE.SCRIPT_PARAM, - TABLE.SCRIPT_TIMEOUT, TABLE.EXECUTE_ACCOUNT, TABLE.DESTINATION_HOST_LIST, TABLE.IS_SECURE_PARAM, - TABLE.STATUS, TABLE.IGNORE_ERROR).from(TABLE).where(conditions).fetchOne(); + Record16 record = context.select( + TABLE.ID, + TABLE.TEMPLATE_ID, + TABLE.STEP_ID, + TABLE.SCRIPT_TYPE, + TABLE.SCRIPT_ID, + TABLE.SCRIPT_VERSION_ID, + TABLE.CONTENT, + TABLE.LANGUAGE, + TABLE.SCRIPT_PARAM, + TABLE.SCRIPT_TIMEOUT, + TABLE.EXECUTE_ACCOUNT, + TABLE.DESTINATION_HOST_LIST, + TABLE.IS_SECURE_PARAM, + TABLE.STATUS, + TABLE.IGNORE_ERROR, + TABLE.SECURE_PARAM_ENCRYPT_ALGORITHM + ).from(TABLE).where(conditions).fetchOne(); if (record != null) { - return DbRecordMapper.convertRecordToTaskScriptStep(record, TaskTypeEnum.TEMPLATE); + return convertRecordToTaskScriptStep(record); } else { return null; } @@ -148,18 +225,40 @@ public long insertScriptStep(TaskScriptStepDTO scriptStep) { ignoreError = UByte.valueOf(1); } TaskTemplateStepScriptRecord record = context.insertInto(TABLE) - .columns(TABLE.TEMPLATE_ID, TABLE.STEP_ID, TABLE.SCRIPT_TYPE, TABLE.SCRIPT_ID, TABLE.SCRIPT_VERSION_ID, - TABLE.CONTENT, TABLE.LANGUAGE, TABLE.SCRIPT_PARAM, TABLE.SCRIPT_TIMEOUT, TABLE.EXECUTE_ACCOUNT, - TABLE.DESTINATION_HOST_LIST, TABLE.IS_SECURE_PARAM, TABLE.STATUS, TABLE.IGNORE_ERROR) - .values(ULong.valueOf(scriptStep.getTemplateId()), ULong.valueOf(scriptStep.getStepId()), - UByte.valueOf(scriptStep.getScriptSource().getType()), scriptStep.getScriptId(), + .columns( + TABLE.TEMPLATE_ID, + TABLE.STEP_ID, + TABLE.SCRIPT_TYPE, + TABLE.SCRIPT_ID, + TABLE.SCRIPT_VERSION_ID, + TABLE.CONTENT, + TABLE.LANGUAGE, + TABLE.SCRIPT_PARAM, + TABLE.SCRIPT_TIMEOUT, + TABLE.EXECUTE_ACCOUNT, + TABLE.DESTINATION_HOST_LIST, + TABLE.IS_SECURE_PARAM, + TABLE.STATUS, + TABLE.IGNORE_ERROR, + TABLE.SECURE_PARAM_ENCRYPT_ALGORITHM + ).values( + ULong.valueOf(scriptStep.getTemplateId()), + ULong.valueOf(scriptStep.getStepId()), + UByte.valueOf(scriptStep.getScriptSource().getType()), + scriptStep.getScriptId(), scriptStep.getScriptVersionId() == null ? null : ULong.valueOf(scriptStep.getScriptVersionId()), - scriptStep.getContent(), UByte.valueOf(scriptStep.getLanguage().getValue()), - scriptStep.getScriptParam(), ULong.valueOf(scriptStep.getTimeout()), + scriptStep.getContent(), + UByte.valueOf(scriptStep.getLanguage().getValue()), + sensitiveParamService.encryptParamIfNeeded(scriptStep.getSecureParam(), scriptStep.getScriptParam()), + ULong.valueOf(scriptStep.getTimeout()), ULong.valueOf(scriptStep.getAccount()), - scriptStep.getExecuteTarget() == null ? null : scriptStep.getExecuteTarget().toJsonString(), isSecureParam, - UByte.valueOf(scriptStep.getStatus()), ignoreError) - .returning(TABLE.ID).fetchOne(); + scriptStep.getExecuteTarget() == null ? null : scriptStep.getExecuteTarget().toJsonString(), + isSecureParam, + UByte.valueOf(scriptStep.getStatus()), + ignoreError, + sensitiveParamService.getSecureParamEncryptAlgorithm(scriptStep.getSecureParam()) + ).returning(TABLE.ID).fetchOne(); + assert record != null; return record.getId().longValue(); } @@ -181,7 +280,10 @@ public boolean updateScriptStepById(TaskScriptStepDTO scriptStep) { scriptStep.getScriptVersionId() == null ? null : ULong.valueOf(scriptStep.getScriptVersionId())) .set(TABLE.CONTENT, scriptStep.getContent()) .set(TABLE.LANGUAGE, UByte.valueOf(scriptStep.getLanguage().getValue())) - .set(TABLE.SCRIPT_PARAM, scriptStep.getScriptParam()) + .set(TABLE.SCRIPT_PARAM, sensitiveParamService.encryptParamIfNeeded( + scriptStep.getSecureParam(), scriptStep.getScriptParam())) + .set(TABLE.SECURE_PARAM_ENCRYPT_ALGORITHM, + sensitiveParamService.getSecureParamEncryptAlgorithm(scriptStep.getSecureParam())) .set(TABLE.SCRIPT_TIMEOUT, ULong.valueOf(scriptStep.getTimeout())) .set(TABLE.EXECUTE_ACCOUNT, ULong.valueOf(scriptStep.getAccount())) .set(TABLE.DESTINATION_HOST_LIST, @@ -209,7 +311,7 @@ public List batchListScriptStepIdByParentIds(List templ Result> result = context .select(TABLE.TEMPLATE_ID, TABLE.SCRIPT_ID, TABLE.SCRIPT_VERSION_ID).from(TABLE).where(conditions).fetch(); List taskScriptStepList = new ArrayList<>(); - if (result != null && result.size() > 0) { + if (result.size() > 0) { result.map(record -> { TaskScriptStepDTO taskScriptStep = new TaskScriptStepDTO(); taskScriptStep.setTemplateId(record.get(TABLE.TEMPLATE_ID).longValue()); @@ -239,10 +341,16 @@ public int countScriptSteps(Long appId, TaskScriptSourceEnum scriptSource) { if (scriptSource != null) { conditions.add(tableTTStepScript.SCRIPT_TYPE.eq(UByte.valueOf(scriptSource.getType()))); } - return context.selectCount().from(tableTTStepScript) - .join(tableTTStep).on(tableTTStep.ID.eq(tableTTStepScript.STEP_ID)) - .join(tableTaskTemplate).on(tableTTStep.TEMPLATE_ID.eq(tableTaskTemplate.ID)) - .where(conditions).fetchOne().value1(); + Record1 record = context.selectCount() + .from(tableTTStepScript) + .join(tableTTStep) + .on(tableTTStep.ID.eq(tableTTStepScript.STEP_ID)) + .join(tableTaskTemplate) + .on(tableTTStep.TEMPLATE_ID.eq(tableTaskTemplate.ID)) + .where(conditions) + .fetchOne(); + assert record != null; + return record.value1(); } @Override @@ -254,10 +362,16 @@ public int countScriptCitedByStepsByScriptIds(Long appId, List scriptIdL if (scriptIdList != null) { conditions.add(tableTTStepScript.SCRIPT_ID.in(scriptIdList)); } - return context.select(DSL.countDistinct(tableTTStepScript.SCRIPT_ID)).from(tableTTStepScript) - .join(tableTTStep).on(tableTTStep.ID.eq(tableTTStepScript.STEP_ID)) - .join(tableTaskTemplate).on(tableTTStep.TEMPLATE_ID.eq(tableTaskTemplate.ID)) - .where(conditions).fetchOne().value1(); + Record1 record = context.select(DSL.countDistinct(tableTTStepScript.SCRIPT_ID)) + .from(tableTTStepScript) + .join(tableTTStep) + .on(tableTTStep.ID.eq(tableTTStepScript.STEP_ID)) + .join(tableTaskTemplate) + .on(tableTTStep.TEMPLATE_ID.eq(tableTaskTemplate.ID)) + .where(conditions) + .fetchOne(); + assert record != null; + return record.value1(); } @Override @@ -269,10 +383,16 @@ public int countScriptStepsByScriptIds(Long appId, List scriptIdList) { if (scriptIdList != null) { conditions.add(tableTTStepScript.SCRIPT_ID.in(scriptIdList)); } - return context.selectCount().from(tableTTStepScript) - .join(tableTTStep).on(tableTTStep.ID.eq(tableTTStepScript.STEP_ID)) - .join(tableTaskTemplate).on(tableTTStep.TEMPLATE_ID.eq(tableTaskTemplate.ID)) - .where(conditions).fetchOne().value1(); + Record1 record = context.selectCount() + .from(tableTTStepScript) + .join(tableTTStep) + .on(tableTTStep.ID.eq(tableTTStepScript.STEP_ID)) + .join(tableTaskTemplate) + .on(tableTTStep.TEMPLATE_ID.eq(tableTaskTemplate.ID)) + .where(conditions) + .fetchOne(); + assert record != null; + return record.value1(); } @Override diff --git a/support-files/sql/job-execute/0023_job_execute_20230519-1000_V3.8.0_mysql.sql b/support-files/sql/job-execute/0023_job_execute_20230519-1000_V3.8.0_mysql.sql new file mode 100644 index 0000000000..5edef0eaad --- /dev/null +++ b/support-files/sql/job-execute/0023_job_execute_20230519-1000_V3.8.0_mysql.sql @@ -0,0 +1,31 @@ +USE job_execute; + +SET NAMES utf8mb4; + +DROP PROCEDURE IF EXISTS job_schema_update; + +DELIMITER + +CREATE PROCEDURE job_schema_update() +BEGIN + + DECLARE db VARCHAR(100); + SET AUTOCOMMIT = 0; + SELECT DATABASE() INTO db; + + IF NOT EXISTS(SELECT 1 + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'step_instance_script' + AND COLUMN_NAME = 'secure_param_encrypt_algorithm') THEN + ALTER TABLE step_instance_script ADD COLUMN `secure_param_encrypt_algorithm` varchar(32) NOT NULL DEFAULT "None"; + END IF; + + COMMIT; +END +DELIMITER ; +COMMIT; + +CALL job_schema_update(); + +DROP PROCEDURE IF EXISTS job_schema_update; diff --git a/support-files/sql/job-manage/0031_job_manage_20230519-1000_V3.8.0_mysql.sql b/support-files/sql/job-manage/0031_job_manage_20230519-1000_V3.8.0_mysql.sql new file mode 100644 index 0000000000..0d81eef5a8 --- /dev/null +++ b/support-files/sql/job-manage/0031_job_manage_20230519-1000_V3.8.0_mysql.sql @@ -0,0 +1,38 @@ +USE job_manage; + +SET NAMES utf8mb4; + +DROP PROCEDURE IF EXISTS job_schema_update; + +DELIMITER + +CREATE PROCEDURE job_schema_update() +BEGIN + + DECLARE db VARCHAR(100); + SET AUTOCOMMIT = 0; + SELECT DATABASE() INTO db; + + -- Update `task_template_step_script` schema + IF NOT EXISTS(SELECT 1 + FROM information_schema.columns + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'task_template_step_script' + AND COLUMN_NAME = 'secure_param_encrypt_algorithm') THEN + ALTER TABLE task_template_step_script ADD COLUMN secure_param_encrypt_algorithm varchar(32) NOT NULL DEFAULT "None"; + END IF; + + IF NOT EXISTS(SELECT 1 + FROM information_schema.columns + WHERE TABLE_SCHEMA = db + AND TABLE_NAME = 'task_plan_step_script' + AND COLUMN_NAME = 'secure_param_encrypt_algorithm') THEN + ALTER TABLE task_plan_step_script ADD COLUMN secure_param_encrypt_algorithm varchar(32) NOT NULL DEFAULT "None"; + END IF; + +COMMIT; +END +DELIMITER ; +CALL job_schema_update(); + +DROP PROCEDURE IF EXISTS job_schema_update;