use of org.opensearch.common.settings.SecureSettings in project OpenSearch by opensearch-project.
the class BootstrapTests method testLoadSecureSettings.
public void testLoadSecureSettings() throws Exception {
final Path configPath = env.configFile();
final SecureString seed;
try (KeyStoreWrapper keyStoreWrapper = KeyStoreWrapper.create()) {
seed = KeyStoreWrapper.SEED_SETTING.get(Settings.builder().setSecureSettings(keyStoreWrapper).build());
assertNotNull(seed);
assertTrue(seed.length() > 0);
keyStoreWrapper.save(configPath, new char[0]);
}
assertTrue(Files.exists(configPath.resolve("opensearch.keystore")));
try (SecureSettings secureSettings = Bootstrap.loadSecureSettings(env)) {
SecureString seedAfterLoad = KeyStoreWrapper.SEED_SETTING.get(Settings.builder().setSecureSettings(secureSettings).build());
assertEquals(seedAfterLoad.toString(), seed.toString());
assertTrue(Files.exists(configPath.resolve("opensearch.keystore")));
}
}
use of org.opensearch.common.settings.SecureSettings in project OpenSearch by opensearch-project.
the class Bootstrap method init.
/**
* This method is invoked by {@link OpenSearch#main(String[])} to startup opensearch.
*/
static void init(final boolean foreground, final Path pidFile, final boolean quiet, final Environment initialEnv) throws BootstrapException, NodeValidationException, UserException {
// force the class initializer for BootstrapInfo to run before
// the security manager is installed
BootstrapInfo.init();
INSTANCE = new Bootstrap();
final SecureSettings keystore = loadSecureSettings(initialEnv);
final Environment environment = createEnvironment(pidFile, keystore, initialEnv.settings(), initialEnv.configFile());
LogConfigurator.setNodeName(Node.NODE_NAME_SETTING.get(environment.settings()));
try {
LogConfigurator.configure(environment);
} catch (IOException e) {
throw new BootstrapException(e);
}
if (JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0) {
final String message = String.format(Locale.ROOT, "future versions of OpenSearch will require Java 11; " + "your Java version from [%s] does not meet this requirement", System.getProperty("java.home"));
DeprecationLogger.getLogger(Bootstrap.class).deprecate("java_version_11_required", message);
}
if (environment.pidFile() != null) {
try {
PidFile.create(environment.pidFile(), true);
} catch (IOException e) {
throw new BootstrapException(e);
}
}
final boolean closeStandardStreams = (foreground == false) || quiet;
try {
if (closeStandardStreams) {
final Logger rootLogger = LogManager.getRootLogger();
final Appender maybeConsoleAppender = Loggers.findAppender(rootLogger, ConsoleAppender.class);
if (maybeConsoleAppender != null) {
Loggers.removeAppender(rootLogger, maybeConsoleAppender);
}
closeSystOut();
}
// fail if somebody replaced the lucene jars
checkLucene();
// install the default uncaught exception handler; must be done before security is
// initialized as we do not want to grant the runtime permission
// setDefaultUncaughtExceptionHandler
Thread.setDefaultUncaughtExceptionHandler(new OpenSearchUncaughtExceptionHandler());
INSTANCE.setup(true, environment);
try {
// any secure settings must be read during node construction
IOUtils.close(keystore);
} catch (IOException e) {
throw new BootstrapException(e);
}
INSTANCE.start();
// startup errors via journalctl.
if (foreground == false) {
closeSysError();
}
} catch (NodeValidationException | RuntimeException e) {
// disable console logging, so user does not see the exception twice (jvm will show it already)
final Logger rootLogger = LogManager.getRootLogger();
final Appender maybeConsoleAppender = Loggers.findAppender(rootLogger, ConsoleAppender.class);
if (foreground && maybeConsoleAppender != null) {
Loggers.removeAppender(rootLogger, maybeConsoleAppender);
}
Logger logger = LogManager.getLogger(Bootstrap.class);
// HACK, it sucks to do this, but we will run users out of disk space otherwise
if (e instanceof CreationException) {
// guice: log the shortened exc to the log file
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream ps = null;
try {
ps = new PrintStream(os, false, "UTF-8");
} catch (UnsupportedEncodingException uee) {
assert false;
e.addSuppressed(uee);
}
new StartupException(e).printStackTrace(ps);
ps.flush();
try {
logger.error("Guice Exception: {}", os.toString("UTF-8"));
} catch (UnsupportedEncodingException uee) {
assert false;
e.addSuppressed(uee);
}
} else if (e instanceof NodeValidationException) {
logger.error("node validation exception\n{}", e.getMessage());
} else {
// full exception
logger.error("Exception", e);
}
// re-enable it if appropriate, so they can see any logging during the shutdown process
if (foreground && maybeConsoleAppender != null) {
Loggers.addAppender(rootLogger, maybeConsoleAppender);
}
throw e;
}
}
use of org.opensearch.common.settings.SecureSettings in project OpenSearch by opensearch-project.
the class ReloadSecureSettingsIT method testReloadWhileKeystoreChanged.
public void testReloadWhileKeystoreChanged() throws Exception {
final PluginsService pluginsService = internalCluster().getInstance(PluginsService.class);
final MockReloadablePlugin mockReloadablePlugin = pluginsService.filterPlugins(MockReloadablePlugin.class).stream().findFirst().get();
final Environment environment = internalCluster().getInstance(Environment.class);
final int initialReloadCount = mockReloadablePlugin.getReloadCount();
for (int i = 0; i < randomIntBetween(4, 8); i++) {
// write keystore
final SecureSettings secureSettings = writeEmptyKeystore(environment, new char[0]);
// read seed setting value from the test case (not from the node)
final String seedValue = KeyStoreWrapper.SEED_SETTING.get(Settings.builder().put(environment.settings()).setSecureSettings(secureSettings).build()).toString();
// reload call
successfulReloadCall();
assertThat(mockReloadablePlugin.getSeedValue(), equalTo(seedValue));
assertThat(mockReloadablePlugin.getReloadCount() - initialReloadCount, equalTo(i + 1));
}
}
use of org.opensearch.common.settings.SecureSettings in project OpenSearch by opensearch-project.
the class ReloadSecureSettingsIT method testMisbehavingPlugin.
public void testMisbehavingPlugin() throws Exception {
final Environment environment = internalCluster().getInstance(Environment.class);
final PluginsService pluginsService = internalCluster().getInstance(PluginsService.class);
final MockReloadablePlugin mockReloadablePlugin = pluginsService.filterPlugins(MockReloadablePlugin.class).stream().findFirst().get();
// make plugins throw on reload
for (final String nodeName : internalCluster().getNodeNames()) {
internalCluster().getInstance(PluginsService.class, nodeName).filterPlugins(MisbehavingReloadablePlugin.class).stream().findFirst().get().setShouldThrow(true);
}
final AtomicReference<AssertionError> reloadSettingsError = new AtomicReference<>();
final int initialReloadCount = mockReloadablePlugin.getReloadCount();
// "some" keystore should be present
final SecureSettings secureSettings = writeEmptyKeystore(environment, new char[0]);
// read seed setting value from the test case (not from the node)
final String seedValue = KeyStoreWrapper.SEED_SETTING.get(Settings.builder().put(environment.settings()).setSecureSettings(secureSettings).build()).toString();
final CountDownLatch latch = new CountDownLatch(1);
final SecureString emptyPassword = randomBoolean() ? new SecureString(new char[0]) : null;
client().admin().cluster().prepareReloadSecureSettings().setSecureStorePassword(emptyPassword).setNodesIds(Strings.EMPTY_ARRAY).execute(new ActionListener<NodesReloadSecureSettingsResponse>() {
@Override
public void onResponse(NodesReloadSecureSettingsResponse nodesReloadResponse) {
try {
assertThat(nodesReloadResponse, notNullValue());
final Map<String, NodesReloadSecureSettingsResponse.NodeResponse> nodesMap = nodesReloadResponse.getNodesMap();
assertThat(nodesMap.size(), equalTo(cluster().size()));
for (final NodesReloadSecureSettingsResponse.NodeResponse nodeResponse : nodesReloadResponse.getNodes()) {
assertThat(nodeResponse.reloadException(), notNullValue());
assertThat(nodeResponse.reloadException().getMessage(), containsString("If shouldThrow I throw"));
}
} catch (final AssertionError e) {
reloadSettingsError.set(e);
} finally {
latch.countDown();
}
}
@Override
public void onFailure(Exception e) {
reloadSettingsError.set(new AssertionError("Nodes request failed", e));
latch.countDown();
}
});
latch.await();
if (reloadSettingsError.get() != null) {
throw reloadSettingsError.get();
}
// even if one plugin fails to reload (throws Exception), others should be
// unperturbed
assertThat(mockReloadablePlugin.getReloadCount() - initialReloadCount, equalTo(1));
// mock plugin should have been reloaded successfully
assertThat(mockReloadablePlugin.getSeedValue(), equalTo(seedValue));
}
use of org.opensearch.common.settings.SecureSettings in project OpenSearch by opensearch-project.
the class InternalTestCluster method buildNode.
/**
* builds a new node
*
* @param nodeId node ordinal
* @param settings the settings to use
* @param reuseExisting if a node with the same name is already part of {@link #nodes}, no new node will be built and
* the method will return the existing one
* @param onTransportServiceStarted callback to run when transport service is started
*/
private synchronized NodeAndClient buildNode(int nodeId, Settings settings, boolean reuseExisting, Runnable onTransportServiceStarted) {
assert Thread.holdsLock(this);
ensureOpen();
Collection<Class<? extends Plugin>> plugins = getPlugins();
String name = settings.get("node.name");
final NodeAndClient nodeAndClient = nodes.get(name);
if (reuseExisting && nodeAndClient != null) {
// reusing an existing node implies its transport service already started
onTransportServiceStarted.run();
return nodeAndClient;
}
assert reuseExisting || nodeAndClient == null : "node name [" + name + "] already exists but not allowed to use it";
SecureSettings secureSettings = Settings.builder().put(settings).getSecureSettings();
if (secureSettings instanceof MockSecureSettings) {
// we clone this here since in the case of a node restart we might need it again
secureSettings = ((MockSecureSettings) secureSettings).clone();
}
MockNode node = new MockNode(settings, plugins, nodeConfigurationSource.nodeConfigPath(nodeId), forbidPrivateIndexSettings);
node.injector().getInstance(TransportService.class).addLifecycleListener(new LifecycleListener() {
@Override
public void afterStart() {
onTransportServiceStarted.run();
}
});
try {
IOUtils.close(secureSettings);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return new NodeAndClient(name, node, settings, nodeId);
}
Aggregations