/*
* 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"));
}
}