-
Notifications
You must be signed in to change notification settings - Fork 365
Expand file tree
/
Copy pathInstallerTests.java
More file actions
505 lines (417 loc) · 20.4 KB
/
InstallerTests.java
File metadata and controls
505 lines (417 loc) · 20.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/
package org.opensearch.security.tools.democonfig;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.HashSet;
import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.opensearch.security.tools.democonfig.Installer.RPM_DEB_OPENSEARCH_HOME;
import static org.opensearch.security.tools.democonfig.Installer.printScriptHeaders;
import static org.opensearch.security.tools.democonfig.util.DemoConfigHelperUtil.createDirectory;
import static org.opensearch.security.tools.democonfig.util.DemoConfigHelperUtil.createFile;
import static org.opensearch.security.tools.democonfig.util.DemoConfigHelperUtil.deleteDirectoryRecursive;
import static org.junit.Assert.assertThrows;
public class InstallerTests {
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private final PrintStream originalOut = System.out;
private final InputStream originalIn = System.in;
private static Installer installer;
// Custom exception to simulate an exit call.
public static class TestExitException extends RuntimeException {
private final int status;
public TestExitException(int status) {
super("Exit code " + status);
this.status = status;
}
public int getStatus() {
return status;
}
}
@Before
public void setUpStreams() {
System.setOut(new PrintStream(outContent));
installer = Installer.getInstance();
installer.buildOptions();
}
@After
public void restoreStreams() {
System.setOut(originalOut);
System.setIn(originalIn);
// Reset installer state to avoid cross-test contamination.
Installer.resetInstance();
}
@Test
public void testPrintScriptHeaders() {
printScriptHeaders();
String expectedOutput = "### OpenSearch Security Demo Installer"
+ System.lineSeparator()
+ "### ** Warning: Do not use on production or public reachable systems **"
+ System.lineSeparator();
assertThat(outContent.toString(), equalTo(expectedOutput));
}
@Test
public void testReadOptions_withoutHelpOption() {
// All options except Help "-h"
String[] validOptions = { "/scriptDir", "-y", "-i", "-c", "-s", "-t" };
installer.readOptions(validOptions);
assertThat(installer.SCRIPT_DIR, equalTo("/scriptDir"));
assertThat(installer.assumeyes, is(true));
assertThat(installer.initsecurity, is(true));
assertThat(installer.cluster_mode, is(true));
assertThat(installer.skip_updates, equalTo(0));
assertThat(installer.environment, equalTo(ExecutionEnvironment.TEST));
}
@Test
public void testReadOptions_help() {
// Set exit handler that throws TestExitException instead of exiting.
installer.setExitHandler(status -> { throw new TestExitException(status); });
String[] helpOption = { "/scriptDir", "-h" };
TestExitException ex = assertThrows(
"Expected exit with status 0",
TestExitException.class,
() -> { installer.readOptions(helpOption); }
);
assertThat(ex.getStatus(), equalTo(0));
verifyStdOutContainsString("usage: install_demo_configuration" + installer.FILE_EXTENSION + " [-c] [-h] [-i] [-s] [-t] [-y]");
}
@Test
public void testGatherUserInputs_withoutAssumeYes() {
// -i & -c options are not passed
String[] validOptions = { "/scriptDir" };
installer.readOptions(validOptions);
assertThat(installer.assumeyes, is(false));
assertThat(installer.initsecurity, is(false));
assertThat(installer.cluster_mode, is(false));
// Provide inputs: "y" then "n", then "n".
readInputStream("y" + System.lineSeparator() + "n" + System.lineSeparator() + "n" + System.lineSeparator());
installer.gatherUserInputs();
verifyStdOutContainsString("Install demo certificates?");
verifyStdOutContainsString("Initialize Security Modules?");
verifyStdOutContainsString("Cluster mode requires additional setup of:");
verifyStdOutContainsString(" - Virtual memory (vm.max_map_count)" + System.lineSeparator());
verifyStdOutContainsString("Enable cluster mode?");
assertThat(installer.initsecurity, is(false));
assertThat(installer.cluster_mode, is(false));
outContent.reset();
// Provide inputs: "y", "y", "y".
readInputStream("y" + System.lineSeparator() + "y" + System.lineSeparator() + "y" + System.lineSeparator());
installer.gatherUserInputs();
verifyStdOutContainsString("Install demo certificates?");
verifyStdOutContainsString("Initialize Security Modules?");
verifyStdOutContainsString("Cluster mode requires additional setup of:");
verifyStdOutContainsString(" - Virtual memory (vm.max_map_count)" + System.lineSeparator());
verifyStdOutContainsString("Enable cluster mode?");
assertThat(installer.initsecurity, is(true));
assertThat(installer.cluster_mode, is(true));
outContent.reset();
// Now test if the first prompt (demo certificates) is answered "n".
installer.setExitHandler(status -> { throw new TestExitException(status); });
readInputStream("n" + System.lineSeparator() + "n" + System.lineSeparator() + "n" + System.lineSeparator());
TestExitException ex = assertThrows(
"Expected exit with status 0",
TestExitException.class,
() -> { installer.gatherUserInputs(); }
);
assertThat(ex.getStatus(), equalTo(0));
verifyStdOutContainsString("Install demo certificates?");
verifyStdOutDoesNotContainString("Initialize Security Modules?");
verifyStdOutDoesNotContainString("Cluster mode requires additional setup of:");
verifyStdOutDoesNotContainString(" - Virtual memory (vm.max_map_count)" + System.lineSeparator());
verifyStdOutDoesNotContainString("Enable cluster mode?");
outContent.reset();
// Now test with -i and -c passed; prompts should not occur.
String[] validOptionsIC = { "/scriptDir", "-i", "-c" };
installer.readOptions(validOptionsIC);
assertThat(installer.assumeyes, is(false));
assertThat(installer.initsecurity, is(true));
assertThat(installer.cluster_mode, is(true));
// Even if input is provided, it should skip further prompts.
readInputStream("y" + System.lineSeparator() + "y" + System.lineSeparator() + "y" + System.lineSeparator());
installer.gatherUserInputs();
verifyStdOutContainsString("Install demo certificates?");
verifyStdOutDoesNotContainString("Initialize Security Modules?");
verifyStdOutDoesNotContainString("Enable cluster mode?");
assertThat(installer.initsecurity, is(true));
assertThat(installer.cluster_mode, is(true));
}
@Test
public void testGatherInputs_withAssumeYes() {
String[] validOptionsYes = { "/scriptDir", "-y" };
installer.readOptions(validOptionsYes);
assertThat(installer.assumeyes, is(true));
installer.gatherUserInputs();
// With assume yes (-y), no further prompts occur.
assertThat(installer.initsecurity, is(false));
assertThat(installer.cluster_mode, is(false));
}
@Test
public void testInitializeVariables_setBaseDir_invalidPath() {
String[] invalidScriptDirPath = { "/nonexistent/opensearch-home", "-y" };
installer.readOptions(invalidScriptDirPath);
installer.setExitHandler(status -> { throw new TestExitException(status); });
TestExitException ex = assertThrows("Expected exit with status -1", TestExitException.class, installer::initializeVariables);
assertThat(ex.getStatus(), equalTo(-1));
verifyStdOutContainsString("DEBUG: basedir does not exist");
}
@Test
public void testSetBaseDir_valid() {
String currentDir = System.getProperty("user.dir");
String[] validBaseDir = { currentDir, "-y" };
installer.readOptions(validBaseDir);
installer.setBaseDir();
String expectedBaseDirValue = new File(currentDir).getAbsolutePath() + File.separator;
assertThat(installer.BASE_DIR, equalTo(expectedBaseDirValue));
}
@Test
public void testSetOpenSearchVariables_invalidPath() {
String currentDir = System.getProperty("user.dir");
String[] validBaseDir = { currentDir, "-y" };
installer.readOptions(validBaseDir);
installer.setExitHandler(status -> { throw new TestExitException(status); });
TestExitException ex = assertThrows("Expected exit with status -1", TestExitException.class, () -> {
installer.setBaseDir();
installer.setOpenSearchVariables();
});
assertThat(ex.getStatus(), equalTo(-1));
verifyStdOutContainsString("Unable to determine OpenSearch config file. Quit.");
verifyStdOutContainsString("Unable to determine OpenSearch bin directory. Quit.");
verifyStdOutContainsString("Unable to determine OpenSearch plugins directory. Quit.");
verifyStdOutContainsString("Unable to determine OpenSearch lib directory. Quit.");
String expectedBaseDirValue = new File(currentDir).getAbsolutePath() + File.separator;
String expectedOpensearchConfFilePath = expectedBaseDirValue + "config" + File.separator + "opensearch.yml";
String expectedOpensearchBinDirPath = expectedBaseDirValue + "bin" + File.separator;
String expectedOpensearchPluginDirPath = expectedBaseDirValue + "plugins" + File.separator;
String expectedOpensearchLibDirPath = expectedBaseDirValue + "lib" + File.separator;
String expectedOpensearchInstallType = installer.determineInstallType();
assertThat(installer.OPENSEARCH_CONF_FILE, equalTo(expectedOpensearchConfFilePath));
assertThat(installer.OPENSEARCH_BIN_DIR, equalTo(expectedOpensearchBinDirPath));
assertThat(installer.OPENSEARCH_PLUGINS_DIR, equalTo(expectedOpensearchPluginDirPath));
assertThat(installer.OPENSEARCH_LIB_PATH, equalTo(expectedOpensearchLibDirPath));
assertThat(installer.OPENSEARCH_INSTALL_TYPE, equalTo(expectedOpensearchInstallType));
}
@Test
public void testDetermineInstallType_windows() {
installer.OS = "Windows";
String installType = installer.determineInstallType();
assertThat(installType, equalTo(".zip"));
}
@Test
public void testDetermineInstallType_rpm_deb() {
installer.OS = "Linux";
String dir = System.getProperty("user.dir");
installer.BASE_DIR = dir;
RPM_DEB_OPENSEARCH_HOME = new File(dir);
String installType = installer.determineInstallType();
assertThat(installType, equalTo("rpm/deb"));
}
@Test
public void testDetermineInstallType_default() {
installer.OS = "Anything else";
installer.BASE_DIR = "/random-dir";
String installType = installer.determineInstallType();
assertThat(installType, equalTo(".tar.gz"));
}
@Test
public void testSetSecurityVariables() {
setUpSecurityDirectories();
installer.setSecurityVariables();
assertThat(installer.OPENSEARCH_VERSION, is(equalTo("3.0.0-Version")));
assertThat(installer.SECURITY_VERSION, is(equalTo("3.0.0.0-version")));
tearDownSecurityDirectories();
}
@Test
public void testSetSecurityVariables_noSecurityPlugin() {
installer.setExitHandler(status -> { throw new TestExitException(status); });
TestExitException ex = assertThrows("Expected exit with status -1", TestExitException.class, installer::setSecurityVariables);
assertThat(ex.getStatus(), equalTo(-1));
}
@Test
public void testPrintVariables() {
installer.OPENSEARCH_INSTALL_TYPE = "installType";
installer.OS = "OS";
installer.OPENSEARCH_CONF_DIR = "confDir";
installer.OPENSEARCH_CONF_FILE = "confFile";
installer.OPENSEARCH_BIN_DIR = "/bin";
installer.OPENSEARCH_PLUGINS_DIR = "/plugins";
installer.OPENSEARCH_LIB_PATH = "/lib";
installer.OPENSEARCH_VERSION = "osVersion";
installer.SECURITY_VERSION = "version";
installer.printVariables();
String expectedOutput = "OpenSearch install type: installType on OS"
+ System.lineSeparator()
+ "OpenSearch config dir: confDir"
+ System.lineSeparator()
+ "OpenSearch config file: confFile"
+ System.lineSeparator()
+ "OpenSearch bin dir: /bin"
+ System.lineSeparator()
+ "OpenSearch plugins dir: /plugins"
+ System.lineSeparator()
+ "OpenSearch lib dir: /lib"
+ System.lineSeparator()
+ "Detected OpenSearch Version: osVersion"
+ System.lineSeparator()
+ "Detected OpenSearch Security Version: version"
+ System.lineSeparator();
assertThat(outContent.toString(), equalTo(expectedOutput));
}
@Test
public void testFinishScriptExecution() {
setUpSecurityDirectories();
SecuritySettingsConfigurer.ADMIN_PASSWORD = "ble";
installer.finishScriptExecution();
String securityAdminScriptPath = installer.OPENSEARCH_PLUGINS_DIR
+ "opensearch-security"
+ File.separator
+ "tools"
+ File.separator
+ "securityadmin"
+ installer.FILE_EXTENSION;
String securityAdminDemoScriptPath = installer.OPENSEARCH_CONF_DIR + "securityadmin_demo" + installer.FILE_EXTENSION;
setWritePermissions(securityAdminDemoScriptPath);
SecuritySettingsConfigurer securitySettingsConfigurer = new SecuritySettingsConfigurer(installer);
String lastLine = securitySettingsConfigurer.getSecurityAdminCommands(securityAdminScriptPath)[1];
String expectedOutput = "### Success"
+ System.lineSeparator()
+ "### Execute this script now on all your nodes and then start all nodes"
+ System.lineSeparator()
+ "### After the whole cluster is up execute: "
+ System.lineSeparator()
+ lastLine
+ System.lineSeparator()
+ "### or run ."
+ File.separator
+ "securityadmin_demo"
+ installer.FILE_EXTENSION
+ System.lineSeparator()
+ "### After that you can also use the Security Plugin ConfigurationGUI"
+ System.lineSeparator()
+ "### To access your secured cluster open https://<hostname>:<HTTP port> and log in with admin/<your-custom-admin-password>."
+ System.lineSeparator()
+ "### (Ignore the SSL certificate warning because we installed self-signed demo certificates)"
+ System.lineSeparator();
assertThat(outContent.toString(), equalTo(expectedOutput));
tearDownSecurityDirectories();
}
@Test
public void testFinishScriptExecution_withInitSecurityEnabled() {
setUpSecurityDirectories();
installer.initsecurity = true;
SecuritySettingsConfigurer.ADMIN_PASSWORD = "ble";
installer.finishScriptExecution();
String securityAdminScriptPath = installer.OPENSEARCH_PLUGINS_DIR
+ "opensearch-security"
+ File.separator
+ "tools"
+ File.separator
+ "securityadmin"
+ installer.FILE_EXTENSION;
String securityAdminDemoScriptPath = installer.OPENSEARCH_CONF_DIR + "securityadmin_demo" + installer.FILE_EXTENSION;
setWritePermissions(securityAdminDemoScriptPath);
SecuritySettingsConfigurer securitySettingsConfigurer = new SecuritySettingsConfigurer(installer);
String lastLine = securitySettingsConfigurer.getSecurityAdminCommands(securityAdminScriptPath)[1];
String expectedOutput = "### Success"
+ System.lineSeparator()
+ "### Execute this script now on all your nodes and then start all nodes"
+ System.lineSeparator()
+ "### OpenSearch Security will be automatically initialized."
+ System.lineSeparator()
+ "### If you like to change the runtime configuration "
+ System.lineSeparator()
+ "### change the files in .."
+ File.separator
+ ".."
+ File.separator
+ ".."
+ File.separator
+ "config"
+ File.separator
+ "opensearch-security and execute: "
+ System.lineSeparator()
+ lastLine
+ System.lineSeparator()
+ "### or run ."
+ File.separator
+ "securityadmin_demo"
+ installer.FILE_EXTENSION
+ System.lineSeparator()
+ "### To use the Security Plugin ConfigurationGUI"
+ System.lineSeparator()
+ "### To access your secured cluster open https://<hostname>:<HTTP port> and log in with admin/<your-custom-admin-password>."
+ System.lineSeparator()
+ "### (Ignore the SSL certificate warning because we installed self-signed demo certificates)"
+ System.lineSeparator();
assertThat(outContent.toString(), equalTo(expectedOutput));
tearDownSecurityDirectories();
}
private void readInputStream(String input) {
System.setIn(new ByteArrayInputStream(input.getBytes()));
}
public void setUpSecurityDirectories() {
String currentDir = System.getProperty("user.dir");
String[] validBaseDir = { currentDir, "-y" };
installer.readOptions(validBaseDir);
installer.setBaseDir();
installer.OPENSEARCH_PLUGINS_DIR = installer.BASE_DIR + "plugins" + File.separator;
installer.OPENSEARCH_LIB_PATH = installer.BASE_DIR + "lib" + File.separator;
installer.OPENSEARCH_CONF_DIR = installer.BASE_DIR + "test-conf" + File.separator;
createDirectory(installer.OPENSEARCH_PLUGINS_DIR);
createDirectory(installer.OPENSEARCH_LIB_PATH);
createDirectory(installer.OPENSEARCH_CONF_DIR);
createDirectory(installer.OPENSEARCH_PLUGINS_DIR + "opensearch-security");
createFile(installer.OPENSEARCH_LIB_PATH + "opensearch-core-3.0.0-Version.jar");
createFile(
installer.OPENSEARCH_PLUGINS_DIR + "opensearch-security" + File.separator + "opensearch-security-common-3.0.0.0-version.jar"
);
createFile(installer.OPENSEARCH_PLUGINS_DIR + "opensearch-security" + File.separator + "opensearch-security-3.0.0.0-version.jar");
createFile(installer.OPENSEARCH_CONF_DIR + File.separator + "securityadmin_demo.sh");
}
public void tearDownSecurityDirectories() {
// Clean up testing directories or files.
deleteDirectoryRecursive(installer.OPENSEARCH_PLUGINS_DIR);
deleteDirectoryRecursive(installer.OPENSEARCH_LIB_PATH);
deleteDirectoryRecursive(installer.OPENSEARCH_CONF_DIR);
}
static void setWritePermissions(String filePath) {
if (!installer.OS.toLowerCase().contains("win")) {
Path file = Paths.get(filePath);
Set<PosixFilePermission> perms = new HashSet<>();
perms.add(PosixFilePermission.OWNER_WRITE);
try {
Files.setPosixFilePermissions(file, perms);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private void verifyStdOutContainsString(String s) {
assertThat(outContent.toString(), containsString(s));
}
private void verifyStdOutDoesNotContainString(String s) {
assertThat(outContent.toString(), not(containsString(s)));
}
}