Skip to content

Commit 8235b25

Browse files
Add EC2 credential test for repository-s3 (#31918)
Add EC2 credential test for repository-s3 Relates to #26913
1 parent 5856c39 commit 8235b25

File tree

6 files changed

+483
-78
lines changed

6 files changed

+483
-78
lines changed

buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterConfiguration.groovy

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,10 @@ class ClusterConfiguration {
137137
this.project = project
138138
}
139139

140-
Map<String, String> systemProperties = new HashMap<>()
140+
// **Note** for systemProperties, settings, keystoreFiles etc:
141+
// value could be a GString that is evaluated to just a String
142+
// there are cases when value depends on task that is not executed yet on configuration stage
143+
Map<String, Object> systemProperties = new HashMap<>()
141144

142145
Map<String, Object> settings = new HashMap<>()
143146

@@ -157,7 +160,7 @@ class ClusterConfiguration {
157160
List<Object> dependencies = new ArrayList<>()
158161

159162
@Input
160-
void systemProperty(String property, String value) {
163+
void systemProperty(String property, Object value) {
161164
systemProperties.put(property, value)
162165
}
163166

buildSrc/src/main/groovy/org/elasticsearch/gradle/test/ClusterFormationTasks.groovy

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,6 @@ class ClusterFormationTasks {
609609

610610
/** Adds a task to start an elasticsearch node with the given configuration */
611611
static Task configureStartTask(String name, Project project, Task setup, NodeInfo node) {
612-
613612
// this closure is converted into ant nodes by groovy's AntBuilder
614613
Closure antRunner = { AntBuilder ant ->
615614
ant.exec(executable: node.executable, spawn: node.config.daemonize, dir: node.cwd, taskname: 'elasticsearch') {
@@ -630,13 +629,6 @@ class ClusterFormationTasks {
630629
node.writeWrapperScript()
631630
}
632631

633-
// we must add debug options inside the closure so the config is read at execution time, as
634-
// gradle task options are not processed until the end of the configuration phase
635-
if (node.config.debug) {
636-
println 'Running elasticsearch in debug mode, suspending until connected on port 8000'
637-
node.env['ES_JAVA_OPTS'] = '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000'
638-
}
639-
640632
node.getCommandString().eachLine { line -> logger.info(line) }
641633

642634
if (logger.isInfoEnabled() || node.config.daemonize == false) {
@@ -654,6 +646,27 @@ class ClusterFormationTasks {
654646
}
655647
start.doLast(elasticsearchRunner)
656648
start.doFirst {
649+
// Configure ES JAVA OPTS - adds system properties, assertion flags, remote debug etc
650+
List<String> esJavaOpts = [node.env.get('ES_JAVA_OPTS', '')]
651+
String collectedSystemProperties = node.config.systemProperties.collect { key, value -> "-D${key}=${value}" }.join(" ")
652+
esJavaOpts.add(collectedSystemProperties)
653+
esJavaOpts.add(node.config.jvmArgs)
654+
if (Boolean.parseBoolean(System.getProperty('tests.asserts', 'true'))) {
655+
// put the enable assertions options before other options to allow
656+
// flexibility to disable assertions for specific packages or classes
657+
// in the cluster-specific options
658+
esJavaOpts.add("-ea")
659+
esJavaOpts.add("-esa")
660+
}
661+
// we must add debug options inside the closure so the config is read at execution time, as
662+
// gradle task options are not processed until the end of the configuration phase
663+
if (node.config.debug) {
664+
println 'Running elasticsearch in debug mode, suspending until connected on port 8000'
665+
esJavaOpts.add('-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000')
666+
}
667+
node.env['ES_JAVA_OPTS'] = esJavaOpts.join(" ")
668+
669+
//
657670
project.logger.info("Starting node in ${node.clusterName} distribution: ${node.config.distribution}")
658671
}
659672
return start

buildSrc/src/main/groovy/org/elasticsearch/gradle/test/NodeInfo.groovy

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -180,15 +180,7 @@ class NodeInfo {
180180
}
181181

182182
args.addAll("-E", "node.portsfile=true")
183-
String collectedSystemProperties = config.systemProperties.collect { key, value -> "-D${key}=${value}" }.join(" ")
184-
String esJavaOpts = config.jvmArgs.isEmpty() ? collectedSystemProperties : collectedSystemProperties + " " + config.jvmArgs
185-
if (Boolean.parseBoolean(System.getProperty('tests.asserts', 'true'))) {
186-
// put the enable assertions options before other options to allow
187-
// flexibility to disable assertions for specific packages or classes
188-
// in the cluster-specific options
189-
esJavaOpts = String.join(" ", "-ea", "-esa", esJavaOpts)
190-
}
191-
env = ['ES_JAVA_OPTS': esJavaOpts]
183+
env = [:]
192184
for (Map.Entry<String, String> property : System.properties.entrySet()) {
193185
if (property.key.startsWith('tests.es.')) {
194186
args.add("-E")

plugins/repository-s3/build.gradle

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,26 @@ String s3TemporarySessionToken = System.getenv("amazon_s3_session_token_temporar
8989
String s3TemporaryBucket = System.getenv("amazon_s3_bucket_temporary")
9090
String s3TemporaryBasePath = System.getenv("amazon_s3_base_path_temporary")
9191

92+
String s3EC2Bucket = System.getenv("amazon_s3_bucket_ec2")
93+
String s3EC2BasePath = System.getenv("amazon_s3_base_path_ec2")
94+
9295
// If all these variables are missing then we are testing against the internal fixture instead, which has the following
9396
// credentials hard-coded in.
9497

95-
if (!s3PermanentAccessKey && !s3PermanentSecretKey && !s3PermanentBucket && !s3PermanentBasePath) {
98+
if (!s3PermanentAccessKey && !s3PermanentSecretKey && !s3PermanentBucket && !s3PermanentBasePath
99+
&& !s3EC2Bucket && !s3EC2BasePath) {
96100
s3PermanentAccessKey = 's3_integration_test_permanent_access_key'
97101
s3PermanentSecretKey = 's3_integration_test_permanent_secret_key'
98102
s3PermanentBucket = 'permanent-bucket-test'
99103
s3PermanentBasePath = 'integration_test'
100104

105+
s3EC2Bucket = 'ec2-bucket-test'
106+
s3EC2BasePath = 'integration_test'
107+
101108
useFixture = true
102109

103-
} else if (!s3PermanentAccessKey || !s3PermanentSecretKey || !s3PermanentBucket || !s3PermanentBasePath) {
110+
} else if (!s3PermanentAccessKey || !s3PermanentSecretKey || !s3PermanentBucket || !s3PermanentBasePath
111+
|| !s3EC2Bucket || !s3EC2BasePath) {
104112
throw new IllegalArgumentException("not all options specified to run against external S3 service")
105113
}
106114

@@ -274,24 +282,52 @@ if (useFixture && minioDistribution) {
274282
integTestMinioRunner.dependsOn(startMinio)
275283
integTestMinioRunner.finalizedBy(stopMinio)
276284
// Minio only supports a single access key, see https://github.com/minio/minio/pull/5968
277-
integTestMinioRunner.systemProperty 'tests.rest.blacklist', 'repository_s3/30_repository_temporary_credentials/*'
285+
integTestMinioRunner.systemProperty 'tests.rest.blacklist', [
286+
'repository_s3/30_repository_temporary_credentials/*',
287+
'repository_s3/40_repository_ec2_credentials/*'
288+
].join(",")
278289

279290
project.check.dependsOn(integTestMinio)
280291
}
281292

293+
File parentFixtures = new File(project.buildDir, "fixtures")
294+
File s3FixtureFile = new File(parentFixtures, 's3Fixture.properties')
295+
296+
task s3FixtureProperties {
297+
outputs.file(s3FixtureFile)
298+
def s3FixtureOptions = [
299+
"tests.seed" : project.testSeed,
300+
"s3Fixture.permanent_bucket_name" : s3PermanentBucket,
301+
"s3Fixture.permanent_key" : s3PermanentAccessKey,
302+
"s3Fixture.temporary_bucket_name" : s3TemporaryBucket,
303+
"s3Fixture.temporary_key" : s3TemporaryAccessKey,
304+
"s3Fixture.temporary_session_token": s3TemporarySessionToken,
305+
"s3Fixture.ec2_bucket_name" : s3EC2Bucket
306+
]
307+
308+
doLast {
309+
file(s3FixtureFile).text = s3FixtureOptions.collect { k, v -> "$k = $v" }.join("\n")
310+
}
311+
}
312+
282313
/** A task to start the AmazonS3Fixture which emulates an S3 service **/
283314
task s3Fixture(type: AntFixture) {
284315
dependsOn testClasses
316+
dependsOn s3FixtureProperties
317+
inputs.file(s3FixtureFile)
318+
285319
env 'CLASSPATH', "${ -> project.sourceSets.test.runtimeClasspath.asPath }"
286320
executable = new File(project.runtimeJavaHome, 'bin/java')
287-
args 'org.elasticsearch.repositories.s3.AmazonS3Fixture', baseDir, s3PermanentBucket, s3TemporaryBucket
321+
args 'org.elasticsearch.repositories.s3.AmazonS3Fixture', baseDir, s3FixtureFile.getAbsolutePath()
288322
}
289323

290324
Map<String, Object> expansions = [
291325
'permanent_bucket': s3PermanentBucket,
292326
'permanent_base_path': s3PermanentBasePath,
293327
'temporary_bucket': s3TemporaryBucket,
294-
'temporary_base_path': s3TemporaryBasePath
328+
'temporary_base_path': s3TemporaryBasePath,
329+
'ec2_bucket': s3EC2Bucket,
330+
'ec2_base_path': s3EC2BasePath
295331
]
296332

297333
processTestResources {
@@ -319,6 +355,10 @@ integTestCluster {
319355
/* Use a closure on the string to delay evaluation until tests are executed */
320356
setting 's3.client.integration_test_permanent.endpoint', "http://${-> s3Fixture.addressAndPort}"
321357
setting 's3.client.integration_test_temporary.endpoint', "http://${-> s3Fixture.addressAndPort}"
358+
setting 's3.client.integration_test_ec2.endpoint', "http://${-> s3Fixture.addressAndPort}"
359+
360+
// to redirect InstanceProfileCredentialsProvider to custom auth point
361+
systemProperty "com.amazonaws.sdk.ec2MetadataServiceEndpointOverride", "http://${-> s3Fixture.addressAndPort}"
322362
} else {
323363
println "Using an external service to test the repository-s3 plugin"
324364
}

0 commit comments

Comments
 (0)