Remove old help files and references to old cli tool stuff

Original commit: elastic/x-pack-elasticsearch@b02faa5251
This commit is contained in:
Ryan Ernst 2016-03-08 14:16:47 -08:00
parent bafbcd9ed3
commit 53d87d158f
23 changed files with 396 additions and 1152 deletions

View File

@ -17,7 +17,7 @@ import joptsimple.OptionSpec;
import org.elasticsearch.cli.Command; import org.elasticsearch.cli.Command;
import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.UserError; import org.elasticsearch.cli.UserError;
import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.cli.Terminal;
import static org.elasticsearch.license.core.CryptUtils.writeEncryptedPrivateKey; import static org.elasticsearch.license.core.CryptUtils.writeEncryptedPrivateKey;
import static org.elasticsearch.license.core.CryptUtils.writeEncryptedPublicKey; import static org.elasticsearch.license.core.CryptUtils.writeEncryptedPublicKey;
@ -49,11 +49,10 @@ public class KeyPairGeneratorTool extends Command {
} }
@Override @Override
protected int execute(Terminal terminal, OptionSet options) throws Exception { protected void execute(Terminal terminal, OptionSet options) throws Exception {
File publicKeyPath = publicKeyPathOption.value(options); File publicKeyPath = publicKeyPathOption.value(options);
File privateKeyPath = privateKeyPathOption.value(options); File privateKeyPath = privateKeyPathOption.value(options);
execute(terminal, publicKeyPath.toPath(), privateKeyPath.toPath()); execute(terminal, publicKeyPath.toPath(), privateKeyPath.toPath());
return ExitCodes.OK;
} }
// pkg private for tests // pkg private for tests

View File

@ -13,7 +13,7 @@ import joptsimple.OptionSpec;
import org.elasticsearch.cli.Command; import org.elasticsearch.cli.Command;
import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.UserError; import org.elasticsearch.cli.UserError;
import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.io.PathUtils;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
@ -57,7 +57,7 @@ public class LicenseGeneratorTool extends Command {
} }
@Override @Override
protected int execute(Terminal terminal, OptionSet options) throws Exception { protected void execute(Terminal terminal, OptionSet options) throws Exception {
Path publicKeyPath = PathUtils.get(publicKeyPathOption.value(options)); Path publicKeyPath = PathUtils.get(publicKeyPathOption.value(options));
Path privateKeyPath = PathUtils.get(privateKeyPathOption.value(options)); Path privateKeyPath = PathUtils.get(privateKeyPathOption.value(options));
String licenseSpecString = null; String licenseSpecString = null;
@ -69,7 +69,6 @@ public class LicenseGeneratorTool extends Command {
licenseSpecPath = PathUtils.get(licenseFileOption.value(options)); licenseSpecPath = PathUtils.get(licenseFileOption.value(options));
} }
execute(terminal, publicKeyPath, privateKeyPath, licenseSpecString, licenseSpecPath); execute(terminal, publicKeyPath, privateKeyPath, licenseSpecString, licenseSpecPath);
return ExitCodes.OK;
} }
// pkg private for testing // pkg private for testing

View File

