Skip to content

Commit 788cac4

Browse files
authored
Add integ test for EC2 special network addresses (#118560) (#118616)
Replaces the `Ec2NetworkTests` unit test suite with an integ test suite to cover the resolution process end-to-end.
1 parent bc7aae5 commit 788cac4

File tree

11 files changed

+247
-195
lines changed

11 files changed

+247
-195
lines changed

modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3ImdsV1CredentialsRestIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public class RepositoryS3ImdsV1CredentialsRestIT extends AbstractRepositoryS3Res
4444
public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
4545
.module("repository-s3")
4646
.setting("s3.client." + CLIENT + ".endpoint", s3Fixture::getAddress)
47-
.systemProperty("com.amazonaws.sdk.ec2MetadataServiceEndpointOverride", ec2ImdsHttpFixture::getAddress)
47+
.systemProperty(Ec2ImdsHttpFixture.ENDPOINT_OVERRIDE_SYSPROP_NAME, ec2ImdsHttpFixture::getAddress)
4848
.build();
4949

5050
@ClassRule

modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3ImdsV2CredentialsRestIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public class RepositoryS3ImdsV2CredentialsRestIT extends AbstractRepositoryS3Res
4444
public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
4545
.module("repository-s3")
4646
.setting("s3.client." + CLIENT + ".endpoint", s3Fixture::getAddress)
47-
.systemProperty("com.amazonaws.sdk.ec2MetadataServiceEndpointOverride", ec2ImdsHttpFixture::getAddress)
47+
.systemProperty(Ec2ImdsHttpFixture.ENDPOINT_OVERRIDE_SYSPROP_NAME, ec2ImdsHttpFixture::getAddress)
4848
.build();
4949

5050
@ClassRule

plugins/discovery-ec2/build.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import org.elasticsearch.gradle.internal.info.BuildParams
99
* License v3.0 only", or the "Server Side Public License, v 1".
1010
*/
1111
apply plugin: 'elasticsearch.internal-java-rest-test'
12+
apply plugin: 'elasticsearch.internal-cluster-test'
1213

1314
esplugin {
1415
description 'The EC2 discovery plugin allows to use AWS API for the unicast discovery mechanism.'
@@ -31,6 +32,8 @@ dependencies {
3132

3233
javaRestTestImplementation project(':plugins:discovery-ec2')
3334
javaRestTestImplementation project(':test:fixtures:ec2-imds-fixture')
35+
36+
internalClusterTestImplementation project(':test:fixtures:ec2-imds-fixture')
3437
}
3538

3639
tasks.named("dependencyLicenses").configure {
@@ -84,7 +87,7 @@ tasks.register("writeTestJavaPolicy") {
8487
}
8588
}
8689

87-
tasks.named("test").configure {
90+
tasks.withType(Test).configureEach {
8891
dependsOn "writeTestJavaPolicy"
8992
// this is needed for insecure plugins, remove if possible!
9093
systemProperty 'tests.artifact', project.name
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.discovery.ec2;
11+
12+
import org.elasticsearch.common.settings.Settings;
13+
import org.elasticsearch.common.util.CollectionUtils;
14+
import org.elasticsearch.http.HttpServerTransport;
15+
import org.elasticsearch.plugins.Plugin;
16+
import org.elasticsearch.test.ESIntegTestCase;
17+
18+
import java.io.IOException;
19+
import java.util.Collection;
20+
21+
@ESIntegTestCase.ClusterScope(numDataNodes = 0)
22+
public abstract class DiscoveryEc2NetworkAddressesTestCase extends ESIntegTestCase {
23+
24+
@Override
25+
protected Collection<Class<? extends Plugin>> nodePlugins() {
26+
return CollectionUtils.appendToCopyNoNullElements(super.nodePlugins(), Ec2DiscoveryPlugin.class);
27+
}
28+
29+
@Override
30+
protected boolean addMockHttpTransport() {
31+
return false;
32+
}
33+
34+
void verifyPublishAddress(String publishAddressSetting, String expectedAddress) throws IOException {
35+
final var node = internalCluster().startNode(Settings.builder().put("http.publish_host", publishAddressSetting));
36+
assertEquals(
37+
expectedAddress,
38+
internalCluster().getInstance(HttpServerTransport.class, node).boundAddress().publishAddress().getAddress()
39+
);
40+
internalCluster().stopNode(node);
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.discovery.ec2;
11+
12+
import fixture.aws.imds.Ec2ImdsHttpFixture;
13+
import fixture.aws.imds.Ec2ImdsServiceBuilder;
14+
import fixture.aws.imds.Ec2ImdsVersion;
15+
16+
import org.elasticsearch.common.settings.Settings;
17+
import org.elasticsearch.transport.BindTransportException;
18+
19+
import java.io.IOException;
20+
import java.util.concurrent.ExecutionException;
21+
22+
import static org.hamcrest.Matchers.containsString;
23+
24+
public class DiscoveryEc2RegularNetworkAddressesIT extends DiscoveryEc2NetworkAddressesTestCase {
25+
public void testLocalIgnoresImds() {
26+
Ec2ImdsHttpFixture.runWithFixture(new Ec2ImdsServiceBuilder(randomFrom(Ec2ImdsVersion.values())), imdsFixture -> {
27+
try (var ignored = Ec2ImdsHttpFixture.withEc2MetadataServiceEndpointOverride(imdsFixture.getAddress())) {
28+
verifyPublishAddress("_local_", "127.0.0.1");
29+
}
30+
});
31+
}
32+
33+
public void testImdsNotAvailable() throws IOException {
34+
try (var ignored = Ec2ImdsHttpFixture.withEc2MetadataServiceEndpointOverride("http://127.0.0.1")) {
35+
// if IMDS is not running, regular values like `_local_` should still work
36+
verifyPublishAddress("_local_", "127.0.0.1");
37+
38+
// but EC2 addresses will cause the node to fail to start
39+
final var assertionError = expectThrows(
40+
AssertionError.class,
41+
() -> internalCluster().startNode(Settings.builder().put("http.publish_host", "_ec2_"))
42+
);
43+
final var executionException = asInstanceOf(ExecutionException.class, assertionError.getCause());
44+
final var bindTransportException = asInstanceOf(BindTransportException.class, executionException.getCause());
45+
assertEquals("Failed to resolve publish address", bindTransportException.getMessage());
46+
final var ioException = asInstanceOf(IOException.class, bindTransportException.getCause());
47+
assertThat(ioException.getMessage(), containsString("/latest/meta-data/local-ipv4"));
48+
}
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.discovery.ec2;
11+
12+
import fixture.aws.imds.Ec2ImdsHttpFixture;
13+
import fixture.aws.imds.Ec2ImdsServiceBuilder;
14+
import fixture.aws.imds.Ec2ImdsVersion;
15+
16+
import com.carrotsearch.randomizedtesting.annotations.Name;
17+
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
18+
19+
import java.util.Map;
20+
import java.util.stream.Stream;
21+
22+
public class DiscoveryEc2SpecialNetworkAddressesIT extends DiscoveryEc2NetworkAddressesTestCase {
23+
24+
private final String imdsAddressName;
25+
private final String elasticsearchAddressName;
26+
private final Ec2ImdsVersion imdsVersion;
27+
28+
public DiscoveryEc2SpecialNetworkAddressesIT(
29+
@Name("imdsAddressName") String imdsAddressName,
30+
@Name("elasticsearchAddressName") String elasticsearchAddressName,
31+
@Name("imdsVersion") Ec2ImdsVersion imdsVersion
32+
) {
33+
this.imdsAddressName = imdsAddressName;
34+
this.elasticsearchAddressName = elasticsearchAddressName;
35+
this.imdsVersion = imdsVersion;
36+
}
37+
38+
@ParametersFactory
39+
public static Iterable<Object[]> parameters() {
40+
return Map.of(
41+
"_ec2:privateIpv4_",
42+
"local-ipv4",
43+
"_ec2:privateDns_",
44+
"local-hostname",
45+
"_ec2:publicIpv4_",
46+
"public-ipv4",
47+
"_ec2:publicDns_",
48+
"public-hostname",
49+
"_ec2:publicIp_",
50+
"public-ipv4",
51+
"_ec2:privateIp_",
52+
"local-ipv4",
53+
"_ec2_",
54+
"local-ipv4"
55+
)
56+
.entrySet()
57+
.stream()
58+
.flatMap(
59+
addresses -> Stream.of(Ec2ImdsVersion.values())
60+
.map(ec2ImdsVersion -> new Object[] { addresses.getValue(), addresses.getKey(), ec2ImdsVersion })
61+
)
62+
.toList();
63+
}
64+
65+
public void testSpecialNetworkAddresses() {
66+
final var publishAddress = "10.0." + between(0, 255) + "." + between(0, 255);
67+
Ec2ImdsHttpFixture.runWithFixture(
68+
new Ec2ImdsServiceBuilder(imdsVersion).addInstanceAddress(imdsAddressName, publishAddress),
69+
imdsFixture -> {
70+
try (var ignored = Ec2ImdsHttpFixture.withEc2MetadataServiceEndpointOverride(imdsFixture.getAddress())) {
71+
verifyPublishAddress(elasticsearchAddressName, publishAddress);
72+
}
73+
}
74+
);
75+
}
76+
77+
}

plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2AvailabilityZoneAttributeTestCase.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
package org.elasticsearch.discovery.ec2;
1111

12+
import fixture.aws.imds.Ec2ImdsHttpFixture;
13+
1214
import org.elasticsearch.client.Request;
1315
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
1416
import org.elasticsearch.test.cluster.ElasticsearchCluster;
@@ -34,7 +36,7 @@ protected static ElasticsearchCluster buildCluster(Supplier<String> imdsFixtureA
3436
return ElasticsearchCluster.local()
3537
.plugin("discovery-ec2")
3638
.setting(AwsEc2Service.AUTO_ATTRIBUTE_SETTING.getKey(), "true")
37-
.systemProperty("com.amazonaws.sdk.ec2MetadataServiceEndpointOverride", imdsFixtureAddressSupplier)
39+
.systemProperty(Ec2ImdsHttpFixture.ENDPOINT_OVERRIDE_SYSPROP_NAME, imdsFixtureAddressSupplier)
3840
.build();
3941
}
4042

0 commit comments

Comments
 (0)