Introduce unified entrypoint for CLI scripts (#85821)

CLI scripts have a common infrastructure in that they call to the shared
elasticsearch-cli shell script which launches them with the appropriate
java command line. However, each underlying Java class must implement
its own main method.

This commit introduces a single main method to be shared by CLIs. The
new CliToolLauncher takes in system properties to determine which tool
is being run, and a new CliToolProvider SPI allows defining and finding
the named tools.

relates #85758

Co-authored-by: William Brafford <william.brafford@elastic.co>
This commit is contained in:
Ryan Ernst 2022-04-14 08:53:36 -07:00 committed by GitHub
parent 7dee198ac7
commit 1d4534f848
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
99 changed files with 802 additions and 344 deletions

View file

@ -230,7 +230,7 @@ configure(subprojects.findAll { ['archives', 'packages'].contains(it.name) }) {
* Properties to expand when copying packaging files *
*****************************************************************************/
configurations {
['libs', 'libsLaunchers', 'libsVersionChecker', 'libsPluginCli', 'libsKeystoreCli', 'libsSecurityCli', 'libsGeoIpCli', 'libsAnsiConsole'].each {
['libs', 'libsLaunchers', 'libsVersionChecker', 'libsCliLauncher', 'libsPluginCli', 'libsKeystoreCli', 'libsSecurityCli', 'libsGeoIpCli', 'libsAnsiConsole'].each {
create(it) {
canBeConsumed = false
canBeResolved = true
@ -251,6 +251,7 @@ configure(subprojects.findAll { ['archives', 'packages'].contains(it.name) }) {
libs project(':server')
libsVersionChecker project(':distribution:tools:java-version-checker')
libsCliLauncher project(':distribution:tools:cli-launcher')
libsLaunchers project(':distribution:tools:launchers')
libsAnsiConsole project(':distribution:tools:ansi-console')
libsPluginCli project(':distribution:tools:plugin-cli')
@ -274,6 +275,9 @@ configure(subprojects.findAll { ['archives', 'packages'].contains(it.name) }) {
into('java-version-checker') {
from(configurations.libsVersionChecker)
}
into('cli-launcher') {
from(configurations.libsCliLauncher)
}
into('tools/geoip-cli') {
from(configurations.libsGeoIpCli)
}
@ -370,12 +374,7 @@ configure(subprojects.findAll { ['archives', 'packages'].contains(it.name) }) {
// module provided bin files
with copySpec {
eachFile { it.setMode(0755) }
if (testDistro == false) {
from(defaultBinFiles)
} else {
from(defaultBinFiles)
include 'x-pack-env', 'x-pack-security-env'
}
from(defaultBinFiles)
if (distributionType != 'zip') {
exclude '*.bat'
}

View file

@ -59,17 +59,15 @@ if [ "x$IS_UPGRADE" != "xtrue" ]; then
# Don't exit immediately on error, we want to hopefully print some helpful banners
set +e
# Attempt to auto-configure security, this seems to be an installation
if ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.AutoConfigureNode \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli \
if CLI_NAME="auto-configure-node" \
CLI_LIBS="modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli" \
/usr/share/elasticsearch/bin/elasticsearch-cli <<< ""; then
# Above command runs as root and TLS keystores are created group-owned by root. It's simple to correct the ownership here
chown root:elasticsearch "${ES_PATH_CONF}"/certs/http.p12
chown root:elasticsearch "${ES_PATH_CONF}"/certs/http_ca.crt
chown root:elasticsearch "${ES_PATH_CONF}"/certs/transport.p12
if INITIAL_PASSWORD=$(ES_MAIN_CLASS=org.elasticsearch.xpack.security.enrollment.tool.AutoConfigGenerateElasticPasswordHash \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli \
if INITIAL_PASSWORD=$(CLI_NAME=auto-config-gen-passwd \
CLI_LIBS="modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli" \
/usr/share/elasticsearch/bin/elasticsearch-cli); then
echo "--------------------------- Security autoconfiguration information ------------------------------"
echo

View file

@ -66,9 +66,8 @@ then
fi
if [[ $ENROLL_TO_CLUSTER = true ]]; then
ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.AutoConfigureNode \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli \
CLI_NAME="auto-configure-node" \
CLI_LIBS="modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli" \
bin/elasticsearch-cli "${ARG_LIST[@]}" <<<"$KEYSTORE_PASSWORD"
elif [[ $ATTEMPT_SECURITY_AUTO_CONFIG = true ]]; then
# It is possible that an auto-conf failure prevents the node from starting, but this is only the exceptional case (exit code 1).
@ -76,9 +75,8 @@ elif [[ $ATTEMPT_SECURITY_AUTO_CONFIG = true ]]; then
# if the error is uncommon or unexpected, but it should otherwise let the node to start as usual.
# It is passed in all the command line options in order to read the node settings ones (-E), while the other parameters are ignored
# (a small caveat is that it also inspects the -v option in order to provide more information on how auto config went)
if ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.AutoConfigureNode \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli \
if CLI_NAME="auto-configure-node" \
CLI_LIBS="modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli" \
bin/elasticsearch-cli "${ARG_LIST[@]}" <<<"$KEYSTORE_PASSWORD"; then
:
else

View file

@ -4,28 +4,21 @@ set -e -o pipefail
source "`dirname "$0"`"/elasticsearch-env
IFS=';' read -r -a additional_sources <<< "$ES_ADDITIONAL_SOURCES"
for additional_source in "${additional_sources[@]}"
do
source "$ES_HOME"/bin/$additional_source
done
IFS=';' read -r -a additional_classpath_directories <<< "$ES_ADDITIONAL_CLASSPATH_DIRECTORIES"
for additional_classpath_directory in "${additional_classpath_directories[@]}"
do
ES_CLASSPATH="$ES_CLASSPATH:$ES_HOME/$additional_classpath_directory/*"
done
# use a small heap size for the CLI tools, and thus the serial collector to
# avoid stealing many CPU cycles; a user can override by setting ES_JAVA_OPTS
ES_JAVA_OPTS="-Xms4m -Xmx64m -XX:+UseSerialGC ${ES_JAVA_OPTS}"
# avoid stealing many CPU cycles; a user can override by setting CLI_JAVA_OPTS
CLI_JAVA_OPTS="-Xms4m -Xmx64m -XX:+UseSerialGC ${CLI_JAVA_OPTS}"
LAUNCHER_CLASSPATH=$ES_HOME/lib/*:$ES_HOME/lib/cli-launcher/*
exec \
"$JAVA" \
$ES_JAVA_OPTS \
$CLI_JAVA_OPTS \
-Dcli.name="$CLI_NAME" \
-Dcli.script="$0" \
-Dcli.libs="$CLI_LIBS" \
-Des.path.home="$ES_HOME" \
-Des.path.conf="$ES_PATH_CONF" \
-Des.distribution.type="$ES_DISTRIBUTION_TYPE" \
-cp "$ES_CLASSPATH" \
"$ES_MAIN_CLASS" \
-cp "$LAUNCHER_CLASSPATH" \
org.elasticsearch.launcher.CliToolLauncher \
"$@"

View file

@ -1,28 +1,27 @@
@echo off
setlocal enabledelayedexpansion
call "%~dp0elasticsearch-env.bat" || exit /b 1
if defined ES_ADDITIONAL_SOURCES (
for %%a in ("%ES_ADDITIONAL_SOURCES:;=","%") do (
call "%~dp0%%a"
)
)
if defined ES_ADDITIONAL_CLASSPATH_DIRECTORIES (
for %%a in ("%ES_ADDITIONAL_CLASSPATH_DIRECTORIES:;=","%") do (
set ES_CLASSPATH=!ES_CLASSPATH!;!ES_HOME!/%%a/*
)
)
rem use a small heap size for the CLI tools, and thus the serial collector to
rem avoid stealing many CPU cycles; a user can override by setting ES_JAVA_OPTS
set ES_JAVA_OPTS=-Xms4m -Xmx64m -XX:+UseSerialGC %ES_JAVA_OPTS%
set LAUNCHER_CLASSPATH=%ES_HOME%/lib/*;%ES_HOME%/lib/cli-launcher/*
%JAVA% ^
%ES_JAVA_OPTS% ^
%CLI_JAVA_OPTS% ^
-Dcli.name="%CLI_NAME%" ^
-Dcli.script="%CLI_SCRIPT%" ^
-Dcli.libs="%CLI_LIBS%" ^
-Des.path.home="%ES_HOME%" ^
-Des.path.conf="%ES_PATH_CONF%" ^
-Des.distribution.type="%ES_DISTRIBUTION_TYPE%" ^
-cp "%ES_CLASSPATH%" ^
"%ES_MAIN_CLASS%" ^
-cp "%LAUNCHER_CLASSPATH%" ^
org.elasticsearch.launcher.CliToolLauncher ^
%*
exit /b %ERRORLEVEL%
endlocal

View file

@ -1,6 +1,4 @@
#!/bin/bash
ES_MAIN_CLASS=org.elasticsearch.geoip.GeoIpCli \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/geoip-cli \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS=lib/tools/geoip-cli
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -3,8 +3,8 @@
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.geoip.GeoIpCli
set ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/geoip-cli
set CLI_SCRIPT=%~0
set CLI_LIBS=lib/tools/geoip-cli
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -1,6 +1,4 @@
#!/bin/bash
ES_MAIN_CLASS=org.elasticsearch.cli.keystore.KeyStoreCli \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/keystore-cli \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS=lib/tools/keystore-cli
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -3,8 +3,8 @@
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.cli.keystore.KeyStoreCli
set ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/keystore-cli
set CLI_SCRIPT=%~0
set CLI_LIBS=lib/tools/keystore-cli
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -1,5 +1,3 @@
#!/bin/bash
ES_MAIN_CLASS=org.elasticsearch.cluster.coordination.NodeToolCli \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -3,7 +3,7 @@
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.cluster.coordination.NodeToolCli
set CLI_SCRIPT=%~0
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -1,7 +1,5 @@
#!/bin/bash
ES_JAVA_OPTS="--add-opens java.base/sun.security.provider=ALL-UNNAMED $ES_JAVA_OPTS" \
ES_MAIN_CLASS=org.elasticsearch.plugins.cli.PluginCli \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/plugin-cli \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_JAVA_OPTS="--add-opens java.base/sun.security.provider=ALL-UNNAMED $CLI_JAVA_OPTS"
CLI_LIBS=lib/tools/plugin-cli
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -3,13 +3,13 @@
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_JAVA_OPTS=--add-opens java.base/sun.security.provider=ALL-UNNAMED %ES_JAVA_OPTS%
set ES_MAIN_CLASS=org.elasticsearch.plugins.cli.PluginCli
set ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/plugin-cli
set CLI_JAVA_OPTS=--add-opens java.base/sun.security.provider=ALL-UNNAMED %CLI_JAVA_OPTS%
set CLI_SCRIPT=%~0
set CLI_LIBS=lib/tools/plugin-cli
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit
endlocal
endlocal

View file

@ -1,5 +1,3 @@
#!/bin/bash
ES_MAIN_CLASS=org.elasticsearch.index.shard.ShardToolCli \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -3,7 +3,7 @@
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.index.shard.ShardToolCli
set CLI_SCRIPT=%~0
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -102,11 +102,9 @@ SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^>=^^^>!
SET KEYSTORE_PASSWORD=!KEYSTORE_PASSWORD:^\=^^^\!
IF "%attemptautoconfig%"=="Y" (
ECHO.!KEYSTORE_PASSWORD!| %JAVA% %ES_JAVA_OPTS% ^
-Des.path.home="%ES_HOME%" ^
-Des.path.conf="%ES_PATH_CONF%" ^
-Des.distribution.type="%ES_DISTRIBUTION_TYPE%" ^
-cp "!ES_CLASSPATH!;!ES_HOME!/lib/tools/security-cli/*;!ES_HOME!/modules/x-pack-core/*;!ES_HOME!/modules/x-pack-security/*" "org.elasticsearch.xpack.security.cli.AutoConfigureNode" !newparams!
SET CLI_NAME=auto-configure-node
SET CLI_LIBS=modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli
ECHO.!KEYSTORE_PASSWORD!|call "%~dp0elasticsearch-cli.bat" !newparams!
SET SHOULDEXIT=Y
IF !ERRORLEVEL! EQU 0 SET SHOULDEXIT=N
IF !ERRORLEVEL! EQU 73 SET SHOULDEXIT=N
@ -118,12 +116,9 @@ IF "%attemptautoconfig%"=="Y" (
)
IF "!enrolltocluster!"=="Y" (
ECHO.!KEYSTORE_PASSWORD!| %JAVA% %ES_JAVA_OPTS% ^
-Des.path.home="%ES_HOME%" ^
-Des.path.conf="%ES_PATH_CONF%" ^
-Des.distribution.type="%ES_DISTRIBUTION_TYPE%" ^
-cp "!ES_CLASSPATH!;!ES_HOME!/lib/tools/security-cli/*;!ES_HOME!/modules/x-pack-core/*;!ES_HOME!/modules/x-pack-security/*" "org.elasticsearch.xpack.security.cli.AutoConfigureNode" ^
!newparams! --enrollment-token %enrollmenttoken%
SET CLI_NAME=auto-configure-node
SET CLI_LIBS=modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli
ECHO.!KEYSTORE_PASSWORD!|call "%~dp0elasticsearch-cli.bat" !newparams! --enrollment-token %enrollmenttoken%
IF !ERRORLEVEL! NEQ 0 (
exit /b !ERRORLEVEL!
)

View file

@ -0,0 +1,9 @@
apply plugin: 'elasticsearch.java'
dependencies {
compileOnly project(':server')
testImplementation project(":test:framework")
}
tasks.named("javadoc").configure { enabled = false }

View file

@ -0,0 +1,79 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.launcher;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
import org.elasticsearch.cli.Terminal;
import org.elasticsearch.core.SuppressForbidden;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
/**
* A unified main method for Elasticsearch tools.
*
* This class should only be called by the elasticsearch-cli script.
*/
class CliToolLauncher {
private static final String SCRIPT_PREFIX = "elasticsearch-";
/**
* Runs a CLI tool.
*
* <p>
* The following system properties may be provided:
* <ul>
* <li><code>cli.name</code> - the name of the tool to run</li>
* <li><code>cli.script</code> - the path to the script that is being run</li>
* <li><code>cli.libs</code> - optional, comma separated list of additional lib directories
* that should be loaded to find the tool</li>
* </ul>
* One of either <code>cli.name</code> or <code>cli.script</code> must be provided.
*
* @param args args to the tool
* @throws Exception if the tool fails with an unknown error
*/
public static void main(String[] args) throws Exception {
Map<String, String> sysprops = getSystemProperties();
String toolname = getToolName(sysprops);
String libs = sysprops.getOrDefault("cli.libs", "");
Command command = CliToolProvider.load(toolname, libs).create();
exit(command.main(args, Terminal.DEFAULT));
}
// package private for tests
static String getToolName(Map<String, String> sysprops) {
String toolname = sysprops.getOrDefault("cli.name", "");
if (toolname.isBlank()) {
String script = sysprops.get("cli.script");
int nameStart = script.lastIndexOf(SCRIPT_PREFIX) + SCRIPT_PREFIX.length();
toolname = script.substring(nameStart);
if (sysprops.get("os.name").startsWith("Windows")) {
int dotIndex = toolname.indexOf(".bat"); // strip off .bat
toolname = toolname.substring(0, dotIndex);
}
}
return toolname;
}
@SuppressForbidden(reason = "collect system properties")
private static Map<String, String> getSystemProperties() {
Properties props = System.getProperties();
return props.entrySet().stream().collect(Collectors.toMap(e -> e.getKey().toString(), e -> e.getValue().toString()));
}
@SuppressForbidden(reason = "System#exit")
private static void exit(int status) {
System.exit(status);
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.launcher;
import org.elasticsearch.test.ESTestCase;
import java.util.Map;
import static org.elasticsearch.launcher.CliToolLauncher.getToolName;
import static org.hamcrest.Matchers.equalTo;
public class CliToolLauncherTests extends ESTestCase {
public void testCliNameSysprop() {
assertThat(getToolName(Map.of("cli.name", "mycli")), equalTo("mycli"));
}
public void testScriptNameSysprop() {
var sysprops = Map.of("cli.name", "", "cli.script", "/foo/bar/elasticsearch-mycli", "os.name", "Linux");
assertThat(getToolName(sysprops), equalTo("mycli"));
}
public void testScriptNameSyspropWindows() {
var sysprops = Map.of("cli.name", "", "cli.script", "C:\\foo\\bar\\elasticsearch-mycli.bat", "os.name", "Windows XP");
assertThat(getToolName(sysprops), equalTo("mycli"));
}
}

View file

@ -154,8 +154,4 @@ public class GeoIpCli extends Command {
return buf;
}
public static void main(String[] args) throws Exception {
exit(new GeoIpCli().main(args, Terminal.DEFAULT));
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.geoip;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class GeoIpCliProvider implements CliToolProvider {
@Override
public String name() {
return "geoip";
}
@Override
public Command create() {
return new GeoIpCli();
}
}

View file

@ -0,0 +1 @@
org.elasticsearch.geoip.GeoIpCliProvider

View file

@ -8,15 +8,14 @@
package org.elasticsearch.cli.keystore;
import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.cli.LoggingAwareMultiCommand;
/**
* A cli tool for managing secrets in the elasticsearch keystore.
*/
public class KeyStoreCli extends LoggingAwareMultiCommand {
class KeyStoreCli extends LoggingAwareMultiCommand {
private KeyStoreCli() {
KeyStoreCli() {
super("A tool for managing settings stored in the elasticsearch keystore");
subcommands.put("create", new CreateKeyStoreCommand());
subcommands.put("list", new ListKeyStoreCommand());
@ -28,9 +27,4 @@ public class KeyStoreCli extends LoggingAwareMultiCommand {
subcommands.put("passwd", new ChangeKeyStorePasswordCommand());
subcommands.put("has-passwd", new HasPasswordKeyStoreCommand());
}
public static void main(String[] args) throws Exception {
exit(new KeyStoreCli().main(args, Terminal.DEFAULT));
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.cli.keystore;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class KeyStoreCliProvider implements CliToolProvider {
@Override
public String name() {
return "keystore";
}
@Override
public Command create() {
return new KeyStoreCli();
}
}

View file

@ -0,0 +1 @@
org.elasticsearch.cli.keystore.KeyStoreCliProvider

View file

@ -9,7 +9,6 @@
package org.elasticsearch.plugins.cli;
import org.elasticsearch.cli.Command;
import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.cli.LoggingAwareMultiCommand;
import org.elasticsearch.core.internal.io.IOUtils;
@ -20,11 +19,11 @@ import java.util.Collections;
/**
* A cli tool for adding, removing and listing plugins for elasticsearch.
*/
public class PluginCli extends LoggingAwareMultiCommand {
class PluginCli extends LoggingAwareMultiCommand {
private final Collection<Command> commands;
private PluginCli() {
PluginCli() {
super("A tool for managing installed elasticsearch plugins");
subcommands.put("list", new ListPluginsCommand());
subcommands.put("install", new InstallPluginCommand());
@ -32,10 +31,6 @@ public class PluginCli extends LoggingAwareMultiCommand {
commands = Collections.unmodifiableCollection(subcommands.values());
}
public static void main(String[] args) throws Exception {
exit(new PluginCli().main(args, Terminal.DEFAULT));
}
@Override
public void close() throws IOException {
IOUtils.close(commands);

View file

@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.plugins.cli;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class PluginCliProvider implements CliToolProvider {
@Override
public String name() {
return "plugin";
}
@Override
public Command create() {
return new PluginCli();
}
}

View file

@ -0,0 +1 @@
org.elasticsearch.plugins.cli.PluginCliProvider

View file

@ -0,0 +1,91 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.cli;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* An interface for command line tools to be instantiated and run.
*/
public interface CliToolProvider {
/**
* Returns the name of the tool provider.
* This must be unique across all tool providers.
*/
String name();
/**
* Constructs the CLI instance to be run.
*/
Command create();
/**
* Loads a tool provider from the Elasticsearch distribution.
*
* @param toolname the name of the tool to load
* @param libs the library directories to load, relative to the Elasticsearch homedir
* @return the instance of the loaded tool
* @throws AssertionError if the given toolname cannot be found or there are more than one tools found with the same name
*/
static CliToolProvider load(String toolname, String libs) {
// the ES homedir is always our working dir
Path homeDir = Paths.get("").toAbsolutePath();
final ClassLoader cliLoader;
if (libs.isBlank()) {
cliLoader = ClassLoader.getSystemClassLoader();
} else {
List<Path> libsToLoad = Stream.of(libs.split(",")).map(homeDir::resolve).toList();
cliLoader = loadJars(libsToLoad);
}
ServiceLoader<CliToolProvider> toolFinder = ServiceLoader.load(CliToolProvider.class, cliLoader);
List<CliToolProvider> tools = StreamSupport.stream(toolFinder.spliterator(), false).filter(p -> p.name().equals(toolname)).toList();
if (tools.size() > 1) {
String names = tools.stream().map(t -> t.getClass().getName()).collect(Collectors.joining(", "));
throw new AssertionError("Multiple ToolProviders found with name [" + toolname + "]: " + names);
}
if (tools.size() == 0) {
var names = StreamSupport.stream(toolFinder.spliterator(), false).map(CliToolProvider::name).toList();
throw new AssertionError("CliToolProvider [" + toolname + "] not found, available names are " + names);
}
return tools.get(0);
}
private static ClassLoader loadJars(List<Path> dirs) {
final List<URL> urls = new ArrayList<>();
for (var dir : dirs) {
try (Stream<Path> jarFiles = Files.list(dir)) {
jarFiles.filter(p -> p.getFileName().toString().endsWith(".jar")).map(p -> {
try {
return p.toUri().toURL();
} catch (MalformedURLException e) {
throw new AssertionError(e);
}
}).forEach(urls::add);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
return URLClassLoader.newInstance(urls.toArray(URL[]::new));
}
}

View file

@ -202,7 +202,10 @@ public class DockerTests extends PackagingTestCase {
// Stuff the proxy settings with garbage, so any attempt to go out to the internet would fail
sh.getEnv()
.put("ES_JAVA_OPTS", "-Dhttp.proxyHost=example.org -Dhttp.proxyPort=9999 -Dhttps.proxyHost=example.org -Dhttps.proxyPort=9999");
.put(
"CLI_JAVA_OPTS",
"-Dhttp.proxyHost=example.org -Dhttp.proxyPort=9999 -Dhttps.proxyHost=example.org -Dhttps.proxyPort=9999"
);
sh.run(bin.pluginTool + " install --batch analysis-icu");
assertThat("Expected " + plugin + " to be installed", listPlugins(), hasItems(plugin));
@ -228,7 +231,7 @@ public class DockerTests extends PackagingTestCase {
.volume(Path.of(EXAMPLE_PLUGIN_PATH), "/analysis-icu.zip")
.envVar("ELASTIC_PASSWORD", PASSWORD)
.envVar(
"ES_JAVA_OPTS",
"CLI_JAVA_OPTS",
"-Dhttp.proxyHost=example.org -Dhttp.proxyPort=9999 -Dhttps.proxyHost=example.org -Dhttps.proxyPort=9999"
)
);
@ -260,7 +263,7 @@ public class DockerTests extends PackagingTestCase {
builder().volume(tempDir.resolve(filename), installation.config.resolve(filename))
.envVar("ELASTIC_PASSWORD", PASSWORD)
.envVar(
"ES_JAVA_OPTS",
"CLI_JAVA_OPTS",
"-Dhttp.proxyHost=example.org -Dhttp.proxyPort=9999 -Dhttps.proxyHost=example.org -Dhttps.proxyPort=9999"
)
);
@ -298,7 +301,7 @@ public class DockerTests extends PackagingTestCase {
.extraArgs("--link " + mockServer.getContainerId() + ":mockserver");
if (useConfigFile == false) {
builder.envVar("ES_JAVA_OPTS", "-Dhttp.proxyHost=mockserver -Dhttp.proxyPort=" + mockServer.getPort());
builder.envVar("CLI_JAVA_OPTS", "-Dhttp.proxyHost=mockserver -Dhttp.proxyPort=" + mockServer.getPort());
}
// Restart the container. This will sync plugins automatically, which will fail because
@ -355,7 +358,7 @@ public class DockerTests extends PackagingTestCase {
builder().volume(tempDir.resolve(filename), installation.config.resolve(filename))
.envVar("ELASTIC_PASSWORD", PASSWORD)
.envVar(
"ES_JAVA_OPTS",
"CLI_JAVA_OPTS",
"-Dhttp.proxyHost=example.org -Dhttp.proxyPort=9999 -Dhttps.proxyHost=example.org -Dhttps.proxyPort=9999"
)
);

View file

@ -111,7 +111,7 @@ public class PluginCliTests extends PackagingTestCase {
}
public void test24JavaOpts() throws Exception {
sh.getEnv().put("ES_JAVA_OPTS", "-XX:+PrintFlagsFinal");
sh.getEnv().put("CLI_JAVA_OPTS", "-XX:+PrintFlagsFinal");
assertWithExamplePlugin(installResult -> assertThat(installResult.stdout(), containsString("MaxHeapSize")));
}

View file

@ -211,10 +211,7 @@ public class Archives {
"elasticsearch-sql-cli",
"elasticsearch-syskeygen",
"elasticsearch-users",
"elasticsearch-service-tokens",
"x-pack-env",
"x-pack-security-env",
"x-pack-watcher-env"
"elasticsearch-service-tokens"
).forEach(executable -> {
assertThat(es.bin(executable), file(File, owner, owner, p755));

View file

@ -246,10 +246,7 @@ public class Packages {
"elasticsearch-sql-cli",
"elasticsearch-syskeygen",
"elasticsearch-users",
"elasticsearch-service-tokens",
"x-pack-env",
"x-pack-security-env",
"x-pack-watcher-env"
"elasticsearch-service-tokens"
).forEach(executable -> assertThat(es.bin(executable), file(File, "root", "root", p755)));
// at this time we only install the current version of archive distributions, but if that changes we'll need to pass

View file

@ -8,7 +8,6 @@
package org.elasticsearch.cluster.coordination;
import org.elasticsearch.cli.MultiCommand;
import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.cli.CommandLoggingConfigurator;
import org.elasticsearch.env.NodeRepurposeCommand;
import org.elasticsearch.env.OverrideNodeVersionCommand;
@ -20,9 +19,9 @@ import org.elasticsearch.env.OverrideNodeVersionCommand;
// Even if we avoid making a static reference to Logger class, there is no nice way to avoid declaring
// UNSAFE_BOOTSTRAP, which depends on ClusterService, which in turn has static Logger.
// TODO execute CommandLoggingConfigurator.configureLoggingWithoutConfig() in the constructor of commands, not in beforeMain
public class NodeToolCli extends MultiCommand {
class NodeToolCli extends MultiCommand {
public NodeToolCli() {
NodeToolCli() {
super("A CLI tool to do unsafe cluster and index manipulations on current node", () -> {});
CommandLoggingConfigurator.configureLoggingWithoutConfig();
subcommands.put("repurpose", new NodeRepurposeCommand());
@ -32,9 +31,4 @@ public class NodeToolCli extends MultiCommand {
subcommands.put("remove-settings", new RemoveSettingsCommand());
subcommands.put("remove-customs", new RemoveCustomsCommand());
}
public static void main(String[] args) throws Exception {
exit(new NodeToolCli().main(args, Terminal.DEFAULT));
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.cluster.coordination;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class NodeToolCliProvider implements CliToolProvider {
@Override
public String name() {
return "node";
}
@Override
public Command create() {
return new NodeToolCli();
}
}

View file

@ -7,21 +7,15 @@
*/
package org.elasticsearch.index.shard;
import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.cli.LoggingAwareMultiCommand;
/**
* Class encapsulating and dispatching commands from the {@code elasticsearch-shard} command line tool
*/
public class ShardToolCli extends LoggingAwareMultiCommand {
class ShardToolCli extends LoggingAwareMultiCommand {
private ShardToolCli() {
ShardToolCli() {
super("A CLI tool to remove corrupted parts of unrecoverable shards");
subcommands.put("remove-corrupted-data", new RemoveCorruptedShardDataCommand());
}
public static void main(String[] args) throws Exception {
exit(new ShardToolCli().main(args, Terminal.DEFAULT));
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.index.shard;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class ShardToolCliProvider implements CliToolProvider {
@Override
public String name() {
return "shard";
}
@Override
public Command create() {
return new ShardToolCli();
}
}

View file

@ -0,0 +1,2 @@
org.elasticsearch.cluster.coordination.NodeToolCliProvider
org.elasticsearch.index.shard.ShardToolCliProvider

View file

@ -53,6 +53,7 @@ List projects = [
'distribution:bwc:minor',
'distribution:bwc:staged',
'distribution:tools:java-version-checker',
'distribution:tools:cli-launcher',
'distribution:tools:launchers',
'distribution:tools:plugin-cli',
'distribution:tools:keystore-cli',

View file

@ -1,9 +0,0 @@
#!/bin/bash
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. Licensed under the Elastic License
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
# include x-pack-core jars in classpath
ES_CLASSPATH="$ES_CLASSPATH:$ES_HOME/modules/x-pack-core/*"

View file

@ -1,6 +0,0 @@
rem Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
rem or more contributor license agreements. Licensed under the Elastic License
rem 2.0; you may not use this file except in compliance with the Elastic License
rem 2.0.
set ES_CLASSPATH=!ES_CLASSPATH!;!ES_HOME!/modules/x-pack-core/*

View file

@ -138,29 +138,25 @@ public class AutoConfigureNode extends EnvironmentAwareCommand {
private final OptionSpec<String> enrollmentTokenParam = parser.accepts("enrollment-token", "The enrollment token to use")
.withRequiredArg();
private final OptionSpec<Void> reconfigure = parser.accepts("reconfigure");
private final boolean inReconfigureMode;
private final BiFunction<Environment, String, CommandLineHttpClient> clientFunction;
public AutoConfigureNode(BiFunction<Environment, String, CommandLineHttpClient> clientFunction) {
public AutoConfigureNode(boolean reconfigure, BiFunction<Environment, String, CommandLineHttpClient> clientFunction) {
super("Generates all the necessary security configuration for a node in a secured cluster");
// This "cli utility" is invoked from the node startup script, where it is passed all the
// node startup options unfiltered. It cannot consume most of them, but it does need to inspect the `-E` ones.
parser.allowsUnrecognizedOptions();
this.inReconfigureMode = reconfigure;
this.clientFunction = clientFunction;
}
public AutoConfigureNode() {
this(CommandLineHttpClient::new);
}
public static void main(String[] args) throws Exception {
exit(new AutoConfigureNode().main(args, Terminal.DEFAULT));
public AutoConfigureNode(boolean reconfigure) {
this(reconfigure, CommandLineHttpClient::new);
}
@Override
protected void execute(Terminal terminal, OptionSet options, Environment env) throws Exception {
final boolean inEnrollmentMode = options.has(enrollmentTokenParam);
final boolean inReconfigureMode = options.has(reconfigure);
// skipping security auto-configuration because node considered as restarting.
for (Path dataPath : env.dataFiles()) {

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.cli;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class AutoConfigureNodeToolProvider implements CliToolProvider {
@Override
public String name() {
return "auto-configure-node";
}
@Override
public Command create() {
return new AutoConfigureNode(false);
}
}

View file

@ -75,7 +75,7 @@ import javax.security.auth.x500.X500Principal;
* @deprecated Replaced by {@link CertificateTool}
*/
@Deprecated
public class CertificateGenerateTool extends EnvironmentAwareCommand {
class CertificateGenerateTool extends EnvironmentAwareCommand {
private static final String AUTO_GEN_CA_DN = "CN=Elastic Certificate Tool Autogenerated CA";
private static final String DESCRIPTION = "Simplifies certificate creation for use with the Elastic Stack";
@ -159,10 +159,6 @@ public class CertificateGenerateTool extends EnvironmentAwareCommand {
.withOptionalArg();
}
public static void main(String[] args) throws Exception {
exit(new CertificateGenerateTool().main(args, Terminal.DEFAULT));
}
@Override
protected void execute(Terminal terminal, OptionSet options, Environment env) throws Exception {
final boolean csrOnly = options.has(csrSpec);

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.cli;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class CertificateGenerateToolProvider implements CliToolProvider {
@Override
public String name() {
return "certgen";
}
@Override
public Command create() {
return new CertificateGenerateTool();
}
}

View file

@ -84,7 +84,7 @@ import javax.security.auth.x500.X500Principal;
/**
* CLI tool to make generation of certificates or certificate requests easier for users
*/
public class CertificateTool extends LoggingAwareMultiCommand {
class CertificateTool extends LoggingAwareMultiCommand {
private static final String AUTO_GEN_CA_DN = "CN=Elastic Certificate Tool Autogenerated CA";
private static final String DESCRIPTION = "Simplifies certificate creation for use with the Elastic Stack";
@ -145,10 +145,6 @@ public class CertificateTool extends LoggingAwareMultiCommand {
}
}
public static void main(String[] args) throws Exception {
exit(new CertificateTool().main(args, Terminal.DEFAULT));
}
CertificateTool() {
super(DESCRIPTION);
subcommands.put("csr", new SigningRequestCommand());

View file

@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.cli;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class CertificateToolProvider implements CliToolProvider {
@Override
public String name() {
return "certutil";
}
@Override
public Command create() {
return new CertificateTool();
}
}

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.cli;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class ReconfigureNodeToolProvider implements CliToolProvider {
@Override
public String name() {
return "reconfigure-node";
}
@Override
public Command create() {
return new AutoConfigureNode(true);
}
}

View file

@ -0,0 +1,4 @@
org.elasticsearch.xpack.security.cli.CertificateToolProvider
org.elasticsearch.xpack.security.cli.CertificateGenerateToolProvider
org.elasticsearch.xpack.security.cli.ReconfigureNodeToolProvider
org.elasticsearch.xpack.security.cli.AutoConfigureNodeToolProvider

View file

@ -262,7 +262,7 @@ public class AutoConfigureNodeTests extends ESTestCase {
private X509Certificate runAutoConfigAndReturnHTTPCertificate(Path configDir, Settings settings) throws Exception {
final Environment env = TestEnvironment.newEnvironment(Settings.builder().put("path.home", configDir).put(settings).build());
// runs the command to auto-generate the config files and the keystore
new AutoConfigureNode().execute(new MockTerminal(), new OptionParser().parse(), env);
new AutoConfigureNode(false).execute(new MockTerminal(), new OptionParser().parse(), env);
KeyStoreWrapper nodeKeystore = KeyStoreWrapper.load(configDir.resolve("config"));
nodeKeystore.decrypt(new char[0]); // the keystore is always bootstrapped with an empty password

View file

@ -5,8 +5,5 @@
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.CertificateGenerateTool \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS="modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -8,9 +8,8 @@ rem 2.0.
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.CertificateGenerateTool
set ES_ADDITIONAL_SOURCES=x-pack-env;x-pack-security-env
set ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli
set CLI_SCRIPT=%~0
set CLI_LIBS=modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -5,8 +5,5 @@
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.CertificateTool \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS="modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -8,9 +8,8 @@ rem 2.0.
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.CertificateTool
set ES_ADDITIONAL_SOURCES=x-pack-env;x-pack-security-env
set ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli
set CLI_SCRIPT=%~0
set CLI_LIBS=modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -5,7 +5,5 @@
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
ES_MAIN_CLASS=org.elasticsearch.xpack.security.enrollment.tool.CreateEnrollmentTokenTool \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS="modules/x-pack-core,modules/x-pack-security"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -8,9 +8,8 @@ rem 2.0.
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.xpack.security.enrollment.tool.CreateEnrollmentTokenTool
set ES_ADDITIONAL_SOURCES=x-pack-env;x-pack-security-env
set ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli
set CLI_SCRIPT=%~0
set CLI_LIBS=modules/x-pack-core,modules/x-pack-security
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -5,8 +5,5 @@
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.AutoConfigureNode \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli \
"`dirname "$0"`"/elasticsearch-cli \
--reconfigure "$@"
CLI_LIBS="modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -8,10 +8,9 @@ rem 2.0.
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.xpack.security.cli.AutoConfigureNode
set ES_ADDITIONAL_SOURCES=x-pack-env;x-pack-security-env
set ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli
call "%~dp0elasticsearch-cli.bat" "--reconfigure" ^
set CLI_SCRIPT=%~0
set CLI_LIBS=modules/x-pack-core,modules/x-pack-security,lib/tools/security-cli
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -5,7 +5,5 @@
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
ES_MAIN_CLASS=org.elasticsearch.xpack.security.authc.esnative.tool.ResetPasswordTool \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS="modules/x-pack-core,modules/x-pack-security"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -8,9 +8,8 @@ rem 2.0.
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.xpack.security.authc.esnative.tool.ResetPasswordTool
set ES_ADDITIONAL_SOURCES=x-pack-env;x-pack-security-env
set ES_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/security-cli
set CLI_SCRIPT=%~0
set CLI_LIBS=modules/x-pack-core,modules/x-pack-security
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -5,7 +5,5 @@
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
ES_MAIN_CLASS=org.elasticsearch.xpack.security.authc.saml.SamlMetadataCommand \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS="modules/x-pack-core,modules/x-pack-security"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -8,8 +8,8 @@ rem 2.0.
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.xpack.security.authc.saml.SamlMetadataCommand
set ES_ADDITIONAL_SOURCES=x-pack-env;x-pack-security-env
set CLI_SCRIPT=%~0
set CLI_LIBS=modules/x-pack-core,modules/x-pack-security
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -5,7 +5,5 @@
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
ES_MAIN_CLASS=org.elasticsearch.xpack.security.authc.service.FileTokensTool \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS="modules/x-pack-core,modules/x-pack-security"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -8,8 +8,8 @@ rem 2.0.
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.xpack.security.authc.service.FileTokensTool
set ES_ADDITIONAL_SOURCES=x-pack-env;x-pack-security-env
set CLI_SCRIPT=%~0
set CLI_LIBS=modules/x-pack-core,modules/x-pack-security
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -5,7 +5,5 @@
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
ES_MAIN_CLASS=org.elasticsearch.xpack.security.authc.esnative.tool.SetupPasswordTool \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS="modules/x-pack-core,modules/x-pack-security"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -8,8 +8,8 @@ rem 2.0.
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.xpack.security.authc.esnative.tool.SetupPasswordTool
set ES_ADDITIONAL_SOURCES=x-pack-env;x-pack-security-env
set CLI_SCRIPT=%~0
set CLI_LIBS=modules/x-pack-core,modules/x-pack-security
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -5,7 +5,5 @@
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
ES_MAIN_CLASS=org.elasticsearch.xpack.security.crypto.tool.SystemKeyTool \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS="modules/x-pack-core,modules/x-pack-security"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -8,8 +8,8 @@ rem 2.0.
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.xpack.security.crypto.tool.SystemKeyTool
set ES_ADDITIONAL_SOURCES=x-pack-env;x-pack-security-env
set CLI_SCRIPT=%~0
set CLI_LIBS=modules/x-pack-core,modules/x-pack-security
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -5,7 +5,5 @@
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
ES_MAIN_CLASS=org.elasticsearch.xpack.security.authc.file.tool.UsersTool \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-security-env" \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS="modules/x-pack-core,modules/x-pack-security"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -8,8 +8,8 @@ rem 2.0.
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.xpack.security.authc.file.tool.UsersTool
set ES_ADDITIONAL_SOURCES=x-pack-env;x-pack-security-env
set CLI_SCRIPT=%~0
set CLI_LIBS=modules/x-pack-core,modules/x-pack-security
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -1,9 +0,0 @@
#!/bin/bash
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. Licensed under the Elastic License
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
# include x-pack-security jars in classpath
ES_CLASSPATH="$ES_CLASSPATH:$ES_HOME/modules/x-pack-security/*"

View file

@ -1,6 +0,0 @@
rem Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
rem or more contributor license agreements. Licensed under the Elastic License
rem 2.0; you may not use this file except in compliance with the Elastic License
rem 2.0.
set ES_CLASSPATH=!ES_CLASSPATH!;!ES_HOME!/modules/x-pack-security/*

View file

@ -34,7 +34,7 @@ import java.util.function.Function;
import static org.elasticsearch.xpack.core.security.CommandLineHttpClient.createURL;
import static org.elasticsearch.xpack.security.tool.CommandUtils.generatePassword;
public class ResetPasswordTool extends BaseRunAsSuperuserCommand {
class ResetPasswordTool extends BaseRunAsSuperuserCommand {
private final Function<Environment, CommandLineHttpClient> clientFunction;
private final OptionSpecBuilder interactive;
@ -42,14 +42,10 @@ public class ResetPasswordTool extends BaseRunAsSuperuserCommand {
private final OptionSpecBuilder batch;
private final OptionSpec<String> usernameOption;
public ResetPasswordTool() {
ResetPasswordTool() {
this(CommandLineHttpClient::new, environment -> KeyStoreWrapper.load(environment.configFile()));
}
public static void main(String[] args) throws Exception {
exit(new ResetPasswordTool().main(args, Terminal.DEFAULT));
}
protected ResetPasswordTool(
Function<Environment, CommandLineHttpClient> clientFunction,
CheckedFunction<Environment, KeyStoreWrapper, Exception> keyStoreFunction

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.authc.esnative.tool;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class ResetPasswordToolProvider implements CliToolProvider {
@Override
public String name() {
return "reset-password";
}
@Override
public Command create() {
return new ResetPasswordTool();
}
}

View file

@ -72,7 +72,7 @@ import static java.util.Arrays.asList;
* elastic user and the ChangePassword API for setting the password of the rest of the built-in users when needed.
*/
@Deprecated
public class SetupPasswordTool extends LoggingAwareMultiCommand {
class SetupPasswordTool extends LoggingAwareMultiCommand {
private static final char[] CHARS = ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789").toCharArray();
public static final List<String> USERS = asList(
@ -124,10 +124,6 @@ public class SetupPasswordTool extends LoggingAwareMultiCommand {
return new InteractiveSetup();
}
public static void main(String[] args) throws Exception {
exit(new SetupPasswordTool().main(args, Terminal.DEFAULT));
}
// Visible for testing
OptionParser getParser() {
return this.parser;

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.authc.esnative.tool;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class SetupPasswordToolProvider implements CliToolProvider {
@Override
public String name() {
return "setup-passwords";
}
@Override
public Command create() {
return new SetupPasswordTool();
}
}

View file

@ -43,11 +43,7 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class UsersTool extends LoggingAwareMultiCommand {
public static void main(String[] args) throws Exception {
exit(new UsersTool().main(args, Terminal.DEFAULT));
}
class UsersTool extends LoggingAwareMultiCommand {
UsersTool() {
super("Manages elasticsearch file users");

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.authc.file.tool;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class UsersToolProvider implements CliToolProvider {
@Override
public String name() {
return "users";
}
@Override
public Command create() {
return new UsersTool();
}
}

View file

@ -69,7 +69,7 @@ import java.util.stream.Collectors;
/**
* CLI tool to generate SAML Metadata for a Service Provider (realm)
*/
public class SamlMetadataCommand extends KeyStoreAwareCommand {
class SamlMetadataCommand extends KeyStoreAwareCommand {
static final String METADATA_SCHEMA = "saml-schema-metadata-2.0.xsd";
@ -90,18 +90,14 @@ public class SamlMetadataCommand extends KeyStoreAwareCommand {
private final CheckedFunction<Environment, KeyStoreWrapper, Exception> keyStoreFunction;
private KeyStoreWrapper keyStoreWrapper;
public static void main(String[] args) throws Exception {
exit(new SamlMetadataCommand().main(args, Terminal.DEFAULT));
}
public SamlMetadataCommand() {
SamlMetadataCommand() {
this((environment) -> {
KeyStoreWrapper ksWrapper = KeyStoreWrapper.load(environment.configFile());
return ksWrapper;
});
}
public SamlMetadataCommand(CheckedFunction<Environment, KeyStoreWrapper, Exception> keyStoreFunction) {
SamlMetadataCommand(CheckedFunction<Environment, KeyStoreWrapper, Exception> keyStoreFunction) {
super("Generate Service Provider Metadata for a SAML realm");
outputPathSpec = parser.accepts("out", "path of the xml file that should be generated").withRequiredArg();
batchSpec = parser.accepts("batch", "Do not prompt");

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.authc.saml;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class SamlMetadataToolProvider implements CliToolProvider {
@Override
public String name() {
return "saml-metadata";
}
@Override
public Command create() {
return new SamlMetadataCommand();
}
}

View file

@ -31,13 +31,9 @@ import java.util.Map;
import java.util.TreeMap;
import java.util.function.Predicate;
public class FileTokensTool extends LoggingAwareMultiCommand {
class FileTokensTool extends LoggingAwareMultiCommand {
public static void main(String[] args) throws Exception {
exit(new FileTokensTool().main(args, Terminal.DEFAULT));
}
public FileTokensTool() {
FileTokensTool() {
super("Manages elasticsearch service account file-tokens");
subcommands.put("create", newCreateFileTokenCommand());
subcommands.put("delete", newDeleteFileTokenCommand());

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.authc.service;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class FileTokensToolProvider implements CliToolProvider {
@Override
public String name() {
return "service-tokens";
}
@Override
public Command create() {
return new FileTokensTool();
}
}

View file

@ -32,7 +32,7 @@ import java.util.Set;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class SystemKeyTool extends EnvironmentAwareCommand {
class SystemKeyTool extends EnvironmentAwareCommand {
static final String KEY_ALGO = "HmacSHA512";
static final int KEY_SIZE = 1024;
@ -49,18 +49,6 @@ public class SystemKeyTool extends EnvironmentAwareCommand {
PosixFilePermission.OWNER_WRITE
);
public static void main(String[] args) throws Exception {
final SystemKeyTool tool = new SystemKeyTool();
int status = main(tool, args, Terminal.DEFAULT);
if (status != ExitCodes.OK) {
exit(status);
}
}
static int main(SystemKeyTool tool, String[] args, Terminal terminal) throws Exception {
return tool.main(args, terminal);
}
@Override
protected void execute(Terminal terminal, OptionSet options, Environment env) throws Exception {
final Path keyPath;

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.crypto.tool;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class SystemKeyToolProvider implements CliToolProvider {
@Override
public String name() {
return "syskeygen";
}
@Override
public Command create() {
return new SystemKeyTool();
}
}

View file

@ -36,16 +36,12 @@ import static org.elasticsearch.xpack.security.tool.CommandUtils.generatePasswor
*
* The generated password is written to stdout upon success. Error messages are printed to stderr.
*/
public class AutoConfigGenerateElasticPasswordHash extends KeyStoreAwareCommand {
class AutoConfigGenerateElasticPasswordHash extends KeyStoreAwareCommand {
public AutoConfigGenerateElasticPasswordHash() {
AutoConfigGenerateElasticPasswordHash() {
super("Generates a password hash for for the elastic user and stores it in elasticsearch.keystore");
}
public static void main(String[] args) throws Exception {
exit(new AutoConfigGenerateElasticPasswordHash().main(args, Terminal.DEFAULT));
}
@Override
protected void execute(Terminal terminal, OptionSet options, Environment env) throws Exception {
final Hasher hasher = Hasher.resolve(XPackSettings.PASSWORD_HASHING_ALGORITHM.get(env.settings()));

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.enrollment.tool;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class AutoConfigGenerateElasticPasswordHashToolProvider implements CliToolProvider {
@Override
public String name() {
return "auto-config-gen-passwd";
}
@Override
public Command create() {
return new AutoConfigGenerateElasticPasswordHash();
}
}

View file

@ -26,7 +26,7 @@ import java.net.URL;
import java.util.List;
import java.util.function.Function;
public class CreateEnrollmentTokenTool extends BaseRunAsSuperuserCommand {
class CreateEnrollmentTokenTool extends BaseRunAsSuperuserCommand {
private final OptionSpec<String> scope;
private final Function<Environment, CommandLineHttpClient> clientFunction;
@ -34,7 +34,6 @@ public class CreateEnrollmentTokenTool extends BaseRunAsSuperuserCommand {
static final List<String> ALLOWED_SCOPES = List.of("node", "kibana");
CreateEnrollmentTokenTool() {
this(
environment -> new CommandLineHttpClient(environment),
environment -> KeyStoreWrapper.load(environment.configFile()),
@ -55,10 +54,6 @@ public class CreateEnrollmentTokenTool extends BaseRunAsSuperuserCommand {
.required();
}
public static void main(String[] args) throws Exception {
exit(new CreateEnrollmentTokenTool().main(args, Terminal.DEFAULT));
}
@Override
protected void validate(Terminal terminal, OptionSet options, Environment env) throws Exception {
if (XPackSettings.ENROLLMENT_ENABLED.get(env.settings()) == false) {

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.security.enrollment.tool;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class CreateEnrollmentTokenToolProvider implements CliToolProvider {
@Override
public String name() {
return "create-enrollment-token";
}
@Override
public Command create() {
return new CreateEnrollmentTokenTool();
}
}

View file

@ -0,0 +1,8 @@
org.elasticsearch.xpack.security.enrollment.tool.CreateEnrollmentTokenToolProvider
org.elasticsearch.xpack.security.authc.esnative.tool.ResetPasswordToolProvider
org.elasticsearch.xpack.security.authc.esnative.tool.SetupPasswordToolProvider
org.elasticsearch.xpack.security.authc.saml.SamlMetadataToolProvider
org.elasticsearch.xpack.security.authc.service.FileTokensToolProvider
org.elasticsearch.xpack.security.crypto.tool.SystemKeyToolProvider
org.elasticsearch.xpack.security.authc.file.tool.UsersToolProvider
org.elasticsearch.xpack.security.enrollment.tool.AutoConfigGenerateElasticPasswordHashToolProvider

View file

@ -9,8 +9,6 @@ CLI_PARAMETERS="$@"
source "`dirname "$0"`"/elasticsearch-env
source "$ES_HOME"/bin/x-pack-env
CLI_JAR=$(ls "$ES_HOME"/bin/elasticsearch-sql-cli-*.jar)
exec \

View file

@ -10,9 +10,7 @@ setlocal enableextensions
call "%~dp0elasticsearch-env.bat" || exit /b 1
call "%ES_HOME%/bin/x-pack-env.bat" || exit /b 1
set CLI_JAR=%ES_HOME%/bin/*
for %%a in (!ES_HOME!\bin\elasticsearch-sql-cli-*.jar) do set CLI_JAR=%%a
%JAVA% ^
-cp "%CLI_JAR%" ^

View file

@ -5,7 +5,5 @@
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
ES_MAIN_CLASS=org.elasticsearch.xpack.watcher.trigger.schedule.tool.CronEvalTool \
ES_ADDITIONAL_SOURCES="x-pack-env;x-pack-watcher-env" \
"`dirname "$0"`"/elasticsearch-cli \
"$@"
CLI_LIBS="modules/x-pack-core,modules/x-pack-watcher"
source "`dirname "$0"`"/elasticsearch-cli

View file

@ -8,8 +8,8 @@ rem 2.0.
setlocal enabledelayedexpansion
setlocal enableextensions
set ES_MAIN_CLASS=org.elasticsearch.xpack.watcher.trigger.schedule.tool.CronEvalTool
set ES_ADDITIONAL_SOURCES=x-pack-env;x-pack-watcher-env
set CLI_SCRIPT=%~0
set CLI_LIBS=modules/x-pack-core,modules/x-pack-watcher
call "%~dp0elasticsearch-cli.bat" ^
%%* ^
|| goto exit

View file

@ -1,9 +0,0 @@
#!/bin/bash
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. Licensed under the Elastic License
# 2.0; you may not use this file except in compliance with the Elastic License
# 2.0.
# include x-pack-security jars in classpath
ES_CLASSPATH="$ES_CLASSPATH:$ES_HOME/modules/x-pack-watcher/*"

View file

@ -1,6 +0,0 @@
rem Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
rem or more contributor license agreements. Licensed under the Elastic License
rem 2.0; you may not use this file except in compliance with the Elastic License
rem 2.0.
set ES_CLASSPATH=!ES_CLASSPATH!;!ES_HOME!/modules/x-pack-watcher/*

View file

@ -24,11 +24,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Locale;
public class CronEvalTool extends LoggingAwareCommand {
public static void main(String[] args) throws Exception {
exit(new CronEvalTool().main(args, Terminal.DEFAULT));
}
class CronEvalTool extends LoggingAwareCommand {
private static final DateFormatter UTC_FORMATTER = DateFormatter.forPattern("EEE, d MMM yyyy HH:mm:ss")
.withZone(ZoneOffset.UTC)

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
package org.elasticsearch.xpack.watcher.trigger.schedule.tool;
import org.elasticsearch.cli.CliToolProvider;
import org.elasticsearch.cli.Command;
public class CronEvalToolProvider implements CliToolProvider {
@Override
public String name() {
return "croneval";
}
@Override
public Command create() {
return new CronEvalTool();
}
}

View file

@ -0,0 +1 @@
org.elasticsearch.xpack.watcher.trigger.schedule.tool.CronEvalToolProvider