/* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.elasticsearch.node; import org.elasticsearch.cli.MockTerminal; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.common.settings.MockSecureSettings; import org.elasticsearch.common.settings.SecureSetting; import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.env.Environment; import org.elasticsearch.test.ESTestCase; import org.junit.After; import org.junit.Before; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.Map; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; public class InternalSettingsPreparerTests extends ESTestCase { Path homeDir; Settings baseEnvSettings; @Before public void createBaseEnvSettings() { homeDir = createTempDir(); baseEnvSettings = Settings.builder() .put(Environment.PATH_HOME_SETTING.getKey(), homeDir) .build(); } @After public void clearBaseEnvSettings() { homeDir = null; baseEnvSettings = null; } public void testEmptySettings() { Settings settings = InternalSettingsPreparer.prepareSettings(Settings.EMPTY); assertNull(settings.get("node.name")); // a name was not set assertNotNull(settings.get(ClusterName.CLUSTER_NAME_SETTING.getKey())); // a cluster name was set int size = settings.names().size(); Environment env = InternalSettingsPreparer.prepareEnvironment(baseEnvSettings, null); settings = env.settings(); assertNull(settings.get("node.name")); // a name was not set assertNotNull(settings.get(ClusterName.CLUSTER_NAME_SETTING.getKey())); // a cluster name was set assertEquals(settings.toString(), size + 1 /* path.home is in the base settings */, settings.names().size()); String home = Environment.PATH_HOME_SETTING.get(baseEnvSettings); String configDir = env.configFile().toString(); assertTrue(configDir, configDir.startsWith(home)); } public void testDefaultClusterName() { Settings settings = InternalSettingsPreparer.prepareSettings(Settings.EMPTY); assertEquals("elasticsearch", settings.get("cluster.name")); settings = InternalSettingsPreparer.prepareSettings(Settings.builder().put("cluster.name", "foobar").build()); assertEquals("foobar", settings.get("cluster.name")); } public void testReplacePromptPlaceholders() { MockTerminal terminal = new MockTerminal(); terminal.addTextInput("text"); terminal.addSecretInput("replaced"); Settings.Builder builder = Settings.builder() .put(baseEnvSettings) .put("password.replace", InternalSettingsPreparer.SECRET_PROMPT_VALUE) .put("dont.replace", "prompt:secret") .put("dont.replace2", "_prompt:secret_") .put("dont.replace3", "_prompt:text__") .put("dont.replace4", "__prompt:text_") .put("dont.replace5", "prompt:secret__") .put("replace_me", InternalSettingsPreparer.TEXT_PROMPT_VALUE); Settings settings = InternalSettingsPreparer.prepareEnvironment(builder.build(), terminal).settings(); assertThat(settings.get("password.replace"), equalTo("replaced")); assertThat(settings.get("replace_me"), equalTo("text")); // verify other values unchanged assertThat(settings.get("dont.replace"), equalTo("prompt:secret")); assertThat(settings.get("dont.replace2"), equalTo("_prompt:secret_")); assertThat(settings.get("dont.replace3"), equalTo("_prompt:text__")); assertThat(settings.get("dont.replace4"), equalTo("__prompt:text_")); assertThat(settings.get("dont.replace5"), equalTo("prompt:secret__")); } public void testReplaceSecretPromptPlaceholderWithNullTerminal() { Settings.Builder builder = Settings.builder() .put(baseEnvSettings) .put("replace_me1", InternalSettingsPreparer.SECRET_PROMPT_VALUE); try { InternalSettingsPreparer.prepareEnvironment(builder.build(), null); fail("an exception should have been thrown since no terminal was provided!"); } catch (UnsupportedOperationException e) { assertThat(e.getMessage(), containsString("with value [" + InternalSettingsPreparer.SECRET_PROMPT_VALUE + "]")); } } public void testReplaceTextPromptPlaceholderWithNullTerminal() { Settings.Builder builder = Settings.builder() .put(baseEnvSettings) .put("replace_me1", InternalSettingsPreparer.TEXT_PROMPT_VALUE); try { InternalSettingsPreparer.prepareEnvironment(builder.build(), null); fail("an exception should have been thrown since no terminal was provided!"); } catch (UnsupportedOperationException e) { assertThat(e.getMessage(), containsString("with value [" + InternalSettingsPreparer.TEXT_PROMPT_VALUE + "]")); } } public void testGarbageIsNotSwallowed() throws IOException { try { InputStream garbage = getClass().getResourceAsStream("/config/garbage/garbage.yml"); Path home = createTempDir(); Path config = home.resolve("config"); Files.createDirectory(config); Files.copy(garbage, config.resolve("elasticsearch.yml")); InternalSettingsPreparer.prepareEnvironment(Settings.builder() .put(baseEnvSettings) .build(), null); } catch (SettingsException e) { assertEquals("Failed to load settings from [elasticsearch.yml]", e.getMessage()); } } public void testMultipleSettingsFileNotAllowed() throws IOException { InputStream yaml = getClass().getResourceAsStream("/config/elasticsearch.yaml"); InputStream json = getClass().getResourceAsStream("/config/elasticsearch.json"); Path config = homeDir.resolve("config"); Files.createDirectory(config); Files.copy(yaml, config.resolve("elasticsearch.yaml")); Files.copy(json, config.resolve("elasticsearch.json")); SettingsException e = expectThrows(SettingsException.class, () -> InternalSettingsPreparer.prepareEnvironment(Settings.builder().put(baseEnvSettings).build(), null) ); assertTrue(e.getMessage(), e.getMessage().contains("multiple settings files found with suffixes")); assertTrue(e.getMessage(), e.getMessage().contains(".yaml")); assertTrue(e.getMessage(), e.getMessage().contains(".json")); } public void testYmlExtension() throws IOException { InputStream yaml = getClass().getResourceAsStream("/config/elasticsearch.yaml"); Path config = homeDir.resolve("config"); Files.createDirectory(config); Files.copy(yaml, config.resolve("elasticsearch.yml")); Environment env = InternalSettingsPreparer.prepareEnvironment(Settings.builder().put(baseEnvSettings).build(), null); assertEquals(".yml", env.configExtension()); } public void testJsonExtension() throws IOException { InputStream yaml = getClass().getResourceAsStream("/config/elasticsearch.json"); Path config = homeDir.resolve("config"); Files.createDirectory(config); Files.copy(yaml, config.resolve("elasticsearch.json")); Environment env = InternalSettingsPreparer.prepareEnvironment(Settings.builder().put(baseEnvSettings).build(), null); assertEquals(".json", env.configExtension()); } public void testSecureSettings() { MockSecureSettings secureSettings = new MockSecureSettings(); secureSettings.setString("foo", "secret"); Settings input = Settings.builder().put(baseEnvSettings).setSecureSettings(secureSettings).build(); Environment env = InternalSettingsPreparer.prepareEnvironment(input, null); Setting<SecureString> fakeSetting = SecureSetting.secureString("foo", null); assertEquals("secret", fakeSetting.get(env.settings()).toString()); } public void testDefaultPropertiesDoNothing() throws Exception { Map<String, String> props = Collections.singletonMap("default.setting", "foo"); Environment env = InternalSettingsPreparer.prepareEnvironment(baseEnvSettings, null, props); assertEquals("foo", env.settings().get("default.setting")); assertNull(env.settings().get("setting")); } }