Skip to content

Commit e25e7af

Browse files
Rework implementation.
Signed-off-by: Yury-Fridlyand <[email protected]>
1 parent e68aedf commit e25e7af

File tree

3 files changed

+128
-102
lines changed

3 files changed

+128
-102
lines changed

integ-test/build.gradle

Lines changed: 80 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424

2525
import org.opensearch.gradle.test.RestIntegTestTask
2626
import org.opensearch.gradle.testclusters.StandaloneRestIntegTestTask
27+
import org.opensearch.gradle.testclusters.OpenSearchCluster
2728

29+
import groovy.xml.XmlParser
2830
import java.nio.file.Paths
29-
import java.time.LocalDateTime
3031
import java.util.concurrent.Callable
3132
import java.util.stream.Collectors
32-
import groovy.xml.XmlParser
3333

3434
plugins {
3535
id "de.undercouch.download" version "5.3.0"
@@ -74,6 +74,63 @@ ext {
7474

7575
return repo + "opensearch-security-${securitySnapshotVersion}.zip"
7676
}
77+
78+
File downloadedSecurityPlugin = null
79+
80+
configureSecurityPlugin = { OpenSearchCluster cluster ->
81+
82+
cluster.getNodes().forEach { node ->
83+
node.getCredentials().add(Map.of('useradd', 'admin', '-p', 'admin'))
84+
}
85+
86+
var projectAbsPath = projectDir.getAbsolutePath()
87+
88+
// add a check to avoid re-downloading multiple times during single test run
89+
if (downloadedSecurityPlugin == null) {
90+
downloadedSecurityPlugin = Paths.get(projectAbsPath, 'bin', 'opensearch-security-snapshot.zip').toFile()
91+
download.run {
92+
src getSecurityPluginDownloadLink()
93+
dest downloadedSecurityPlugin
94+
}
95+
}
96+
97+
// Config below including files are copied from security demo configuration
98+
['esnode.pem', 'esnode-key.pem', 'root-ca.pem'].forEach { file ->
99+
File local = Paths.get(projectAbsPath, 'bin', file).toFile()
100+
download.run {
101+
src "https://raw.githubusercontent.com/opensearch-project/security/main/bwc-test/src/test/resources/security/" + file
102+
dest local
103+
overwrite false
104+
}
105+
cluster.extraConfigFile file, local
106+
}
107+
[
108+
'plugins.security.ssl.transport.pemcert_filepath' : 'esnode.pem',
109+
'plugins.security.ssl.transport.pemkey_filepath' : 'esnode-key.pem',
110+
'plugins.security.ssl.transport.pemtrustedcas_filepath' : 'root-ca.pem',
111+
'plugins.security.ssl.transport.enforce_hostname_verification' : 'false',
112+
// https is disabled : because `OpenSearchCluster` is hardcoded to validate cluster health by http
113+
// refer how IT framework implemented in security plugin and reuse/copy to activate https
114+
'plugins.security.ssl.http.enabled' : 'false',
115+
'plugins.security.ssl.http.pemcert_filepath' : 'esnode.pem',
116+
'plugins.security.ssl.http.pemkey_filepath' : 'esnode-key.pem',
117+
'plugins.security.ssl.http.pemtrustedcas_filepath' : 'root-ca.pem',
118+
'plugins.security.allow_unsafe_democertificates' : 'true',
119+
120+
'plugins.security.allow_default_init_securityindex' : 'true',
121+
//'plugins.security.authcz.admin_dn' : 'CN=kirk,OU=client,O=client,L=test,C=de',
122+
'plugins.security.authcz.admin_dn' : 'CN=admin,OU=SSL,O=Test,L=Test,C=DE',
123+
'plugins.security.audit.type' : 'internal_opensearch',
124+
'plugins.security.enable_snapshot_restore_privilege' : 'true',
125+
'plugins.security.check_snapshot_restore_write_privileges' : 'true',
126+
'plugins.security.restapi.roles_enabled' : '["all_access", "security_rest_api_access"]',
127+
'plugins.security.system_indices.enabled' : 'true'
128+
].forEach { name, value ->
129+
cluster.setting name, value
130+
}
131+
132+
cluster.plugin provider((Callable<RegularFile>) (() -> (RegularFile) (() -> downloadedSecurityPlugin)))
133+
}
77134
}
78135