@ -5,35 +5,23 @@
*/ */
package org.elasticsearch.license.licensor.tools; package org.elasticsearch.license.licensor.tools;
import java.nio.file.Files;
import java.nio.file.Path;
import joptsimple.OptionSet; import joptsimple.OptionSet;
import joptsimple.OptionSpec; import joptsimple.OptionSpec;
import org.apache.commons.cli.CommandLine;
import org.elasticsearch.cli.Command; import org.elasticsearch.cli.Command;
import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.UserError; import org.elasticsearch.cli.UserError;
import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.cli.CliTool;
import org.elasticsearch.common.cli.CliToolConfig;
import org.elasticsearch.common.cli.Terminal;
import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.io.PathUtils;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.env.Environment;
import org.elasticsearch.license.core.License; import org.elasticsearch.license.core.License;
import org.elasticsearch.license.core.LicenseVerifier; import org.elasticsearch.license.core.LicenseVerifier;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.elasticsearch.common.cli.CliToolConfig.Builder.cmd;
import static org.elasticsearch.common.cli.CliToolConfig.Builder.option;
import static org.elasticsearch.common.cli.CliToolConfig.config;
public class LicenseVerificationTool extends Command { public class LicenseVerificationTool extends Command {
private final OptionSpec<String> publicKeyPathOption; private final OptionSpec<String> publicKeyPathOption;
@ -57,7 +45,7 @@ public class LicenseVerificationTool extends Command {
} }
@Override @Override
protected int execute(Terminal terminal, OptionSet options) throws Exception { protected void execute(Terminal terminal, OptionSet options) throws Exception {
Path publicKeyPath = PathUtils.get(publicKeyPathOption.value(options)); Path publicKeyPath = PathUtils.get(publicKeyPathOption.value(options));
String licenseSpecString = null; String licenseSpecString = null;
if (options.has(licenseOption)) { if (options.has(licenseOption)) {
@ -68,7 +56,6 @@ public class LicenseVerificationTool extends Command {
licenseSpecPath = PathUtils.get(licenseFileOption.value(options)); licenseSpecPath = PathUtils.get(licenseFileOption.value(options));
} }
execute(terminal, publicKeyPath, licenseSpecString, licenseSpecPath); execute(terminal, publicKeyPath, licenseSpecString, licenseSpecPath);
return ExitCodes.OK;
} }
// pkg private for tests // pkg private for tests

View File

@ -1,22 +0,0 @@
NAME
key-pair-generator - generates a key pair with RSA 2048-bit security
SYNOPSIS
key-pair-generator -pub publicKeyPath -pri privateKeyPath
DESCRIPTION
This tool generates and saves a key pair to the provided publicKeyPath
and privateKeyPath. The tool checks the existence of the provided key paths
and will not override if any existing keys are found.
OPTIONS
-h,--help Shows this message
-pub,--publicKeyPath <path> Save the generated public key to path
-pri,--privateKeyPath <path> Save the generated private key to path

View File

@ -1,26 +0,0 @@
NAME
license-generator - generates signed elasticsearch license(s) for a given license spec(s)
SYNOPSIS
license-generator -l licenseSpec -pub publicKeyPath -pri privateKeyPath
DESCRIPTION
This tool generate elasticsearch license(s) for the provided license spec(s). The tool
can take arbitrary number of `--license` and/or `--licenseFile` to generate corrosponding
signed license(s).
OPTIONS
-h,--help Shows this message
-l,--license <license spec> License spec to generate a signed license from
-lf,--licenseFile <path> Path to a license spec file
-pub,--publicKeyPath <path> Path to public key to be used
-pri,--privateKeyPath <path> Path to private key to be used

View File

@ -1,28 +0,0 @@
NAME
verify-license - verifies the integrity of elasticsearch signed license(s)
SYNOPSIS
verify-license -l signedLicense -pub publicKeyPath
DESCRIPTION
This tool assumes the configured public key to be the same as that of the production license plugin public key.
The tool can take arbitrary number of `--license` and/or `--licenseFile` for verifying signed license(s). If any
of the provided license(s) are invalid, the tool will error out, otherwise it will output a effective licenses file.
Effective Licenses:
A set of licenses that only has one effective sub-license for every feature provided through the input license file.
Where effective sub-licenses are identified as the sub-licenses with the latest `expiry_date` for a `feature`
and the sub-license has not already expired.
OPTIONS
-h,--help Shows this message
-l,--license <signed license> signed license(s) string
-lf,--licenseFile <path> Path to signed license(s) file
-pub,--publicKeyPath <path> Path to public key to verify against

View File

@ -10,7 +10,7 @@ import java.nio.file.Path;
import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.UserError; import org.elasticsearch.cli.UserError;
import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.cli.Terminal;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.containsString;

View File

@ -12,7 +12,7 @@ import java.nio.file.Path;
import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.UserError; import org.elasticsearch.cli.UserError;
import org.elasticsearch.cli.MockTerminal; import org.elasticsearch.cli.MockTerminal;
import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.cli.Terminal;
import org.elasticsearch.license.core.License; import org.elasticsearch.license.core.License;
import org.elasticsearch.license.licensor.TestUtils; import org.elasticsearch.license.licensor.TestUtils;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;

View File

@ -11,7 +11,7 @@ import java.nio.file.Path;
import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.UserError; import org.elasticsearch.cli.UserError;
import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.license.core.License; import org.elasticsearch.license.core.License;
import org.elasticsearch.license.licensor.TestUtils; import org.elasticsearch.license.licensor.TestUtils;

View File

@ -5,19 +5,27 @@
*/ */
package org.elasticsearch.shield.authc.esusers.tool; package org.elasticsearch.shield.authc.esusers.tool;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import joptsimple.OptionSet; import joptsimple.OptionSet;
import joptsimple.OptionSpec; import joptsimple.OptionSpec;
import org.apache.commons.cli.CommandLine;
import org.elasticsearch.cli.Command; import org.elasticsearch.cli.Command;
import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.MultiCommand; import org.elasticsearch.cli.MultiCommand;
import org.elasticsearch.cli.UserError; import org.elasticsearch.cli.UserError;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.cli.CliTool; import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.cli.CliToolConfig;
import org.elasticsearch.common.cli.Terminal;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.ArrayUtils;
import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.node.internal.InternalSettingsPreparer; import org.elasticsearch.node.internal.InternalSettingsPreparer;
@ -31,21 +39,6 @@ import org.elasticsearch.shield.authz.store.FileRolesStore;
import org.elasticsearch.shield.support.FileAttributesChecker; import org.elasticsearch.shield.support.FileAttributesChecker;
import org.elasticsearch.shield.support.Validation; import org.elasticsearch.shield.support.Validation;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.elasticsearch.common.cli.CliToolConfig.Builder.cmd;
public class ESUsersTool extends MultiCommand { public class ESUsersTool extends MultiCommand {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -93,47 +86,19 @@ public class ESUsersTool extends MultiCommand {
} }
@Override @Override
protected int execute(Terminal terminal, OptionSet options) throws Exception { protected void execute(Terminal terminal, OptionSet options) throws Exception {
String username = arguments.value(options); String username = parseUsername(arguments.values(options));
String passwordStr = passwordOption.value(options);
String rolesCsv = rolesOption.value(options);
Validation.Error validationError = Validation.ESUsers.validateUsername(username); Validation.Error validationError = Validation.ESUsers.validateUsername(username);
if (validationError != null) { if (validationError != null) {
throw new UserError(ExitCodes.DATA_ERROR, "Invalid username [" + username + "]... " + validationError); throw new UserError(ExitCodes.DATA_ERROR, "Invalid username [" + username + "]... " + validationError);
} }
char[] password; char[] password = parsePassword(terminal, passwordOption.value(options));
if (passwordStr != null) { String[] roles = parseRoles(terminal, env, rolesOption.value(options));
password = passwordStr.toCharArray();
validationError = Validation.ESUsers.validatePassword(password);
if (validationError != null) {
throw new UserError(ExitCodes.DATA_ERROR, "Invalid password..." + validationError);
}
} else {
password = terminal.readSecret("Enter new password: ");
validationError = Validation.ESUsers.validatePassword(password);
if (validationError != null) {
throw new UserError(ExitCodes.DATA_ERROR, "Invalid password..." + validationError);
}
char[] retyped = terminal.readSecret("Retype new password: ");
if (Arrays.equals(password, retyped) == false) {
throw new UserError(ExitCodes.DATA_ERROR, "Password mismatch");
}
}
String[] roles = rolesCsv.split(",");
for (String role : roles) {
validationError = Validation.Roles.validateRoleName(role);
if (validationError != null) {
throw new UserError(ExitCodes.DATA_ERROR, "Invalid role [" + role + "]... " + validationError);
}
}
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE); Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
Path passwordFile = FileUserPasswdStore.resolveFile(esusersSettings, env); Path passwordFile = FileUserPasswdStore.resolveFile(esusersSettings, env);
Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env); Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env);
verifyRoles(terminal, env.settings(), env, roles);
FileAttributesChecker attributesChecker = new FileAttributesChecker(passwordFile, rolesFile); FileAttributesChecker attributesChecker = new FileAttributesChecker(passwordFile, rolesFile);
Map<String, char[]> users = new HashMap<>(FileUserPasswdStore.parseFile(passwordFile, null)); Map<String, char[]> users = new HashMap<>(FileUserPasswdStore.parseFile(passwordFile, null));
@ -151,7 +116,6 @@ public class ESUsersTool extends MultiCommand {
} }
attributesChecker.check(terminal); attributesChecker.check(terminal);
return ExitCodes.OK;
} }
} }
@ -178,14 +142,8 @@ public class ESUsersTool extends MultiCommand {
} }
@Override @Override
protected int execute(Terminal terminal, OptionSet options) throws Exception { protected void execute(Terminal terminal, OptionSet options) throws Exception {
String username = arguments.value(options); String username = parseUsername(arguments.values(options));
execute(terminal, username);
return ExitCodes.OK;
}
// pkg private for testing
void execute(Terminal terminal, String username) throws Exception {
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE); Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
Path passwordFile = FileUserPasswdStore.resolveFile(esusersSettings, env); Path passwordFile = FileUserPasswdStore.resolveFile(esusersSettings, env);
Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env); Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env);
@ -241,33 +199,9 @@ public class ESUsersTool extends MultiCommand {
} }
@Override @Override
protected int execute(Terminal terminal, OptionSet options) throws Exception { protected void execute(Terminal terminal, OptionSet options) throws Exception {
String username = arguments.value(options); String username = parseUsername(arguments.values(options));
String password = passwordOption.value(options); char[] password = parsePassword(terminal, passwordOption.value(options));
execute(terminal, username, password);
return ExitCodes.OK;
}
// pkg private for testing
void execute(Terminal terminal, String username, String passwordStr) throws Exception {
char[] password;
if (passwordStr != null) {
password = passwordStr.toCharArray();
Validation.Error validationError = Validation.ESUsers.validatePassword(password);
if (validationError != null) {
throw new UserError(ExitCodes.DATA_ERROR, "Invalid password..." + validationError);
}
} else {
password = terminal.readSecret("Enter new password: ");
Validation.Error validationError = Validation.ESUsers.validatePassword(password);
if (validationError != null) {
throw new UserError(ExitCodes.DATA_ERROR, "Invalid password..." + validationError);
}
char[] retyped = terminal.readSecret("Retype new password: ");
if (Arrays.equals(password, retyped) == false) {
throw new UserError(ExitCodes.DATA_ERROR, "Password mismatch");
}
}
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE); Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
Path file = FileUserPasswdStore.resolveFile(esusersSettings, env); Path file = FileUserPasswdStore.resolveFile(esusersSettings, env);
@ -276,17 +210,15 @@ public class ESUsersTool extends MultiCommand {
if (users.containsKey(username) == false) { if (users.containsKey(username) == false) {
throw new UserError(ExitCodes.NO_USER, "User [" + username + "] doesn't exist"); throw new UserError(ExitCodes.NO_USER, "User [" + username + "] doesn't exist");
} }
Hasher hasher = Hasher.BCRYPT; users.put(username, Hasher.BCRYPT.hash(new SecuredString(password)));
users.put(username, hasher.hash(new SecuredString(password)));
FileUserPasswdStore.writeFile(users, file); FileUserPasswdStore.writeFile(users, file);
attributesChecker.check(terminal); attributesChecker.check(terminal);
} }
} }
static class RolesCommand extends Command { static class RolesCommand extends Command {
public static final Pattern ROLE_PATTERN = Pattern.compile("[\\w@-]+");
private final Environment env; private final Environment env;
private final OptionSpec<String> addOption; private final OptionSpec<String> addOption;
private final OptionSpec<String> removeOption; private final OptionSpec<String> removeOption;
@ -313,17 +245,11 @@ public class ESUsersTool extends MultiCommand {
} }
@Override @Override
protected int execute(Terminal terminal, OptionSet options) throws Exception { protected void execute(Terminal terminal, OptionSet options) throws Exception {
String username = arguments.value(options); String username = parseUsername(arguments.values(options));
String addRoles = addOption.value(options); String[] addRoles = parseRoles(terminal, env, addOption.value(options));
String removeRoles = removeOption.value(options); String[] removeRoles = parseRoles(terminal, env, removeOption.value(options));
execute(terminal, username, addRoles, removeRoles);
return ExitCodes.OK;
}
void execute(Terminal terminal, String username, String addRolesStr, String removeRolesStr) throws Exception {
String[] addRoles = addRolesStr.split(",");
String[] removeRoles = removeRolesStr.split(",");
// check if just need to return data as no write operation happens // check if just need to return data as no write operation happens
// Nothing to add, just list the data for a username // Nothing to add, just list the data for a username
boolean readOnlyUserListing = removeRoles.length == 0 && addRoles.length == 0; boolean readOnlyUserListing = removeRoles.length == 0 && addRoles.length == 0;
@ -332,15 +258,6 @@ public class ESUsersTool extends MultiCommand {
return; return;
} }
// check for roles if they match
String[] allRoles = ArrayUtils.concat(addRoles, removeRoles, String.class);
for (String role : allRoles) {
if (!ROLE_PATTERN.matcher(role).matches()) {
throw new UserError(ExitCodes.DATA_ERROR,
"Role name [" + role + "] is not valid. Please use lowercase and numbers only");
}
}
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE); Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
Path usersFile = FileUserPasswdStore.resolveFile(esusersSettings, env); Path usersFile = FileUserPasswdStore.resolveFile(esusersSettings, env);
Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env); Path rolesFile = FileUserRolesStore.resolveFile(esusersSettings, env);
@ -356,7 +273,6 @@ public class ESUsersTool extends MultiCommand {
if (userRoles.get(username) != null) { if (userRoles.get(username) != null) {
roles.addAll(Arrays.asList(userRoles.get(username))); roles.addAll(Arrays.asList(userRoles.get(username)));
} }
verifyRoles(terminal, env.settings(), env, addRoles);
roles.addAll(Arrays.asList(addRoles)); roles.addAll(Arrays.asList(addRoles));
roles.removeAll(Arrays.asList(removeRoles)); roles.removeAll(Arrays.asList(removeRoles));
@ -391,21 +307,20 @@ public class ESUsersTool extends MultiCommand {
} }
@Override @Override
protected int execute(Terminal terminal, OptionSet options) throws Exception { protected void execute(Terminal terminal, OptionSet options) throws Exception {
String username = null; String username = null;
if (options.has(arguments)) { if (options.has(arguments)) {
username = arguments.value(options); username = arguments.value(options);
} }
listUsersAndRoles(terminal, env, username); listUsersAndRoles(terminal, env, username);
return ExitCodes.OK;
} }
} }
// pkg private for tests // pkg private for tests
static void listUsersAndRoles(Terminal terminal, Environment env, String username) throws Exception { static void listUsersAndRoles(Terminal terminal, Environment env, String username) throws Exception {
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE); Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
Set<String> knownRoles = loadRoleNames(terminal, env.settings(), env);
Path userRolesFilePath = FileUserRolesStore.resolveFile(esusersSettings, env); Path userRolesFilePath = FileUserRolesStore.resolveFile(esusersSettings, env);
Set<String> knownRoles = FileRolesStore.parseFileForRoleNames(userRolesFilePath, null);
Map<String, String[]> userRoles = FileUserRolesStore.parseFile(userRolesFilePath, null); Map<String, String[]> userRoles = FileUserRolesStore.parseFile(userRolesFilePath, null);
Path userFilePath = FileUserPasswdStore.resolveFile(esusersSettings, env); Path userFilePath = FileUserPasswdStore.resolveFile(esusersSettings, env);
Set<String> users = FileUserPasswdStore.parseFile(userFilePath, null).keySet(); Set<String> users = FileUserPasswdStore.parseFile(userFilePath, null).keySet();
@ -465,18 +380,6 @@ public class ESUsersTool extends MultiCommand {
} }
} }
private static Set<String> loadRoleNames(Terminal terminal, Settings settings, Environment env) {
Path rolesFile = FileRolesStore.resolveFile(settings, env);
try {
return FileRolesStore.parseFileForRoleNames(rolesFile, null);
} catch (Throwable t) {
// if for some reason, parsing fails (malformatted perhaps) we just warn
terminal.println(String.format(Locale.ROOT, "Warning: Could not parse [%s] for roles verification. Please revise and fix it." +
" Nonetheless, the user will still be associated with all specified roles", rolesFile.toAbsolutePath()));
}
return null;
}
private static String[] markUnknownRoles(String[] roles, Set<String> unknownRoles) { private static String[] markUnknownRoles(String[] roles, Set<String> unknownRoles) {
if (unknownRoles.isEmpty()) { if (unknownRoles.isEmpty()) {
return roles; return roles;
@ -492,14 +395,73 @@ public class ESUsersTool extends MultiCommand {
return marked; return marked;
} }
// pkg private for testing
static String parseUsername(List<String> args) throws UserError {
if (args.isEmpty()) {
throw new UserError(ExitCodes.USAGE, "Missing username argument");
} else if (args.size() > 1) {
throw new UserError(ExitCodes.USAGE, "Expected a single username argument, found extra: " + args.toString());
}
String username = args.get(0);
Validation.Error validationError = Validation.ESUsers.validateUsername(username);
if (validationError != null) {
throw new UserError(ExitCodes.DATA_ERROR, "Invalid username [" + username + "]... " + validationError);
}
return username;
}
// pkg private for testing
static char[] parsePassword(Terminal terminal, String passwordStr) throws UserError {
char[] password;
if (passwordStr != null) {
password = passwordStr.toCharArray();
Validation.Error validationError = Validation.ESUsers.validatePassword(password);
if (validationError != null) {
throw new UserError(ExitCodes.DATA_ERROR, "Invalid password..." + validationError);
}
} else {
password = terminal.readSecret("Enter new password: ");
Validation.Error validationError = Validation.ESUsers.validatePassword(password);
if (validationError != null) {
throw new UserError(ExitCodes.DATA_ERROR, "Invalid password..." + validationError);
}
char[] retyped = terminal.readSecret("Retype new password: ");
if (Arrays.equals(password, retyped) == false) {
throw new UserError(ExitCodes.DATA_ERROR, "Password mismatch");
}
}
return password;
}
private static void verifyRoles(Terminal terminal, Settings settings, Environment env, String[] roles) { private static void verifyRoles(Terminal terminal, Settings settings, Environment env, String[] roles) {
Set<String> knownRoles = loadRoleNames(terminal, settings, env); Path rolesFile = FileRolesStore.resolveFile(settings, env);
assert Files.exists(rolesFile);
Set<String> knownRoles = FileRolesStore.parseFileForRoleNames(rolesFile, null);
Set<String> unknownRoles = Sets.difference(Sets.newHashSet(roles), knownRoles); Set<String> unknownRoles = Sets.difference(Sets.newHashSet(roles), knownRoles);
if (!unknownRoles.isEmpty()) { if (!unknownRoles.isEmpty()) {
Path rolesFile = FileRolesStore.resolveFile(settings, env);
terminal.println(String.format(Locale.ROOT, "Warning: The following roles [%s] are unknown. Make sure to add them to the [%s]" + terminal.println(String.format(Locale.ROOT, "Warning: The following roles [%s] are unknown. Make sure to add them to the [%s]" +
" file. Nonetheless the user will still be associated with all specified roles", " file. Nonetheless the user will still be associated with all specified roles",
Strings.collectionToCommaDelimitedString(unknownRoles), rolesFile.toAbsolutePath())); Strings.collectionToCommaDelimitedString(unknownRoles), rolesFile.toAbsolutePath()));
terminal.println("Known roles: " + knownRoles.toString());
} }
} }
// pkg private for testing
static String[] parseRoles(Terminal terminal, Environment env, String rolesStr) throws UserError {
if (rolesStr.isEmpty()) {
return Strings.EMPTY_ARRAY;
}
String[] roles = rolesStr.split(",");
for (String role : roles) {
Validation.Error validationError = Validation.Roles.validateRoleName(role);
if (validationError != null) {
throw new UserError(ExitCodes.DATA_ERROR, "Invalid role [" + role + "]... " + validationError);
}
}
Settings esusersSettings = Realms.internalRealmSettings(env.settings(), ESUsersRealm.TYPE);
verifyRoles(terminal, esusersSettings, env, roles);
return roles;
}
} }

View File

@ -19,14 +19,13 @@ import joptsimple.OptionSpec;
import org.elasticsearch.cli.Command; import org.elasticsearch.cli.Command;
import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.UserError; import org.elasticsearch.cli.UserError;
import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.io.PathUtils;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.node.internal.InternalSettingsPreparer; import org.elasticsearch.node.internal.InternalSettingsPreparer;
import org.elasticsearch.shield.crypto.InternalCryptoService; import org.elasticsearch.shield.crypto.InternalCryptoService;
import org.elasticsearch.shield.support.FileAttributesChecker;
public class SystemKeyTool extends Command { public class SystemKeyTool extends Command {
@ -48,7 +47,7 @@ public class SystemKeyTool extends Command {
} }
@Override @Override
protected int execute(Terminal terminal, OptionSet options) throws Exception { protected void execute(Terminal terminal, OptionSet options) throws Exception {
Path keyPath = null; Path keyPath = null;
List<String> args = arguments.values(options); List<String> args = arguments.values(options);
if (args.size() > 1) { if (args.size() > 1) {
@ -57,7 +56,6 @@ public class SystemKeyTool extends Command {
keyPath = PathUtils.get(args.get(0)); keyPath = PathUtils.get(args.get(0));
} }
execute(terminal, keyPath); execute(terminal, keyPath);
return ExitCodes.OK;
} }
// pkg private for tests // pkg private for tests

View File

@ -12,7 +12,7 @@ import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFileAttributes; import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermissions; import java.nio.file.attribute.PosixFilePermissions;
import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.cli.Terminal;
/** /**
* A utility for cli tools to capture file attributes * A utility for cli tools to capture file attributes

View File

@ -1,17 +0,0 @@
NAME
list - List existing users and their corresponding roles
SYNOPSIS
esusers list <username>
DESCRIPTION
The list command allows to list all existing users and their
corresponding roles. Alternatively you can also list just a
single user.
OPTIONS
-h,--help Shows this message

View File

@ -1,22 +0,0 @@
NAME
passwd - Changes the password of an existing native user
SYNOPSIS
esusers passwd <username> [-p <password>]
DESCRIPTION
The passwd command changes passwords for native user accounts. The tool
prompts twice for a replacement password. The second entry is compared
against the first and both are required to match in order for the
password to be changed. If non-default users file is used (a different
file location is configured in elasticsearch.yml) the appropriate file
will be resolved from the settings.
OPTIONS
-h,--help Shows this message
-p,--password <password> The new password for the user

View File

@ -1,21 +0,0 @@
NAME
roles - Edit roles of an existing user
SYNOPSIS
esusers roles <username> [-a roles] [-r roles]
DESCRIPTION
The roles command allows to edit roles for an existing user.
corresponding roles. Alternatively you can also list just a
single users roles, if you do not specify the -a or the -r parameter.
OPTIONS
-h,--help Shows this message
-a,--add <roles> Adds supplied roles for the specified user
-r,--remove <roles> Adds supplied roles for the specified user

View File

@ -1,28 +0,0 @@
NAME
useradd - Adds a native user
SYNOPSIS
esusers useradd <username> [-p <password>] [-r <roles>]
DESCRIPTION
Adds a native user to elasticsearch (via internal realm). The user will
be added to the users file and its roles will be added to the
users_roles file. If non-default files are used (different file
locations are configured in elasticsearch.yml) the appropriate files
will be resolved from the settings and the user and its roles will be
added to them.
OPTIONS
-h,--help Shows this message
-p,--password <password> The user password
-r,--roles <roles> Comma-separated list of the roles of the user
SEE ALSO
[1] esusers userdel

View File

@ -1,24 +0,0 @@
NAME
userdel - Delete an existing native user
SYNOPSIS
esusers userdel <username>
DESCRIPTION
Removes an existing native user from elasticsearch. The user will be
removed from the users file and its roles will be removed to the
users_roles file. If non-default files are used (different file
locations are configured in elasticsearch.yml) the appropriate files
will be resolved from the settings and the user and its roles will be
removed to them.
OPTIONS
-h,--help Shows this message
SEE ALSO
[1] esusers useradd

View File

@ -1,30 +0,0 @@
NAME
esusers - Manages elasticsearch native users
SYNOPSIS
esusers <command>
DESCRIPTION
This tool manages all native security aspects in elasticsearch, saving
the administrator from needing to modify security related fields manually.
This tool provides several commands for different security management
tasks
COMMANDS
passwd Changes passwords for a native user
useradd Adds a new native user to the system
userdel Removes an existing native user from the system
roles Manage roles of a single user
list List users and roles
NOTES
[*] For usage help on specific commands please type "esusers <command> -h"

View File

@ -12,7 +12,7 @@ import java.nio.file.attribute.PosixFilePermission;
import java.util.Set; import java.util.Set;
import org.elasticsearch.cli.MockTerminal; import org.elasticsearch.cli.MockTerminal;
import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.shield.crypto.InternalCryptoService; import org.elasticsearch.shield.crypto.InternalCryptoService;

View File

@ -10,26 +10,16 @@ import java.util.List;
import joptsimple.OptionSet; import joptsimple.OptionSet;
import joptsimple.OptionSpec; import joptsimple.OptionSpec;
import org.apache.commons.cli.CommandLine;
import org.elasticsearch.cli.Command; import org.elasticsearch.cli.Command;
import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.cli.ExitCodes;
import org.elasticsearch.cli.UserError; import org.elasticsearch.cli.UserError;
import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.cli.CliTool;
import org.elasticsearch.common.cli.CliToolConfig;
import org.elasticsearch.common.cli.Terminal;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.watcher.trigger.schedule.Cron; import org.elasticsearch.watcher.trigger.schedule.Cron;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.DateTimeZone; import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeFormatter;
import static org.elasticsearch.common.cli.CliToolConfig.Builder.cmd;
import static org.elasticsearch.common.cli.CliToolConfig.Builder.option;
import static org.elasticsearch.common.cli.CliToolConfig.config;
public class CronEvalTool extends Command { public class CronEvalTool extends Command {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -52,14 +42,13 @@ public class CronEvalTool extends Command {
} }
@Override @Override
protected int execute(Terminal terminal, OptionSet options) throws Exception { protected void execute(Terminal terminal, OptionSet options) throws Exception {
int count = Integer.parseInt(countOption.value(options)); int count = Integer.parseInt(countOption.value(options));
List<String> args = arguments.values(options); List<String> args = arguments.values(options);
if (args.size() != 1) { if (args.size() != 1) {
throw new UserError(ExitCodes.USAGE, "expecting a single argument that is the cron expression to evaluate"); throw new UserError(ExitCodes.USAGE, "expecting a single argument that is the cron expression to evaluate");
} }
execute(terminal, args.get(0), count); execute(terminal, args.get(0), count);
return ExitCodes.OK;
} }
void execute(Terminal terminal, String expression, int count) throws Exception { void execute(Terminal terminal, String expression, int count) throws Exception {

View File

@ -6,7 +6,7 @@
package org.elasticsearch.watcher.actions.email.service; package org.elasticsearch.watcher.actions.email.service;
import org.apache.lucene.util.LuceneTestCase.AwaitsFix; import org.apache.lucene.util.LuceneTestCase.AwaitsFix;
import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.cli.Terminal;
import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;

View File

@ -5,7 +5,7 @@
*/ */
package org.elasticsearch.watcher.trigger.schedule.tool; package org.elasticsearch.watcher.trigger.schedule.tool;
import org.elasticsearch.common.cli.Terminal; import org.elasticsearch.cli.Terminal;
/** /**
* A small executable tool that can eval crons * A small executable tool that can eval crons