This is an automated email from the ASF dual-hosted git repository.
yqm pushed a commit to branch 35.0.0
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/35.0.0 by this push:
new 7b0ed737585 Add sessionToken support for S3InputSource (#18609)
7b0ed737585 is described below
commit 7b0ed73758596e8a5519bdf8ca7d5230bed2a455
Author: jtuglu1 <[email protected]>
AuthorDate: Thu Oct 9 12:49:20 2025 -0700
Add sessionToken support for S3InputSource (#18609)
Allows Druid to use an AWS_SESSION_TOKEN (and skip assuming a role to fetch
a token) if provided in the spec. No explicit assumptions are made with the
input (e.g. that adding sessionToken and assumeRoleAre are mutually exclusive).
This support falls in line with how other engines use things like external
catalogs, etc. to vend temporary credentials to access S3, while leaving things
like the exact ARN opaque to the caller.
---
docs/ingestion/input-sources.md | 5 +-
.../catalog/model/table/S3InputSourceDefn.java | 9 +-
.../apache/druid/data/input/s3/S3InputSource.java | 23 +++-
.../druid/data/input/s3/S3InputSourceConfig.java | 25 +++-
.../catalog/model/table/S3InputSourceDefnTest.java | 3 +-
.../data/input/s3/S3InputSourceConfigTest.java | 6 +-
.../druid/data/input/s3/S3InputSourceTest.java | 151 ++++++++++++++++++++-
.../druid/msq/util/MSQTaskQueryMakerUtils.java | 2 +-
.../druid/msq/util/MSQTaskQueryMakerUtilsTest.java | 4 +-
website/.spelling | 1 +
10 files changed, 206 insertions(+), 23 deletions(-)
diff --git a/docs/ingestion/input-sources.md b/docs/ingestion/input-sources.md
index 3066ba7386d..49cf90cdbf5 100644
--- a/docs/ingestion/input-sources.md
+++ b/docs/ingestion/input-sources.md
@@ -204,8 +204,9 @@ Properties Object:
|Property|Description|Default|Required|
|--------|-----------|-------|---------|
-|accessKeyId|The [Password Provider](../operations/password-provider.md) or
plain text string of this S3 input source access key|None|yes if
secretAccessKey is given|
-|secretAccessKey|The [Password Provider](../operations/password-provider.md)
or plain text string of this S3 input source secret key|None|yes if accessKeyId
is given|
+|accessKeyId|The [Password Provider](../operations/password-provider.md) or
plain text string of this S3 input source access key|None|Yes, if
`secretAccessKey` or `sessionToken` is given.|
+|secretAccessKey|The [Password Provider](../operations/password-provider.md)
or plain text string of this S3 input source secret key|None|Yes, if
`accessKeyId` or `sessionToken` is given.|
+|sessionToken|The [Password Provider](../operations/password-provider.md) or
plain text string of this S3 input source session token|None|no|
|assumeRoleArn|AWS ARN of the role to assume
[see](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html).
**assumeRoleArn** can be used either with the ingestion spec AWS credentials
or with the default S3 credentials|None|no|
|assumeRoleExternalId|A unique identifier that might be required when you
assume a role in another account
[see](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)|None|no|
diff --git
a/extensions-core/s3-extensions/src/main/java/org/apache/druid/catalog/model/table/S3InputSourceDefn.java
b/extensions-core/s3-extensions/src/main/java/org/apache/druid/catalog/model/table/S3InputSourceDefn.java
index 358862d0332..ca84236d14a 100644
---
a/extensions-core/s3-extensions/src/main/java/org/apache/druid/catalog/model/table/S3InputSourceDefn.java
+++
b/extensions-core/s3-extensions/src/main/java/org/apache/druid/catalog/model/table/S3InputSourceDefn.java
@@ -79,6 +79,7 @@ public class S3InputSourceDefn extends
FormattedInputSourceDefn
public static final String ACCESS_KEY_ID_PARAMETER = "accessKeyId";
public static final String SECRET_ACCESS_KEY_PARAMETER = "secretAccessKey";
public static final String ASSUME_ROLE_ARN_PARAMETER = "assumeRoleArn";
+ public static final String SESSION_TOKEN_PARAMETER = "sessionToken";
/**
* The {@code objectGlob} property exists in S3, but is not documented. The
corresponding
@@ -102,7 +103,8 @@ public class S3InputSourceDefn extends
FormattedInputSourceDefn
private static final List<ParameterDefn> SECURITY_PARAMS = Arrays.asList(
new Parameter(ACCESS_KEY_ID_PARAMETER, ParameterType.VARCHAR, true),
new Parameter(SECRET_ACCESS_KEY_PARAMETER, ParameterType.VARCHAR, true),
- new Parameter(ASSUME_ROLE_ARN_PARAMETER, ParameterType.VARCHAR, true)
+ new Parameter(ASSUME_ROLE_ARN_PARAMETER, ParameterType.VARCHAR, true),
+ new Parameter(SESSION_TOKEN_PARAMETER, ParameterType.VARCHAR, true)
);
// Field names in the S3InputSource
@@ -114,6 +116,7 @@ public class S3InputSourceDefn extends
FormattedInputSourceDefn
private static final String ACCESS_KEY_ID_FIELD = "accessKeyId";
private static final String SECRET_ACCESS_KEY_FIELD = "secretAccessKey";
private static final String ASSUME_ROLE_ARN_FIELD = "assumeRoleArn";
+ private static final String SESSION_TOKEN_FIELD = "sessionToken";
@Override
public String typeValue()
@@ -250,6 +253,7 @@ public class S3InputSourceDefn extends
FormattedInputSourceDefn
final String accessKeyId = CatalogUtils.getNonBlankString(args,
ACCESS_KEY_ID_PARAMETER);
final String secretAccessKey = CatalogUtils.getNonBlankString(args,
SECRET_ACCESS_KEY_PARAMETER);
final String assumeRoleArn = CatalogUtils.getNonBlankString(args,
ASSUME_ROLE_ARN_PARAMETER);
+ final String sessionToken = CatalogUtils.getNonBlankString(args,
SESSION_TOKEN_PARAMETER);
if (accessKeyId != null || secretAccessKey != null || assumeRoleArn !=
null) {
Map<String, Object> properties = new HashMap<>();
if (accessKeyId != null) {
@@ -258,6 +262,9 @@ public class S3InputSourceDefn extends
FormattedInputSourceDefn
if (secretAccessKey != null) {
properties.put(SECRET_ACCESS_KEY_FIELD, secretAccessKey);
}
+ if (sessionToken != null) {
+ properties.put(SESSION_TOKEN_FIELD, sessionToken);
+ }
if (assumeRoleArn != null) {
properties.put(ASSUME_ROLE_ARN_FIELD, assumeRoleArn);
}
diff --git
a/extensions-core/s3-extensions/src/main/java/org/apache/druid/data/input/s3/S3InputSource.java
b/extensions-core/s3-extensions/src/main/java/org/apache/druid/data/input/s3/S3InputSource.java
index 69f97c24669..df0c69c8e56 100644
---
a/extensions-core/s3-extensions/src/main/java/org/apache/druid/data/input/s3/S3InputSource.java
+++
b/extensions-core/s3-extensions/src/main/java/org/apache/druid/data/input/s3/S3InputSource.java
@@ -21,8 +21,10 @@ package org.apache.druid.data.input.s3;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.AWSSessionCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.model.ObjectMetadata;
@@ -282,12 +284,21 @@ public class S3InputSource extends CloudObjectInputSource
@Nonnull
private AWSStaticCredentialsProvider
createStaticCredentialsProvider(S3InputSourceConfig s3InputSourceConfig)
{
- return new AWSStaticCredentialsProvider(
- new BasicAWSCredentials(
- s3InputSourceConfig.getAccessKeyId().getPassword(),
- s3InputSourceConfig.getSecretAccessKey().getPassword()
- )
- );
+ if (s3InputSourceConfig.getSessionToken() != null) {
+ AWSSessionCredentials sessionCredentials = new BasicSessionCredentials(
+ s3InputSourceConfig.getAccessKeyId().getPassword(),
+ s3InputSourceConfig.getSecretAccessKey().getPassword(),
+ s3InputSourceConfig.getSessionToken().getPassword()
+ );
+ return new AWSStaticCredentialsProvider(sessionCredentials);
+ } else {
+ return new AWSStaticCredentialsProvider(
+ new BasicAWSCredentials(
+ s3InputSourceConfig.getAccessKeyId().getPassword(),
+ s3InputSourceConfig.getSecretAccessKey().getPassword()
+ )
+ );
+ }
}
@Nullable
diff --git
a/extensions-core/s3-extensions/src/main/java/org/apache/druid/data/input/s3/S3InputSourceConfig.java
b/extensions-core/s3-extensions/src/main/java/org/apache/druid/data/input/s3/S3InputSourceConfig.java
index e46a095dec7..e7698a6264d 100644
---
a/extensions-core/s3-extensions/src/main/java/org/apache/druid/data/input/s3/S3InputSourceConfig.java
+++
b/extensions-core/s3-extensions/src/main/java/org/apache/druid/data/input/s3/S3InputSourceConfig.java
@@ -39,24 +39,27 @@ public class S3InputSourceConfig
private final String assumeRoleExternalId;
private final PasswordProvider accessKeyId;
private final PasswordProvider secretAccessKey;
+ private final PasswordProvider sessionToken;
@JsonCreator
public S3InputSourceConfig(
@JsonProperty("accessKeyId") @Nullable PasswordProvider accessKeyId,
@JsonProperty("secretAccessKey") @Nullable PasswordProvider
secretAccessKey,
@JsonProperty("assumeRoleArn") @Nullable String assumeRoleArn,
- @JsonProperty("assumeRoleExternalId") @Nullable String
assumeRoleExternalId
+ @JsonProperty("assumeRoleExternalId") @Nullable String
assumeRoleExternalId,
+ @JsonProperty("sessionToken") @Nullable PasswordProvider sessionToken
)
{
this.assumeRoleArn = assumeRoleArn;
this.assumeRoleExternalId = assumeRoleExternalId;
- if (accessKeyId != null || secretAccessKey != null) {
- this.accessKeyId = Preconditions.checkNotNull(accessKeyId, "accessKeyId
cannot be null if secretAccessKey is given");
- this.secretAccessKey = Preconditions.checkNotNull(secretAccessKey,
"secretAccessKey cannot be null if accessKeyId is given");
+ if (sessionToken != null || accessKeyId != null || secretAccessKey !=
null) {
+ this.accessKeyId = Preconditions.checkNotNull(accessKeyId,
"'accessKeyId' cannot be null if 'secretAccessKey' or 'sessionToken' is given");
+ this.secretAccessKey = Preconditions.checkNotNull(secretAccessKey,
"'secretAccessKey' cannot be null if 'accessKeyId' or 'sessionToken' is given");
} else {
this.accessKeyId = null;
this.secretAccessKey = null;
}
+ this.sessionToken = sessionToken;
}
@Nullable
@@ -91,6 +94,14 @@ public class S3InputSourceConfig
return secretAccessKey;
}
+ @Nullable
+ @JsonProperty
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ public PasswordProvider getSessionToken()
+ {
+ return sessionToken;
+ }
+
@JsonIgnore
public boolean isCredentialsConfigured()
{
@@ -106,6 +117,7 @@ public class S3InputSourceConfig
", secretAccessKey=" + secretAccessKey +
", assumeRoleArn=" + assumeRoleArn +
", assumeRoleExternalId=" + assumeRoleExternalId +
+ ", sessionToken=" + sessionToken +
'}';
}
@@ -122,12 +134,13 @@ public class S3InputSourceConfig
return Objects.equals(accessKeyId, that.accessKeyId) &&
Objects.equals(secretAccessKey, that.secretAccessKey) &&
Objects.equals(assumeRoleArn, that.assumeRoleArn) &&
- Objects.equals(assumeRoleExternalId, that.assumeRoleExternalId);
+ Objects.equals(assumeRoleExternalId, that.assumeRoleExternalId) &&
+ Objects.equals(sessionToken, that.sessionToken);
}
@Override
public int hashCode()
{
- return Objects.hash(accessKeyId, secretAccessKey, assumeRoleArn,
assumeRoleExternalId);
+ return Objects.hash(accessKeyId, secretAccessKey, assumeRoleArn,
assumeRoleExternalId, sessionToken);
}
}
diff --git
a/extensions-core/s3-extensions/src/test/java/org/apache/druid/catalog/model/table/S3InputSourceDefnTest.java
b/extensions-core/s3-extensions/src/test/java/org/apache/druid/catalog/model/table/S3InputSourceDefnTest.java
index c35bc1824bc..0aa21a478b8 100644
---
a/extensions-core/s3-extensions/src/test/java/org/apache/druid/catalog/model/table/S3InputSourceDefnTest.java
+++
b/extensions-core/s3-extensions/src/test/java/org/apache/druid/catalog/model/table/S3InputSourceDefnTest.java
@@ -42,7 +42,6 @@ import org.junit.Before;
import org.junit.Test;
import javax.annotation.Nullable;
-
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
@@ -558,7 +557,7 @@ public class S3InputSourceDefnTest
@Test
public void testFullTableSpecHappyPath()
{
- S3InputSourceConfig config = new S3InputSourceConfig(null, null, "foo",
null);
+ S3InputSourceConfig config = new S3InputSourceConfig(null, null, "foo",
null, null);
S3InputSource s3InputSource = s3InputSource(
Arrays.asList("s3://foo/bar/", "s3://mumble/"), null, null, "*.csv",
config);
TableMetadata table = TableBuilder.external("foo")
diff --git
a/extensions-core/s3-extensions/src/test/java/org/apache/druid/data/input/s3/S3InputSourceConfigTest.java
b/extensions-core/s3-extensions/src/test/java/org/apache/druid/data/input/s3/S3InputSourceConfigTest.java
index fbec6f8f3e8..cdcd0167f60 100644
---
a/extensions-core/s3-extensions/src/test/java/org/apache/druid/data/input/s3/S3InputSourceConfigTest.java
+++
b/extensions-core/s3-extensions/src/test/java/org/apache/druid/data/input/s3/S3InputSourceConfigTest.java
@@ -36,7 +36,8 @@ public class S3InputSourceConfigTest
new DefaultPasswordProvider("the-access-key"),
new DefaultPasswordProvider("the-secret-key"),
null,
- null
+ null,
+ new DefaultPasswordProvider("the-secret-token")
);
Assert.assertEquals(
@@ -53,7 +54,8 @@ public class S3InputSourceConfigTest
null,
null,
"the-role-arn",
- "the-role-external-id"
+ "the-role-external-id",
+ null
);
Assert.assertEquals(
diff --git
a/extensions-core/s3-extensions/src/test/java/org/apache/druid/data/input/s3/S3InputSourceTest.java
b/extensions-core/s3-extensions/src/test/java/org/apache/druid/data/input/s3/S3InputSourceTest.java
index d2c2a33293f..d4891f0195e 100644
---
a/extensions-core/s3-extensions/src/test/java/org/apache/druid/data/input/s3/S3InputSourceTest.java
+++
b/extensions-core/s3-extensions/src/test/java/org/apache/druid/data/input/s3/S3InputSourceTest.java
@@ -158,7 +158,10 @@ public class S3InputSourceTest extends
InitializedNullHandlingTest
);
private static final S3InputSourceConfig CLOUD_CONFIG_PROPERTIES = new
S3InputSourceConfig(
- new DefaultPasswordProvider("myKey"), new
DefaultPasswordProvider("mySecret"), null, null);
+ new DefaultPasswordProvider("myKey"), new
DefaultPasswordProvider("mySecret"), null, null, null);
+ private static final S3InputSourceConfig
CLOUD_CONFIG_PROPERTIES_WITH_SESSION_TOKEN = new S3InputSourceConfig(
+ new DefaultPasswordProvider("myKey"), new
DefaultPasswordProvider("mySecret"), null, null,
+ new DefaultPasswordProvider("mySessionToken"));
private static final AWSEndpointConfig ENDPOINT_CONFIG = new
AWSEndpointConfig();
private static final AWSProxyConfig PROXY_CONFIG = new AWSProxyConfig();
private static final AWSClientConfig CLIENT_CONFIG = new AWSClientConfig();
@@ -370,6 +373,152 @@ public class S3InputSourceTest extends
InitializedNullHandlingTest
EasyMock.verify(SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER);
}
+ @Test
+ public void testSerdeWithCloudConfigPropertiesWithSessionToken() throws
Exception
+ {
+ EasyMock.reset(SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER);
+
EasyMock.expect(SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER.getAmazonS3ClientBuilder())
+ .andStubReturn(AMAZON_S3_CLIENT_BUILDER);
+ AMAZON_S3_CLIENT_BUILDER.withClientConfiguration(CLIENT_CONFIGURATION);
+ EasyMock.expect(SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER.build())
+ .andReturn(SERVICE);
+ EasyMock.replay(SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER);
+ final S3InputSource withSessionToken = new S3InputSource(
+ SERVICE,
+ SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER,
+ INPUT_DATA_CONFIG,
+ null,
+ null,
+ EXPECTED_LOCATION,
+ null,
+ CLOUD_CONFIG_PROPERTIES_WITH_SESSION_TOKEN,
+ null,
+ null,
+ null
+ );
+ final S3InputSource serdeWithSessionToken =
+ MAPPER.readValue(MAPPER.writeValueAsString(withSessionToken),
S3InputSource.class);
+ // This is to force the s3ClientSupplier to initialize the
ServerSideEncryptingAmazonS3
+ serdeWithSessionToken.createEntity(new CloudObjectLocation("bucket",
"path"));
+ Assert.assertEquals(withSessionToken, serdeWithSessionToken);
+ // Verify that the session token is properly set
+ Assert.assertNotNull(serdeWithSessionToken.getS3InputSourceConfig());
+
Assert.assertNotNull(serdeWithSessionToken.getS3InputSourceConfig().getSessionToken());
+ Assert.assertEquals("mySessionToken",
serdeWithSessionToken.getS3InputSourceConfig().getSessionToken().getPassword());
+ EasyMock.verify(SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER);
+ }
+
+ @Test
+ public void testGetSetSessionToken()
+ {
+ // Test that session token getter/setter work correctly
+ final S3InputSource inputSourceWithSessionToken = new S3InputSource(
+ SERVICE,
+ SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER,
+ INPUT_DATA_CONFIG,
+ EXPECTED_URIS,
+ null,
+ null,
+ null,
+ CLOUD_CONFIG_PROPERTIES_WITH_SESSION_TOKEN,
+ null,
+ null,
+ null
+ );
+
+ Assert.assertNotNull(inputSourceWithSessionToken.getS3InputSourceConfig());
+
Assert.assertNotNull(inputSourceWithSessionToken.getS3InputSourceConfig().getSessionToken());
+ Assert.assertEquals(
+ "mySessionToken",
+
inputSourceWithSessionToken.getS3InputSourceConfig().getSessionToken().getPassword()
+ );
+
+ // Test without session token
+ final S3InputSource inputSourceWithoutSessionToken = new S3InputSource(
+ SERVICE,
+ SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER,
+ INPUT_DATA_CONFIG,
+ EXPECTED_URIS,
+ null,
+ null,
+ null,
+ CLOUD_CONFIG_PROPERTIES,
+ null,
+ null,
+ null
+ );
+
+
Assert.assertNotNull(inputSourceWithoutSessionToken.getS3InputSourceConfig());
+
Assert.assertNull(inputSourceWithoutSessionToken.getS3InputSourceConfig().getSessionToken());
+ }
+
+ @Test
+ public void testSessionCredentialsUsedWhenSessionTokenProvided() throws
IOException
+ {
+ // This test verifies that when session token is provided, the
S3InputSource
+ // correctly uses BasicSessionCredentials instead of BasicAWSCredentials
+ EasyMock.reset(S3_CLIENT);
+ expectListObjects(PREFIXES.get(0), ImmutableList.of(EXPECTED_URIS.get(0)),
CONTENT);
+ expectGetObject(EXPECTED_URIS.get(0));
+ EasyMock.replay(S3_CLIENT);
+
+ EasyMock.reset(SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER);
+
EasyMock.expect(SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER.getAmazonS3ClientBuilder())
+ .andStubReturn(AMAZON_S3_CLIENT_BUILDER);
+ EasyMock.expect(SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER.build())
+ .andReturn(SERVICE);
+ EasyMock.replay(SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER);
+
+ // Create S3InputSource with session token
+ S3InputSource inputSource = new S3InputSource(
+ SERVICE,
+ SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER,
+ INPUT_DATA_CONFIG,
+ null,
+ ImmutableList.of(PREFIXES.get(0)),
+ null,
+ null,
+ CLOUD_CONFIG_PROPERTIES_WITH_SESSION_TOKEN,
+ null,
+ null,
+ null
+ );
+
+ // Verify session token is set
+ Assert.assertNotNull(inputSource.getS3InputSourceConfig());
+
Assert.assertNotNull(inputSource.getS3InputSourceConfig().getSessionToken());
+ Assert.assertEquals(
+ "mySessionToken",
+ inputSource.getS3InputSourceConfig().getSessionToken().getPassword()
+ );
+
+ // Create a reader which will trigger the s3ClientSupplier and use the
session credentials
+ InputRowSchema someSchema = new InputRowSchema(
+ new TimestampSpec("time", "auto", null),
+ new
DimensionsSpec(DimensionsSpec.getDefaultSchemas(ImmutableList.of("dim1",
"dim2"))),
+ ColumnsFilter.all()
+ );
+
+ InputSourceReader reader = inputSource.reader(
+ someSchema,
+ new CsvInputFormat(ImmutableList.of("time", "dim1", "dim2"), "|",
false, null, 0, null),
+ temporaryFolder.newFolder()
+ );
+
+ // Read data - this exercises the session credentials path
+ CloseableIterator<InputRow> iterator = reader.read();
+
+ while (iterator.hasNext()) {
+ InputRow nextRow = iterator.next();
+ Assert.assertEquals(NOW, nextRow.getTimestamp());
+ Assert.assertEquals("hello", nextRow.getDimension("dim1").get(0));
+ Assert.assertEquals("world", nextRow.getDimension("dim2").get(0));
+ }
+
+ EasyMock.verify(S3_CLIENT);
+ EasyMock.verify(SERVER_SIDE_ENCRYPTING_AMAZON_S3_BUILDER);
+ }
+
@Test
public void testGetTypes()
{
diff --git
a/multi-stage-query/src/main/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtils.java
b/multi-stage-query/src/main/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtils.java
index 2e9e67a7534..955bc3483c1 100644
---
a/multi-stage-query/src/main/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtils.java
+++
b/multi-stage-query/src/main/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtils.java
@@ -40,7 +40,7 @@ import java.util.stream.Collectors;
public class MSQTaskQueryMakerUtils
{
- public static final Set<String> SENSISTIVE_JSON_KEYS =
ImmutableSet.of("accessKeyId", "secretAccessKey");
+ public static final Set<String> SENSISTIVE_JSON_KEYS =
ImmutableSet.of("accessKeyId", "secretAccessKey", "sessionToken");
public static final Set<Pattern> SENSITIVE_KEYS_REGEX_PATTERNS =
SENSISTIVE_JSON_KEYS.stream()
.map(sensitiveKey ->
Pattern.compile(
diff --git
a/multi-stage-query/src/test/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtilsTest.java
b/multi-stage-query/src/test/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtilsTest.java
index bb0bdcd34d1..8febf4bfdc2 100644
---
a/multi-stage-query/src/test/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtilsTest.java
+++
b/multi-stage-query/src/test/java/org/apache/druid/msq/util/MSQTaskQueryMakerUtilsTest.java
@@ -57,7 +57,7 @@ public class MSQTaskQueryMakerUtilsTest
+ "OVERWRITE ALL\\n"
+ "WITH ext AS "
+ "(SELECT *\\nFROM TABLE(\\n "
- + "EXTERN(\\n
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"},\\\"secretAccessKey\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"}}}',\\n"
+ + "EXTERN(\\n
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"},\\\"secretAccessKey\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"},\\\"sessionToken\\\":{\\\"type\\\":\\\"default\\\",\\\"password\\\":\\\"secret_pass\\\"}}}',\\n"
+ "'{\\\"type\\\":\\\"json\\\"}',\\n"
+
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
)\\n))\\n"
+ "SELECT\\n TIME_PARSE(\\\"time\\\") AS __time,\\n
name,\\n country "
@@ -113,7 +113,7 @@ public class MSQTaskQueryMakerUtilsTest
+ "OVERWRITE ALL\\n"
+ "WITH ext AS "
+ "(SELECT *\\nFROM TABLE(\\n "
- + "EXTERN(\\n
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":<masked>,\\\"secretAccessKey\\\":<masked>}}',\\n"
+ + "EXTERN(\\n
'{\\\"type\\\":\\\"s3\\\",\\\"prefixes\\\":[\\\"s3://prefix\\\"],\\\"properties\\\":{\\\"accessKeyId\\\":<masked>,\\\"secretAccessKey\\\":<masked>,\\\"sessionToken\\\":<masked>}}',\\n"
+ "'{\\\"type\\\":\\\"json\\\"}',\\n"
+
"'[{\\\"name\\\":\\\"time\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"name\\\",\\\"type\\\":\\\"string\\\"}]'\\n
)\\n))\\n"
+ "SELECT\\n TIME_PARSE(\\\"time\\\") AS __time,\\n name,\\n
country "
diff --git a/website/.spelling b/website/.spelling
index 767ef4249ab..82711ff8442 100644
--- a/website/.spelling
+++ b/website/.spelling
@@ -1481,6 +1481,7 @@ httpAuthenticationPassword
accessKeyId
secretAccessKey
accessKeyId
+sessionToken
httpAuthenticationPassword
countryName
appendToExisting
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]