79136
tasks.withType(licenseHeaders.class) {
@@ -142,73 +199,23 @@ compileTestJava {
142199

143200
testClusters.all {
144201
testDistribution = 'archive'
202+
plugin ":opensearch-sql-plugin"
145203

146204
// debug with command, ./gradlew opensearch-sql:run -DdebugJVM. --debug-jvm does not work with keystore.
147205
if (System.getProperty("debugJVM") != null) {
148206
jvmArgs '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005'
149207
}
150208
}
151209

152-
testClusters.integTest {
153-
plugin ":opensearch-sql-plugin"
154-
setting "plugins.query.datasources.encryption.masterkey", "1234567812345678"
155-
}
156-
157-
File downloadedSecurityPlugin = null
158-
159210
testClusters {
211+
integTest {
212+
setting "plugins.query.datasources.encryption.masterkey", "1234567812345678"
213+
}
160214
remoteCluster {
161-
plugin ":opensearch-sql-plugin"
162215
}
163-
integTestWithSecurity { // OpenSearchCluster
164-
165-
getNodes().forEach { node ->
166-
node.getCredentials().add(Map.of('useradd', 'admin', '-p', 'admin'))
167-
}
168-
169-
var projectAbsPath = projectDir.getAbsolutePath()
170-
171-
// add a check to avoid re-downloading multiple times during single test run
172-
if (downloadedSecurityPlugin == null) {
173-
downloadedSecurityPlugin = Paths.get(projectAbsPath, 'bin', 'opensearch-security-snapshot.zip').toFile()
174-
download.run {
175-
src getSecurityPluginDownloadLink()
176-
dest downloadedSecurityPlugin
177-
}
178-
}
179-
180-
// Config below including files are copied from security demo configuration
181-
['esnode.pem', 'esnode-key.pem', 'root-ca.pem'].forEach { file ->
182-
File local = Paths.get(projectAbsPath, 'bin', file).toFile()
183-
download.run {
184-
src "https://raw.githubusercontent.com/opensearch-project/security/main/bwc-test/src/test/resources/security/" + file
185-
dest local
186-
overwrite false
187-
}
188-
extraConfigFile file, local
189-
}
190-
setting 'plugins.security.ssl.transport.pemcert_filepath', 'esnode.pem'
191-
setting 'plugins.security.ssl.transport.pemkey_filepath', 'esnode-key.pem'
192-
setting 'plugins.security.ssl.transport.pemtrustedcas_filepath', 'root-ca.pem'
193-
setting 'plugins.security.ssl.transport.enforce_hostname_verification', 'false'
194-
// https is disabled, because `OpenSearchCluster` is hardcoded to validate cluster health by http
195-
// refer how IT framework implemented in security plugin and reuse/copy to activate https
196-
setting 'plugins.security.ssl.http.enabled', 'false'
197-
setting 'plugins.security.ssl.http.pemcert_filepath', 'esnode.pem'
198-
setting 'plugins.security.ssl.http.pemkey_filepath', 'esnode-key.pem'
199-
setting 'plugins.security.ssl.http.pemtrustedcas_filepath', 'root-ca.pem'
200-
setting 'plugins.security.allow_unsafe_democertificates', 'true'
201-
202-
setting 'plugins.security.allow_default_init_securityindex', 'true'
203-
setting 'plugins.security.authcz.admin_dn', 'CN=admin,OU=SSL,O=Test,L=Test,C=DE'//'CN=kirk,OU=client,O=client,L=test, C=de'
204-
setting 'plugins.security.audit.type', 'internal_opensearch'
205-
setting 'plugins.security.enable_snapshot_restore_privilege', 'true'
206-
setting 'plugins.security.check_snapshot_restore_write_privileges', 'true'
207-
setting 'plugins.security.restapi.roles_enabled', '["all_access", "security_rest_api_access"]'
208-
setting 'plugins.security.system_indices.enabled', 'true'
209-
210-
plugin ":opensearch-sql-plugin"
211-
plugin provider((Callable<RegularFile>) (() -> (RegularFile) (() -> downloadedSecurityPlugin)))
216+
integTestWithSecurity {
217+
}
218+
anotherintegTestWithSecurity {
212219
}
213220
}
214221

@@ -290,6 +297,15 @@ task integJdbcTest(type: RestIntegTestTask) {
290297

291298
task integTestWithSecurity(type: RestIntegTestTask) {
292299
useCluster testClusters.integTestWithSecurity
300+
useCluster testClusters.anotherintegTestWithSecurity
301+
302+
// Don't use `getClusters`: cluster order is important. IT framework adds/uses a cluster
303+
// named as the task as default and uses it to init default REST client
304+
systemProperty "cluster.names", "integTestWithSecurity,anotherintegTestWithSecurity"
305+
306+
getClusters().forEach { cluster ->
307+
configureSecurityPlugin(cluster)
308+
}
293309

294310
useJUnitPlatform()
295311
dependsOn ':opensearch-sql-plugin:bundlePlugin'
@@ -311,6 +327,7 @@ task integTestWithSecurity(type: RestIntegTestTask) {
311327
doFirst {
312328
systemProperty 'cluster.debug', getDebug()
313329
getClusters().forEach { cluster ->
330+
314331
String allTransportSocketURI = cluster.nodes.stream().flatMap { node ->
315332
node.getAllTransportPortURI().stream()
316333
}.collect(Collectors.joining(","))
@@ -320,13 +337,11 @@ task integTestWithSecurity(type: RestIntegTestTask) {
320337

321338
systemProperty "tests.rest.${cluster.name}.http_hosts", "${-> allHttpSocketURI}"
322339
systemProperty "tests.rest.${cluster.name}.transport_hosts", "${-> allTransportSocketURI}"
323-
systemProperty "tests.rest.remoteCluster.http_hosts", "${-> allHttpSocketURI}"
324-
systemProperty "tests.rest.remoteCluster.transport_hosts", "${-> allTransportSocketURI}"
325-
326-
systemProperty "https", "false"
327-
systemProperty "user", "admin"
328-
systemProperty "password", "admin"
329340
}
341+
342+
systemProperty "https", "false"
343+
systemProperty "user", "admin"
344+
systemProperty "password", "admin"
330345
}
331346

332347
if (System.getProperty("test.debug") != null) {

integ-test/src/test/java/org/opensearch/sql/legacy/OpenSearchSQLRestTestCase.java

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -105,27 +105,25 @@ protected RestClient buildClient(Settings settings, HttpHost[] hosts) throws IOE
105105
}
106106

107107
// Modified from initClient in OpenSearchRestTestCase
108-
public void initRemoteClient() throws IOException {
109-
if (remoteClient == null) {
110-
assert remoteAdminClient == null;
111-
String cluster = getTestRestCluster(REMOTE_CLUSTER);
112-
String[] stringUrls = cluster.split(",");
113-
List<HttpHost> hosts = new ArrayList<>(stringUrls.length);
114-
for (String stringUrl : stringUrls) {
115-
int portSeparator = stringUrl.lastIndexOf(':');
116-
if (portSeparator < 0) {
117-
throw new IllegalArgumentException("Illegal cluster url [" + stringUrl + "]");
118-
}
119-
String host = stringUrl.substring(0, portSeparator);
120-
int port = Integer.valueOf(stringUrl.substring(portSeparator + 1));
121-
hosts.add(buildHttpHost(host, port));
108+
public void initRemoteClient(String clusterName) throws IOException {
109+
remoteClient = remoteAdminClient = initClient(clusterName);
110+
}
111+
112+
public RestClient initClient(String clusterName) throws IOException {
113+
String cluster = getTestRestCluster(clusterName);
114+
String[] stringUrls = cluster.split(",");
115+
List<HttpHost> hosts = new ArrayList<>(stringUrls.length);
116+
for (String stringUrl : stringUrls) {
117+
int portSeparator = stringUrl.lastIndexOf(':');
118+
if (portSeparator < 0) {
119+
throw new IllegalArgumentException("Illegal cluster url [" + stringUrl + "]");
122120
}
123-
final List<HttpHost> clusterHosts = unmodifiableList(hosts);
124-
remoteClient = buildClient(restClientSettings(), clusterHosts.toArray(new HttpHost[0]));
125-
remoteAdminClient = buildClient(restAdminSettings(), clusterHosts.toArray(new HttpHost[0]));
121+
String host = stringUrl.substring(0, portSeparator);
122+
int port = Integer.valueOf(stringUrl.substring(portSeparator + 1));
123+
hosts.add(buildHttpHost(host, port));
126124
}
127-
assert remoteClient != null;
128-
assert remoteAdminClient != null;
125+
final List<HttpHost> clusterHosts = unmodifiableList(hosts);
126+
return buildClient(restClientSettings(), clusterHosts.toArray(new HttpHost[0]));
129127
}
130128

131129
/**
@@ -268,15 +266,26 @@ protected static void configureHttpsClient(RestClientBuilder builder, Settings s
268266
* Initialize rest client to remote cluster,
269267
* and create a connection to it from the coordinating cluster.
270268
*/
271-
public void configureMultiClusters() throws IOException {
272-
initRemoteClient();
269+
public void configureMultiClusters(String remote)
270+
throws IOException {
271+
initRemoteClient(remote);
273272

274273
Request connectionRequest = new Request("PUT", "_cluster/settings");
275-
String connectionSetting = "{\"persistent\": {\"cluster\": {\"remote\": {\""
276-
+ REMOTE_CLUSTER
277-
+ "\": {\"seeds\": [\""
278-
+ getTestTransportCluster(REMOTE_CLUSTER).split(",")[0]
279-
+ "\"]}}}}}";
274+
String connectionSetting = String.format(
275+
"{"
276+
+ "\"persistent\": {"
277+
+ " \"cluster\": {"
278+
+ " \"remote\": {"
279+
+ " \"%s\": {"
280+
+ " \"seeds\": ["
281+
+ " \"%s\""
282+
+ " ]"
283+
+ " }"
284+
+ " }"
285+
+ " }"
286+
+ "}"
287+
+ "}",
288+
remote, getTestTransportCluster(remote).split(",")[0]);
280289
connectionRequest.setJsonEntity(connectionSetting);
281290
adminClient().performRequest(connectionRequest);
282291
}

integ-test/src/test/java/org/opensearch/sql/ppl/CrossClusterSearchIT.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,19 @@
1717
import java.io.IOException;
1818
import lombok.SneakyThrows;
1919
import org.json.JSONObject;
20-
import org.junit.Rule;
2120
import org.junit.jupiter.api.BeforeEach;
2221
import org.junit.jupiter.api.Test;
23-
import org.junit.rules.ExpectedException;
2422
import org.opensearch.client.ResponseException;
2523

2624
public class CrossClusterSearchIT extends PPLIntegTestCase {
2725

28-
@Rule
29-
public ExpectedException exceptionRule = ExpectedException.none();
26+
// Set second cluster as a remote
27+
static {
28+
String[] clusterNames = System.getProperty("cluster.names", ",remoteCluster").split(",");
29+
REMOTE_CLUSTER = clusterNames[1];
30+
}
31+
32+
public static final String REMOTE_CLUSTER;
3033

3134
private final static String TEST_INDEX_BANK_REMOTE = REMOTE_CLUSTER + ":" + TEST_INDEX_BANK;
3235
private final static String TEST_INDEX_DOG_REMOTE = REMOTE_CLUSTER + ":" + TEST_INDEX_DOG;
@@ -46,12 +49,12 @@ public void initialize() {
4649

4750
@Override
4851
protected void init() throws Exception {
49-
configureMultiClusters();
52+
configureMultiClusters(REMOTE_CLUSTER);
5053
loadIndex(Index.BANK);
5154
loadIndex(Index.BANK, remoteClient());
5255
loadIndex(Index.DOG);
5356
loadIndex(Index.DOG, remoteClient());
54-
loadIndex(Index.ACCOUNT, remoteClient());
57+
loadIndex(Index.ACCOUNT);
5558
}
5659

5760
@Test
@@ -68,11 +71,10 @@ public void testMatchAllCrossClusterSearchAllFields() throws IOException {
6871

6972
@Test
7073
public void testCrossClusterSearchWithoutLocalFieldMappingShouldFail() throws IOException {
71-
exceptionRule.expect(ResponseException.class);
72-
exceptionRule.expectMessage("400 Bad Request");
73-
exceptionRule.expectMessage("IndexNotFoundException");
74-
75-
executeQuery(String.format("search source=%s", TEST_INDEX_ACCOUNT_REMOTE));
74+
var exception = assertThrows(ResponseException.class, () ->
75+
executeQuery(String.format("search source=%s", TEST_INDEX_ACCOUNT_REMOTE)));
76+
assertTrue(exception.getMessage().contains("IndexNotFoundException")
77+
&& exception.getMessage().contains("400 Bad Request"));
7678
}
7779

7880
@Test

0 commit comments

Comments
 (0)