This is an automated email from the ASF dual-hosted git repository.
klion26 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/amoro.git
The following commit(s) were added to refs/heads/master by this push:
new 66a5254e5 [AMORO-3335] Add interface ConfigShade to support encryption
of sensitive configuration items and provide a base64 encoding implementation
(#3396)
66a5254e5 is described below
commit 66a5254e56cc62c27e4d6f4a890237059ee11756
Author: Jzjsnow <[email protected]>
AuthorDate: Wed Feb 5 10:09:16 2025 +0800
[AMORO-3335] Add interface ConfigShade to support encryption of sensitive
configuration items and provide a base64 encoding implementation (#3396)
* [AMORO-3335] Add interface ConfigShade to support encryption of sensitive
configuration items and provide a base64 encoding implementation
---
.../apache/amoro/server/AmoroServiceContainer.java | 6 +-
.../amoro/server/config/TestConfigShade.java | 137 +++++++++++++++++++++
.../resources/configs/config-base64-shade.yaml | 38 ++++++
.../resources/configs/config-default-shade.yaml | 37 ++++++
.../org/apache/amoro/config/shade/ConfigShade.java | 48 ++++++++
.../amoro/config/shade/impl/Base64ConfigShade.java | 41 ++++++
.../amoro/config/shade/utils/ConfigShadeUtils.java | 137 +++++++++++++++++++++
.../org.apache.amoro.config.shade.ConfigShade | 20 +++
charts/amoro/templates/amoro-configmap.yaml | 13 +-
charts/amoro/tests/amoro-configmap_test.yaml | 28 +++++
charts/amoro/values.yaml | 6 +
dist/src/main/amoro-bin/conf/config.yaml | 5 +
12 files changed, 514 insertions(+), 2 deletions(-)
diff --git
a/amoro-ams/src/main/java/org/apache/amoro/server/AmoroServiceContainer.java
b/amoro-ams/src/main/java/org/apache/amoro/server/AmoroServiceContainer.java
index f2880ebf6..a751eeea1 100644
--- a/amoro-ams/src/main/java/org/apache/amoro/server/AmoroServiceContainer.java
+++ b/amoro-ams/src/main/java/org/apache/amoro/server/AmoroServiceContainer.java
@@ -27,6 +27,7 @@ import org.apache.amoro.api.AmoroTableMetastore;
import org.apache.amoro.api.OptimizingService;
import org.apache.amoro.config.ConfigHelpers;
import org.apache.amoro.config.Configurations;
+import org.apache.amoro.config.shade.utils.ConfigShadeUtils;
import org.apache.amoro.exception.AmoroRuntimeException;
import org.apache.amoro.server.catalog.CatalogManager;
import org.apache.amoro.server.catalog.DefaultCatalogManager;
@@ -459,6 +460,8 @@ public class AmoroServiceContainer {
// If same configurations in files and environment variables,
environment variables have
// higher priority.
expandedConfigurationMap.putAll(envConfig);
+ // Decrypt the sensitive configurations if specified
+ expandedConfigurationMap =
ConfigShadeUtils.decryptConfig(expandedConfigurationMap);
serviceConfig = Configurations.fromObjectMap(expandedConfigurationMap);
AmoroManagementConfValidator.validateConfig(serviceConfig);
dataSource = DataSourceFactory.createDataSource(serviceConfig);
@@ -533,7 +536,8 @@ public class AmoroServiceContainer {
}
@SuppressWarnings("unchecked")
- private void expandConfigMap(
+ @VisibleForTesting
+ public static void expandConfigMap(
Map<String, Object> config, String prefix, Map<String, Object> result) {
for (Map.Entry<String, Object> entry : config.entrySet()) {
String key = entry.getKey();
diff --git
a/amoro-ams/src/test/java/org/apache/amoro/server/config/TestConfigShade.java
b/amoro-ams/src/test/java/org/apache/amoro/server/config/TestConfigShade.java
new file mode 100644
index 000000000..92530936f
--- /dev/null
+++
b/amoro-ams/src/test/java/org/apache/amoro/server/config/TestConfigShade.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.amoro.server.config;
+
+import static org.apache.amoro.server.AmoroServiceContainer.expandConfigMap;
+
+import org.apache.amoro.config.shade.impl.Base64ConfigShade;
+import org.apache.amoro.config.shade.utils.ConfigShadeUtils;
+import org.apache.amoro.server.AmoroManagementConf;
+import org.apache.amoro.shade.guava32.com.google.common.collect.ImmutableMap;
+import org.apache.amoro.shade.guava32.com.google.common.collect.Maps;
+import org.apache.amoro.shade.guava32.com.google.common.io.Resources;
+import
org.apache.amoro.shade.jackson2.com.fasterxml.jackson.core.type.TypeReference;
+import org.apache.amoro.shade.jackson2.com.fasterxml.jackson.databind.JsonNode;
+import org.apache.amoro.utils.JacksonUtil;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.yaml.snakeyaml.Yaml;
+
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Base64;
+import java.util.Map;
+
+public class TestConfigShade {
+ private static final String USERNAME = "admin";
+ private static final String PASSWORD = "password";
+
+ private static final String BASE64_CONFIG_SHADE_IDENTIFIER =
+ new Base64ConfigShade().getIdentifier();
+
+ @Test
+ public void testDecryptOptions() {
+ String encryptUsername = getBase64EncodedText(USERNAME);
+ String encryptPassword = getBase64EncodedText(PASSWORD);
+ Assertions.assertEquals(encryptUsername, "YWRtaW4=");
+ Assertions.assertEquals(encryptPassword, "cGFzc3dvcmQ=");
+
+ String decryptUsername =
+ ConfigShadeUtils.decryptOption(BASE64_CONFIG_SHADE_IDENTIFIER,
encryptUsername);
+ String decryptPassword =
+ ConfigShadeUtils.decryptOption(BASE64_CONFIG_SHADE_IDENTIFIER,
encryptPassword);
+ Assertions.assertEquals(decryptUsername, USERNAME);
+ Assertions.assertEquals(decryptPassword, PASSWORD);
+ }
+
+ private String getBase64EncodedText(String plaintext) {
+ return
Base64.getEncoder().encodeToString(plaintext.getBytes(StandardCharsets.UTF_8));
+ }
+
+ @Test
+ void testDecryptServiceConfigWithDefaultShade() throws Exception {
+ URL resource = Resources.getResource("configs/config-default-shade.yaml");
+ JsonNode yamlConfig =
+ JacksonUtil.fromObjects(
+ new
Yaml().loadAs(Files.newInputStream(Paths.get(resource.toURI())), Map.class));
+ Map<String, Object> systemConfig =
+ JacksonUtil.getMap(
+ yamlConfig,
+ AmoroManagementConf.SYSTEM_CONFIG,
+ new TypeReference<Map<String, Object>>() {});
+ Map<String, Object> expandedConfigurationMap = Maps.newHashMap();
+ expandConfigMap(systemConfig, "", expandedConfigurationMap);
+ expandedConfigurationMap =
ConfigShadeUtils.decryptConfig(expandedConfigurationMap);
+
+ Assertions.assertEquals(decryptedServiceConfigWithDefaultShade,
expandedConfigurationMap);
+ }
+
+ @Test
+ void testDecryptServiceConfigWithBase64Shade() throws Exception {
+ URL resource = Resources.getResource("configs/config-base64-shade.yaml");
+ JsonNode yamlConfig =
+ JacksonUtil.fromObjects(
+ new
Yaml().loadAs(Files.newInputStream(Paths.get(resource.toURI())), Map.class));
+ Map<String, Object> systemConfig =
+ JacksonUtil.getMap(
+ yamlConfig,
+ AmoroManagementConf.SYSTEM_CONFIG,
+ new TypeReference<Map<String, Object>>() {});
+ Map<String, Object> expandedConfigurationMap = Maps.newHashMap();
+ expandConfigMap(systemConfig, "", expandedConfigurationMap);
+ expandedConfigurationMap =
ConfigShadeUtils.decryptConfig(expandedConfigurationMap);
+
+ Assertions.assertEquals(decryptedServiceConfigWithBase64Shade,
expandedConfigurationMap);
+ }
+
+ private final Map<String, String> decryptedServiceConfigWithDefaultShade =
+ ImmutableMap.<String, String>builder()
+ .put("admin-username", "admin")
+ .put("admin-password", "admin")
+ .put("server-bind-host", "0.0.0.0")
+ .put("server-expose-host", "127.0.0.1")
+ .put("shade.identifier", "default")
+ .put("database.type", "mysql")
+ .put("database.jdbc-driver-class", "com.mysql.cj.jdbc.Driver")
+ .put(
+ "database.url",
+
"jdbc:mysql://127.0.0.1:3306/amoro?useUnicode=true&characterEncoding=UTF8&autoReconnect=true&useAffectedRows=true&allowPublicKeyRetrieval=true&useSSL=false")
+ .put("database.username", "root")
+ .put("database.password", "password")
+ .build();
+
+ private final Map<String, String> decryptedServiceConfigWithBase64Shade =
+ ImmutableMap.<String, String>builder()
+ .put("admin-username", "admin")
+ .put("admin-password", "admin")
+ .put("server-bind-host", "0.0.0.0")
+ .put("server-expose-host", "127.0.0.1")
+ .put("shade.identifier", "base64")
+ .put("shade.sensitive-keywords", "admin-password;database.password")
+ .put("database.type", "mysql")
+ .put("database.jdbc-driver-class", "com.mysql.cj.jdbc.Driver")
+ .put(
+ "database.url",
+
"jdbc:mysql://127.0.0.1:3306/amoro?useUnicode=true&characterEncoding=UTF8&autoReconnect=true&useAffectedRows=true&allowPublicKeyRetrieval=true&useSSL=false")
+ .put("database.username", "root")
+ .put("database.password", "password")
+ .build();
+}
diff --git a/amoro-ams/src/test/resources/configs/config-base64-shade.yaml
b/amoro-ams/src/test/resources/configs/config-base64-shade.yaml
new file mode 100644
index 000000000..9338ecbb9
--- /dev/null
+++ b/amoro-ams/src/test/resources/configs/config-base64-shade.yaml
@@ -0,0 +1,38 @@
+################################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+################################################################################
+
+ams:
+ admin-username: admin
+ admin-password: YWRtaW4=
+ server-bind-host: "0.0.0.0"
+ server-expose-host: "127.0.0.1"
+
+ shade:
+ identifier: base64
+ sensitive-keywords: admin-password;database.password
+
+ database:
+ type: mysql
+ jdbc-driver-class: com.mysql.cj.jdbc.Driver
+ url:
jdbc:mysql://127.0.0.1:3306/amoro?useUnicode=true&characterEncoding=UTF8&autoReconnect=true&useAffectedRows=true&allowPublicKeyRetrieval=true&useSSL=false
+ username: root
+ password: cGFzc3dvcmQ=
+
+containers:
+ - name: localContainer
+ container-impl: org.apache.amoro.server.manager.LocalOptimizerContainer
\ No newline at end of file
diff --git a/amoro-ams/src/test/resources/configs/config-default-shade.yaml
b/amoro-ams/src/test/resources/configs/config-default-shade.yaml
new file mode 100644
index 000000000..c512b891f
--- /dev/null
+++ b/amoro-ams/src/test/resources/configs/config-default-shade.yaml
@@ -0,0 +1,37 @@
+################################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+################################################################################
+
+ams:
+ admin-username: admin
+ admin-password: admin
+ server-bind-host: "0.0.0.0"
+ server-expose-host: "127.0.0.1"
+
+ shade:
+ identifier: default
+
+ database:
+ type: mysql
+ jdbc-driver-class: com.mysql.cj.jdbc.Driver
+ url:
jdbc:mysql://127.0.0.1:3306/amoro?useUnicode=true&characterEncoding=UTF8&autoReconnect=true&useAffectedRows=true&allowPublicKeyRetrieval=true&useSSL=false
+ username: root
+ password: password
+
+containers:
+ - name: localContainer
+ container-impl: org.apache.amoro.server.manager.LocalOptimizerContainer
\ No newline at end of file
diff --git
a/amoro-common/src/main/java/org/apache/amoro/config/shade/ConfigShade.java
b/amoro-common/src/main/java/org/apache/amoro/config/shade/ConfigShade.java
new file mode 100644
index 000000000..07d223ebb
--- /dev/null
+++ b/amoro-common/src/main/java/org/apache/amoro/config/shade/ConfigShade.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.amoro.config.shade;
+
+import org.apache.amoro.config.Configurations;
+
+/**
+ * The interface that provides the ability to decrypt {@link
+ * org.apache.amoro.config.Configurations}.
+ */
+public interface ConfigShade {
+ /**
+ * Initializes the custom instance using the AMS configuration.
+ *
+ * <p>This method can be useful when decryption requires an external file
(e.g. a key file)
+ * defined in the service configs.
+ */
+ default void initialize(Configurations serviceConfig) throws Exception {}
+
+ /**
+ * The unique identifier of the current interface, used it to select the
expected {@link
+ * ConfigShade}.
+ */
+ String getIdentifier();
+
+ /**
+ * Decrypt the content.
+ *
+ * @param content The content to decrypt
+ */
+ String decrypt(String content);
+}
diff --git
a/amoro-common/src/main/java/org/apache/amoro/config/shade/impl/Base64ConfigShade.java
b/amoro-common/src/main/java/org/apache/amoro/config/shade/impl/Base64ConfigShade.java
new file mode 100644
index 000000000..0446e626c
--- /dev/null
+++
b/amoro-common/src/main/java/org/apache/amoro/config/shade/impl/Base64ConfigShade.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.amoro.config.shade.impl;
+
+import org.apache.amoro.config.shade.ConfigShade;
+
+import java.util.Base64;
+
+/** Base64 ConfigShade. */
+public class Base64ConfigShade implements ConfigShade {
+
+ private static final Base64.Decoder DECODER = Base64.getDecoder();
+
+ private static final String IDENTIFIER = "base64";
+
+ @Override
+ public String getIdentifier() {
+ return IDENTIFIER;
+ }
+
+ @Override
+ public String decrypt(String content) {
+ return new String(DECODER.decode(content));
+ }
+}
diff --git
a/amoro-common/src/main/java/org/apache/amoro/config/shade/utils/ConfigShadeUtils.java
b/amoro-common/src/main/java/org/apache/amoro/config/shade/utils/ConfigShadeUtils.java
new file mode 100644
index 000000000..53ef1d740
--- /dev/null
+++
b/amoro-common/src/main/java/org/apache/amoro/config/shade/utils/ConfigShadeUtils.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.amoro.config.shade.utils;
+
+import org.apache.amoro.config.ConfigOption;
+import org.apache.amoro.config.ConfigOptions;
+import org.apache.amoro.config.Configurations;
+import org.apache.amoro.config.shade.ConfigShade;
+import
org.apache.amoro.shade.guava32.com.google.common.annotations.VisibleForTesting;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.function.BiFunction;
+
+/** Config shade utilities. */
+public final class ConfigShadeUtils {
+ private static final Logger LOG =
LoggerFactory.getLogger(ConfigShadeUtils.class);
+
+ private static final Map<String, ConfigShade> CONFIG_SHADES = new
HashMap<>();
+
+ private static final ConfigShade DEFAULT_SHADE = new DefaultConfigShade();
+
+ public static final ConfigOption<String> SHADE_IDENTIFIER_OPTION =
+ ConfigOptions.key("shade.identifier")
+ .stringType()
+ .defaultValue("default")
+ .withDescription(
+ "The identifier of the encryption method for decryption.
Defaults to \"default\", indicating no encryption");
+
+ public static final ConfigOption<List<String>> SHADE_SENSITIVE_KEYWORDS =
+ ConfigOptions.key("shade.sensitive-keywords")
+ .stringType()
+ .asList()
+ .defaultValues("admin-password", "database.password")
+ .withDescription(
+ "A semicolon-separated list of keywords for the configuration
items to be decrypted.");
+
+ static {
+ ServiceLoader<ConfigShade> serviceLoader =
ServiceLoader.load(ConfigShade.class);
+ Iterator<ConfigShade> it = serviceLoader.iterator();
+ it.forEachRemaining(
+ configShade -> {
+ CONFIG_SHADES.put(configShade.getIdentifier(), configShade);
+ LOG.info(
+ "Load config shade spi [{}] from {}",
+ configShade.getIdentifier(),
+ configShade.getClass());
+ });
+ }
+
+ @VisibleForTesting
+ public static String decryptOption(String identifier, String content) {
+ ConfigShade configShade = CONFIG_SHADES.getOrDefault(identifier,
DEFAULT_SHADE);
+ return configShade.decrypt(content);
+ }
+
+ public static Map<String, Object> decryptConfig(Map<String, Object>
configMap) throws Exception {
+ Configurations serviceConfig = Configurations.fromObjectMap(configMap);
+ String identifier = serviceConfig.get(SHADE_IDENTIFIER_OPTION);
+ List<String> sensitiveOptions =
serviceConfig.get(SHADE_SENSITIVE_KEYWORDS);
+ return decryptConfig(identifier, configMap, sensitiveOptions,
serviceConfig);
+ }
+
+ public static Map<String, Object> decryptConfig(
+ String identifier,
+ Map<String, Object> configMap,
+ List<String> sensitiveOptions,
+ Configurations serviceConfig)
+ throws Exception {
+ ConfigShade configShade = CONFIG_SHADES.get(identifier);
+ if (configShade == null) {
+ LOG.error("Can not find config shade: {}", identifier);
+ throw new IllegalStateException("Can not find config shade: " +
identifier);
+ }
+ configShade.initialize(serviceConfig);
+
+ if (DEFAULT_SHADE.getIdentifier().equals(configShade.getIdentifier())) {
+ return configMap;
+ }
+
+ LOG.info("Use config shade: {}", identifier);
+ BiFunction<String, Object, String> processFunction =
+ (key, value) -> configShade.decrypt(value.toString());
+
+ for (String sensitiveOption : sensitiveOptions) {
+ try {
+ configMap.computeIfPresent(sensitiveOption, processFunction);
+ } catch (Exception e) {
+ LOG.error("Failed to decrypt sensitive option {}:", sensitiveOption,
e);
+ throw e;
+ }
+ }
+ LOG.info(
+ "Sensitive option{} {} {} been decrypted and refreshed",
+ sensitiveOptions.size() > 1 ? "s" : "",
+ sensitiveOptions,
+ sensitiveOptions.size() > 1 ? "have" : "has");
+
+ return configMap;
+ }
+
+ /** Default ConfigShade. */
+ public static class DefaultConfigShade implements ConfigShade {
+ private static final String IDENTIFIER = "default";
+
+ @Override
+ public String getIdentifier() {
+ return IDENTIFIER;
+ }
+
+ @Override
+ public String decrypt(String content) {
+ return content;
+ }
+ }
+}
diff --git
a/amoro-common/src/main/resources/META-INF/services/org.apache.amoro.config.shade.ConfigShade
b/amoro-common/src/main/resources/META-INF/services/org.apache.amoro.config.shade.ConfigShade
new file mode 100644
index 000000000..8d3697dc0
--- /dev/null
+++
b/amoro-common/src/main/resources/META-INF/services/org.apache.amoro.config.shade.ConfigShade
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+# *
+# http://www.apache.org/licenses/LICENSE-2.0
+# *
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.amoro.config.shade.utils.ConfigShadeUtils$DefaultConfigShade
+org.apache.amoro.config.shade.impl.Base64ConfigShade
\ No newline at end of file
diff --git a/charts/amoro/templates/amoro-configmap.yaml
b/charts/amoro/templates/amoro-configmap.yaml
index bf06c4038..ec4cb9c83 100644
--- a/charts/amoro/templates/amoro-configmap.yaml
+++ b/charts/amoro/templates/amoro-configmap.yaml
@@ -40,7 +40,18 @@ data:
ams:
server-bind-host: "0.0.0.0"
server-expose-host: "127.0.0.1"
-
+
+ {{- if or .Values.amoroConf.shade.identifier
.Values.amoroConf.shade.sensitiveKeywords}}
+
+ shade:
+ {{- if .Values.amoroConf.shade.identifier }}
+ identifier: {{ .Values.amoroConf.shade.identifier }}
+ {{- end }}
+ {{- if .Values.amoroConf.shade.sensitiveKeywords }}
+ sensitive-keywords: {{ .Values.amoroConf.shade.sensitiveKeywords }}
+ {{- end }}
+ {{- end }}
+
thrift-server:
max-message-size: 104857600 # 100MB
selector-thread-count: 2
diff --git a/charts/amoro/tests/amoro-configmap_test.yaml
b/charts/amoro/tests/amoro-configmap_test.yaml
index 73a5fe97c..66d674fc8 100644
--- a/charts/amoro/tests/amoro-configmap_test.yaml
+++ b/charts/amoro/tests/amoro-configmap_test.yaml
@@ -73,6 +73,34 @@ tests:
pattern:
|
kyuubi.jdbc.url: "jdbc:hive2://127.0.0.1:10009/"
+ - it: Amoro configMap should show shade configs if shade.identifier is set
+ set:
+ amoroConf:
+ shade:
+ identifier: base64
+ asserts:
+ - matchRegex:
+ path: data["config.yaml"]
+ pattern: "shade:\\s*identifier: base64"
+ - it: Amoro configMap should show shade configs if shade.sensitiveKeywords
is set
+ set:
+ amoroConf:
+ shade:
+ sensitiveKeywords: admin-password;database.password
+ asserts:
+ - matchRegex:
+ path: data["config.yaml"]
+ pattern: "shade:\\s*sensitive-keywords:
admin-password;database.password"
+ - it: Amoro configMap should show shade configs if both shade.identifier and
shade.sensitiveKeywords are set
+ set:
+ amoroConf:
+ shade:
+ identifier: base64
+ sensitiveKeywords: admin-password;database.password
+ asserts:
+ - matchRegex:
+ path: data["config.yaml"]
+ pattern: "shade:\\s*identifier: base64\\s*sensitive-keywords:
admin-password;database.password"
- it: Amoro configMap should show flink if flink optimizer enabled is set
true
set:
optimizer:
diff --git a/charts/amoro/values.yaml b/charts/amoro/values.yaml
index bcb058565..312fefaea 100644
--- a/charts/amoro/values.yaml
+++ b/charts/amoro/values.yaml
@@ -144,6 +144,12 @@ amoroConf:
adminUsername: admin
adminPassword: admin
+ ## AMS config shade properties
+ ##
+ shade:
+ identifier: ~
+ sensitiveKeywords: ~
+
## AMS database properties, default value is derby. For production
environment, suggest to use mysql
##
database:
diff --git a/dist/src/main/amoro-bin/conf/config.yaml
b/dist/src/main/amoro-bin/conf/config.yaml
index 0e8c6f5cb..6f3f4849d 100644
--- a/dist/src/main/amoro-bin/conf/config.yaml
+++ b/dist/src/main/amoro-bin/conf/config.yaml
@@ -94,6 +94,11 @@ ams:
catalog-meta-cache:
expiration-interval: 60s
+ # Support for encrypted sensitive configuration items
+ shade:
+ identifier: default # Built-in support for default/base64. Defaults to
"default", indicating no encryption
+ sensitive-keywords: admin-password;database.password
+
database:
type: derby
jdbc-driver-class: org.apache.derby.jdbc.EmbeddedDriver