diff --git a/src/main/java/org/opensearch/security/tools/democonfig/CertificateGenerator.java b/src/main/java/org/opensearch/security/tools/democonfig/CertificateGenerator.java index a7b39c226e..077bf4610f 100644 --- a/src/main/java/org/opensearch/security/tools/democonfig/CertificateGenerator.java +++ b/src/main/java/org/opensearch/security/tools/democonfig/CertificateGenerator.java @@ -19,14 +19,20 @@ /** * This class creates demo certificate files */ -public class CertificateGenerator extends Installer { +public class CertificateGenerator { + + private final Installer installer; + + public CertificateGenerator(Installer installer) { + this.installer = installer; + } /** * Creates demo super-admin, node and root certificates by iterating through Certificates enum */ public void createDemoCertificates() { for (Certificates cert : Certificates.values()) { - String filePath = OPENSEARCH_CONF_DIR + File.separator + cert.getFileName(); + String filePath = this.installer.OPENSEARCH_CONF_DIR + File.separator + cert.getFileName(); writeCertificateToFile(filePath, cert.getContent()); } } diff --git a/src/main/java/org/opensearch/security/tools/democonfig/Installer.java b/src/main/java/org/opensearch/security/tools/democonfig/Installer.java index 6971298a2b..89179715a5 100644 --- a/src/main/java/org/opensearch/security/tools/democonfig/Installer.java +++ b/src/main/java/org/opensearch/security/tools/democonfig/Installer.java @@ -28,50 +28,65 @@ */ public class Installer { - static boolean assumeyes = false; - static boolean initsecurity = false; - static boolean cluster_mode = false; - static int skip_updates = -1; - static String SCRIPT_DIR; - static String BASE_DIR; - static String OPENSEARCH_CONF_FILE; - static String OPENSEARCH_BIN_DIR; - static String OPENSEARCH_PLUGINS_DIR; - static String OPENSEARCH_LIB_PATH; - static String OPENSEARCH_INSTALL_TYPE; - static String OPENSEARCH_CONF_DIR; - static String OPENSEARCH_VERSION; - static String SECURITY_VERSION; + private static Installer instance; - static ExecutionEnvironment environment = ExecutionEnvironment.DEMO; + private static SecuritySettingsConfigurer securitySettingsConfigurer; - static String OS = System.getProperty("os.name") + " " + System.getProperty("os.version") + " " + System.getProperty("os.arch"); + private static CertificateGenerator certificateGenerator; - static final String FILE_EXTENSION = OS.toLowerCase().contains("win") ? ".bat" : ".sh"; + boolean assumeyes = false; + boolean initsecurity = false; + boolean cluster_mode = false; + int skip_updates = -1; + String SCRIPT_DIR; + String BASE_DIR; + String OPENSEARCH_CONF_FILE; + String OPENSEARCH_BIN_DIR; + String OPENSEARCH_PLUGINS_DIR; + String OPENSEARCH_LIB_PATH; + String OPENSEARCH_INSTALL_TYPE; + String OPENSEARCH_CONF_DIR; + String OPENSEARCH_VERSION; + String SECURITY_VERSION; - static final String SYSTEM_INDICES = ".plugins-ml-config, .plugins-ml-connector, .plugins-ml-model-group, .plugins-ml-model, " - + ".plugins-ml-task, .plugins-ml-conversation-meta, .plugins-ml-conversation-interactions, .opendistro-alerting-config, .opendistro-alerting-alert*, " - + ".opendistro-anomaly-results*, .opendistro-anomaly-detector*, .opendistro-anomaly-checkpoints, .opendistro-anomaly-detection-state, " - + ".opendistro-reports-*, .opensearch-notifications-*, .opensearch-notebooks, .opensearch-observability, .ql-datasources, " - + ".opendistro-asynchronous-search-response*, .replication-metadata-store, .opensearch-knn-models, .geospatial-ip2geo-data*"; + ExecutionEnvironment environment = ExecutionEnvironment.DEMO; - static CertificateGenerator certificateGenerator; + String OS; - static File RPM_DEB_OPENSEARCH_FILE = new File("/usr/share/opensearch"); + final String FILE_EXTENSION; - public static void main(String[] options) { - certificateGenerator = new CertificateGenerator(); + static File RPM_DEB_OPENSEARCH_HOME = new File("/usr/share/opensearch"); - printScriptHeaders(); + private Installer() { + this.OS = System.getProperty("os.name") + " " + System.getProperty("os.version") + " " + System.getProperty("os.arch"); + FILE_EXTENSION = OS.toLowerCase().contains("win") ? ".bat" : ".sh"; + } + + public static Installer getInstance() { + if (instance == null) { + instance = new Installer(); + securitySettingsConfigurer = new SecuritySettingsConfigurer(instance); + certificateGenerator = new CertificateGenerator(instance); + } + return instance; + } + + public void installDemoConfiguration(String[] options) { readOptions(options); + printScriptHeaders(); gatherUserInputs(); initializeVariables(); printVariables(); - SecuritySettingsConfigurer.configureSecuritySettings(); + securitySettingsConfigurer.configureSecuritySettings(); certificateGenerator.createDemoCertificates(); finishScriptExecution(); } + public static void main(String[] options) { + Installer installer = Installer.getInstance(); + installer.installDemoConfiguration(options); + } + /** * Prints headers that indicate the start of script execution */ @@ -84,7 +99,7 @@ static void printScriptHeaders() { * Reads the options passed to the script * @param options an array of strings containing options passed to the script */ - static void readOptions(String[] options) { + void readOptions(String[] options) { // set script execution dir SCRIPT_DIR = options[0]; @@ -118,7 +133,7 @@ static void readOptions(String[] options) { /** * Prints the help menu when -h option is passed */ - static void showHelp() { + void showHelp() { System.out.println("install_demo_configuration.sh [-y] [-i] [-c]"); System.out.println(" -h show help"); System.out.println(" -y confirm all installation dialogues automatically"); @@ -135,7 +150,7 @@ static void showHelp() { * Prompt the user and collect user inputs * Input collection will be skipped if -y option was passed */ - static void gatherUserInputs() { + void gatherUserInputs() { if (!assumeyes) { try (Scanner scanner = new Scanner(System.in, StandardCharsets.UTF_8)) { @@ -165,7 +180,7 @@ static void gatherUserInputs() { * @param message prompt question * @return true or false based on user input */ - static boolean confirmAction(Scanner scanner, String message) { + boolean confirmAction(Scanner scanner, String message) { System.out.print(message + " [y/N] "); String response = scanner.nextLine(); return response.equalsIgnoreCase("yes") || response.equalsIgnoreCase("y"); @@ -174,7 +189,7 @@ static boolean confirmAction(Scanner scanner, String message) { /** * Initialize all class level variables required */ - static void initializeVariables() { + void initializeVariables() { setBaseDir(); setOpenSearchVariables(); setSecurityVariables(); @@ -183,7 +198,7 @@ static void initializeVariables() { /** * Sets the base directory to be used by the script */ - static void setBaseDir() { + void setBaseDir() { File baseDirFile = new File(SCRIPT_DIR).getParentFile().getParentFile().getParentFile(); BASE_DIR = baseDirFile != null ? baseDirFile.getAbsolutePath() : null; @@ -198,7 +213,7 @@ static void setBaseDir() { /** * Sets the variables for items at OpenSearch level */ - static void setOpenSearchVariables() { + void setOpenSearchVariables() { OPENSEARCH_CONF_FILE = BASE_DIR + "config" + File.separator + "opensearch.yml"; OPENSEARCH_BIN_DIR = BASE_DIR + "bin" + File.separator; OPENSEARCH_PLUGINS_DIR = BASE_DIR + "plugins" + File.separator; @@ -221,7 +236,7 @@ static void setOpenSearchVariables() { * Returns a set of error messages for the paths that didn't contain files/directories * @return a set containing error messages if any, empty otherwise */ - private static Set validatePaths() { + private Set validatePaths() { Set errorMessages = new HashSet<>(); if (!(new File(OPENSEARCH_CONF_FILE).exists())) { errorMessages.add("Unable to determine OpenSearch config file. Quit."); @@ -245,14 +260,14 @@ private static Set validatePaths() { * Returns the installation type based on the underlying operating system * @return will be one of `.zip`, `.tar.gz` or `rpm/deb` */ - static String determineInstallType() { + String determineInstallType() { // windows (.bat execution) if (OS.toLowerCase().contains("win")) { return ".zip"; } // other OS (.sh execution) - if (RPM_DEB_OPENSEARCH_FILE.exists() && RPM_DEB_OPENSEARCH_FILE.equals(new File(BASE_DIR))) { + if (RPM_DEB_OPENSEARCH_HOME.exists() && RPM_DEB_OPENSEARCH_HOME.equals(new File(BASE_DIR))) { OPENSEARCH_CONF_FILE = "/usr/share/opensearch/config/opensearch.yml"; if (!new File(OPENSEARCH_CONF_FILE).exists()) { OPENSEARCH_CONF_FILE = "/etc/opensearch/opensearch.yml"; @@ -265,7 +280,7 @@ static String determineInstallType() { /** * Sets the path variables for items at OpenSearch security plugin level */ - static void setSecurityVariables() { + void setSecurityVariables() { if (!(new File(OPENSEARCH_PLUGINS_DIR + "opensearch-security").exists())) { System.out.println("OpenSearch Security plugin not installed. Quit."); System.exit(-1); @@ -292,7 +307,7 @@ static void setSecurityVariables() { /** * Prints the initialized variables */ - static void printVariables() { + void printVariables() { System.out.println("OpenSearch install type: " + OPENSEARCH_INSTALL_TYPE + " on " + OS); System.out.println("OpenSearch config dir: " + OPENSEARCH_CONF_DIR); System.out.println("OpenSearch config file: " + OPENSEARCH_CONF_FILE); @@ -306,7 +321,7 @@ static void printVariables() { /** * Prints end of script execution message and creates security admin demo file. */ - static void finishScriptExecution() { + void finishScriptExecution() { System.out.println("### Success"); System.out.println("### Execute this script now on all your nodes and then start all nodes"); @@ -320,7 +335,7 @@ static void finishScriptExecution() { + FILE_EXTENSION; String securityAdminDemoScriptPath = OPENSEARCH_CONF_DIR + "securityadmin_demo" + FILE_EXTENSION; - SecuritySettingsConfigurer.createSecurityAdminDemoScript(securityAdminScriptPath, securityAdminDemoScriptPath); + securitySettingsConfigurer.createSecurityAdminDemoScript(securityAdminScriptPath, securityAdminDemoScriptPath); // Make securityadmin_demo script executable // not needed for windows @@ -380,26 +395,7 @@ static void finishScriptExecution() { } } - /** - * FOR TESTS ONLY - * Resets the class-level variables to their original values - * Is needed for tests since the variables are declared static - */ - static void resetState() { - assumeyes = false; - initsecurity = false; - cluster_mode = false; - environment = ExecutionEnvironment.DEMO; - OS = System.getProperty("os.name") + " " + System.getProperty("os.version") + " " + System.getProperty("os.arch"); - SCRIPT_DIR = null; - BASE_DIR = null; - OPENSEARCH_CONF_FILE = null; - OPENSEARCH_BIN_DIR = null; - OPENSEARCH_PLUGINS_DIR = null; - OPENSEARCH_LIB_PATH = null; - OPENSEARCH_INSTALL_TYPE = null; - OPENSEARCH_CONF_DIR = null; - OPENSEARCH_VERSION = null; - SECURITY_VERSION = null; + public static void resetInstance() { + instance = null; } } diff --git a/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java b/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java index 891d6058dd..39644367b4 100644 --- a/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java +++ b/src/main/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurer.java @@ -29,6 +29,7 @@ import org.opensearch.security.dlic.rest.validation.PasswordValidator; import org.opensearch.security.dlic.rest.validation.RequestContentValidator; import org.opensearch.security.tools.Hasher; + import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @@ -39,18 +40,48 @@ /** * This class updates the security related configuration, as needed. */ -public class SecuritySettingsConfigurer extends Installer { - - private static final List REST_ENABLED_ROLES_LIST = List.of("all_access", "security_rest_api_access"); +public class SecuritySettingsConfigurer { + + static final List REST_ENABLED_ROLES = List.of("all_access", "security_rest_api_access"); + static final List SYSTEM_INDICES = List.of( + ".plugins-ml-config", + ".plugins-ml-connector", + ".plugins-ml-model-group", + ".plugins-ml-model", + ".plugins-ml-task", + ".plugins-ml-conversation-meta", + ".plugins-ml-conversation-interactions", + ".opendistro-alerting-config", + ".opendistro-alerting-alert*", + ".opendistro-anomaly-results*", + ".opendistro-anomaly-detector*", + ".opendistro-anomaly-checkpoints", + ".opendistro-anomaly-detection-state", + ".opendistro-reports-*", + ".opensearch-notifications-*", + ".opensearch-notebooks", + ".opensearch-observability", + ".ql-datasources", + ".opendistro-asynchronous-search-response*", + ".replication-metadata-store", + ".opensearch-knn-models", + ".geospatial-ip2geo-data*" + ); static String ADMIN_PASSWORD = ""; + private final Installer installer; + + public SecuritySettingsConfigurer(Installer installer) { + this.installer = installer; + } + /** * Configures security related changes to the opensearch configuration * 1. Checks if plugins is already configuration. If yes, exit * 2. Sets the custom admin password (Generates one if none is provided) * 3. Write the security config to opensearch.yml */ - public static void configureSecuritySettings() { + public void configureSecuritySettings() { checkIfSecurityPluginIsAlreadyConfigured(); updateAdminPassword(); writeSecurityConfigToOpenSearchYML(); @@ -59,11 +90,14 @@ public static void configureSecuritySettings() { /** * Replaces the admin password in internal_users.yml with the custom or generated password */ - static void updateAdminPassword() { + void updateAdminPassword() { String initialAdminPassword = System.getenv().get("initialAdminPassword"); - String ADMIN_PASSWORD_FILE_PATH = OPENSEARCH_CONF_DIR + "initialAdminPassword.txt"; - String INTERNAL_USERS_FILE_PATH = OPENSEARCH_CONF_DIR + "opensearch-security" + File.separator + "internal_users.yml"; - boolean shouldValidatePassword = environment.equals(ExecutionEnvironment.DEMO); + String ADMIN_PASSWORD_FILE_PATH = this.installer.OPENSEARCH_CONF_DIR + "initialAdminPassword.txt"; + String INTERNAL_USERS_FILE_PATH = this.installer.OPENSEARCH_CONF_DIR + + "opensearch-security" + + File.separator + + "internal_users.yml"; + boolean shouldValidatePassword = this.installer.environment.equals(ExecutionEnvironment.DEMO); try { final PasswordValidator passwordValidator = PasswordValidator.of( Settings.builder() @@ -124,7 +158,7 @@ static void updateAdminPassword() { * @param internalUsersFile the file path string to internal_users.yml file * @throws IOException while reading, writing to files */ - static void writePasswordToInternalUsersFile(String adminPassword, String internalUsersFile) throws IOException { + void writePasswordToInternalUsersFile(String adminPassword, String internalUsersFile) throws IOException { String hashedAdminPassword = Hasher.hash(adminPassword.toCharArray()); if (hashedAdminPassword.isEmpty()) { @@ -158,15 +192,15 @@ static void writePasswordToInternalUsersFile(String adminPassword, String intern /** * Checks if security plugin is already configured. If so, the script execution will not continue. */ - static void checkIfSecurityPluginIsAlreadyConfigured() { + void checkIfSecurityPluginIsAlreadyConfigured() { // Check if the configuration file contains the 'plugins.security' string - if (OPENSEARCH_CONF_FILE != null && new File(OPENSEARCH_CONF_FILE).exists()) { - try (BufferedReader br = new BufferedReader(new FileReader(OPENSEARCH_CONF_FILE, StandardCharsets.UTF_8))) { + if (this.installer.OPENSEARCH_CONF_FILE != null && new File(this.installer.OPENSEARCH_CONF_FILE).exists()) { + try (BufferedReader br = new BufferedReader(new FileReader(this.installer.OPENSEARCH_CONF_FILE, StandardCharsets.UTF_8))) { String line; while ((line = br.readLine()) != null) { if (line.toLowerCase().contains("plugins.security")) { - System.out.println(OPENSEARCH_CONF_FILE + " seems to be already configured for Security. Quit."); - System.exit(skip_updates); + System.out.println(this.installer.OPENSEARCH_CONF_FILE + " seems to be already configured for Security. Quit."); + System.exit(this.installer.skip_updates); } } } catch (IOException e) { @@ -182,16 +216,18 @@ static void checkIfSecurityPluginIsAlreadyConfigured() { /** * Update opensearch.yml with security configuration information */ - static void writeSecurityConfigToOpenSearchYML() { - String configHeader = System.lineSeparator() + System.lineSeparator() + - "######## Start OpenSearch Security Demo Configuration ########" + System.lineSeparator() - + "# WARNING: revise all the lines below before you go into production" + System.lineSeparator(); + void writeSecurityConfigToOpenSearchYML() { + String configHeader = System.lineSeparator() + + System.lineSeparator() + + "######## Start OpenSearch Security Demo Configuration ########" + + System.lineSeparator() + + "# WARNING: revise all the lines below before you go into production" + + System.lineSeparator(); String configFooter = "######## End OpenSearch Security Demo Configuration ########" + System.lineSeparator(); Map securityConfigAsMap = buildSecurityConfigMap(); - - try (FileWriter writer = new FileWriter(OPENSEARCH_CONF_FILE, StandardCharsets.UTF_8, true)) { + try (FileWriter writer = new FileWriter(this.installer.OPENSEARCH_CONF_FILE, StandardCharsets.UTF_8, true)) { writer.write(configHeader); Yaml yaml = new Yaml(); DumperOptions options = new DumperOptions(); @@ -209,7 +245,7 @@ static void writeSecurityConfigToOpenSearchYML() { * Helper method to build security configuration to append to opensearch.yml * @return the configuration map to be written to opensearch.yml */ - private static Map buildSecurityConfigMap() { + Map buildSecurityConfigMap() { Map configMap = new LinkedHashMap<>(); configMap.put("plugins.security.ssl.transport.pemcert_filepath", Certificates.NODE_CERT.getFileName()); @@ -222,7 +258,7 @@ private static Map buildSecurityConfigMap() { configMap.put("plugins.security.ssl.http.pemtrustedcas_filepath", Certificates.ROOT_CA.getFileName()); configMap.put("plugins.security.allow_unsafe_democertificates", true); - if (initsecurity) { + if (this.installer.initsecurity) { configMap.put("plugins.security.allow_default_init_securityindex", true); } @@ -231,20 +267,20 @@ private static Map buildSecurityConfigMap() { configMap.put("plugins.security.audit.type", "internal_opensearch"); configMap.put("plugins.security.enable_snapshot_restore_privilege", true); configMap.put("plugins.security.check_snapshot_restore_write_privileges", true); - configMap.put("plugins.security.restapi.roles_enabled", REST_ENABLED_ROLES_LIST); + configMap.put("plugins.security.restapi.roles_enabled", REST_ENABLED_ROLES); configMap.put("plugins.security.system_indices.enabled", true); configMap.put("plugins.security.system_indices.indices", SYSTEM_INDICES); - if (!isNetworkHostAlreadyPresent(OPENSEARCH_CONF_FILE)) { - if (cluster_mode) { + if (!isNetworkHostAlreadyPresent(this.installer.OPENSEARCH_CONF_FILE)) { + if (this.installer.cluster_mode) { configMap.put("network.host", "0.0.0.0"); configMap.put("node.name", "smoketestnode"); configMap.put("cluster.initial_cluster_manager_nodes", "smoketestnode"); } } - if (!isNodeMaxLocalStorageNodesAlreadyPresent(OPENSEARCH_CONF_FILE)) { + if (!isNodeMaxLocalStorageNodesAlreadyPresent(this.installer.OPENSEARCH_CONF_FILE)) { configMap.put("node.max_local_storage_nodes", 3); } @@ -304,7 +340,7 @@ static boolean isStringAlreadyPresentInFile(String filePath, String searchString * @param securityAdminDemoScriptPath path to security admin demo script * @throws IOException if there was error reading/writing the file */ - static void createSecurityAdminDemoScript(String securityAdminScriptPath, String securityAdminDemoScriptPath) throws IOException { + void createSecurityAdminDemoScript(String securityAdminScriptPath, String securityAdminDemoScriptPath) throws IOException { String[] securityAdminCommands = getSecurityAdminCommands(securityAdminScriptPath); // Write securityadmin_demo script @@ -315,22 +351,22 @@ static void createSecurityAdminDemoScript(String securityAdminScriptPath, String writer.close(); } - static String[] getSecurityAdminCommands(String securityAdminScriptPath) { + String[] getSecurityAdminCommands(String securityAdminScriptPath) { String securityAdminExecutionPath = securityAdminScriptPath + "\" -cd \"" - + OPENSEARCH_CONF_DIR + + this.installer.OPENSEARCH_CONF_DIR + "opensearch-security\" -icl -key \"" - + OPENSEARCH_CONF_DIR + + this.installer.OPENSEARCH_CONF_DIR + Certificates.ADMIN_CERT_KEY.getFileName() + "\" -cert \"" - + OPENSEARCH_CONF_DIR + + this.installer.OPENSEARCH_CONF_DIR + Certificates.ADMIN_CERT.getFileName() + "\" -cacert \"" - + OPENSEARCH_CONF_DIR + + this.installer.OPENSEARCH_CONF_DIR + Certificates.ROOT_CA.getFileName() + "\" -nhnv"; - if (OS.toLowerCase().contains("win")) { + if (this.installer.OS.toLowerCase().contains("win")) { return new String[] { "@echo off", "call \"" + securityAdminExecutionPath }; } diff --git a/src/test/java/org/opensearch/security/tools/democonfig/CertificateGeneratorTests.java b/src/test/java/org/opensearch/security/tools/democonfig/CertificateGeneratorTests.java index dd2cf0c6bd..5ca26f47e9 100644 --- a/src/test/java/org/opensearch/security/tools/democonfig/CertificateGeneratorTests.java +++ b/src/test/java/org/opensearch/security/tools/democonfig/CertificateGeneratorTests.java @@ -37,33 +37,37 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.tools.democonfig.Installer.OPENSEARCH_CONF_DIR; import static org.opensearch.security.tools.democonfig.util.DemoConfigHelperUtil.createDirectory; import static org.opensearch.security.tools.democonfig.util.DemoConfigHelperUtil.deleteDirectoryRecursive; import static org.junit.Assert.fail; public class CertificateGeneratorTests { + private static Installer installer; + @Before public void setUp() { - OPENSEARCH_CONF_DIR = System.getProperty("user.dir") + File.separator + "test-conf"; - createDirectory(OPENSEARCH_CONF_DIR); + installer = Installer.getInstance(); + installer.OPENSEARCH_CONF_DIR = System.getProperty("user.dir") + File.separator + "test-conf"; + createDirectory(installer.OPENSEARCH_CONF_DIR); } @After public void tearDown() { - deleteDirectoryRecursive(OPENSEARCH_CONF_DIR); + + deleteDirectoryRecursive(installer.OPENSEARCH_CONF_DIR); + Installer.resetInstance(); } @Test public void testCreateDemoCertificates() { - CertificateGenerator certificateGenerator = new CertificateGenerator(); + CertificateGenerator certificateGenerator = new CertificateGenerator(installer); Certificates[] certificatesArray = Certificates.values(); certificateGenerator.createDemoCertificates(); for (Certificates cert : certificatesArray) { - String certFilePath = OPENSEARCH_CONF_DIR + File.separator + cert.getFileName(); + String certFilePath = installer.OPENSEARCH_CONF_DIR + File.separator + cert.getFileName(); File certFile = new File(certFilePath); assertThat(certFile.exists(), is(equalTo(true))); assertThat(certFile.canRead(), is(equalTo(true))); @@ -78,8 +82,8 @@ public void testCreateDemoCertificates() { @Test public void testCreateDemoCertificates_invalidPath() { - OPENSEARCH_CONF_DIR = "invalidPath"; - CertificateGenerator certificateGenerator = new CertificateGenerator(); + installer.OPENSEARCH_CONF_DIR = "invalidPath"; + CertificateGenerator certificateGenerator = new CertificateGenerator(installer); try { System.setSecurityManager(new NoExitSecurityManager()); certificateGenerator.createDemoCertificates(); diff --git a/src/test/java/org/opensearch/security/tools/democonfig/InstallerTests.java b/src/test/java/org/opensearch/security/tools/democonfig/InstallerTests.java index 0818edca5a..52553573a0 100644 --- a/src/test/java/org/opensearch/security/tools/democonfig/InstallerTests.java +++ b/src/test/java/org/opensearch/security/tools/democonfig/InstallerTests.java @@ -36,35 +36,8 @@ 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.BASE_DIR; -import static org.opensearch.security.tools.democonfig.Installer.FILE_EXTENSION; -import static org.opensearch.security.tools.democonfig.Installer.OPENSEARCH_BIN_DIR; -import static org.opensearch.security.tools.democonfig.Installer.OPENSEARCH_CONF_DIR; -import static org.opensearch.security.tools.democonfig.Installer.OPENSEARCH_CONF_FILE; -import static org.opensearch.security.tools.democonfig.Installer.OPENSEARCH_INSTALL_TYPE; -import static org.opensearch.security.tools.democonfig.Installer.OPENSEARCH_LIB_PATH; -import static org.opensearch.security.tools.democonfig.Installer.OPENSEARCH_PLUGINS_DIR; -import static org.opensearch.security.tools.democonfig.Installer.OPENSEARCH_VERSION; -import static org.opensearch.security.tools.democonfig.Installer.OS; -import static org.opensearch.security.tools.democonfig.Installer.RPM_DEB_OPENSEARCH_FILE; -import static org.opensearch.security.tools.democonfig.Installer.SCRIPT_DIR; -import static org.opensearch.security.tools.democonfig.Installer.SECURITY_VERSION; -import static org.opensearch.security.tools.democonfig.Installer.assumeyes; -import static org.opensearch.security.tools.democonfig.Installer.cluster_mode; -import static org.opensearch.security.tools.democonfig.Installer.determineInstallType; -import static org.opensearch.security.tools.democonfig.Installer.environment; -import static org.opensearch.security.tools.democonfig.Installer.finishScriptExecution; -import static org.opensearch.security.tools.democonfig.Installer.gatherUserInputs; -import static org.opensearch.security.tools.democonfig.Installer.initializeVariables; -import static org.opensearch.security.tools.democonfig.Installer.initsecurity; +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.Installer.printVariables; -import static org.opensearch.security.tools.democonfig.Installer.readOptions; -import static org.opensearch.security.tools.democonfig.Installer.resetState; -import static org.opensearch.security.tools.democonfig.Installer.setBaseDir; -import static org.opensearch.security.tools.democonfig.Installer.setOpenSearchVariables; -import static org.opensearch.security.tools.democonfig.Installer.setSecurityVariables; -import static org.opensearch.security.tools.democonfig.Installer.skip_updates; 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; @@ -77,16 +50,19 @@ public class InstallerTests { private final PrintStream originalOut = System.out; private final InputStream originalIn = System.in; + private static Installer installer; + @Before public void setUpStreams() { System.setOut(new PrintStream(outContent)); - resetState(); + installer = Installer.getInstance(); } @After public void restoreStreams() { System.setOut(originalOut); System.setIn(originalIn); + Installer.resetInstance(); } @Test @@ -104,14 +80,14 @@ public void testPrintScriptHeaders() { public void testReadOptions_withoutHelpOption() { // All options except Help `-h` String[] validOptions = { "/scriptDir", "-y", "-i", "-c", "-s", "-t" }; - readOptions(validOptions); - - assertEquals("/scriptDir", SCRIPT_DIR); - assertThat(assumeyes, is(true)); - assertThat(initsecurity, is(true)); - assertThat(cluster_mode, is(true)); - assertEquals(0, skip_updates); - assertEquals(ExecutionEnvironment.TEST, environment); + installer.readOptions(validOptions); + + assertEquals("/scriptDir", installer.SCRIPT_DIR); + assertThat(installer.assumeyes, is(true)); + assertThat(installer.initsecurity, is(true)); + assertThat(installer.cluster_mode, is(true)); + assertEquals(0, installer.skip_updates); + assertEquals(ExecutionEnvironment.TEST, installer.environment); } @Test @@ -120,7 +96,7 @@ public void testReadOptions_help() { System.setSecurityManager(new NoExitSecurityManager()); String[] helpOption = { "/scriptDir", "-h" }; - readOptions(helpOption); + installer.readOptions(helpOption); assertThat(outContent.toString(), containsString("install_demo_configuration.sh [-y] [-i] [-c]")); assertThat(outContent.toString(), containsString("-h show help")); @@ -141,15 +117,15 @@ public void testReadOptions_help() { public void testGatherUserInputs_withoutAssumeYes() { // -i & -c option is not passed String[] validOptions = { "/scriptDir" }; - readOptions(validOptions); - assertThat(assumeyes, is(false)); - assertThat(initsecurity, is(false)); - assertThat(cluster_mode, is(false)); + installer.readOptions(validOptions); + assertThat(installer.assumeyes, is(false)); + assertThat(installer.initsecurity, is(false)); + assertThat(installer.cluster_mode, is(false)); // set initsecurity and cluster_mode to no readInputStream("y" + System.lineSeparator() + "n" + System.lineSeparator() + "n" + System.lineSeparator()); // pass all 3 inputs as // y - gatherUserInputs(); + installer.gatherUserInputs(); assertThat(outContent.toString(), containsString("Install demo certificates?")); assertThat(outContent.toString(), containsString("Initialize Security Modules?")); @@ -157,15 +133,15 @@ public void testGatherUserInputs_withoutAssumeYes() { assertThat(outContent.toString(), containsString(" - Virtual memory (vm.max_map_count)" + System.lineSeparator())); assertThat(outContent.toString(), containsString("Enable cluster mode?")); - assertThat(initsecurity, is(false)); - assertThat(cluster_mode, is(false)); + assertThat(installer.initsecurity, is(false)); + assertThat(installer.cluster_mode, is(false)); outContent.reset(); // set initsecurity and cluster_mode to no readInputStream("y" + System.lineSeparator() + "y" + System.lineSeparator() + "y" + System.lineSeparator()); // pass all 3 inputs as // y - gatherUserInputs(); + installer.gatherUserInputs(); assertThat(outContent.toString(), containsString("Install demo certificates?")); assertThat(outContent.toString(), containsString("Initialize Security Modules?")); @@ -173,8 +149,8 @@ public void testGatherUserInputs_withoutAssumeYes() { assertThat(outContent.toString(), containsString(" - Virtual memory (vm.max_map_count)" + System.lineSeparator())); assertThat(outContent.toString(), containsString("Enable cluster mode?")); - assertThat(initsecurity, is(true)); - assertThat(cluster_mode, is(true)); + assertThat(installer.initsecurity, is(true)); + assertThat(installer.cluster_mode, is(true)); outContent.reset(); @@ -183,7 +159,7 @@ public void testGatherUserInputs_withoutAssumeYes() { System.setSecurityManager(new NoExitSecurityManager()); readInputStream("n" + System.lineSeparator() + "n" + System.lineSeparator() + "n" + System.lineSeparator()); - gatherUserInputs(); + installer.gatherUserInputs(); assertThat(outContent.toString(), containsString("Install demo certificates?")); assertThat(outContent.toString(), not(containsString("Initialize Security Modules?"))); @@ -200,51 +176,49 @@ public void testGatherUserInputs_withoutAssumeYes() { // pass initsecurity and cluster_mode options String[] validOptionsIC = { "/scriptDir", "-i", "-c" }; - readOptions(validOptionsIC); - assertThat(assumeyes, is(false)); - assertThat(initsecurity, is(true)); - assertThat(cluster_mode, is(true)); + installer.readOptions(validOptionsIC); + assertThat(installer.assumeyes, is(false)); + assertThat(installer.initsecurity, is(true)); + assertThat(installer.cluster_mode, is(true)); readInputStream("y" + System.lineSeparator() + "y" + System.lineSeparator() + "y" + System.lineSeparator()); // pass all 3 inputs as // y - gatherUserInputs(); + installer.gatherUserInputs(); assertThat(outContent.toString(), containsString("Install demo certificates?")); assertThat(outContent.toString(), not(containsString("Initialize Security Modules?"))); assertThat(outContent.toString(), not(containsString("Enable cluster mode?"))); - assertThat(initsecurity, is(true)); - assertThat(cluster_mode, is(true)); + assertThat(installer.initsecurity, is(true)); + assertThat(installer.cluster_mode, is(true)); } @Test public void testGatherInputs_withAssumeYes() { String[] validOptionsYes = { "/scriptDir", "-y" }; - readOptions(validOptionsYes); - assertThat(assumeyes, is(true)); + installer.readOptions(validOptionsYes); + assertThat(installer.assumeyes, is(true)); - gatherUserInputs(); + installer.gatherUserInputs(); - assertThat(initsecurity, is(true)); - assertThat(cluster_mode, is(true)); + assertThat(installer.initsecurity, is(true)); + assertThat(installer.cluster_mode, is(true)); } @Test public void testInitializeVariables_setBaseDir_invalidPath() { String[] invalidScriptDirPath = { "/scriptDir", "-y" }; - readOptions(invalidScriptDirPath); - - assertThrows("Expected NullPointerException to be thrown", NullPointerException.class, Installer::initializeVariables); + installer.readOptions(invalidScriptDirPath); - resetState(); + assertThrows("Expected NullPointerException to be thrown", NullPointerException.class, installer::initializeVariables); String[] invalidScriptDirPath2 = { "/opensearch/plugins/opensearch-security/tools", "-y" }; - readOptions(invalidScriptDirPath2); + installer.readOptions(invalidScriptDirPath2); try { System.setSecurityManager(new NoExitSecurityManager()); - initializeVariables(); + installer.initializeVariables(); assertThat(outContent.toString(), containsString("DEBUG: basedir does not exist")); } catch (SecurityException e) { assertThat(e.getMessage(), equalTo("System.exit(-1) blocked to allow print statement testing.")); @@ -258,13 +232,13 @@ public void testSetBaseDir_valid() { String currentDir = System.getProperty("user.dir"); String[] validBaseDir = { currentDir, "-y" }; - readOptions(validBaseDir); + installer.readOptions(validBaseDir); - setBaseDir(); + installer.setBaseDir(); String expectedBaseDirValue = new File(currentDir).getParentFile().getParentFile().getParentFile().getAbsolutePath() + File.separator; - assertThat(BASE_DIR, equalTo(expectedBaseDirValue)); + assertThat(installer.BASE_DIR, equalTo(expectedBaseDirValue)); } @Test @@ -272,13 +246,13 @@ public void testSetOpenSearchVariables_invalidPath() { String currentDir = System.getProperty("user.dir"); String[] validBaseDir = { currentDir, "-y" }; - readOptions(validBaseDir); + installer.readOptions(validBaseDir); try { System.setSecurityManager(new NoExitSecurityManager()); - setBaseDir(); - setOpenSearchVariables(); + installer.setBaseDir(); + installer.setOpenSearchVariables(); assertThat(outContent.toString(), containsString("Unable to determine OpenSearch config file. Quit.")); assertThat(outContent.toString(), containsString("Unable to determine OpenSearch bin directory. Quit.")); @@ -297,42 +271,42 @@ public void testSetOpenSearchVariables_invalidPath() { String expectedOpensearchBinDirPath = expectedBaseDirValue + "bin" + File.separator; String expectedOpensearchPluginDirPath = expectedBaseDirValue + "plugins" + File.separator; String expectedOpensearchLibDirPath = expectedBaseDirValue + "lib" + File.separator; - String expectedOpensearchInstallType = determineInstallType(); + String expectedOpensearchInstallType = installer.determineInstallType(); - assertThat(OPENSEARCH_CONF_FILE, equalTo(expectedOpensearchConfFilePath)); - assertThat(OPENSEARCH_BIN_DIR, equalTo(expectedOpensearchBinDirPath)); - assertThat(OPENSEARCH_PLUGINS_DIR, equalTo(expectedOpensearchPluginDirPath)); - assertThat(OPENSEARCH_LIB_PATH, equalTo(expectedOpensearchLibDirPath)); - assertThat(OPENSEARCH_INSTALL_TYPE, equalTo(expectedOpensearchInstallType)); + 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() { - OS = "Windows"; + installer.OS = "Windows"; - String installType = determineInstallType(); + String installType = installer.determineInstallType(); assertEquals(".zip", installType); } @Test public void testDetermineInstallType_rpm_deb() { - OS = "Linux"; + installer.OS = "Linux"; String dir = System.getProperty("user.dir"); - BASE_DIR = dir; - RPM_DEB_OPENSEARCH_FILE = new File(dir); + installer.BASE_DIR = dir; + RPM_DEB_OPENSEARCH_HOME = new File(dir); - String installType = determineInstallType(); + String installType = installer.determineInstallType(); assertEquals("rpm/deb", installType); } @Test public void testDetermineInstallType_default() { - OS = "Anything else"; - BASE_DIR = "/random-dir"; - String installType = determineInstallType(); + installer.OS = "Anything else"; + installer.BASE_DIR = "/random-dir"; + String installType = installer.determineInstallType(); assertEquals(".tar.gz", installType); } @@ -340,10 +314,10 @@ public void testDetermineInstallType_default() { @Test public void testSetSecurityVariables() { setUpSecurityDirectories(); - setSecurityVariables(); + installer.setSecurityVariables(); - assertThat(OPENSEARCH_VERSION, is(equalTo("osVersion"))); - assertThat(SECURITY_VERSION, is(equalTo("version"))); + assertThat(installer.OPENSEARCH_VERSION, is(equalTo("osVersion"))); + assertThat(installer.SECURITY_VERSION, is(equalTo("version"))); tearDownSecurityDirectories(); } @@ -352,7 +326,7 @@ public void testSetSecurityVariables_noSecurityPlugin() { try { System.setSecurityManager(new NoExitSecurityManager()); - setSecurityVariables(); + installer.setSecurityVariables(); fail("Expected System.exit(-1) to be called"); } catch (SecurityException e) { assertThat(e.getMessage(), equalTo("System.exit(-1) blocked to allow print statement testing.")); @@ -363,17 +337,17 @@ public void testSetSecurityVariables_noSecurityPlugin() { @Test public void testPrintVariables() { - OPENSEARCH_INSTALL_TYPE = "installType"; - OS = "OS"; - OPENSEARCH_CONF_DIR = "confDir"; - OPENSEARCH_CONF_FILE = "confFile"; - OPENSEARCH_BIN_DIR = "/bin"; - OPENSEARCH_PLUGINS_DIR = "/plugins"; - OPENSEARCH_LIB_PATH = "/lib"; - OPENSEARCH_VERSION = "osVersion"; - SECURITY_VERSION = "version"; - - printVariables(); + 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() @@ -400,20 +374,21 @@ public void testFinishScriptExecution() { setUpSecurityDirectories(); SecuritySettingsConfigurer.ADMIN_PASSWORD = "ble"; - finishScriptExecution(); + installer.finishScriptExecution(); - String securityAdminScriptPath = OPENSEARCH_PLUGINS_DIR + String securityAdminScriptPath = installer.OPENSEARCH_PLUGINS_DIR + "opensearch-security" + File.separator + "tools" + File.separator + "securityadmin" - + FILE_EXTENSION; - String securityAdminDemoScriptPath = OPENSEARCH_CONF_DIR + "securityadmin_demo" + FILE_EXTENSION; + + installer.FILE_EXTENSION; + String securityAdminDemoScriptPath = installer.OPENSEARCH_CONF_DIR + "securityadmin_demo" + installer.FILE_EXTENSION; setWritePermissions(securityAdminDemoScriptPath); - String lastLine = SecuritySettingsConfigurer.getSecurityAdminCommands(securityAdminScriptPath)[1]; - // Verify the expected output + 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" @@ -421,12 +396,11 @@ public void testFinishScriptExecution() { + "### After the whole cluster is up execute: " + System.lineSeparator() + lastLine - + "" + System.lineSeparator() + "### or run ." + File.separator + "securityadmin_demo" - + FILE_EXTENSION + + installer.FILE_EXTENSION + System.lineSeparator() + "### After that you can also use the Security Plugin ConfigurationGUI" + System.lineSeparator() @@ -445,22 +419,24 @@ public void testFinishScriptExecution() { @Test public void testFinishScriptExecution_withInitSecurityEnabled() { setUpSecurityDirectories(); - initsecurity = true; + installer.initsecurity = true; SecuritySettingsConfigurer.ADMIN_PASSWORD = "ble"; - finishScriptExecution(); + installer.finishScriptExecution(); - String securityAdminScriptPath = OPENSEARCH_PLUGINS_DIR + String securityAdminScriptPath = installer.OPENSEARCH_PLUGINS_DIR + "opensearch-security" + File.separator + "tools" + File.separator + "securityadmin" - + FILE_EXTENSION; - String securityAdminDemoScriptPath = OPENSEARCH_CONF_DIR + "securityadmin_demo" + FILE_EXTENSION; + + installer.FILE_EXTENSION; + String securityAdminDemoScriptPath = installer.OPENSEARCH_CONF_DIR + "securityadmin_demo" + installer.FILE_EXTENSION; setWritePermissions(securityAdminDemoScriptPath); - String lastLine = SecuritySettingsConfigurer.getSecurityAdminCommands(securityAdminScriptPath)[1]; + 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" @@ -484,7 +460,7 @@ public void testFinishScriptExecution_withInitSecurityEnabled() { + "### or run ." + File.separator + "securityadmin_demo" - + FILE_EXTENSION + + installer.FILE_EXTENSION + System.lineSeparator() + "### To use the Security Plugin ConfigurationGUI" + System.lineSeparator() @@ -508,30 +484,30 @@ public void setUpSecurityDirectories() { String currentDir = System.getProperty("user.dir"); String[] validBaseDir = { currentDir, "-y" }; - readOptions(validBaseDir); - setBaseDir(); - OPENSEARCH_PLUGINS_DIR = BASE_DIR + "plugins" + File.separator; - OPENSEARCH_LIB_PATH = BASE_DIR + "lib" + File.separator; - OPENSEARCH_CONF_DIR = BASE_DIR + "test-conf" + File.separator; - - createDirectory(OPENSEARCH_PLUGINS_DIR); - createDirectory(OPENSEARCH_LIB_PATH); - createDirectory(OPENSEARCH_CONF_DIR); - createDirectory(OPENSEARCH_PLUGINS_DIR + "opensearch-security"); - createFile(OPENSEARCH_LIB_PATH + "opensearch-osVersion.jar"); - createFile(OPENSEARCH_PLUGINS_DIR + "opensearch-security" + File.separator + "opensearch-security-version.jar"); - createFile(OPENSEARCH_CONF_DIR + File.separator + "securityadmin_demo.sh"); + 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-osVersion.jar"); + createFile(installer.OPENSEARCH_PLUGINS_DIR + "opensearch-security" + File.separator + "opensearch-security-version.jar"); + createFile(installer.OPENSEARCH_CONF_DIR + File.separator + "securityadmin_demo.sh"); } public void tearDownSecurityDirectories() { // Clean up testing directories or files - deleteDirectoryRecursive(OPENSEARCH_PLUGINS_DIR); - deleteDirectoryRecursive(OPENSEARCH_LIB_PATH); - deleteDirectoryRecursive(OPENSEARCH_CONF_DIR); + deleteDirectoryRecursive(installer.OPENSEARCH_PLUGINS_DIR); + deleteDirectoryRecursive(installer.OPENSEARCH_LIB_PATH); + deleteDirectoryRecursive(installer.OPENSEARCH_CONF_DIR); } static void setWritePermissions(String filePath) { - if (!OS.toLowerCase().contains("win")) { + if (!installer.OS.toLowerCase().contains("win")) { Path file = Paths.get(filePath); Set perms = new HashSet<>(); perms.add(PosixFilePermission.OWNER_WRITE); diff --git a/src/test/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurerTests.java b/src/test/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurerTests.java index 85c1b8a10b..ab343b27ba 100644 --- a/src/test/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurerTests.java +++ b/src/test/java/org/opensearch/security/tools/democonfig/SecuritySettingsConfigurerTests.java @@ -24,6 +24,7 @@ import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; import java.util.Collections; +import java.util.List; import java.util.Map; import org.junit.After; @@ -37,13 +38,9 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import static org.opensearch.security.tools.democonfig.Installer.FILE_EXTENSION; -import static org.opensearch.security.tools.democonfig.Installer.OPENSEARCH_CONF_DIR; -import static org.opensearch.security.tools.democonfig.Installer.OPENSEARCH_CONF_FILE; -import static org.opensearch.security.tools.democonfig.Installer.resetState; -import static org.opensearch.security.tools.democonfig.SecuritySettingsConfigurer.getSecurityAdminCommands; +import static org.opensearch.security.tools.democonfig.SecuritySettingsConfigurer.REST_ENABLED_ROLES; +import static org.opensearch.security.tools.democonfig.SecuritySettingsConfigurer.SYSTEM_INDICES; import static org.opensearch.security.tools.democonfig.SecuritySettingsConfigurer.isStringAlreadyPresentInFile; -import static org.opensearch.security.tools.democonfig.SecuritySettingsConfigurer.writeSecurityConfigToOpenSearchYML; 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; @@ -59,9 +56,15 @@ public class SecuritySettingsConfigurerTests { private final String adminPasswordKey = "initialAdminPassword"; + private static SecuritySettingsConfigurer securitySettingsConfigurer; + + private static Installer installer; + @Before public void setUp() { System.setOut(new PrintStream(outContent)); + installer = Installer.getInstance(); + securitySettingsConfigurer = new SecuritySettingsConfigurer(installer); setUpConf(); } @@ -69,10 +72,10 @@ public void setUp() { public void tearDown() throws NoSuchFieldException, IllegalAccessException { System.setOut(originalOut); System.setIn(originalIn); - deleteDirectoryRecursive(OPENSEARCH_CONF_DIR); - Installer.environment = ExecutionEnvironment.DEMO; + deleteDirectoryRecursive(installer.OPENSEARCH_CONF_DIR); + installer.environment = ExecutionEnvironment.DEMO; unsetEnv(adminPasswordKey); - resetState(); + Installer.resetInstance(); } @Test @@ -80,7 +83,7 @@ public void testUpdateAdminPasswordWithCustomPassword() throws NoSuchFieldExcept String customPassword = "myStrongPassword123"; // generateStrongPassword(); setEnv(adminPasswordKey, customPassword); - SecuritySettingsConfigurer.updateAdminPassword(); + securitySettingsConfigurer.updateAdminPassword(); assertThat(customPassword, is(equalTo(SecuritySettingsConfigurer.ADMIN_PASSWORD))); @@ -104,7 +107,7 @@ public void testUpdateAdminPasswordWithFilePassword() throws IOException { throw new IOException("Unable to update the internal users file with the hashed password."); } - SecuritySettingsConfigurer.updateAdminPassword(); + securitySettingsConfigurer.updateAdminPassword(); assertEquals(customPassword, SecuritySettingsConfigurer.ADMIN_PASSWORD); assertThat(outContent.toString(), containsString("ADMIN PASSWORD SET TO: " + customPassword)); @@ -117,7 +120,7 @@ public void testUpdateAdminPasswordWithWeakPassword() throws NoSuchFieldExceptio try { System.setSecurityManager(new NoExitSecurityManager()); - SecuritySettingsConfigurer.updateAdminPassword(); + securitySettingsConfigurer.updateAdminPassword(); assertThat(outContent.toString(), containsString("Password weakpassword is weak. Please re-try with a stronger password.")); @@ -131,8 +134,8 @@ public void testUpdateAdminPasswordWithWeakPassword() throws NoSuchFieldExceptio @Test public void testUpdateAdminPasswordWithWeakPassword_skipPasswordValidation() throws NoSuchFieldException, IllegalAccessException { setEnv(adminPasswordKey, "weakpassword"); - Installer.environment = ExecutionEnvironment.TEST; - SecuritySettingsConfigurer.updateAdminPassword(); + installer.environment = ExecutionEnvironment.TEST; + securitySettingsConfigurer.updateAdminPassword(); assertThat("weakpassword", is(equalTo(SecuritySettingsConfigurer.ADMIN_PASSWORD))); assertThat(outContent.toString(), containsString("ADMIN PASSWORD SET TO: weakpassword")); @@ -140,12 +143,12 @@ public void testUpdateAdminPasswordWithWeakPassword_skipPasswordValidation() thr @Test public void testSecurityPluginAlreadyConfigured() { - writeSecurityConfigToOpenSearchYML(); + securitySettingsConfigurer.writeSecurityConfigToOpenSearchYML(); try { System.setSecurityManager(new NoExitSecurityManager()); - String expectedMessage = OPENSEARCH_CONF_FILE + " seems to be already configured for Security. Quit."; + String expectedMessage = installer.OPENSEARCH_CONF_FILE + " seems to be already configured for Security. Quit."; - SecuritySettingsConfigurer.checkIfSecurityPluginIsAlreadyConfigured(); + securitySettingsConfigurer.checkIfSecurityPluginIsAlreadyConfigured(); assertThat(outContent.toString(), containsString(expectedMessage)); } catch (SecurityException e) { assertThat(e.getMessage(), equalTo("System.exit(-1) blocked to allow print statement testing.")); @@ -157,7 +160,7 @@ public void testSecurityPluginAlreadyConfigured() { @Test public void testSecurityPluginNotConfigured() { try { - SecuritySettingsConfigurer.checkIfSecurityPluginIsAlreadyConfigured(); + securitySettingsConfigurer.checkIfSecurityPluginIsAlreadyConfigured(); } catch (Exception e) { fail("Expected checkIfSecurityPluginIsAlreadyConfigured to succeed without any errors."); } @@ -165,12 +168,12 @@ public void testSecurityPluginNotConfigured() { @Test public void testConfigFileDoesNotExist() { - OPENSEARCH_CONF_FILE = "path/to/nonexistentfile"; + installer.OPENSEARCH_CONF_FILE = "path/to/nonexistentfile"; try { System.setSecurityManager(new NoExitSecurityManager()); String expectedMessage = "OpenSearch configuration file does not exist. Quit."; - SecuritySettingsConfigurer.checkIfSecurityPluginIsAlreadyConfigured(); + securitySettingsConfigurer.checkIfSecurityPluginIsAlreadyConfigured(); assertThat(outContent.toString(), containsString(expectedMessage)); } catch (SecurityException e) { assertThat(e.getMessage(), equalTo("System.exit(-1) blocked to allow print statement testing.")); @@ -178,68 +181,41 @@ public void testConfigFileDoesNotExist() { System.setSecurityManager(null); } // reset the file pointer - OPENSEARCH_CONF_FILE = OPENSEARCH_CONF_DIR + "opensearch.yml"; + installer.OPENSEARCH_CONF_FILE = installer.OPENSEARCH_CONF_DIR + "opensearch.yml"; } @Test - public void testBuildSecurityConfigString() { - String actual = SecuritySettingsConfigurer.buildSecurityConfigString(); - - String expected = System.lineSeparator() - + "######## Start OpenSearch Security Demo Configuration ########" - + System.lineSeparator() - + "# WARNING: revise all the lines below before you go into production" - + System.lineSeparator() - + "plugins.security.ssl.transport.pemcert_filepath: esnode.pem" - + System.lineSeparator() - + "plugins.security.ssl.transport.pemkey_filepath: esnode-key.pem" - + System.lineSeparator() - + "plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem" - + System.lineSeparator() - + "plugins.security.ssl.transport.enforce_hostname_verification: false" - + System.lineSeparator() - + "plugins.security.ssl.http.enabled: true" - + System.lineSeparator() - + "plugins.security.ssl.http.pemcert_filepath: esnode.pem" - + System.lineSeparator() - + "plugins.security.ssl.http.pemkey_filepath: esnode-key.pem" - + System.lineSeparator() - + "plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem" - + System.lineSeparator() - + "plugins.security.allow_unsafe_democertificates: true" - + System.lineSeparator() - + "plugins.security.authcz.admin_dn:" - + System.lineSeparator() - + " - CN=kirk,OU=client,O=client,L=test, C=de" - + System.lineSeparator() - + System.lineSeparator() - + "plugins.security.audit.type: internal_opensearch" - + System.lineSeparator() - + "plugins.security.enable_snapshot_restore_privilege: true" - + System.lineSeparator() - + "plugins.security.check_snapshot_restore_write_privileges: true" - + System.lineSeparator() - + "plugins.security.restapi.roles_enabled: [\"all_access\", \"security_rest_api_access\"]" - + System.lineSeparator() - + "plugins.security.system_indices.enabled: true" - + System.lineSeparator() - + "plugins.security.system_indices.indices: [.plugins-ml-config, .plugins-ml-connector, .plugins-ml-model-group, .plugins-ml-model, .plugins-ml-task, .plugins-ml-conversation-meta, .plugins-ml-conversation-interactions, .opendistro-alerting-config, .opendistro-alerting-alert*, .opendistro-anomaly-results*, .opendistro-anomaly-detector*, .opendistro-anomaly-checkpoints, .opendistro-anomaly-detection-state, .opendistro-reports-*, .opensearch-notifications-*, .opensearch-notebooks, .opensearch-observability, .ql-datasources, .opendistro-asynchronous-search-response*, .replication-metadata-store, .opensearch-knn-models, .geospatial-ip2geo-data*]" - + System.lineSeparator() - + "node.max_local_storage_nodes: 3" - + System.lineSeparator() - + "######## End OpenSearch Security Demo Configuration ########" - + System.lineSeparator(); - assertThat(actual, is(equalTo(expected))); - - Installer.initsecurity = true; - actual = SecuritySettingsConfigurer.buildSecurityConfigString(); - assertThat(actual, containsString("plugins.security.allow_default_init_securityindex: true" + System.lineSeparator())); - - Installer.cluster_mode = true; - actual = SecuritySettingsConfigurer.buildSecurityConfigString(); - assertThat(actual, containsString("network.host: 0.0.0.0" + System.lineSeparator())); - assertThat(actual, containsString("node.name: smoketestnode" + System.lineSeparator())); - assertThat(actual, containsString("cluster.initial_cluster_manager_nodes: smoketestnode" + System.lineSeparator())); + public void testBuildSecurityConfigMap() { + Map actual = securitySettingsConfigurer.buildSecurityConfigMap(); + + assertThat(actual.size(), is(17)); + assertThat(actual.get("plugins.security.ssl.transport.pemcert_filepath"), is(equalTo(Certificates.NODE_CERT.getFileName()))); + assertThat(actual.get("plugins.security.ssl.transport.pemkey_filepath"), is(equalTo(Certificates.NODE_KEY.getFileName()))); + assertThat(actual.get("plugins.security.ssl.transport.pemtrustedcas_filepath"), is(equalTo(Certificates.ROOT_CA.getFileName()))); + assertThat(actual.get("plugins.security.ssl.transport.enforce_hostname_verification"), is(equalTo(false))); + assertThat(actual.get("plugins.security.ssl.http.enabled"), is(equalTo(true))); + assertThat(actual.get("plugins.security.ssl.http.pemcert_filepath"), is(equalTo(Certificates.NODE_CERT.getFileName()))); + assertThat(actual.get("plugins.security.ssl.http.pemkey_filepath"), is(equalTo(Certificates.NODE_KEY.getFileName()))); + assertThat(actual.get("plugins.security.ssl.http.pemtrustedcas_filepath"), is(equalTo(Certificates.ROOT_CA.getFileName()))); + assertThat(actual.get("plugins.security.allow_unsafe_democertificates"), is(equalTo(true))); + assertThat(actual.get("plugins.security.authcz.admin_dn"), is(equalTo(List.of("CN=kirk,OU=client,O=client,L=test,C=de")))); + assertThat(actual.get("plugins.security.audit.type"), is(equalTo("internal_opensearch"))); + assertThat(actual.get("plugins.security.enable_snapshot_restore_privilege"), is(equalTo(true))); + assertThat(actual.get("plugins.security.check_snapshot_restore_write_privileges"), is(equalTo(true))); + assertThat(actual.get("plugins.security.restapi.roles_enabled"), is(equalTo(REST_ENABLED_ROLES))); + assertThat(actual.get("plugins.security.system_indices.enabled"), is(equalTo(true))); + assertThat(actual.get("plugins.security.system_indices.indices"), is(equalTo(SYSTEM_INDICES))); + assertThat(actual.get("node.max_local_storage_nodes"), is(equalTo(3))); + + installer.initsecurity = true; + actual = securitySettingsConfigurer.buildSecurityConfigMap(); + assertThat(actual.get("plugins.security.allow_default_init_securityindex"), is(equalTo(true))); + + installer.cluster_mode = true; + actual = securitySettingsConfigurer.buildSecurityConfigMap(); + assertThat(actual.get("network.host"), is(equalTo("0.0.0.0"))); + assertThat(actual.get("node.name"), is(equalTo("smoketestnode"))); + assertThat(actual.get("cluster.initial_cluster_manager_nodes"), is(equalTo("smoketestnode"))); } @Test @@ -247,27 +223,27 @@ public void testIsStringAlreadyPresentInFile() throws IOException { String str1 = "network.host"; String str2 = "some.random.config"; - Installer.initsecurity = true; - writeSecurityConfigToOpenSearchYML(); + installer.initsecurity = true; + securitySettingsConfigurer.writeSecurityConfigToOpenSearchYML(); - assertThat(isStringAlreadyPresentInFile(OPENSEARCH_CONF_FILE, str1), is(equalTo(false))); - assertThat(isStringAlreadyPresentInFile(OPENSEARCH_CONF_FILE, str2), is(equalTo(false))); + assertThat(isStringAlreadyPresentInFile(installer.OPENSEARCH_CONF_FILE, str1), is(equalTo(false))); + assertThat(isStringAlreadyPresentInFile(installer.OPENSEARCH_CONF_FILE, str2), is(equalTo(false))); - Installer.cluster_mode = true; - writeSecurityConfigToOpenSearchYML(); + installer.cluster_mode = true; + securitySettingsConfigurer.writeSecurityConfigToOpenSearchYML(); - assertThat(isStringAlreadyPresentInFile(OPENSEARCH_CONF_FILE, str1), is(equalTo(true))); - assertThat(isStringAlreadyPresentInFile(OPENSEARCH_CONF_FILE, str2), is(equalTo(false))); + assertThat(isStringAlreadyPresentInFile(installer.OPENSEARCH_CONF_FILE, str1), is(equalTo(true))); + assertThat(isStringAlreadyPresentInFile(installer.OPENSEARCH_CONF_FILE, str2), is(equalTo(false))); } @Test public void testCreateSecurityAdminDemoScriptAndGetSecurityAdminCommands() throws IOException { - String demoPath = OPENSEARCH_CONF_DIR + "securityadmin_demo" + FILE_EXTENSION; - SecuritySettingsConfigurer.createSecurityAdminDemoScript("scriptPath", demoPath); + String demoPath = installer.OPENSEARCH_CONF_DIR + "securityadmin_demo" + installer.FILE_EXTENSION; + securitySettingsConfigurer.createSecurityAdminDemoScript("scriptPath", demoPath); assertThat(new File(demoPath).exists(), is(equalTo(true))); - String[] commands = getSecurityAdminCommands("scriptPath"); + String[] commands = securitySettingsConfigurer.getSecurityAdminCommands("scriptPath"); try (BufferedReader reader = new BufferedReader(new FileReader(demoPath, StandardCharsets.UTF_8))) { assertThat(reader.readLine(), is(commands[0])); @@ -279,7 +255,7 @@ public void testCreateSecurityAdminDemoScriptAndGetSecurityAdminCommands() throw public void testCreateSecurityAdminDemoScript_invalidPath() { String demoPath = null; try { - SecuritySettingsConfigurer.createSecurityAdminDemoScript("scriptPath", demoPath); + securitySettingsConfigurer.createSecurityAdminDemoScript("scriptPath", demoPath); fail("Expected to throw Exception"); } catch (IOException | NullPointerException e) { // expected @@ -318,11 +294,11 @@ public static void unsetEnv(String key) throws NoSuchFieldException, IllegalAcce } void setUpConf() { - OPENSEARCH_CONF_DIR = System.getProperty("user.dir") + File.separator + "test-conf" + File.separator; - OPENSEARCH_CONF_FILE = OPENSEARCH_CONF_DIR + "opensearch.yml"; - String securityConfDir = OPENSEARCH_CONF_DIR + "opensearch-security" + File.separator; + installer.OPENSEARCH_CONF_DIR = System.getProperty("user.dir") + File.separator + "test-conf" + File.separator; + installer.OPENSEARCH_CONF_FILE = installer.OPENSEARCH_CONF_DIR + "opensearch.yml"; + String securityConfDir = installer.OPENSEARCH_CONF_DIR + "opensearch-security" + File.separator; createDirectory(securityConfDir); createFile(securityConfDir + "internal_users.yml"); - createFile(OPENSEARCH_CONF_FILE); + createFile(installer.OPENSEARCH_CONF_FILE); } }