This is an automated email from the ASF dual-hosted git repository.
singhpk234 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg.git
The following commit(s) were added to refs/heads/main by this push:
new 77bc1d08ec Make KMS endpoint configurable via kms.endpoint AWS
property (#14246)
77bc1d08ec is described below
commit 77bc1d08ecd46b1d62a3fb51ad7d1935788f30be
Author: Thomas Powell <[email protected]>
AuthorDate: Sat Oct 11 18:16:29 2025 +0100
Make KMS endpoint configurable via kms.endpoint AWS property (#14246)
Co-authored-by: Thomas Powell <[email protected]>
---
.../iceberg/aws/TestDefaultAwsClientFactory.java | 13 ++++++++++
.../org/apache/iceberg/aws/AwsClientFactories.java | 7 ++++--
.../java/org/apache/iceberg/aws/AwsProperties.java | 29 ++++++++++++++++++++++
3 files changed, 47 insertions(+), 2 deletions(-)
diff --git
a/aws/src/integration/java/org/apache/iceberg/aws/TestDefaultAwsClientFactory.java
b/aws/src/integration/java/org/apache/iceberg/aws/TestDefaultAwsClientFactory.java
index e9803c8bb1..7a7e34fcf2 100644
---
a/aws/src/integration/java/org/apache/iceberg/aws/TestDefaultAwsClientFactory.java
+++
b/aws/src/integration/java/org/apache/iceberg/aws/TestDefaultAwsClientFactory.java
@@ -30,6 +30,7 @@ import
software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.glue.GlueClient;
import software.amazon.awssdk.services.glue.model.GetDatabaseRequest;
+import software.amazon.awssdk.services.kms.KmsClient;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
@@ -99,4 +100,16 @@ public class TestDefaultAwsClientFactory {
.isInstanceOf(SdkClientException.class)
.hasMessageContaining("Unable to execute HTTP request: unknown");
}
+
+ @Test
+ public void testKmsEndpointOverride() {
+ Map<String, String> properties = Maps.newHashMap();
+ properties.put(AwsProperties.KMS_ENDPOINT, "https://unknown:1234");
+ AwsClientFactory factory = AwsClientFactories.from(properties);
+ KmsClient kmsClient = factory.kms();
+ assertThatThrownBy(kmsClient::listKeys)
+ .cause()
+ .isInstanceOf(SdkClientException.class)
+ .hasMessageContaining("Unable to execute HTTP request: unknown");
+ }
}
diff --git a/aws/src/main/java/org/apache/iceberg/aws/AwsClientFactories.java
b/aws/src/main/java/org/apache/iceberg/aws/AwsClientFactories.java
index cd5715b93b..0ee4bf26e6 100644
--- a/aws/src/main/java/org/apache/iceberg/aws/AwsClientFactories.java
+++ b/aws/src/main/java/org/apache/iceberg/aws/AwsClientFactories.java
@@ -39,6 +39,7 @@ import
software.amazon.awssdk.services.dynamodb.DynamoDbClientBuilder;
import software.amazon.awssdk.services.glue.GlueClient;
import software.amazon.awssdk.services.glue.GlueClientBuilder;
import software.amazon.awssdk.services.kms.KmsClient;
+import software.amazon.awssdk.services.kms.KmsClientBuilder;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.S3BaseClientBuilder;
import software.amazon.awssdk.services.s3.S3Client;
@@ -155,6 +156,7 @@ public class AwsClientFactories {
return KmsClient.builder()
.applyMutation(awsClientProperties::applyClientRegionConfiguration)
.applyMutation(httpClientProperties::applyHttpClientConfigurations)
+ .applyMutation(awsProperties::applyKmsEndpointConfigurations)
.applyMutation(awsClientProperties::applyClientCredentialConfigurations)
.applyMutation(awsClientProperties::applyRetryConfigurations)
.build();
@@ -208,8 +210,9 @@ public class AwsClientFactories {
* @deprecated Not for public use. To configure the endpoint for a client,
please use {@link
* S3FileIOProperties#applyEndpointConfigurations(S3BaseClientBuilder)},
{@link
* AwsProperties#applyGlueEndpointConfigurations(GlueClientBuilder)}, or
{@link
- *
AwsProperties#applyDynamoDbEndpointConfigurations(DynamoDbClientBuilder)}
accordingly. It
- * will be removed in 2.0.0
+ *
AwsProperties#applyDynamoDbEndpointConfigurations(DynamoDbClientBuilder)}, or
{@link
+ * AwsProperties#applyKmsEndpointConfigurations(KmsClientBuilder)}
accordingly. It will be
+ * removed in 2.0.0
*/
@Deprecated
public static <T extends SdkClientBuilder> void configureEndpoint(T builder,
String endpoint) {
diff --git a/aws/src/main/java/org/apache/iceberg/aws/AwsProperties.java
b/aws/src/main/java/org/apache/iceberg/aws/AwsProperties.java
index 62d541da0c..a37406e1fa 100644
--- a/aws/src/main/java/org/apache/iceberg/aws/AwsProperties.java
+++ b/aws/src/main/java/org/apache/iceberg/aws/AwsProperties.java
@@ -41,6 +41,7 @@ import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain;
import software.amazon.awssdk.services.dynamodb.DynamoDbClientBuilder;
import software.amazon.awssdk.services.glue.GlueClientBuilder;
+import software.amazon.awssdk.services.kms.KmsClientBuilder;
import software.amazon.awssdk.services.kms.model.DataKeySpec;
import software.amazon.awssdk.services.kms.model.EncryptionAlgorithmSpec;
@@ -208,6 +209,14 @@ public class AwsProperties implements Serializable {
*/
public static final String REST_SESSION_TOKEN = "rest.session-token";
+ /**
+ * Configure an alternative endpoint of the KMS service for
AwsKeyManagementClient to access.
+ *
+ * <p>This could be used to use KMS key management with any KMS-compatible
service that has a
+ * different endpoint
+ */
+ public static final String KMS_ENDPOINT = "kms.endpoint";
+
/** Encryption algorithm used to encrypt/decrypt master table keys */
public static final String KMS_ENCRYPTION_ALGORITHM_SPEC =
"kms.encryption-algorithm-spec";
@@ -243,6 +252,7 @@ public class AwsProperties implements Serializable {
private String restAccessKeyId;
private String restSecretAccessKey;
private String restSessionToken;
+ private final String kmsEndpoint;
private EncryptionAlgorithmSpec kmsEncryptionAlgorithmSpec;
private DataKeySpec kmsDataKeySpec;
@@ -268,6 +278,7 @@ public class AwsProperties implements Serializable {
this.restSigningName = REST_SIGNING_NAME_DEFAULT;
+ this.kmsEndpoint = null;
this.kmsEncryptionAlgorithmSpec = KMS_ENCRYPTION_ALGORITHM_SPEC_DEFAULT;
this.kmsDataKeySpec = KMS_DATA_KEY_SPEC_DEFAULT;
}
@@ -312,6 +323,7 @@ public class AwsProperties implements Serializable {
this.restSecretAccessKey = properties.get(REST_SECRET_ACCESS_KEY);
this.restSessionToken = properties.get(REST_SESSION_TOKEN);
+ this.kmsEndpoint = properties.get(KMS_ENDPOINT);
this.kmsEncryptionAlgorithmSpec =
EncryptionAlgorithmSpec.fromValue(
properties.getOrDefault(
@@ -411,6 +423,19 @@ public class AwsProperties implements Serializable {
configureEndpoint(builder, dynamoDbEndpoint);
}
+ /**
+ * Override the endpoint for a KMS client.
+ *
+ * <p>Sample usage:
+ *
+ * <pre>
+ *
KmsClient.builder().applyMutation(awsProperties::applyKmsEndpointConfigurations)
+ * </pre>
+ */
+ public <T extends KmsClientBuilder> void applyKmsEndpointConfigurations(T
builder) {
+ configureEndpoint(builder, kmsEndpoint);
+ }
+
public Region restSigningRegion() {
if (restSigningRegion == null) {
this.restSigningRegion =
DefaultAwsRegionProviderChain.builder().build().getRegion().id();
@@ -428,6 +453,10 @@ public class AwsProperties implements Serializable {
this.restAccessKeyId, this.restSecretAccessKey, this.restSessionToken);
}
+ public String kmsEndpoint() {
+ return this.kmsEndpoint;
+ }
+
public EncryptionAlgorithmSpec kmsEncryptionAlgorithmSpec() {
return this.kmsEncryptionAlgorithmSpec;
}