Skip to content

Commit cb4485e

Browse files
authored
[Entitlements] External IT test for checkSystemExit (#116435) (#116705)
1 parent 88a1b69 commit cb4485e

File tree

7 files changed

+204
-1
lines changed

7 files changed

+204
-1
lines changed

libs/entitlement/bridge/build.gradle

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

1010
apply plugin: 'elasticsearch.build'
1111

12+
configurations {
13+
bridgeJar {
14+
canBeConsumed = true
15+
canBeResolved = false
16+
}
17+
}
18+
19+
artifacts {
20+
bridgeJar(jar)
21+
}
1222

1323
tasks.named('forbiddenApisMain').configure {
1424
replaceSignatureFiles 'jdk-signatures'
1525
}
16-

qa/entitlements/build.gradle

Lines changed: 42 additions & 0 deletions
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+
apply plugin: 'elasticsearch.base-internal-es-plugin'
11+
apply plugin: 'elasticsearch.internal-java-rest-test'
12+
// Necessary to use tests in Serverless
13+
apply plugin: 'elasticsearch.internal-test-artifact'
14+
15+
esplugin {
16+
name 'entitlement-qa'
17+
description 'A test module that triggers entitlement checks'
18+
classname 'org.elasticsearch.test.entitlements.EntitlementsCheckPlugin'
19+
}
20+
21+
configurations {
22+
entitlementBridge {
23+
canBeConsumed = false
24+
}
25+
}
26+
27+
dependencies {
28+
clusterPlugins project(':qa:entitlements')
29+
entitlementBridge project(':libs:entitlement:bridge')
30+
}
31+
32+
tasks.named('javaRestTest') {
33+
systemProperty "tests.entitlement-bridge.jar-name", configurations.entitlementBridge.singleFile.getName()
34+
usesDefaultDistribution()
35+
systemProperty "tests.security.manager", "false"
36+
}
37+
38+
tasks.named("javadoc").configure {
39+
// There seems to be some problem generating javadoc on a QA project that has a module definition
40+
enabled = false
41+
}
42+
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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.test.entitlements;
11+
12+
import org.elasticsearch.client.Request;
13+
import org.elasticsearch.test.ESTestCase;
14+
import org.elasticsearch.test.cluster.ElasticsearchCluster;
15+
import org.elasticsearch.test.cluster.local.distribution.DistributionType;
16+
import org.elasticsearch.test.rest.ESRestTestCase;
17+
import org.junit.ClassRule;
18+
19+
import java.io.IOException;
20+
21+
import static org.hamcrest.Matchers.containsString;
22+
23+
@ESTestCase.WithoutSecurityManager
24+
public class EntitlementsIT extends ESRestTestCase {
25+
26+
private static final String ENTITLEMENT_BRIDGE_JAR_NAME = System.getProperty("tests.entitlement-bridge.jar-name");
27+
28+
@ClassRule
29+
public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
30+
.distribution(DistributionType.INTEG_TEST)
31+
.plugin("entitlement-qa")
32+
.systemProperty("es.entitlements.enabled", "true")
33+
.setting("xpack.security.enabled", "false")
34+
.jvmArg("-Djdk.attach.allowAttachSelf=true")
35+
.jvmArg("-XX:+EnableDynamicAgentLoading")
36+
.jvmArg("--patch-module=java.base=lib/entitlement-bridge/" + ENTITLEMENT_BRIDGE_JAR_NAME)
37+
.jvmArg("--add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement")
38+
.build();
39+
40+
@Override
41+
protected String getTestRestCluster() {
42+
return cluster.getHttpAddresses();
43+
}
44+
45+
public void testCheckSystemExit() {
46+
var exception = expectThrows(
47+
IOException.class,
48+
() -> { client().performRequest(new Request("GET", "/_entitlement/_check_system_exit")); }
49+
);
50+
assertThat(exception.getMessage(), containsString("not_entitled_exception"));
51+
}
52+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module elasticsearch.qa.entitlements {
2+
requires org.elasticsearch.server;
3+
requires org.elasticsearch.base;
4+
requires org.apache.logging.log4j;
5+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
package org.elasticsearch.test.entitlements;
10+
11+
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
12+
import org.elasticsearch.cluster.node.DiscoveryNodes;
13+
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
14+
import org.elasticsearch.common.settings.ClusterSettings;
15+
import org.elasticsearch.common.settings.IndexScopedSettings;
16+
import org.elasticsearch.common.settings.Settings;
17+
import org.elasticsearch.common.settings.SettingsFilter;
18+
import org.elasticsearch.core.SuppressForbidden;
19+
import org.elasticsearch.features.NodeFeature;
20+
import org.elasticsearch.plugins.ActionPlugin;
21+
import org.elasticsearch.plugins.Plugin;
22+
import org.elasticsearch.rest.RestController;
23+
import org.elasticsearch.rest.RestHandler;
24+
25+
import java.util.Collections;
26+
import java.util.List;
27+
import java.util.function.Predicate;
28+
import java.util.function.Supplier;
29+
30+
public class EntitlementsCheckPlugin extends Plugin implements ActionPlugin {
31+
32+
@Override
33+
@SuppressForbidden(reason = "Specifically testing System.exit")
34+
public List<RestHandler> getRestHandlers(
35+
final Settings settings,
36+
NamedWriteableRegistry namedWriteableRegistry,
37+
final RestController restController,
38+
final ClusterSettings clusterSettings,
39+
final IndexScopedSettings indexScopedSettings,
40+
final SettingsFilter settingsFilter,
41+
final IndexNameExpressionResolver indexNameExpressionResolver,
42+
final Supplier<DiscoveryNodes> nodesInCluster,
43+
Predicate<NodeFeature> clusterSupportsFeature
44+
) {
45+
return Collections.singletonList(new RestEntitlementsCheckSystemExitAction());
46+
}
47+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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.test.entitlements;
11+
12+
import org.apache.logging.log4j.LogManager;
13+
import org.apache.logging.log4j.Logger;
14+
import org.elasticsearch.client.internal.node.NodeClient;
15+
import org.elasticsearch.rest.BaseRestHandler;
16+
import org.elasticsearch.rest.RestRequest;
17+
18+
import java.util.List;
19+
20+
import static org.elasticsearch.rest.RestRequest.Method.GET;
21+
22+
public class RestEntitlementsCheckSystemExitAction extends BaseRestHandler {
23+
24+
private static final Logger logger = LogManager.getLogger(RestEntitlementsCheckSystemExitAction.class);
25+
26+
RestEntitlementsCheckSystemExitAction() {}
27+
28+
@Override
29+
public List<Route> routes() {
30+
return List.of(new Route(GET, "/_entitlement/_check_system_exit"));
31+
}
32+
33+
@Override
34+
public String getName() {
35+
return "check_system_exit_action";
36+
}
37+
38+
@Override
39+
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) {
40+
logger.info("RestEntitlementsCheckSystemExitAction rest handler");
41+
return channel -> {
42+
logger.info("Calling System.exit(123);");
43+
System.exit(123);
44+
};
45+
}
46+
}

server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,11 @@ private static void initPhase2(Bootstrap bootstrap) throws IOException {
200200
);
201201

202202
if (Boolean.parseBoolean(System.getProperty("es.entitlements.enabled"))) {
203+
logger.info("Bootstrapping Entitlements");
203204
EntitlementBootstrap.bootstrap();
204205
} else {
205206
// install SM after natives, shutdown hooks, etc.
207+
logger.info("Bootstrapping java SecurityManager");
206208
org.elasticsearch.bootstrap.Security.configure(
207209
nodeEnv,
208210
SECURITY_FILTER_BAD_DEFAULTS_SETTING.get(args.nodeSettings()),

0 commit comments

Comments
 (0)