Skip to content

Commit ddb66e2

Browse files
retagithub-actions[bot]
authored andcommitted
Support use of IRSA for repository-s3 plugin credentials: added YAML Rest test case (#3499)
Signed-off-by: Andriy Redko <[email protected]> (cherry picked from commit 6c769d4)
1 parent 253891e commit ddb66e2

File tree

6 files changed

+496
-13
lines changed

6 files changed

+496
-13
lines changed

plugins/repository-s3/build.gradle

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ String s3EC2BasePath = System.getenv("amazon_s3_base_path_ec2")
131131
String s3ECSBucket = System.getenv("amazon_s3_bucket_ecs")
132132
String s3ECSBasePath = System.getenv("amazon_s3_base_path_ecs")
133133

134+
String s3EKSBucket = System.getenv("amazon_s3_bucket_eks")
135+
String s3EKSBasePath = System.getenv("amazon_s3_base_path_eks")
136+
134137
boolean s3DisableChunkedEncoding = (new Random(Long.parseUnsignedLong(BuildParams.testSeed.tokenize(':').get(0), 16))).nextBoolean()
135138

136139
// If all these variables are missing then we are testing against the internal fixture instead, which has the following
@@ -160,13 +163,15 @@ if (!s3TemporaryAccessKey && !s3TemporarySecretKey && !s3TemporaryBucket && !s3T
160163
throw new IllegalArgumentException("not all options specified to run against external S3 service as temporary credentials are present")
161164
}
162165

163-
if (!s3EC2Bucket && !s3EC2BasePath && !s3ECSBucket && !s3ECSBasePath) {
166+
if (!s3EC2Bucket && !s3EC2BasePath && !s3ECSBucket && !s3ECSBasePath && !s3EKSBucket && !s3EKSBasePath) {
164167
s3EC2Bucket = 'ec2_bucket'
165168
s3EC2BasePath = 'ec2_base_path'
166169
s3ECSBucket = 'ecs_bucket'
167170
s3ECSBasePath = 'ecs_base_path'
168-
} else if (!s3EC2Bucket || !s3EC2BasePath || !s3ECSBucket || !s3ECSBasePath) {
169-
throw new IllegalArgumentException("not all options specified to run EC2/ECS tests are present")
171+
s3EKSBucket = 'eks_bucket'
172+
s3EKSBasePath = 'eks_base_path'
173+
} else if (!s3EC2Bucket || !s3EC2BasePath || !s3ECSBucket || !s3ECSBasePath || !s3EKSBucket || !s3EKSBasePath) {
174+
throw new IllegalArgumentException("not all options specified to run EC2/ECS/EKS tests are present")
170175
}
171176

172177
processYamlRestTestResources {
@@ -179,7 +184,9 @@ processYamlRestTestResources {
179184
'ec2_base_path': s3EC2BasePath,
180185
'ecs_bucket': s3ECSBucket,
181186
'ecs_base_path': s3ECSBasePath,
182-
'disable_chunked_encoding': s3DisableChunkedEncoding,
187+
'eks_bucket': s3EKSBucket,
188+
'eks_base_path': s3EKSBasePath,
189+
'disable_chunked_encoding': s3DisableChunkedEncoding
183190
]
184191
inputs.properties(expansions)
185192
MavenFilteringHack.filter(it, expansions)
@@ -198,7 +205,8 @@ yamlRestTest {
198205
[
199206
'repository_s3/30_repository_temporary_credentials/*',
200207
'repository_s3/40_repository_ec2_credentials/*',
201-
'repository_s3/50_repository_ecs_credentials/*'
208+
'repository_s3/50_repository_ecs_credentials/*',
209+
'repository_s3/60_repository_eks_credentials/*'
202210
]
203211
).join(",")
204212
}
@@ -215,6 +223,7 @@ testClusters.yamlRestTest {
215223
testFixtures.useFixture(':test:fixtures:s3-fixture', 's3-fixture')
216224
testFixtures.useFixture(':test:fixtures:s3-fixture', 's3-fixture-with-session-token')
217225
testFixtures.useFixture(':test:fixtures:s3-fixture', 's3-fixture-with-ec2')
226+
testFixtures.useFixture(':test:fixtures:s3-fixture', 's3-fixture-with-eks')
218227

219228
normalization {
220229
runtimeClasspath {
@@ -223,12 +232,21 @@ testClusters.yamlRestTest {
223232
}
224233
}
225234

235+
keystore 's3.client.integration_test_eks.role_arn', "arn:aws:iam::000000000000:role/test"
236+
keystore 's3.client.integration_test_eks.role_session_name', "s3-test"
237+
keystore 's3.client.integration_test_eks.access_key', "access_key"
238+
keystore 's3.client.integration_test_eks.secret_key', "secret_key"
239+
226240
setting 's3.client.integration_test_permanent.endpoint', { "${-> fixtureAddress('s3-fixture', 's3-fixture', '80')}" }, IGNORE_VALUE
227241
setting 's3.client.integration_test_temporary.endpoint', { "${-> fixtureAddress('s3-fixture', 's3-fixture-with-session-token', '80')}" }, IGNORE_VALUE
228242
setting 's3.client.integration_test_ec2.endpoint', { "${-> fixtureAddress('s3-fixture', 's3-fixture-with-ec2', '80')}" }, IGNORE_VALUE
243+
setting 's3.client.integration_test_eks.endpoint', { "${-> fixtureAddress('s3-fixture', 's3-fixture-with-eks', '80')}" }, IGNORE_VALUE
244+
setting 's3.client.integration_test_eks.region', { "us-east-2" }, IGNORE_VALUE
229245
230246
// to redirect InstanceProfileCredentialsProvider to custom auth point
231247
systemProperty "com.amazonaws.sdk.ec2MetadataServiceEndpointOverride", { "${-> fixtureAddress('s3-fixture', 's3-fixture-with-ec2', '80')}" }, IGNORE_VALUE
248+
// to redirect AWSSecurityTokenServiceClient to custom auth point
249+
systemProperty "com.amazonaws.sdk.stsEndpointOverride", { "${-> fixtureAddress('s3-fixture', 's3-fixture-with-eks', '80')}/eks_credentials_endpoint" }, IGNORE_VALUE
232250
} else {
233251
println "Using an external service to test the repository-s3 plugin"
234252
}
@@ -250,7 +268,8 @@ if (useFixture) {
250268
systemProperty 'tests.rest.denylist', [
251269
'repository_s3/30_repository_temporary_credentials/*',
252270
'repository_s3/40_repository_ec2_credentials/*',
253-
'repository_s3/50_repository_ecs_credentials/*'
271+
'repository_s3/50_repository_ecs_credentials/*',
272+
'repository_s3/60_repository_eks_credentials/*'
254273
].join(",")
255274
}
256275
check.dependsOn(yamlRestTestMinio)
@@ -277,7 +296,8 @@ if (useFixture) {
277296
'repository_s3/10_basic/*',
278297
'repository_s3/20_repository_permanent_credentials/*',
279298
'repository_s3/30_repository_temporary_credentials/*',
280-
'repository_s3/40_repository_ec2_credentials/*'
299+
'repository_s3/40_repository_ec2_credentials/*',
300+
'repository_s3/60_repository_eks_credentials/*'
281301
].join(",")
282302
}
283303
check.dependsOn(yamlRestTestECS)
@@ -289,6 +309,41 @@ if (useFixture) {
289309
}
290310
}
291311
312+
// EKS
313+
if (useFixture) {
314+
testFixtures.useFixture(':test:fixtures:s3-fixture', 's3-fixture-with-eks')
315+
task yamlRestTestEKS(type: RestIntegTestTask.class) {
316+
description = "Runs tests using the EKS repository."
317+
dependsOn('bundlePlugin')
318+
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
319+
SourceSet yamlRestTestSourceSet = sourceSets.getByName(YamlRestTestPlugin.SOURCE_SET_NAME)
320+
setTestClassesDirs(yamlRestTestSourceSet.getOutput().getClassesDirs())
321+
setClasspath(yamlRestTestSourceSet.getRuntimeClasspath())
322+
systemProperty 'tests.rest.denylist', [
323+
'repository_s3/10_basic/*',
324+
'repository_s3/20_repository_permanent_credentials/*',
325+
'repository_s3/30_repository_temporary_credentials/*',
326+
'repository_s3/40_repository_ec2_credentials/*',
327+
'repository_s3/50_repository_ecs_credentials/*'
328+
].join(",")
329+
}
330+
check.dependsOn(yamlRestTestEKS)
331+
332+
testClusters.yamlRestTestEKS {
333+
keystore 's3.client.integration_test_eks.role_arn', "arn:aws:iam::000000000000:role/test"
334+
keystore 's3.client.integration_test_eks.role_session_name', "s3-test"
335+
keystore 's3.client.integration_test_eks.access_key', "access_key"
336+
keystore 's3.client.integration_test_eks.secret_key', "secret_key"
337+
338+
setting 's3.client.integration_test_eks.endpoint', { "${-> fixtureAddress('s3-fixture', 's3-fixture-with-eks', '80')}" }, IGNORE_VALUE
339+
setting 's3.client.integration_test_eks.region', { "us-east-2" }, IGNORE_VALUE
340+
plugin tasks.bundlePlugin.archiveFile
341+
342+
// to redirect AWSSecurityTokenServiceClient to custom auth point
343+
systemProperty "com.amazonaws.sdk.stsEndpointOverride", { "${-> fixtureAddress('s3-fixture', 's3-fixture-with-eks', '80')}/eks_credentials_endpoint" }, IGNORE_VALUE
344+
}
345+
}
346+
292347
// 3rd Party Tests
293348
TaskProvider s3ThirdPartyTest = tasks.register("s3ThirdPartyTest", Test) {
294349
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);

plugins/repository-s3/src/main/java/org/opensearch/repositories/s3/S3Service.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.amazonaws.auth.STSAssumeRoleSessionCredentialsProvider;
4242
import com.amazonaws.auth.STSAssumeRoleWithWebIdentitySessionCredentialsProvider;
4343
import com.amazonaws.client.builder.AwsClientBuilder;
44+
import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration;
4445
import com.amazonaws.http.IdleConnectionReaper;
4546
import com.amazonaws.http.SystemPropertyTlsKeyManagersProvider;
4647
import com.amazonaws.http.conn.ssl.SdkTLSSocketFactory;
@@ -82,6 +83,8 @@
8283
class S3Service implements Closeable {
8384
private static final Logger logger = LogManager.getLogger(S3Service.class);
8485

86+
private static final String STS_ENDPOINT_OVERRIDE_SYSTEM_PROPERTY = "com.amazonaws.sdk.stsEndpointOverride";
87+
8588
private volatile Map<S3ClientSettings, AmazonS3Reference> clientsCache = emptyMap();
8689

8790
/**
@@ -280,13 +283,25 @@ static AWSCredentialsProvider buildCredentials(Logger logger, S3ClientSettings c
280283

281284
AWSSecurityTokenService securityTokenService = null;
282285
final String region = Strings.hasLength(clientSettings.region) ? clientSettings.region : null;
286+
283287
if (region != null || basicCredentials != null) {
284-
securityTokenService = SocketAccess.doPrivileged(
285-
() -> AWSSecurityTokenServiceClientBuilder.standard()
286-
.withCredentials((basicCredentials != null) ? new AWSStaticCredentialsProvider(basicCredentials) : null)
287-
.withRegion(region)
288-
.build()
289-
);
288+
securityTokenService = SocketAccess.doPrivileged(() -> {
289+
AWSSecurityTokenServiceClientBuilder builder = AWSSecurityTokenServiceClientBuilder.standard();
290+
291+
// Use similar approach to override STS endpoint as SDKGlobalConfiguration.EC2_METADATA_SERVICE_OVERRIDE_SYSTEM_PROPERTY
292+
final String stsEndpoint = System.getProperty(STS_ENDPOINT_OVERRIDE_SYSTEM_PROPERTY);
293+
if (region != null && stsEndpoint != null) {
294+
builder = builder.withEndpointConfiguration(new EndpointConfiguration(stsEndpoint, region));
295+
} else {
296+
builder = builder.withRegion(region);
297+
}
298+
299+
if (basicCredentials != null) {
300+
builder = builder.withCredentials(new AWSStaticCredentialsProvider(basicCredentials));
301+
}
302+
303+
return builder.build();
304+
});
290305
}
291306

292307
if (irsaCredentials.getIdentityTokenFile() == null) {

0 commit comments

Comments
 (0)