This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.0 by this push:
new a7bfa14db6b branch-4.0: [feature](tde) Support rotating root key
command (#55901) #56342 (#56770)
a7bfa14db6b is described below
commit a7bfa14db6b449bd75fd59a7c8327fdcebda06a3
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sat Oct 11 16:00:01 2025 +0800
branch-4.0: [feature](tde) Support rotating root key command (#55901)
#56342 (#56770)
Cherry-picked from #56342
Co-authored-by: Siyang Tang <[email protected]>
---
.../antlr4/org/apache/doris/nereids/DorisLexer.g4 | 2 +
.../antlr4/org/apache/doris/nereids/DorisParser.g4 | 3 +
.../doris/encryption/KeyManagerInterface.java | 8 +++
.../org/apache/doris/encryption/RootKeyInfo.java | 35 ++++++++++-
.../doris/nereids/parser/LogicalPlanBuilder.java | 8 +++
.../apache/doris/nereids/trees/plans/PlanType.java | 1 +
.../commands/AdminRotateTdeRootKeyCommand.java | 67 ++++++++++++++++++++++
.../trees/plans/visitor/CommandVisitor.java | 5 ++
.../doris/nereids/parser/NereidsParserTest.java | 16 ++++++
9 files changed, 144 insertions(+), 1 deletion(-)
diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4
b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4
index 360a498f611..0e1dc32b32e 100644
--- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4
+++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisLexer.g4
@@ -468,6 +468,7 @@ ROLES: 'ROLES';
ROLLBACK: 'ROLLBACK';
ROLLUP: 'ROLLUP';
ROOT: 'ROOT';
+ROTATE: 'ROTATE';
ROUTINE: 'ROUTINE';
ROW: 'ROW';
ROWS: 'ROWS';
@@ -525,6 +526,7 @@ TABLETS: 'TABLETS';
TAG: 'TAG';
TASK: 'TASK';
TASKS: 'TASKS';
+TDE: 'TDE';
TEMPORARY: 'TEMPORARY';
TERMINATED: 'TERMINATED';
TEXT: 'TEXT';
diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
index 25075996fba..11bf78caa2b 100644
--- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
+++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4
@@ -608,6 +608,7 @@ supportedAdminStatement
| ADMIN SET AUTO CLUSTER SNAPSHOT propertyClause?
#adminSetAutoClusterSnapshot
| ADMIN DROP CLUSTER SNAPSHOT WHERE (key=identifier) EQ
(value=STRING_LITERAL) #adminDropClusterSnapshot
| ADMIN SET CLUSTER SNAPSHOT FEATURE (ON | OFF)
#adminSetClusterSnapshotFeatureSwitch
+ | ADMIN ROTATE TDE ROOT KEY properties=propertyClause?
#adminRotateTdeRootKey
;
supportedRecoverStatement
@@ -2141,6 +2142,7 @@ nonReserved
| ROLLBACK
| ROLLUP
| ROOT
+ | ROTATE
| ROUTINE
| S3
| SAMPLE
@@ -2179,6 +2181,7 @@ nonReserved
| TAG
| TASK
| TASKS
+ | TDE
| TEMPORARY
| TEXT
| THAN
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/encryption/KeyManagerInterface.java
b/fe/fe-core/src/main/java/org/apache/doris/encryption/KeyManagerInterface.java
index ea0e71e458e..a4c97b53e92 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/encryption/KeyManagerInterface.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/encryption/KeyManagerInterface.java
@@ -20,6 +20,7 @@ package org.apache.doris.encryption;
import org.apache.doris.persist.KeyOperationInfo;
import java.util.List;
+import java.util.Map;
/**
* Interface for managing cryptographic keys, including root key setup,
@@ -64,4 +65,11 @@ public interface KeyManagerInterface {
* (may include versioning or metadata as part of each key object)
*/
public List<EncryptionKey> getAllMasterKeys();
+
+ /**
+ * Rotate root key
+ *
+ * @param properties rotate info
+ */
+ void rotateRootKey(Map<String, String> properties) throws Exception;
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/encryption/RootKeyInfo.java
b/fe/fe-core/src/main/java/org/apache/doris/encryption/RootKeyInfo.java
index a379a125707..f056a5a95fe 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/encryption/RootKeyInfo.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/encryption/RootKeyInfo.java
@@ -19,9 +19,42 @@ package org.apache.doris.encryption;
import com.google.gson.annotations.SerializedName;
+import java.util.Objects;
+
public class RootKeyInfo {
public enum RootKeyType {
- LOCAL, AWS_KMS;
+ LOCAL("local"),
+ AWS_KMS("aws_kms");
+
+ public static RootKeyType tryFrom(String name) {
+ Objects.requireNonNull(name);
+ if (LOCAL.name.equalsIgnoreCase(name)) {
+ return LOCAL;
+ }
+ if (AWS_KMS.name.equalsIgnoreCase(name)) {
+ return AWS_KMS;
+ }
+ throw new IllegalArgumentException("invalid name" + name);
+ }
+
+ RootKeyType(String name) {
+ this.name = name;
+ }
+
+ String name;
+ }
+
+ public RootKeyInfo() {}
+
+ public RootKeyInfo(RootKeyInfo info) {
+ this.type = info.type;
+ this.algorithm = info.algorithm;
+ this.region = info.region;
+ this.endpoint = info.endpoint;
+ this.cmkId = info.cmkId;
+ this.ak = info.ak;
+ this.sk = info.sk;
+ this.password = info.password;
}
@SerializedName(value = "type")
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
index 828285c66df..2cb725dc55e 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java
@@ -86,6 +86,7 @@ import
org.apache.doris.nereids.DorisParser.AdminCheckTabletsContext;
import org.apache.doris.nereids.DorisParser.AdminCompactTableContext;
import org.apache.doris.nereids.DorisParser.AdminDiagnoseTabletContext;
import org.apache.doris.nereids.DorisParser.AdminRebalanceDiskContext;
+import org.apache.doris.nereids.DorisParser.AdminRotateTdeRootKeyContext;
import org.apache.doris.nereids.DorisParser.AdminSetEncryptionRootKeyContext;
import org.apache.doris.nereids.DorisParser.AdminSetTableStatusContext;
import
org.apache.doris.nereids.DorisParser.AdminShowReplicaDistributionContext;
@@ -602,6 +603,7 @@ import
org.apache.doris.nereids.trees.plans.commands.AdminCreateClusterSnapshotC
import
org.apache.doris.nereids.trees.plans.commands.AdminDropClusterSnapshotCommand;
import org.apache.doris.nereids.trees.plans.commands.AdminRebalanceDiskCommand;
import org.apache.doris.nereids.trees.plans.commands.AdminRepairTableCommand;
+import
org.apache.doris.nereids.trees.plans.commands.AdminRotateTdeRootKeyCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetAutoClusterSnapshotCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetClusterSnapshotFeatureSwitchCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetEncryptionRootKeyCommand;
@@ -1746,6 +1748,12 @@ public class LogicalPlanBuilder extends
DorisParserBaseVisitor<Object> {
return new AdminSetEncryptionRootKeyCommand(properties);
}
+ @Override
+ public LogicalPlan visitAdminRotateTdeRootKey(AdminRotateTdeRootKeyContext
ctx) {
+ Map<String, String> properties =
visitPropertyClause(ctx.propertyClause());
+ return new AdminRotateTdeRootKeyCommand(properties);
+ }
+
@Override
public LogicalPlan visitShowConstraint(ShowConstraintContext ctx) {
List<String> parts = visitMultipartIdentifier(ctx.table);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
index dfb15ca2328..ab9743e64ae 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/PlanType.java
@@ -398,6 +398,7 @@ public enum PlanType {
ADMIN_SET_AUTO_CLUSTER_SNAPSHOT_COMMAND,
ADMIN_SET_CLUSTER_SNAPSHOT_FEATURE_SWITCH_COMMAND,
ADMIN_DROP_CLUSTER_SNAPSHOT_COMMAND,
+ ADMIN_ROTATE_TDE_ROOT_KEY,
SHOW_CREATE_ROUTINE_LOAD_COMMAND,
PAUSE_ROUTINE_LOAD_COMMAND,
PAUSE_ALL_ROUTINE_COMMAND,
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AdminRotateTdeRootKeyCommand.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AdminRotateTdeRootKeyCommand.java
new file mode 100644
index 00000000000..4952c6c586a
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AdminRotateTdeRootKeyCommand.java
@@ -0,0 +1,67 @@
+// 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.doris.nereids.trees.plans.commands;
+
+import org.apache.doris.common.AnalysisException;
+import org.apache.doris.encryption.KeyManagerInterface;
+import org.apache.doris.nereids.trees.plans.PlanType;
+import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.qe.StmtExecutor;
+
+import java.util.Map;
+
+/**
+ * Rotate TDE root key command
+ */
+public class AdminRotateTdeRootKeyCommand extends Command implements
ForwardWithSync {
+
+ public static final String DORIS_TDE_KEY_PROVIDER =
"doris_tde_key_provider";
+
+ public static final String DORIS_TDE_KEY_PASSWORD =
"doris_tde_key_password";
+
+ public static final String DORIS_TDE_KEY_ORIGINAL_PASSWORD =
"doris_tde_key_original_password";
+
+ public static final String DORIS_TDE_KEY_ID = "doris_tde_key_id";
+
+ public static final String DORIS_TDE_KEY_ENDPOINT =
"doris_tde_key_endpoint";
+
+ public static final String DORIS_TDE_KEY_REGION = "doris_tde_key_region";
+
+ private final Map<String, String> properties;
+
+ public AdminRotateTdeRootKeyCommand(Map<String, String> properties) {
+ super(PlanType.ADMIN_ROTATE_TDE_ROOT_KEY);
+ this.properties = properties;
+ }
+
+ @Override
+ public void run(ConnectContext ctx, StmtExecutor executor) throws
Exception {
+ KeyManagerInterface keyManager = ctx.getEnv().getKeyManager();
+ if (keyManager != null) {
+ keyManager.rotateRootKey(properties);
+ } else {
+ throw new AnalysisException("TDE is disabled, cannot rotate root
key");
+ }
+ }
+
+ @Override
+ public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+ return visitor.visitAdminRotateTdeRootKeyCommand(this, context);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
index 0a2d76e8e62..8c78e8583f8 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/visitor/CommandVisitor.java
@@ -28,6 +28,7 @@ import
org.apache.doris.nereids.trees.plans.commands.AdminCreateClusterSnapshotC
import
org.apache.doris.nereids.trees.plans.commands.AdminDropClusterSnapshotCommand;
import org.apache.doris.nereids.trees.plans.commands.AdminRebalanceDiskCommand;
import org.apache.doris.nereids.trees.plans.commands.AdminRepairTableCommand;
+import
org.apache.doris.nereids.trees.plans.commands.AdminRotateTdeRootKeyCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetAutoClusterSnapshotCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetClusterSnapshotFeatureSwitchCommand;
import
org.apache.doris.nereids.trees.plans.commands.AdminSetFrontendConfigCommand;
@@ -1457,6 +1458,10 @@ public interface CommandVisitor<R, C> {
return visitCommand(dropMaterializedViewCommand, context);
}
+ default R visitAdminRotateTdeRootKeyCommand(AdminRotateTdeRootKeyCommand
rotateTdeRootKeyCommand, C context) {
+ return visitCommand(rotateTdeRootKeyCommand, context);
+ }
+
default R visitEmptyCommand(EmptyCommand emptyCommand, C context) {
return visitCommand(emptyCommand, context);
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
index fdcda7f1b74..0d173aed5ce 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/NereidsParserTest.java
@@ -1284,4 +1284,20 @@ public class NereidsParserTest extends ParserTestBase {
}
}
+ @Test
+ public void testAdminRotateTdeRootKey() {
+ NereidsParser nereidsParser = new NereidsParser();
+ String sql = "admin rotate tde root key";
+ nereidsParser.parseSingle(sql);
+
+ sql = "admin rotate tde root key properties(\"k\" = \"v\")";
+ nereidsParser.parseSingle(sql);
+
+ sql = "admin rotate tde root key properties(\"k0\" = \"v0\", \"k1\" =
\"v1\")";
+ nereidsParser.parseSingle(sql);
+
+ parsePlan("admin rotate tde root key properties()")
+ .assertThrowsExactly(ParseException.class)
+ .assertMessageContains("mismatched input ')' expecting");
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]