mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-24 17:09:48 +00:00
Create keystore on package install (#28928)
This commit removes the ability to specify that a plugin requires the keystore and instead creates the keystore on package installation or when Elasticsearch is started for the first time. The reason that we opt to create the keystore on package installation is to ensure that the keystore has the correct permissions (the package installation scripts run as root as opposed to Elasticsearch running as the elasticsearch user) and to enable removing the keystore on package removal if the keystore is not modified.
This commit is contained in:
parent
a7b53fd3b7
commit
6331bcaf76
@ -43,6 +43,3 @@ extended.plugins=${extendedPlugins}
|
||||
#
|
||||
# 'has.native.controller': whether or not the plugin has a native controller
|
||||
has.native.controller=${hasNativeController}
|
||||
#
|
||||
# 'requires.keystore': whether or not the plugin needs the elasticsearch keystore be created
|
||||
requires.keystore=${requiresKeystore}
|
||||
|
@ -104,11 +104,18 @@ chmod g+s /etc/elasticsearch
|
||||
chmod 0750 /etc/elasticsearch
|
||||
|
||||
if [ -f /etc/default/elasticsearch ]; then
|
||||
chown root:elasticsearch /etc/default/elasticsearch
|
||||
chown root:elasticsearch /etc/default/elasticsearch
|
||||
fi
|
||||
|
||||
if [ -f /etc/sysconfig/elasticsearch ]; then
|
||||
chown root:elasticsearch /etc/sysconfig/elasticsearch
|
||||
chown root:elasticsearch /etc/sysconfig/elasticsearch
|
||||
fi
|
||||
|
||||
if [ ! -f "$ES_PATH_CONF"/elasticsearch.keystore ]; then
|
||||
/usr/share/elasticsearch/bin/elasticsearch-keystore create
|
||||
chown root:elasticsearch "$ES_PATH_CONF"/elasticsearch.keystore
|
||||
chmod 660 "$ES_PATH_CONF"/elasticsearch.keystore
|
||||
md5sum "$ES_PATH_CONF"/elasticsearch.keystore > "$ES_PATH_CONF"/.elasticsearch.keystore.initial_md5sum
|
||||
fi
|
||||
|
||||
${scripts.footer}
|
||||
|
@ -44,6 +44,11 @@ case "$1" in
|
||||
;;
|
||||
esac
|
||||
|
||||
ES_ENV_FILE="${path.env}"
|
||||
if [ -f "$ES_ENV_FILE" ]; then
|
||||
. "$ES_ENV_FILE"
|
||||
fi
|
||||
|
||||
# Stops the service
|
||||
if [ "$STOP_REQUIRED" = "true" ]; then
|
||||
echo -n "Stopping elasticsearch service..."
|
||||
@ -67,6 +72,12 @@ if [ "$STOP_REQUIRED" = "true" ]; then
|
||||
echo " OK"
|
||||
fi
|
||||
|
||||
if [ -f "$ES_PATH_CONF"/elasticsearch.keystore ]; then
|
||||
if md5sum --status -c "$ES_PATH_CONF"/.elasticsearch.keystore.initial_md5sum; then
|
||||
rm "$ES_PATH_CONF"/elasticsearch.keystore "$ES_PATH_CONF"/.elasticsearch.keystore.initial_md5sum
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$REMOVE_SERVICE" = "true" ]; then
|
||||
if command -v systemctl >/dev/null; then
|
||||
systemctl disable elasticsearch.service > /dev/null 2>&1 || true
|
||||
|
@ -686,12 +686,6 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
||||
}
|
||||
}
|
||||
movePlugin(tmpRoot, destination);
|
||||
for (PluginInfo info : pluginInfos) {
|
||||
if (info.requiresKeystore()) {
|
||||
createKeystoreIfNeeded(terminal, env, info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
String[] plugins = pluginInfos.stream().map(PluginInfo::getName).toArray(String[]::new);
|
||||
terminal.println("-> Installed " + metaInfo.getName() + " with: " + Strings.arrayToCommaDelimitedString(plugins));
|
||||
}
|
||||
@ -716,9 +710,6 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
||||
installPluginSupportFiles(info, tmpRoot, env.binFile().resolve(info.getName()),
|
||||
env.configFile().resolve(info.getName()), deleteOnFailure);
|
||||
movePlugin(tmpRoot, destination);
|
||||
if (info.requiresKeystore()) {
|
||||
createKeystoreIfNeeded(terminal, env, info);
|
||||
}
|
||||
terminal.println("-> Installed " + info.getName());
|
||||
}
|
||||
|
||||
@ -824,15 +815,6 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
|
||||
IOUtils.rm(tmpConfigDir); // clean up what we just copied
|
||||
}
|
||||
|
||||
private void createKeystoreIfNeeded(Terminal terminal, Environment env, PluginInfo info) throws Exception {
|
||||
KeyStoreWrapper keystore = KeyStoreWrapper.load(env.configFile());
|
||||
if (keystore == null) {
|
||||
terminal.println("Elasticsearch keystore is required by plugin [" + info.getName() + "], creating...");
|
||||
keystore = KeyStoreWrapper.create();
|
||||
keystore.save(env.configFile(), new char[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setOwnerGroup(final Path path, final PosixFileAttributes attributes) throws IOException {
|
||||
Objects.requireNonNull(attributes);
|
||||
PosixFileAttributeView fileAttributeView = Files.getFileAttributeView(path, PosixFileAttributeView.class);
|
||||
|
@ -1140,45 +1140,6 @@ public class InstallPluginCommandTests extends ESTestCase {
|
||||
assertTrue(e.getMessage(), e.getMessage().contains("SHA-1 mismatch, expected foobar"));
|
||||
}
|
||||
|
||||
public void testKeystoreNotRequired() throws Exception {
|
||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||
Path pluginDir = createPluginDir(temp);
|
||||
String pluginZip = createPluginUrl("fake", pluginDir, "requires.keystore", "false");
|
||||
installPlugin(pluginZip, env.v1());
|
||||
assertFalse(Files.exists(KeyStoreWrapper.keystorePath(env.v2().configFile())));
|
||||
}
|
||||
|
||||
public void testKeystoreRequiredAlreadyExists() throws Exception {
|
||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||
KeyStoreWrapper keystore = KeyStoreWrapper.create();
|
||||
keystore.save(env.v2().configFile(), new char[0]);
|
||||
byte[] expectedBytes = Files.readAllBytes(KeyStoreWrapper.keystorePath(env.v2().configFile()));
|
||||
Path pluginDir = createPluginDir(temp);
|
||||
String pluginZip = createPluginUrl("fake", pluginDir, "requires.keystore", "true");
|
||||
installPlugin(pluginZip, env.v1());
|
||||
byte[] gotBytes = Files.readAllBytes(KeyStoreWrapper.keystorePath(env.v2().configFile()));
|
||||
assertArrayEquals("Keystore was modified", expectedBytes, gotBytes);
|
||||
}
|
||||
|
||||
public void testKeystoreRequiredCreated() throws Exception {
|
||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||
Path pluginDir = createPluginDir(temp);
|
||||
String pluginZip = createPluginUrl("fake", pluginDir, "requires.keystore", "true");
|
||||
installPlugin(pluginZip, env.v1());
|
||||
assertTrue(Files.exists(KeyStoreWrapper.keystorePath(env.v2().configFile())));
|
||||
}
|
||||
|
||||
public void testKeystoreRequiredCreatedWithMetaPlugin() throws Exception {
|
||||
Tuple<Path, Environment> env = createEnv(fs, temp);
|
||||
Path metaDir = createPluginDir(temp);
|
||||
Path pluginDir = metaDir.resolve("fake");
|
||||
Files.createDirectory(pluginDir);
|
||||
writePlugin("fake", pluginDir, "requires.keystore", "true");
|
||||
String metaZip = createMetaPluginUrl("my_plugins", metaDir);
|
||||
installPlugin(metaZip, env.v1());
|
||||
assertTrue(Files.exists(KeyStoreWrapper.keystorePath(env.v2().configFile())));
|
||||
}
|
||||
|
||||
private Function<byte[], String> checksum(final MessageDigest digest) {
|
||||
return checksumAndString(digest, "");
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -93,7 +92,7 @@ public class ListPluginsCommandTests extends ESTestCase {
|
||||
final String description,
|
||||
final String name,
|
||||
final String classname) throws IOException {
|
||||
buildFakePlugin(env, null, description, name, classname, false, false);
|
||||
buildFakePlugin(env, null, description, name, classname, false);
|
||||
}
|
||||
|
||||
private static void buildFakePlugin(
|
||||
@ -102,17 +101,16 @@ public class ListPluginsCommandTests extends ESTestCase {
|
||||
final String description,
|
||||
final String name,
|
||||
final String classname) throws IOException {
|
||||
buildFakePlugin(env, metaPlugin, description, name, classname, false, false);
|
||||
buildFakePlugin(env, metaPlugin, description, name, classname, false);
|
||||
}
|
||||
|
||||
private static void buildFakePlugin(
|
||||
final Environment env,
|
||||
final String description,
|
||||
final String name,
|
||||
final String classname,
|
||||
final boolean hasNativeController,
|
||||
final boolean requiresKeystore) throws IOException {
|
||||
buildFakePlugin(env, null, description, name, classname, hasNativeController, requiresKeystore);
|
||||
final Environment env,
|
||||
final String description,
|
||||
final String name,
|
||||
final String classname,
|
||||
final boolean hasNativeController) throws IOException {
|
||||
buildFakePlugin(env, null, description, name, classname, hasNativeController);
|
||||
}
|
||||
|
||||
private static void buildFakePlugin(
|
||||
@ -121,8 +119,7 @@ public class ListPluginsCommandTests extends ESTestCase {
|
||||
final String description,
|
||||
final String name,
|
||||
final String classname,
|
||||
final boolean hasNativeController,
|
||||
final boolean requiresKeystore) throws IOException {
|
||||
final boolean hasNativeController) throws IOException {
|
||||
Path dest = metaPlugin != null ? env.pluginsFile().resolve(metaPlugin) : env.pluginsFile();
|
||||
PluginTestUtil.writePluginProperties(
|
||||
dest.resolve(name),
|
||||
@ -132,8 +129,7 @@ public class ListPluginsCommandTests extends ESTestCase {
|
||||
"elasticsearch.version", Version.CURRENT.toString(),
|
||||
"java.version", "1.8",
|
||||
"classname", classname,
|
||||
"has.native.controller", Boolean.toString(hasNativeController),
|
||||
"requires.keystore", Boolean.toString(requiresKeystore));
|
||||
"has.native.controller", Boolean.toString(hasNativeController));
|
||||
}
|
||||
|
||||
private static void buildFakeMetaPlugin(
|
||||
@ -195,14 +191,13 @@ public class ListPluginsCommandTests extends ESTestCase {
|
||||
"Elasticsearch Version: " + Version.CURRENT.toString(),
|
||||
"Java Version: 1.8",
|
||||
"Native Controller: false",
|
||||
"Requires Keystore: false",
|
||||
"Extended Plugins: []",
|
||||
" * Classname: org.fake"),
|
||||
terminal.getOutput());
|
||||
}
|
||||
|
||||
public void testPluginWithNativeController() throws Exception {
|
||||
buildFakePlugin(env, "fake desc 1", "fake_plugin1", "org.fake", true, false);
|
||||
buildFakePlugin(env, "fake desc 1", "fake_plugin1", "org.fake", true);
|
||||
String[] params = { "-v" };
|
||||
MockTerminal terminal = listPlugins(home, params);
|
||||
assertEquals(
|
||||
@ -216,28 +211,6 @@ public class ListPluginsCommandTests extends ESTestCase {
|
||||
"Elasticsearch Version: " + Version.CURRENT.toString(),
|
||||
"Java Version: 1.8",
|
||||
"Native Controller: true",
|
||||
"Requires Keystore: false",
|
||||
"Extended Plugins: []",
|
||||
" * Classname: org.fake"),
|
||||
terminal.getOutput());
|
||||
}
|
||||
|
||||
public void testPluginWithRequiresKeystore() throws Exception {
|
||||
buildFakePlugin(env, "fake desc 1", "fake_plugin1", "org.fake", false, true);
|
||||
String[] params = { "-v" };
|
||||
MockTerminal terminal = listPlugins(home, params);
|
||||
assertEquals(
|
||||
buildMultiline(
|
||||
"Plugins directory: " + env.pluginsFile(),
|
||||
"fake_plugin1",
|
||||
"- Plugin information:",
|
||||
"Name: fake_plugin1",
|
||||
"Description: fake desc 1",
|
||||
"Version: 1.0",
|
||||
"Elasticsearch Version: " + Version.CURRENT.toString(),
|
||||
"Java Version: 1.8",
|
||||
"Native Controller: false",
|
||||
"Requires Keystore: true",
|
||||
"Extended Plugins: []",
|
||||
" * Classname: org.fake"),
|
||||
terminal.getOutput());
|
||||
@ -259,7 +232,6 @@ public class ListPluginsCommandTests extends ESTestCase {
|
||||
"Elasticsearch Version: " + Version.CURRENT.toString(),
|
||||
"Java Version: 1.8",
|
||||
"Native Controller: false",
|
||||
"Requires Keystore: false",
|
||||
"Extended Plugins: []",
|
||||
" * Classname: org.fake",
|
||||
"fake_plugin2",
|
||||
@ -270,7 +242,6 @@ public class ListPluginsCommandTests extends ESTestCase {
|
||||
"Elasticsearch Version: " + Version.CURRENT.toString(),
|
||||
"Java Version: 1.8",
|
||||
"Native Controller: false",
|
||||
"Requires Keystore: false",
|
||||
"Extended Plugins: []",
|
||||
" * Classname: org.fake2"),
|
||||
terminal.getOutput());
|
||||
@ -294,7 +265,6 @@ public class ListPluginsCommandTests extends ESTestCase {
|
||||
"\tElasticsearch Version: " + Version.CURRENT.toString(),
|
||||
"\tJava Version: 1.8",
|
||||
"\tNative Controller: false",
|
||||
"\tRequires Keystore: false",
|
||||
"\tExtended Plugins: []",
|
||||
"\t * Classname: org.fake",
|
||||
"\tfake_plugin2",
|
||||
@ -305,7 +275,6 @@ public class ListPluginsCommandTests extends ESTestCase {
|
||||
"\tElasticsearch Version: " + Version.CURRENT.toString(),
|
||||
"\tJava Version: 1.8",
|
||||
"\tNative Controller: false",
|
||||
"\tRequires Keystore: false",
|
||||
"\tExtended Plugins: []",
|
||||
"\t * Classname: org.fake2"),
|
||||
terminal.getOutput());
|
||||
|
@ -100,6 +100,14 @@ setup() {
|
||||
}
|
||||
}
|
||||
|
||||
@test "[TAR] test creating elasticearch.keystore" {
|
||||
sudo -E -u elasticsearch "$ESHOME/bin/elasticsearch-keystore" create
|
||||
assert_file "$ESCONFIG/elasticsearch.keystore" f elasticsearch elasticsearch 660
|
||||
sudo -E -u elasticsearch "$ESHOME/bin/elasticsearch-keystore" list | grep "keystore.seed"
|
||||
# cleanup for the next test
|
||||
rm -rf "$ESCONFIG/elasticsearch.keystore"
|
||||
}
|
||||
|
||||
##################################
|
||||
# Check that Elasticsearch is working
|
||||
##################################
|
||||
@ -109,6 +117,13 @@ setup() {
|
||||
stop_elasticsearch_service
|
||||
}
|
||||
|
||||
@test "[TAR] test auto-creating elasticearch.keystore" {
|
||||
# a keystore should automatically be created after the service is started
|
||||
assert_file "$ESCONFIG/elasticsearch.keystore" f elasticsearch elasticsearch 660
|
||||
# the keystore should be seeded
|
||||
sudo -E -u elasticsearch "$ESHOME/bin/elasticsearch-keystore" list | grep "keystore.seed"
|
||||
}
|
||||
|
||||
@test "[TAR] start Elasticsearch with custom JVM options" {
|
||||
local es_java_opts=$ES_JAVA_OPTS
|
||||
local es_path_conf=$ES_PATH_CONF
|
||||
|
@ -149,6 +149,9 @@ setup() {
|
||||
|
||||
# The configuration files are still here
|
||||
assert_file_exist "/etc/elasticsearch"
|
||||
# TODO: use ucf to handle these better for Debian-based systems
|
||||
assert_file_not_exist "/etc/elasticsearch/elasticsearch.keystore"
|
||||
assert_file_not_exist "/etc/elasticsearch/.elasticsearch.keystore.initial_md5sum"
|
||||
assert_file_exist "/etc/elasticsearch/elasticsearch.yml"
|
||||
assert_file_exist "/etc/elasticsearch/jvm.options"
|
||||
assert_file_exist "/etc/elasticsearch/log4j2.properties"
|
||||
@ -170,6 +173,8 @@ setup() {
|
||||
@test "[DEB] verify package purge" {
|
||||
# all remaining files are deleted by the purge
|
||||
assert_file_not_exist "/etc/elasticsearch"
|
||||
assert_file_not_exist "/etc/elasticsearch/elasticsearch.keystore"
|
||||
assert_file_not_exist "/etc/elasticsearch/.elasticsearch.keystore.initial_md5sum"
|
||||
assert_file_not_exist "/etc/elasticsearch/elasticsearch.yml"
|
||||
assert_file_not_exist "/etc/elasticsearch/jvm.options"
|
||||
assert_file_not_exist "/etc/elasticsearch/log4j2.properties"
|
||||
|
@ -155,6 +155,7 @@ setup() {
|
||||
}
|
||||
|
||||
@test "[RPM] reremove package" {
|
||||
echo foobar | "$ESHOME/bin/elasticsearch-keystore" add --stdin foo.bar
|
||||
echo "# ping" >> "/etc/elasticsearch/elasticsearch.yml"
|
||||
echo "# ping" >> "/etc/elasticsearch/jvm.options"
|
||||
echo "# ping" >> "/etc/elasticsearch/log4j2.properties"
|
||||
@ -181,6 +182,7 @@ setup() {
|
||||
assert_file_not_exist "/usr/share/elasticsearch/modules"
|
||||
assert_file_not_exist "/usr/share/elasticsearch/modules/lang-painless"
|
||||
|
||||
assert_file_exist "/etc/elasticsearch/elasticsearch.keystore"
|
||||
assert_file_not_exist "/etc/elasticsearch/elasticsearch.yml"
|
||||
assert_file_exist "/etc/elasticsearch/elasticsearch.yml.rpmsave"
|
||||
assert_file_not_exist "/etc/elasticsearch/jvm.options"
|
||||
|
@ -95,6 +95,11 @@ verify_package_installation() {
|
||||
assert_file "$ESHOME/bin/elasticsearch-translog" f root root 755
|
||||
assert_file "$ESHOME/lib" d root root 755
|
||||
assert_file "$ESCONFIG" d root elasticsearch 2750
|
||||
assert_file "$ESCONFIG/elasticsearch.keystore" f root elasticsearch 660
|
||||
|
||||
sudo -u elasticsearch "$ESHOME/bin/elasticsearch-keystore" list | grep "keystore.seed"
|
||||
|
||||
assert_file "$ESCONFIG/.elasticsearch.keystore.initial_md5sum" f root elasticsearch 644
|
||||
assert_file "$ESCONFIG/elasticsearch.yml" f root elasticsearch 660
|
||||
assert_file "$ESCONFIG/jvm.options" f root elasticsearch 660
|
||||
assert_file "$ESCONFIG/log4j2.properties" f root elasticsearch 660
|
||||
|
@ -101,4 +101,5 @@ verify_archive_installation() {
|
||||
assert_file "$ESHOME/NOTICE.txt" f elasticsearch elasticsearch 644
|
||||
assert_file "$ESHOME/LICENSE.txt" f elasticsearch elasticsearch 644
|
||||
assert_file "$ESHOME/README.textile" f elasticsearch elasticsearch 644
|
||||
assert_file_not_exist "$ESCONFIG/elasticsearch.keystore"
|
||||
}
|
||||
|
@ -226,13 +226,16 @@ final class Bootstrap {
|
||||
} catch (IOException e) {
|
||||
throw new BootstrapException(e);
|
||||
}
|
||||
if (keystore == null) {
|
||||
return null; // no keystore
|
||||
}
|
||||
|
||||
try {
|
||||
keystore.decrypt(new char[0] /* TODO: read password from stdin */);
|
||||
KeyStoreWrapper.upgrade(keystore, initialEnv.configFile(), new char[0]);
|
||||
if (keystore == null) {
|
||||
final KeyStoreWrapper keyStoreWrapper = KeyStoreWrapper.create();
|
||||
keyStoreWrapper.save(initialEnv.configFile(), new char[0]);
|
||||
return keyStoreWrapper;
|
||||
} else {
|
||||
keystore.decrypt(new char[0] /* TODO: read password from stdin */);
|
||||
KeyStoreWrapper.upgrade(keystore, initialEnv.configFile(), new char[0]);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new BootstrapException(e);
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import org.elasticsearch.Version;
|
||||
import org.elasticsearch.bootstrap.JarHell;
|
||||
import org.elasticsearch.common.Booleans;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.io.FileSystemUtils;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
@ -32,18 +31,14 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -63,7 +58,6 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
||||
private final String classname;
|
||||
private final List<String> extendedPlugins;
|
||||
private final boolean hasNativeController;
|
||||
private final boolean requiresKeystore;
|
||||
|
||||
/**
|
||||
* Construct plugin info.
|
||||
@ -76,10 +70,9 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
||||
* @param classname the entry point to the plugin
|
||||
* @param extendedPlugins other plugins this plugin extends through SPI
|
||||
* @param hasNativeController whether or not the plugin has a native controller
|
||||
* @param requiresKeystore whether or not the plugin requires the elasticsearch keystore to be created
|
||||
*/
|
||||
public PluginInfo(String name, String description, String version, Version elasticsearchVersion, String javaVersion,
|
||||
String classname, List<String> extendedPlugins, boolean hasNativeController, boolean requiresKeystore) {
|
||||
String classname, List<String> extendedPlugins, boolean hasNativeController) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.version = version;
|
||||
@ -88,7 +81,6 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
||||
this.classname = classname;
|
||||
this.extendedPlugins = Collections.unmodifiableList(extendedPlugins);
|
||||
this.hasNativeController = hasNativeController;
|
||||
this.requiresKeystore = requiresKeystore;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,10 +113,12 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
||||
} else {
|
||||
hasNativeController = false;
|
||||
}
|
||||
if (in.getVersion().onOrAfter(Version.V_6_0_0_beta2)) {
|
||||
requiresKeystore = in.readBoolean();
|
||||
} else {
|
||||
requiresKeystore = false;
|
||||
if (in.getVersion().onOrAfter(Version.V_6_0_0_beta2) && in.getVersion().before(Version.V_7_0_0_alpha1)) {
|
||||
/*
|
||||
* Elasticsearch versions in [6.0.0-beta2, 7.0.0) allowed plugins to specify that they require the keystore and this was
|
||||
* serialized into the plugin info. Therefore, we have to read and ignore this value from the stream.
|
||||
*/
|
||||
in.readBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,8 +138,12 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
||||
if (out.getVersion().onOrAfter(Version.V_5_4_0)) {
|
||||
out.writeBoolean(hasNativeController);
|
||||
}
|
||||
if (out.getVersion().onOrAfter(Version.V_6_0_0_beta2)) {
|
||||
out.writeBoolean(requiresKeystore);
|
||||
if (out.getVersion().onOrAfter(Version.V_6_0_0_beta2) && out.getVersion().before(Version.V_7_0_0_alpha1)) {
|
||||
/*
|
||||
* Elasticsearch versions in [6.0.0-beta2, 7.0.0) allowed plugins to specify that they require the keystore and this was
|
||||
* serialized into the plugin info. Therefore, we have to write out a value for this boolean.
|
||||
*/
|
||||
out.writeBoolean(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,16 +232,8 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
||||
}
|
||||
}
|
||||
|
||||
String requiresKeystoreValue = propsMap.remove("requires.keystore");
|
||||
if (requiresKeystoreValue == null) {
|
||||
requiresKeystoreValue = "false";
|
||||
}
|
||||
final boolean requiresKeystore;
|
||||
try {
|
||||
requiresKeystore = Booleans.parseBoolean(requiresKeystoreValue);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IllegalArgumentException("property [requires.keystore] must be [true] or [false]," +
|
||||
" but was [" + requiresKeystoreValue + "]", e);
|
||||
if (esVersion.before(Version.V_6_3_0) && esVersion.onOrAfter(Version.V_6_0_0_beta2)) {
|
||||
propsMap.remove("requires.keystore");
|
||||
}
|
||||
|
||||
if (propsMap.isEmpty() == false) {
|
||||
@ -251,7 +241,7 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
||||
}
|
||||
|
||||
return new PluginInfo(name, description, version, esVersion, javaVersionString,
|
||||
classname, extendedPlugins, hasNativeController, requiresKeystore);
|
||||
classname, extendedPlugins, hasNativeController);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -326,15 +316,6 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
||||
return hasNativeController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the plugin requires the elasticsearch keystore to exist.
|
||||
*
|
||||
* @return {@code true} if the plugin requires a keystore, {@code false} otherwise
|
||||
*/
|
||||
public boolean requiresKeystore() {
|
||||
return requiresKeystore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
@ -347,7 +328,6 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
||||
builder.field("classname", classname);
|
||||
builder.field("extended_plugins", extendedPlugins);
|
||||
builder.field("has_native_controller", hasNativeController);
|
||||
builder.field("requires_keystore", requiresKeystore);
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
@ -387,7 +367,6 @@ public class PluginInfo implements Writeable, ToXContentObject {
|
||||
.append(prefix).append("Elasticsearch Version: ").append(elasticsearchVersion).append("\n")
|
||||
.append(prefix).append("Java Version: ").append(javaVersion).append("\n")
|
||||
.append(prefix).append("Native Controller: ").append(hasNativeController).append("\n")
|
||||
.append(prefix).append("Requires Keystore: ").append(requiresKeystore).append("\n")
|
||||
.append(prefix).append("Extended Plugins: ").append(extendedPlugins).append("\n")
|
||||
.append(prefix).append(" * Classname: ").append(classname);
|
||||
return information.toString();
|
||||
|
@ -110,7 +110,7 @@ public class PluginsService extends AbstractComponent {
|
||||
for (Class<? extends Plugin> pluginClass : classpathPlugins) {
|
||||
Plugin plugin = loadPlugin(pluginClass, settings, configPath);
|
||||
PluginInfo pluginInfo = new PluginInfo(pluginClass.getName(), "classpath plugin", "NA", Version.CURRENT, "1.8",
|
||||
pluginClass.getName(), Collections.emptyList(), false, false);
|
||||
pluginClass.getName(), Collections.emptyList(), false);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("plugin loaded from classpath [{}]", pluginInfo);
|
||||
}
|
||||
|
@ -145,14 +145,14 @@ public class NodeInfoStreamingTests extends ESTestCase {
|
||||
for (int i = 0; i < numPlugins; i++) {
|
||||
plugins.add(new PluginInfo(randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10),
|
||||
randomAlphaOfLengthBetween(3, 10), VersionUtils.randomVersion(random()), "1.8",
|
||||
randomAlphaOfLengthBetween(3, 10), Collections.emptyList(), randomBoolean(), randomBoolean()));
|
||||
randomAlphaOfLengthBetween(3, 10), Collections.emptyList(), randomBoolean()));
|
||||
}
|
||||
int numModules = randomIntBetween(0, 5);
|
||||
List<PluginInfo> modules = new ArrayList<>();
|
||||
for (int i = 0; i < numModules; i++) {
|
||||
modules.add(new PluginInfo(randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10),
|
||||
randomAlphaOfLengthBetween(3, 10), VersionUtils.randomVersion(random()), "1.8",
|
||||
randomAlphaOfLengthBetween(3, 10), Collections.emptyList(), randomBoolean(), randomBoolean()));
|
||||
randomAlphaOfLengthBetween(3, 10), Collections.emptyList(), randomBoolean()));
|
||||
}
|
||||
pluginsAndModules = new PluginsAndModules(plugins, modules);
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ public class PluginInfoTests extends ESTestCase {
|
||||
|
||||
public void testSerialize() throws Exception {
|
||||
PluginInfo info = new PluginInfo("c", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
|
||||
Collections.singletonList("foo"), randomBoolean(), randomBoolean());
|
||||
Collections.singletonList("foo"), randomBoolean());
|
||||
BytesStreamOutput output = new BytesStreamOutput();
|
||||
info.writeTo(output);
|
||||
ByteBuffer buffer = ByteBuffer.wrap(output.bytes().toBytesRef().bytes);
|
||||
@ -198,15 +198,15 @@ public class PluginInfoTests extends ESTestCase {
|
||||
public void testPluginListSorted() {
|
||||
List<PluginInfo> plugins = new ArrayList<>();
|
||||
plugins.add(new PluginInfo("c", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
|
||||
Collections.emptyList(), randomBoolean(), randomBoolean()));
|
||||
Collections.emptyList(), randomBoolean()));
|
||||
plugins.add(new PluginInfo("b", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
|
||||
Collections.emptyList(), randomBoolean(), randomBoolean()));
|
||||
Collections.emptyList(), randomBoolean()));
|
||||
plugins.add(new PluginInfo( "e", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
|
||||
Collections.emptyList(), randomBoolean(), randomBoolean()));
|
||||
Collections.emptyList(), randomBoolean()));
|
||||
plugins.add(new PluginInfo("a", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
|
||||
Collections.emptyList(), randomBoolean(), randomBoolean()));
|
||||
Collections.emptyList(), randomBoolean()));
|
||||
plugins.add(new PluginInfo("d", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass",
|
||||
Collections.emptyList(), randomBoolean(), randomBoolean()));
|
||||
Collections.emptyList(), randomBoolean()));
|
||||
PluginsAndModules pluginsInfo = new PluginsAndModules(plugins, Collections.emptyList());
|
||||
|
||||
final List<PluginInfo> infos = pluginsInfo.getPluginInfos();
|
||||
|
@ -283,7 +283,7 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
public void testSortBundlesCycleSelfReference() throws Exception {
|
||||
Path pluginDir = createTempDir();
|
||||
PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.singletonList("foo"), false, false);
|
||||
"MyPlugin", Collections.singletonList("foo"), false);
|
||||
PluginsService.Bundle bundle = new PluginsService.Bundle(info, pluginDir);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
PluginsService.sortBundles(Collections.singleton(bundle))
|
||||
@ -295,16 +295,16 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
Path pluginDir = createTempDir();
|
||||
Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order, so we get know the beginning of the cycle
|
||||
PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Arrays.asList("bar", "other"), false, false);
|
||||
"MyPlugin", Arrays.asList("bar", "other"), false);
|
||||
bundles.add(new PluginsService.Bundle(info, pluginDir));
|
||||
PluginInfo info2 = new PluginInfo("bar", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.singletonList("baz"), false, false);
|
||||
"MyPlugin", Collections.singletonList("baz"), false);
|
||||
bundles.add(new PluginsService.Bundle(info2, pluginDir));
|
||||
PluginInfo info3 = new PluginInfo("baz", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.singletonList("foo"), false, false);
|
||||
"MyPlugin", Collections.singletonList("foo"), false);
|
||||
bundles.add(new PluginsService.Bundle(info3, pluginDir));
|
||||
PluginInfo info4 = new PluginInfo("other", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.emptyList(), false, false);
|
||||
"MyPlugin", Collections.emptyList(), false);
|
||||
bundles.add(new PluginsService.Bundle(info4, pluginDir));
|
||||
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () -> PluginsService.sortBundles(bundles));
|
||||
@ -314,7 +314,7 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
public void testSortBundlesSingle() throws Exception {
|
||||
Path pluginDir = createTempDir();
|
||||
PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.emptyList(), false, false);
|
||||
"MyPlugin", Collections.emptyList(), false);
|
||||
PluginsService.Bundle bundle = new PluginsService.Bundle(info, pluginDir);
|
||||
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(Collections.singleton(bundle));
|
||||
assertThat(sortedBundles, Matchers.contains(bundle));
|
||||
@ -324,15 +324,15 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
Path pluginDir = createTempDir();
|
||||
Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order
|
||||
PluginInfo info1 = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.emptyList(), false, false);
|
||||
"MyPlugin", Collections.emptyList(), false);
|
||||
PluginsService.Bundle bundle1 = new PluginsService.Bundle(info1, pluginDir);
|
||||
bundles.add(bundle1);
|
||||
PluginInfo info2 = new PluginInfo("bar", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.emptyList(), false, false);
|
||||
"MyPlugin", Collections.emptyList(), false);
|
||||
PluginsService.Bundle bundle2 = new PluginsService.Bundle(info2, pluginDir);
|
||||
bundles.add(bundle2);
|
||||
PluginInfo info3 = new PluginInfo("baz", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.emptyList(), false, false);
|
||||
"MyPlugin", Collections.emptyList(), false);
|
||||
PluginsService.Bundle bundle3 = new PluginsService.Bundle(info3, pluginDir);
|
||||
bundles.add(bundle3);
|
||||
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles);
|
||||
@ -342,7 +342,7 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
public void testSortBundlesMissingDep() throws Exception {
|
||||
Path pluginDir = createTempDir();
|
||||
PluginInfo info = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.singletonList("dne"), false, false);
|
||||
"MyPlugin", Collections.singletonList("dne"), false);
|
||||
PluginsService.Bundle bundle = new PluginsService.Bundle(info, pluginDir);
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () ->
|
||||
PluginsService.sortBundles(Collections.singleton(bundle))
|
||||
@ -354,19 +354,19 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
Path pluginDir = createTempDir();
|
||||
Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order
|
||||
PluginInfo info1 = new PluginInfo("grandparent", "desc", "1.0",Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.emptyList(), false, false);
|
||||
"MyPlugin", Collections.emptyList(), false);
|
||||
PluginsService.Bundle bundle1 = new PluginsService.Bundle(info1, pluginDir);
|
||||
bundles.add(bundle1);
|
||||
PluginInfo info2 = new PluginInfo("foo", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.singletonList("common"), false, false);
|
||||
"MyPlugin", Collections.singletonList("common"), false);
|
||||
PluginsService.Bundle bundle2 = new PluginsService.Bundle(info2, pluginDir);
|
||||
bundles.add(bundle2);
|
||||
PluginInfo info3 = new PluginInfo("bar", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.singletonList("common"), false, false);
|
||||
"MyPlugin", Collections.singletonList("common"), false);
|
||||
PluginsService.Bundle bundle3 = new PluginsService.Bundle(info3, pluginDir);
|
||||
bundles.add(bundle3);
|
||||
PluginInfo info4 = new PluginInfo("common", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.singletonList("grandparent"), false, false);
|
||||
"MyPlugin", Collections.singletonList("grandparent"), false);
|
||||
PluginsService.Bundle bundle4 = new PluginsService.Bundle(info4, pluginDir);
|
||||
bundles.add(bundle4);
|
||||
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles);
|
||||
@ -377,11 +377,11 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
Path pluginDir = createTempDir();
|
||||
Set<PluginsService.Bundle> bundles = new LinkedHashSet<>(); // control iteration order
|
||||
PluginInfo info1 = new PluginInfo("dep", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.emptyList(), false, false);
|
||||
"MyPlugin", Collections.emptyList(), false);
|
||||
PluginsService.Bundle bundle1 = new PluginsService.Bundle(info1, pluginDir);
|
||||
bundles.add(bundle1);
|
||||
PluginInfo info2 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.singletonList("dep"), false, false);
|
||||
"MyPlugin", Collections.singletonList("dep"), false);
|
||||
PluginsService.Bundle bundle2 = new PluginsService.Bundle(info2, pluginDir);
|
||||
bundles.add(bundle2);
|
||||
List<PluginsService.Bundle> sortedBundles = PluginsService.sortBundles(bundles);
|
||||
@ -440,7 +440,7 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
Map<String, Set<URL>> transitiveDeps = new HashMap<>();
|
||||
transitiveDeps.put("dep", Collections.singleton(dupJar.toUri().toURL()));
|
||||
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.singletonList("dep"), false, false);
|
||||
"MyPlugin", Collections.singletonList("dep"), false);
|
||||
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
PluginsService.checkBundleJarHell(bundle, transitiveDeps));
|
||||
@ -459,7 +459,7 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
transitiveDeps.put("dep1", Collections.singleton(dupJar.toUri().toURL()));
|
||||
transitiveDeps.put("dep2", Collections.singleton(dupJar.toUri().toURL()));
|
||||
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Arrays.asList("dep1", "dep2"), false, false);
|
||||
"MyPlugin", Arrays.asList("dep1", "dep2"), false);
|
||||
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
PluginsService.checkBundleJarHell(bundle, transitiveDeps));
|
||||
@ -476,7 +476,7 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
Path pluginJar = pluginDir.resolve("plugin.jar");
|
||||
makeJar(pluginJar, Level.class);
|
||||
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.emptyList(), false, false);
|
||||
"MyPlugin", Collections.emptyList(), false);
|
||||
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
PluginsService.checkBundleJarHell(bundle, new HashMap<>()));
|
||||
@ -495,7 +495,7 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
Map<String, Set<URL>> transitiveDeps = new HashMap<>();
|
||||
transitiveDeps.put("dep", Collections.singleton(depJar.toUri().toURL()));
|
||||
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Collections.singletonList("dep"), false, false);
|
||||
"MyPlugin", Collections.singletonList("dep"), false);
|
||||
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
PluginsService.checkBundleJarHell(bundle, transitiveDeps));
|
||||
@ -518,7 +518,7 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
transitiveDeps.put("dep1", Collections.singleton(dep1Jar.toUri().toURL()));
|
||||
transitiveDeps.put("dep2", Collections.singleton(dep2Jar.toUri().toURL()));
|
||||
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Arrays.asList("dep1", "dep2"), false, false);
|
||||
"MyPlugin", Arrays.asList("dep1", "dep2"), false);
|
||||
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () ->
|
||||
PluginsService.checkBundleJarHell(bundle, transitiveDeps));
|
||||
@ -541,7 +541,7 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
transitiveDeps.put("dep1", Collections.singleton(dep1Jar.toUri().toURL()));
|
||||
transitiveDeps.put("dep2", Collections.singleton(dep2Jar.toUri().toURL()));
|
||||
PluginInfo info1 = new PluginInfo("myplugin", "desc", "1.0", Version.CURRENT, "1.8",
|
||||
"MyPlugin", Arrays.asList("dep1", "dep2"), false, false);
|
||||
"MyPlugin", Arrays.asList("dep1", "dep2"), false);
|
||||
PluginsService.Bundle bundle = new PluginsService.Bundle(info1, pluginDir);
|
||||
PluginsService.checkBundleJarHell(bundle, transitiveDeps);
|
||||
Set<URL> deps = transitiveDeps.get("myplugin");
|
||||
@ -590,14 +590,14 @@ public class PluginsServiceTests extends ESTestCase {
|
||||
|
||||
public void testIncompatibleElasticsearchVersion() throws Exception {
|
||||
PluginInfo info = new PluginInfo("my_plugin", "desc", "1.0", Version.V_5_0_0,
|
||||
"1.8", "FakePlugin", Collections.emptyList(), false, false);
|
||||
"1.8", "FakePlugin", Collections.emptyList(), false);
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> PluginsService.verifyCompatibility(info));
|
||||
assertThat(e.getMessage(), containsString("was built for Elasticsearch version 5.0.0"));
|
||||
}
|
||||
|
||||
public void testIncompatibleJavaVersion() throws Exception {
|
||||
PluginInfo info = new PluginInfo("my_plugin", "desc", "1.0", Version.CURRENT,
|
||||
"1000000.0", "FakePlugin", Collections.emptyList(), false, false);
|
||||
"1000000.0", "FakePlugin", Collections.emptyList(), false);
|
||||
IllegalStateException e = expectThrows(IllegalStateException.class, () -> PluginsService.verifyCompatibility(info));
|
||||
assertThat(e.getMessage(), containsString("my_plugin requires Java"));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user