Repository: incubator-geode Updated Branches: refs/heads/develop 11ef3ebbe -> b2e776859
GEODE-1959: prompt for password when starting a server if username is specified Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/b2e77685 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/b2e77685 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/b2e77685 Branch: refs/heads/develop Commit: b2e77685907c51b1af346e6f8b8da3f5b598b361 Parents: 11ef3eb Author: Jinmei Liao <jil...@pivotal.io> Authored: Tue Oct 18 09:13:26 2016 -0700 Committer: Jinmei Liao <jil...@pivotal.io> Committed: Wed Oct 19 21:16:23 2016 -0700 ---------------------------------------------------------------------- .../LauncherLifecycleCommandsDUnitTest.java | 22 ++++++ .../geode/distributed/ServerLauncher.java | 78 ++++++++++++++------ .../membership/gms/membership/GMSJoinLeave.java | 7 +- .../cli/commands/LauncherLifecycleCommands.java | 29 +++++++- .../internal/cli/commands/ShellCommands.java | 48 +++--------- .../internal/cli/i18n/CliStrings.java | 13 +++- .../management/internal/cli/shell/Gfsh.java | 41 ++++++---- .../cli/commands/golden-help-offline.properties | 9 +++ 8 files changed, 166 insertions(+), 81 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b2e77685/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java index 490e309..933d152 100644 --- a/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java +++ b/geode-assembly/src/test/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommandsDUnitTest.java @@ -437,6 +437,28 @@ public class LauncherLifecycleCommandsDUnitTest extends CliCommandTestBase { } @Test + public void testStartServerFailsFastOnMissingPassword() throws IOException { + + CommandStringBuilder command = new CommandStringBuilder(CliStrings.START_SERVER); + + String pathName = getClass().getSimpleName().concat("_").concat(getTestMethodName()); + final File workingDirectory = temporaryFolder.newFolder(pathName); + + command.addOption(CliStrings.START_SERVER__NAME, pathName); + command.addOption(CliStrings.START_SERVER__DIR, workingDirectory.getCanonicalPath()); + command.addOption(CliStrings.START_SERVER__USERNAME, "test"); + + CommandResult result = executeCommand(command.toString()); + + assertNotNull(result); + assertEquals(Result.Status.ERROR, result.getStatus()); + + String resultString = toString(result); + + assertTrue(resultString, resultString.contains("password must be specified")); + } + + @Test public void test005StartServerFailsFastOnMissingGemFireSecurityPropertiesFile() throws IOException { String gemfireSecuritiesPropertiesFile = "/path/to/missing/gemfire-securities.properties"; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b2e77685/geode-core/src/main/java/org/apache/geode/distributed/ServerLauncher.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/distributed/ServerLauncher.java b/geode-core/src/main/java/org/apache/geode/distributed/ServerLauncher.java index a3d3845..088b670 100755 --- a/geode-core/src/main/java/org/apache/geode/distributed/ServerLauncher.java +++ b/geode-core/src/main/java/org/apache/geode/distributed/ServerLauncher.java @@ -19,6 +19,32 @@ package org.apache.geode.distributed; import static org.apache.geode.distributed.ConfigurationProperties.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.ServiceLoader; +import java.util.TreeMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; + +import joptsimple.OptionException; +import joptsimple.OptionParser; +import joptsimple.OptionSet; + import org.apache.geode.SystemFailure; import org.apache.geode.cache.Cache; import org.apache.geode.cache.partition.PartitionRegionHelper; @@ -27,14 +53,31 @@ import org.apache.geode.distributed.internal.DefaultServerLauncherCacheProvider; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.internal.GemFireVersion; -import org.apache.geode.internal.net.SocketCreator; -import org.apache.geode.internal.cache.*; +import org.apache.geode.internal.cache.AbstractCacheServer; +import org.apache.geode.internal.cache.CacheConfig; +import org.apache.geode.internal.cache.CacheServerLauncher; +import org.apache.geode.internal.cache.GemFireCacheImpl; +import org.apache.geode.internal.cache.PartitionedRegion; import org.apache.geode.internal.cache.tier.sockets.CacheServerHelper; import org.apache.geode.internal.i18n.LocalizedStrings; import org.apache.geode.internal.lang.ObjectUtils; import org.apache.geode.internal.lang.StringUtils; import org.apache.geode.internal.lang.SystemUtils; -import org.apache.geode.internal.process.*; +import org.apache.geode.internal.net.SocketCreator; +import org.apache.geode.internal.process.ClusterConfigurationNotAvailableException; +import org.apache.geode.internal.process.ConnectionFailedException; +import org.apache.geode.internal.process.ControlNotificationHandler; +import org.apache.geode.internal.process.ControllableProcess; +import org.apache.geode.internal.process.FileAlreadyExistsException; +import org.apache.geode.internal.process.MBeanInvocationFailedException; +import org.apache.geode.internal.process.PidUnavailableException; +import org.apache.geode.internal.process.ProcessController; +import org.apache.geode.internal.process.ProcessControllerFactory; +import org.apache.geode.internal.process.ProcessControllerParameters; +import org.apache.geode.internal.process.ProcessLauncherContext; +import org.apache.geode.internal.process.ProcessType; +import org.apache.geode.internal.process.StartupStatusListener; +import org.apache.geode.internal.process.UnableToControlProcessException; import org.apache.geode.internal.util.IOUtils; import org.apache.geode.lang.AttachAPINotFoundException; import org.apache.geode.management.internal.cli.i18n.CliStrings; @@ -42,25 +85,8 @@ import org.apache.geode.management.internal.cli.json.GfJsonArray; import org.apache.geode.management.internal.cli.json.GfJsonException; import org.apache.geode.management.internal.cli.json.GfJsonObject; import org.apache.geode.pdx.PdxSerializer; -import joptsimple.OptionException; -import joptsimple.OptionParser; -import joptsimple.OptionSet; - -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -import static org.apache.geode.distributed.ConfigurationProperties.SERVER_BIND_ADDRESS; +import org.apache.geode.security.AuthenticationRequiredException; +import org.apache.geode.security.GemFireSecurityException; /** * The ServerLauncher class is a launcher class with main method to start a GemFire Server (implying a GemFire Cache @@ -730,6 +756,14 @@ public class ServerLauncher extends AbstractLauncher<String> { return new ServerState(this, Status.ONLINE); } + catch(AuthenticationRequiredException e){ + failOnStart(e); + throw new AuthenticationRequiredException("user/password required. Please start your server with --user and --password. "+ e.getMessage()); + } + catch(GemFireSecurityException e){ + failOnStart(e); + throw new GemFireSecurityException(e.getMessage()); + } catch (IOException e) { failOnStart(e); throw new RuntimeException(LocalizedStrings.Launcher_Command_START_IO_ERROR_MESSAGE.toLocalizedString( http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b2e77685/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java index 89a9a37..f5198bb 100644 --- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java +++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java @@ -41,6 +41,8 @@ import java.util.concurrent.Future; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.logging.log4j.Logger; + import org.apache.geode.GemFireConfigException; import org.apache.geode.SystemConnectException; import org.apache.geode.distributed.DistributedMember; @@ -70,8 +72,8 @@ import org.apache.geode.distributed.internal.membership.gms.messages.ViewAckMess import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.Version; import org.apache.geode.internal.i18n.LocalizedStrings; +import org.apache.geode.security.AuthenticationRequiredException; import org.apache.geode.security.GemFireSecurityException; -import org.apache.logging.log4j.Logger; /** * GMSJoinLeave handles membership communication with other processes in the @@ -413,6 +415,9 @@ public class GMSJoinLeave implements JoinLeave, MessageHandler { || failReason.contains("15806")) { throw new SystemConnectException(failReason); } + else if(failReason.contains("Failed to find credentials")){ + throw new AuthenticationRequiredException(failReason); + } throw new GemFireSecurityException(failReason); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b2e77685/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommands.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommands.java index 4ffe082..892a92d 100755 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommands.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/LauncherLifecycleCommands.java @@ -17,6 +17,7 @@ package org.apache.geode.management.internal.cli.commands; import static org.apache.geode.distributed.ConfigurationProperties.*; +import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__PASSWORD; import java.awt.Desktop; import java.io.BufferedReader; @@ -115,6 +116,7 @@ import org.apache.geode.management.internal.cli.util.VisualVmNotFoundException; import org.apache.geode.management.internal.configuration.domain.SharedConfigurationStatus; import org.apache.geode.management.internal.configuration.messages.SharedConfigurationStatusRequest; import org.apache.geode.management.internal.configuration.messages.SharedConfigurationStatusResponse; +import org.apache.geode.management.internal.security.ResourceConstants; import org.apache.geode.security.AuthenticationFailedException; /** @@ -1498,11 +1500,28 @@ public class LauncherLifecycleCommands extends AbstractCommandsSupport { @CliOption(key = CliStrings.START_SERVER__HTTP_SERVICE_BIND_ADDRESS, unspecifiedDefaultValue = CacheServer.HTTP_SERVICE_DEFAULT_BIND_ADDRESS, help = CliStrings.START_SERVER__HTTP_SERVICE_BIND_ADDRESS__HELP) - final String httpServiceBindAddress) + final String httpServiceBindAddress, + @CliOption(key = CliStrings.START_SERVER__USERNAME, + unspecifiedDefaultValue = "", + help = CliStrings.START_SERVER__USERNAME__HELP) + final String userName, + @CliOption(key = START_SERVER__PASSWORD, + unspecifiedDefaultValue = "", + help = CliStrings.START_SERVER__PASSWORD__HELP) + String passwordToUse) // NOTICE: keep the parameters in alphabetical order based on their CliStrings.START_SERVER_* text { - try { + // prompt for password is username is specified in the command + if (!StringUtils.isBlank(userName)) { + if (StringUtils.isBlank(passwordToUse)) { + passwordToUse = getGfsh().readPassword(START_SERVER__PASSWORD + ": "); + } + if (StringUtils.isBlank(passwordToUse)) { + return ResultBuilder.createConnectionErrorResult(CliStrings.START_SERVER__MSG__PASSWORD_MUST_BE_SPECIFIED); + } + } + if (workingDirectory == null) { // attempt to use or make sub-directory using memberName... File serverWorkingDirectory = new File(memberName); @@ -1560,10 +1579,14 @@ public class LauncherLifecycleCommands extends AbstractCommandsSupport { gemfireProperties.setProperty(USE_CLUSTER_CONFIGURATION, StringUtils.valueOf(requestSharedConfiguration, Boolean.TRUE.toString())); gemfireProperties.setProperty(LOCK_MEMORY, StringUtils.valueOf(lockMemory, StringUtils.EMPTY_STRING)); gemfireProperties.setProperty(OFF_HEAP_MEMORY_SIZE, StringUtils.valueOf(offHeapMemorySize, StringUtils.EMPTY_STRING)); - gemfireProperties.setProperty(START_DEV_REST_API, StringUtils.valueOf(startRestApi, StringUtils.EMPTY_STRING)); gemfireProperties.setProperty(HTTP_SERVICE_PORT, StringUtils.valueOf(httpServicePort, StringUtils.EMPTY_STRING)); gemfireProperties.setProperty(HTTP_SERVICE_BIND_ADDRESS, StringUtils.valueOf(httpServiceBindAddress, StringUtils.EMPTY_STRING)); + // if username is specified in the command line, it will overwrite what's set in the properties file + if(!StringUtils.isBlank(userName)){ + gemfireProperties.setProperty(ResourceConstants.USER_NAME, userName); + gemfireProperties.setProperty(ResourceConstants.PASSWORD, passwordToUse); + } // read the OSProcess enable redirect system property here -- TODO: replace with new GFSH argument http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b2e77685/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ShellCommands.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ShellCommands.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ShellCommands.java index 792a8ab..ee09167 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ShellCommands.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ShellCommands.java @@ -88,14 +88,6 @@ import org.apache.geode.management.internal.web.shell.HttpOperationInvoker; import org.apache.geode.management.internal.web.shell.RestHttpOperationInvoker; import org.apache.geode.security.AuthenticationFailedException; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.ExitShellRequest; -import org.springframework.shell.core.annotation.CliAvailabilityIndicator; -import org.springframework.shell.core.annotation.CliCommand; -import org.springframework.shell.core.annotation.CliOption; - -import static org.apache.geode.distributed.ConfigurationProperties.*; - /** * * @since GemFire 7.0 @@ -200,7 +192,7 @@ public class ShellCommands implements CommandMarker { try { if (userName != null && userName.length() > 0) { if (passwordToUse == null || passwordToUse.length() == 0) { - passwordToUse = this.readPassword(gfsh, "password: "); + passwordToUse = gfsh.readPassword(CliStrings.CONNECT__PASSWORD + ": "); } if (passwordToUse == null || passwordToUse.length() == 0) { return ResultBuilder.createConnectionErrorResult(CliStrings.CONNECT__MSG__JMX_PASSWORD_MUST_BE_SPECIFIED); @@ -282,8 +274,8 @@ public class ShellCommands implements CommandMarker { // otherwise, prompt for username and password and retry the conenction try { - userName = this.readText(gfsh, "username: "); - passwordToUse = this.readPassword(gfsh, "password: "); + userName = gfsh.readText(CliStrings.CONNECT__USERNAME + ": "); + passwordToUse = gfsh.readPassword(CliStrings.CONNECT__PASSWORD + ": "); return httpConnect(sslConfigProps, useSsl, url, userName, passwordToUse); } catch (IOException ioe) { @@ -370,8 +362,8 @@ public class ShellCommands implements CommandMarker { // otherwise, prompt for username and password and retry the conenction try { - userName = this.readText(gfsh, "username: "); - passwordToUse = this.readPassword(gfsh, "password: "); + userName = gfsh.readText(CliStrings.CONNECT__USERNAME + ": "); + passwordToUse = gfsh.readPassword(CliStrings.CONNECT__PASSWORD + ": "); return jmxConnect(sslConfigProps, hostPortToConnect, null, useSsl, userName, passwordToUse, gfSecurityPropertiesPath, true); } catch (IOException ioe) { @@ -522,7 +514,7 @@ public class ShellCommands implements CommandMarker { if (numTimesPrompted > 0) { //NOTE: sslConfigProps map was empty - keystoreToUse = readText(gfshInstance, CliStrings.CONNECT__KEY_STORE + ": "); + keystoreToUse = gfshInstance.readText(CliStrings.CONNECT__KEY_STORE + ": "); } if (keystoreToUse != null && keystoreToUse.length() > 0) { if (keystorePasswordToUse == null || keystorePasswordToUse.length() == 0) { @@ -530,7 +522,7 @@ public class ShellCommands implements CommandMarker { keystorePasswordToUse = sslConfigProps.get(Gfsh.SSL_KEYSTORE_PASSWORD); if (keystorePasswordToUse == null || keystorePasswordToUse.length() == 0) { // not even in properties file, prompt user for it - keystorePasswordToUse = readPassword(gfshInstance, CliStrings.CONNECT__KEY_STORE_PASSWORD + ": "); + keystorePasswordToUse = gfshInstance.readPassword(CliStrings.CONNECT__KEY_STORE_PASSWORD + ": "); sslConfigProps.put(Gfsh.SSL_KEYSTORE_PASSWORD, keystorePasswordToUse); } } @@ -541,7 +533,7 @@ public class ShellCommands implements CommandMarker { } if (numTimesPrompted > 0) { - truststoreToUse = readText(gfshInstance, CliStrings.CONNECT__TRUST_STORE + ": "); + truststoreToUse = gfshInstance.readText(CliStrings.CONNECT__TRUST_STORE + ": "); } if (truststoreToUse != null && truststoreToUse.length() > 0) { if (truststorePasswordToUse == null || truststorePasswordToUse.length() == 0) { @@ -549,7 +541,7 @@ public class ShellCommands implements CommandMarker { truststorePasswordToUse = sslConfigProps.get(Gfsh.SSL_TRUSTSTORE_PASSWORD); if (truststorePasswordToUse == null || truststorePasswordToUse.length() == 0) { // not even in properties file, prompt user for it - truststorePasswordToUse = readPassword(gfshInstance, CliStrings.CONNECT__TRUST_STORE_PASSWORD + ": "); + truststorePasswordToUse = gfshInstance.readPassword(CliStrings.CONNECT__TRUST_STORE_PASSWORD + ": "); sslConfigProps.put(Gfsh.SSL_TRUSTSTORE_PASSWORD, truststorePasswordToUse); } } @@ -560,7 +552,7 @@ public class ShellCommands implements CommandMarker { } if (numTimesPrompted > 0) { - sslCiphersToUse = readText(gfshInstance, CliStrings.CONNECT__SSL_CIPHERS + ": "); + sslCiphersToUse = gfshInstance.readText(CliStrings.CONNECT__SSL_CIPHERS + ": "); } if (sslCiphersToUse != null && sslCiphersToUse.length() > 0) { //sslConfigProps.put(DistributionConfig.CLUSTER_SSL_CIPHERS_NAME, sslCiphersToUse); @@ -568,7 +560,7 @@ public class ShellCommands implements CommandMarker { } if (numTimesPrompted > 0) { - sslProtocolsToUse = readText(gfshInstance, CliStrings.CONNECT__SSL_PROTOCOLS + ": "); + sslProtocolsToUse = gfshInstance.readText(CliStrings.CONNECT__SSL_PROTOCOLS + ": "); } if (sslProtocolsToUse != null && sslProtocolsToUse.length() > 0) { //sslConfigProps.put(DistributionConfig.CLUSTER_SSL_PROTOCOLS_NAME, sslProtocolsToUse); @@ -585,24 +577,6 @@ public class ShellCommands implements CommandMarker { return CliStrings.format(CliStrings.GFSH__PLEASE_CHECK_LOGS_AT_0, logFilePath); } - private String readText(Gfsh gfsh, String textToPrompt) throws IOException { - if (!gfsh.isHeadlessMode() || !gfsh.isQuietMode()) { - return gfsh.interact(textToPrompt); - } - else { - return null; - } - } - - private String readPassword(Gfsh gfsh, String textToPrompt) throws IOException { - if (!gfsh.isHeadlessMode() || !gfsh.isQuietMode()) { - return gfsh.readWithMask(textToPrompt, '*'); - } - else { - return null; - } - } - /* package-private */ static Map<String, String> loadPropertiesFromURL(URL gfSecurityPropertiesUrl) { Map<String, String> propsMap = Collections.emptyMap(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b2e77685/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java index 51887cf..0a6330a 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/i18n/CliStrings.java @@ -16,6 +16,10 @@ */ package org.apache.geode.management.internal.cli.i18n; +import static org.apache.geode.distributed.ConfigurationProperties.*; + +import java.text.MessageFormat; + import org.apache.geode.cache.PartitionAttributesFactory; import org.apache.geode.cache.server.CacheServer; import org.apache.geode.distributed.ConfigurationProperties; @@ -24,10 +28,6 @@ import org.apache.geode.distributed.internal.SharedConfiguration; import org.apache.geode.internal.cache.xmlcache.CacheXml; import org.apache.geode.management.internal.cli.shell.Gfsh; -import java.text.MessageFormat; - -import static org.apache.geode.distributed.ConfigurationProperties.*; - /**- * * Contains 'String' constants used as key to the Localized strings to be used * in classes under <code>org.apache.geode.management.internal.cli</code> @@ -2203,6 +2203,11 @@ public class CliStrings { public static final String START_SERVER__HTTP_SERVICE_PORT__HELP = "Port on which HTTP Service will listen on"; public static final String START_SERVER__HTTP_SERVICE_BIND_ADDRESS = "http-service-bind-address"; public static final String START_SERVER__HTTP_SERVICE_BIND_ADDRESS__HELP = "The IP address on which the HTTP Service will be bound. By default, the Server is bound to all local addresses."; + public static final String START_SERVER__USERNAME = "user"; + public static final String START_SERVER__USERNAME__HELP = "User name to securely connect to the cluster. If the --password parameter is not specified then it will be prompted for."; + public static final String START_SERVER__PASSWORD = "password"; + public static final String START_SERVER__PASSWORD__HELP = "Password to securely connect to the cluster."; + public static final String START_SERVER__MSG__PASSWORD_MUST_BE_SPECIFIED = "password must be specified."; /** * Creates a MessageFormat with the given pattern and uses it to format the given argument. * http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b2e77685/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java index 467682d..e729f20 100755 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/Gfsh.java @@ -20,7 +20,6 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; -import java.io.InputStream; import java.io.PrintStream; import java.net.URL; import java.text.MessageFormat; @@ -37,6 +36,18 @@ import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger; +import jline.Terminal; +import jline.console.ConsoleReader; +import org.springframework.shell.core.AbstractShell; +import org.springframework.shell.core.CommandMarker; +import org.springframework.shell.core.Converter; +import org.springframework.shell.core.ExecutionStrategy; +import org.springframework.shell.core.ExitShellRequest; +import org.springframework.shell.core.JLineLogHandler; +import org.springframework.shell.core.JLineShell; +import org.springframework.shell.core.Parser; +import org.springframework.shell.event.ShellStatus.Status; + import org.apache.geode.internal.Banner; import org.apache.geode.internal.GemFireVersion; import org.apache.geode.internal.lang.ClassUtils; @@ -62,19 +73,6 @@ import org.apache.geode.management.internal.cli.shell.jline.GfshUnsupportedTermi import org.apache.geode.management.internal.cli.shell.unsafe.GfshSignalHandler; import org.apache.geode.management.internal.cli.util.CommentSkipHelper; -import org.springframework.shell.core.AbstractShell; -import org.springframework.shell.core.CommandMarker; -import org.springframework.shell.core.Converter; -import org.springframework.shell.core.ExecutionStrategy; -import org.springframework.shell.core.ExitShellRequest; -import org.springframework.shell.core.JLineLogHandler; -import org.springframework.shell.core.JLineShell; -import org.springframework.shell.core.Parser; -import org.springframework.shell.event.ShellStatus.Status; - -import jline.Terminal; -import jline.console.ConsoleReader; - /** * Extends an interactive shell provided by <a * href="https://github.com/SpringSource/spring-shell">Spring Shell</a> library. @@ -324,6 +322,21 @@ public class Gfsh extends JLineShell { return signalHandler; } + public String readPassword(String textToPrompt) throws IOException { + if(isHeadlessMode && isQuietMode()) + return null; + + return readWithMask(textToPrompt, '*'); + } + + public String readText(String textToPrompt) throws IOException { + if(isHeadlessMode && isQuietMode()) + return null; + + return interact(textToPrompt); + + } + /** * Starts this GemFire Shell with console. */ http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/b2e77685/geode-core/src/test/resources/org/apache/geode/management/internal/cli/commands/golden-help-offline.properties ---------------------------------------------------------------------- diff --git a/geode-core/src/test/resources/org/apache/geode/management/internal/cli/commands/golden-help-offline.properties b/geode-core/src/test/resources/org/apache/geode/management/internal/cli/commands/golden-help-offline.properties index 28083f3..40c28d2 100644 --- a/geode-core/src/test/resources/org/apache/geode/management/internal/cli/commands/golden-help-offline.properties +++ b/geode-core/src/test/resources/org/apache/geode/management/internal/cli/commands/golden-help-offline.properties @@ -2522,6 +2522,7 @@ SYNTAX\n\ \ \ \ \ [--server-port=value] [--socket-buffer-size=value] [--spring-xml-location=value]\n\ \ \ \ \ [--statistic-archive-file=value] [--use-cluster-configuration(=value)?]\n\ \ \ \ \ [--start-rest-api(=value)?] [--http-service-port=value] [--http-service-bind-address=value]\n\ +\ \ \ \ [--user=value] [--password=value]\n\ PARAMETERS\n\ \ \ \ \ assign-buckets\n\ \ \ \ \ \ \ \ \ Whether to assign buckets to the partitioned regions of the cache on server start.\n\ @@ -2735,6 +2736,14 @@ PARAMETERS\n\ \ \ \ \ \ \ \ \ The IP address on which the HTTP Service will be bound. By default, the Server is bound to\n\ \ \ \ \ \ \ \ \ all local addresses.\n\ \ \ \ \ \ \ \ \ Required: false\n\ +\ \ \ \ user\n\ +\ \ \ \ \ \ \ \ User name to securely connect to the cluster. If the --password parameter is not specified\n\ +\ \ \ \ \ \ \ \ then it will be prompted for.\n\ +\ \ \ \ \ \ \ \ Required: false\n\ +\ \ \ \ password\n\ +\ \ \ \ \ \ \ \ Password to securely connect to the cluster.\n\ +\ \ \ \ \ \ \ \ Required: false\n\ + start-vsd.help=\ NAME\n\