Skip to content

Commit

Permalink
Refactor for JPMS Support
Browse files Browse the repository at this point in the history
Signed-off-by: Prudhvi Godithi <[email protected]>
  • Loading branch information
prudhvigodithi committed Jan 29, 2025
1 parent b5234a5 commit b60cdc9
Show file tree
Hide file tree
Showing 87 changed files with 365 additions and 204 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Deprecate CamelCase `PathHierarchy` tokenizer name in favor to lowercase `path_hierarchy` ([#10894](https://github.com/opensearch-project/OpenSearch/pull/10894))
- Breaking change: Do not request "search_pipelines" metrics by default in NodesInfoRequest ([#12497](https://github.com/opensearch-project/OpenSearch/pull/12497))
- Refactor `:libs` module `bootstrap` package to eliminate top level split packages [#17117](https://github.com/opensearch-project/OpenSearch/pull/17117))
- Refactor `:server` and `:distribution:tools:keystore-cli` module to eliminate top level split packages. [#17153](https://github.com/opensearch-project/OpenSearch/pull/17153))

### Deprecated

Expand Down
2 changes: 1 addition & 1 deletion distribution/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ configure(subprojects.findAll { ['archives', 'packages'].contains(it.name) }) {
}
}
}

jreFiles = { Project project, String platform, String architecture ->
return copySpec {
/*
Expand Down
2 changes: 1 addition & 1 deletion distribution/src/bin/opensearch-keystore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set -e -o pipefail

OPENSEARCH_MAIN_CLASS=org.opensearch.common.settings.KeyStoreCli \
OPENSEARCH_MAIN_CLASS=org.opensearch.tools.cli.keystore.KeyStoreCli \
OPENSEARCH_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/keystore-cli \
"`dirname "$0"`"/opensearch-cli \
"$@"
2 changes: 1 addition & 1 deletion distribution/src/bin/opensearch-keystore.bat
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
setlocal enabledelayedexpansion
setlocal enableextensions

set OPENSEARCH_MAIN_CLASS=org.opensearch.common.settings.KeyStoreCli
set OPENSEARCH_MAIN_CLASS=org.opensearch.tools.cli.keystore.KeyStoreCli
set OPENSEARCH_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/keystore-cli
call "%~dp0opensearch-cli.bat" ^
%%* ^
Expand Down
2 changes: 1 addition & 1 deletion distribution/src/bin/opensearch-plugin
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set -e -o pipefail

OPENSEARCH_MAIN_CLASS=org.opensearch.plugins.PluginCli \
OPENSEARCH_MAIN_CLASS=org.opensearch.tools.cli.plugin.PluginCli \
OPENSEARCH_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/plugin-cli \
"`dirname "$0"`"/opensearch-cli \
"$@"
2 changes: 1 addition & 1 deletion distribution/src/bin/opensearch-plugin.bat
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
setlocal enabledelayedexpansion
setlocal enableextensions

set OPENSEARCH_MAIN_CLASS=org.opensearch.plugins.PluginCli
set OPENSEARCH_MAIN_CLASS=org.opensearch.tools.cli.plugin.PluginCli
set OPENSEARCH_ADDITIONAL_CLASSPATH_DIRECTORIES=lib/tools/plugin-cli
call "%~dp0opensearch-cli.bat" ^
%%* ^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* GitHub history for details.
*/

package org.opensearch.common.settings;
package org.opensearch.tools.cli.keystore;

import joptsimple.OptionSet;
import joptsimple.OptionSpec;
Expand All @@ -39,6 +39,7 @@
import org.opensearch.cli.UserException;
import org.opensearch.common.SuppressForbidden;
import org.opensearch.common.io.PathUtils;
import org.opensearch.common.settings.KeyStoreWrapper;
import org.opensearch.env.Environment;

import java.nio.file.Files;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@
* GitHub history for details.
*/

package org.opensearch.common.settings;
package org.opensearch.tools.cli.keystore;

import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.opensearch.cli.ExitCodes;
import org.opensearch.cli.Terminal;
import org.opensearch.cli.UserException;
import org.opensearch.common.CheckedFunction;
import org.opensearch.common.settings.KeyStoreWrapper;
import org.opensearch.env.Environment;

import java.io.BufferedReader;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
* GitHub history for details.
*/

package org.opensearch.common.settings;
package org.opensearch.tools.cli.keystore;

import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.opensearch.cli.ExitCodes;
import org.opensearch.cli.KeyStoreAwareCommand;
import org.opensearch.cli.Terminal;
import org.opensearch.cli.UserException;
import org.opensearch.common.settings.KeyStoreWrapper;
import org.opensearch.core.common.settings.SecureString;
import org.opensearch.env.Environment;

Expand All @@ -53,13 +53,36 @@ public abstract class BaseKeyStoreCommand extends KeyStoreAwareCommand {
private KeyStoreWrapper keyStore;
private SecureString keyStorePassword;
private final boolean keyStoreMustExist;
OptionSpec<Void> forceOption;

/**
* Option to force operations without prompting for confirmation.
* When specified, operations proceed without asking for user input.
*/
protected OptionSpec<Void> forceOption;

/**
* Creates a new BaseKeyStoreCommand with the specified description and existence requirement.
*
* @param description The description of the command
* @param keyStoreMustExist If true, the keystore must exist before executing the command.
* If false, a new keystore may be created if none exists.
*/
public BaseKeyStoreCommand(String description, boolean keyStoreMustExist) {
super(description);
this.keyStoreMustExist = keyStoreMustExist;
}

/**
* Executes the keystore command by loading/creating the keystore and handling password management.
* If the keystore doesn't exist and keyStoreMustExist is false, prompts to create a new one
* unless the force option is specified.
*
* @param terminal The terminal to use for user interaction
* @param options The command-line options provided
* @param env The environment settings
* @throws Exception if there are errors during keystore operations
* @throws UserException if the keystore is required but doesn't exist
*/
@Override
protected final void execute(Terminal terminal, OptionSet options, Environment env) throws Exception {
try {
Expand Down Expand Up @@ -96,19 +119,34 @@ protected final void execute(Terminal terminal, OptionSet options, Environment e
}
}

/**
* Gets the current keystore instance.
*
* @return The current {@link KeyStoreWrapper} instance being operated on
*/
protected KeyStoreWrapper getKeyStore() {
return keyStore;
}

/**
* Gets the password for the current keystore.
*
* @return The {@link SecureString} containing the keystore password
*/
protected SecureString getKeyStorePassword() {
return keyStorePassword;
}

/**
* This is called after the keystore password has been read from the stdin and the keystore is decrypted and
* loaded. The keystore and keystore passwords are available to classes extending {@link BaseKeyStoreCommand}
* using {@link BaseKeyStoreCommand#getKeyStore()} and {@link BaseKeyStoreCommand#getKeyStorePassword()}
* respectively.
* Executes the specific keystore command implementation.
* This is called after the keystore password has been read and the keystore
* is decrypted and loaded. The keystore and keystore passwords are available using
* {@link #getKeyStore()} and {@link #getKeyStorePassword()} respectively.
*
* @param terminal The terminal to use for user interaction
* @param options The command line options that were specified
* @param env The environment configuration
* @throws Exception if there is an error executing the command
*/
protected abstract void executeCommand(Terminal terminal, OptionSet options, Environment env) throws Exception;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@
* GitHub history for details.
*/

package org.opensearch.common.settings;
package org.opensearch.tools.cli.keystore;

import joptsimple.OptionSet;
import org.opensearch.cli.ExitCodes;
import org.opensearch.cli.Terminal;
import org.opensearch.cli.UserException;
import org.opensearch.common.settings.KeyStoreWrapper;
import org.opensearch.core.common.settings.SecureString;
import org.opensearch.env.Environment;

Expand All @@ -44,12 +45,27 @@
*
* @opensearch.internal
*/
class ChangeKeyStorePasswordCommand extends BaseKeyStoreCommand {
public class ChangeKeyStorePasswordCommand extends BaseKeyStoreCommand {

ChangeKeyStorePasswordCommand() {
super("Changes the password of a keystore", true);
}

/**
* Executes the password change command by prompting for a new password
* and saving the keystore with the updated password.
* <p>
* This implementation will:
* 1. Prompt for a new password with verification
* 2. Save the keystore with the new password
* 3. Display a success message upon completion
*
* @param terminal The terminal to use for user interaction
* @param options The command-line options provided
* @param env The environment settings containing configuration directory
* @throws Exception if there are errors during password change
* @throws UserException if there are security-related errors
*/
@Override
protected void executeCommand(Terminal terminal, OptionSet options, Environment env) throws Exception {
try (SecureString newPassword = readPassword(terminal, true)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
* GitHub history for details.
*/

package org.opensearch.common.settings;
package org.opensearch.tools.cli.keystore;

import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.opensearch.cli.ExitCodes;
import org.opensearch.cli.KeyStoreAwareCommand;
import org.opensearch.cli.Terminal;
import org.opensearch.cli.UserException;
import org.opensearch.common.settings.KeyStoreWrapper;
import org.opensearch.core.common.settings.SecureString;
import org.opensearch.env.Environment;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,49 @@
* GitHub history for details.
*/

package org.opensearch.common.settings;
package org.opensearch.tools.cli.keystore;

import joptsimple.OptionSet;
import org.opensearch.cli.KeyStoreAwareCommand;
import org.opensearch.cli.Terminal;
import org.opensearch.cli.UserException;
import org.opensearch.common.settings.KeyStoreWrapper;
import org.opensearch.env.Environment;

import java.nio.file.Path;

/**
* KeyStore command that has a password.
* KeyStore command that checks if the keystore exists and is password-protected.
* Exits with a non-zero status code if the keystore is missing or not password-protected.
*
* @opensearch.internal
*/
public class HasPasswordKeyStoreCommand extends KeyStoreAwareCommand {

static final int NO_PASSWORD_EXIT_CODE = 1;

/**
* Creates a new HasPasswordKeyStoreCommand.
* This command checks for the existence of a password-protected keystore
* and exits with {@link #NO_PASSWORD_EXIT_CODE} if the keystore is missing
* or not password-protected.
*/
HasPasswordKeyStoreCommand() {
super(
"Succeeds if the keystore exists and is password-protected, " + "fails with exit code " + NO_PASSWORD_EXIT_CODE + " otherwise."
);
}

/**
* Executes the password check command by verifying if the keystore exists
* and is password-protected.
*
* @param terminal The terminal for user interaction and output
* @param options The command-line options provided
* @param env The environment settings containing configuration directory
* @throws UserException with {@link #NO_PASSWORD_EXIT_CODE} if the keystore
* is missing or not password-protected
* @throws Exception if there are other errors during execution
*/
@Override
protected void execute(Terminal terminal, OptionSet options, Environment env) throws Exception {
final Path configFile = env.configDir();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@
* GitHub history for details.
*/

package org.opensearch.cli;
package org.opensearch.tools.cli.keystore;

import joptsimple.OptionSet;
import org.opensearch.cli.ExitCodes;
import org.opensearch.cli.Terminal;
import org.opensearch.cli.UserException;
import org.opensearch.common.cli.EnvironmentAwareCommand;
import org.opensearch.common.settings.KeyStoreWrapper;
import org.opensearch.core.common.settings.SecureString;
import org.opensearch.env.Environment;
Expand All @@ -42,19 +46,22 @@
import java.util.Arrays;

/**
* An {@link org.opensearch.cli.EnvironmentAwareCommand} that needs to access the opensearch keystore, possibly
* An {@link EnvironmentAwareCommand} that needs to access the opensearch keystore, possibly
* decrypting it if it is password protected.
*
* @opensearch.internal
*/
public abstract class KeyStoreAwareCommand extends EnvironmentAwareCommand {

/**
* Creates a new KeyStoreAwareCommand with the given description.
*
* @param description A description of the command's purpose and functionality
*/
public KeyStoreAwareCommand(String description) {
super(description);
}

/** Arbitrarily chosen maximum passphrase length */
public static final int MAX_PASSPHRASE_LENGTH = 128;

/**
* Reads the keystore password from the {@link Terminal}, prompting for verification where applicable and returns it as a
* {@link SecureString}.
Expand All @@ -69,9 +76,9 @@ protected static SecureString readPassword(Terminal terminal, boolean withVerifi
if (withVerification) {
passwordArray = terminal.readSecret(
"Enter new password for the opensearch keystore (empty for no password): ",
MAX_PASSPHRASE_LENGTH
EnvironmentAwareCommand.MAX_PASSPHRASE_LENGTH
);
char[] passwordVerification = terminal.readSecret("Enter same password again: ", MAX_PASSPHRASE_LENGTH);
char[] passwordVerification = terminal.readSecret("Enter same password again: ", EnvironmentAwareCommand.MAX_PASSPHRASE_LENGTH);
if (Arrays.equals(passwordArray, passwordVerification) == false) {
throw new UserException(ExitCodes.DATA_ERROR, "Passwords are not equal, exiting.");
}
Expand All @@ -83,7 +90,15 @@ protected static SecureString readPassword(Terminal terminal, boolean withVerifi
}

/**
* Decrypt the {@code keyStore}, prompting the user to enter the password in the {@link Terminal} if it is password protected
* Decrypts the provided keystore using a password obtained from the terminal.
* If the keystore is password-protected, prompts the user to enter the password.
* If not password-protected, uses an empty password.
*
* @param keyStore The keystore to decrypt
* @param terminal The terminal to use for password input
* @throws UserException If there is an error with the provided password
* @throws GeneralSecurityException If there is an error during decryption
* @throws IOException If there is an error reading from the terminal
*/
protected static void decryptKeyStore(KeyStoreWrapper keyStore, Terminal terminal) throws UserException, GeneralSecurityException,
IOException {
Expand All @@ -94,5 +109,13 @@ protected static void decryptKeyStore(KeyStoreWrapper keyStore, Terminal termina
}
}

/**
* Executes the keystore command with the given parameters.
*
* @param terminal The terminal to use for user interaction
* @param options The command-line options provided
* @param env The environment settings
* @throws Exception if there are any errors during execution
*/
protected abstract void execute(Terminal terminal, OptionSet options, Environment env) throws Exception;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
* GitHub history for details.
*/

package org.opensearch.common.settings;
package org.opensearch.tools.cli.keystore;

import org.opensearch.cli.LoggingAwareMultiCommand;
import org.opensearch.cli.Terminal;
import org.opensearch.common.cli.LoggingAwareMultiCommand;

/**
* A CLI tool for managing secrets in the OpenSearch keystore.
Expand Down
Loading

0 comments on commit b60cdc9

Please sign in to comment.