Repository: incubator-slider
Updated Branches:
  refs/heads/develop 3e711eba0 -> 477f18dee


SLIDER-625 re-enable reading passwords from the command line, use that 
mechanism for some accumulo tests


Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/477f18de
Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/477f18de
Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/477f18de

Branch: refs/heads/develop
Commit: 477f18dee38a3985d5bd615f9b938f735b014996
Parents: 3e711eb
Author: Billie Rinaldi <[email protected]>
Authored: Tue Nov 11 12:41:10 2014 -0800
Committer: Billie Rinaldi <[email protected]>
Committed: Wed Nov 12 16:46:13 2014 -0800

----------------------------------------------------------------------
 .../funtest/accumulo/AccumuloBasicIT.groovy     |  8 +--
 .../funtest/accumulo/AccumuloSSLTestBase.groovy |  1 -
 .../src/test/resources/test_password_file       |  4 ++
 slider-assembly/src/main/scripts/slider.py      | 28 +++++++-
 .../org/apache/slider/client/SliderClient.java  | 75 ++++++++++++++++----
 5 files changed, 94 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/477f18de/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloBasicIT.groovy
----------------------------------------------------------------------
diff --git 
a/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloBasicIT.groovy
 
b/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloBasicIT.groovy
index bb9abba..f1e1899 100644
--- 
a/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloBasicIT.groovy
+++ 
b/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloBasicIT.groovy
@@ -95,12 +95,9 @@ class AccumuloBasicIT extends AccumuloAgentCommandTestBase {
     conf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, jks)
     CredentialProvider provider =
       CredentialProviderFactory.getProviders(conf).get(0)
-    provider.createCredentialEntry(
-      CustomAuthenticator.ROOT_INITIAL_PASSWORD_PROPERTY, 
PASSWORD.toCharArray())
+    // root initial password and trace password will be initialized at runtime
     provider.createCredentialEntry(Property.INSTANCE_SECRET.toString(),
       INSTANCE_SECRET.toCharArray())
-    provider.createCredentialEntry(Property.TRACE_TOKEN_PROPERTY_PREFIX
-      .toString() + "password", PASSWORD.toCharArray())
     provider.createCredentialEntry(Property.RPC_SSL_KEYSTORE_PASSWORD
       .toString(), KEY_PASS.toCharArray())
     provider.createCredentialEntry(Property.RPC_SSL_TRUSTSTORE_PASSWORD
@@ -131,7 +128,8 @@ class AccumuloBasicIT extends AccumuloAgentCommandTestBase {
       [
         ACTION_CREATE, getClusterName(),
         ARG_TEMPLATE, APP_TEMPLATE,
-        ARG_RESOURCES, APP_RESOURCE
+        ARG_RESOURCES, APP_RESOURCE, "<",
+        sysprop("test.app.resources.dir") + "/test_password_file"
       ])
 
     logShell(shell)

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/477f18de/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloSSLTestBase.groovy
----------------------------------------------------------------------
diff --git 
a/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloSSLTestBase.groovy
 
b/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloSSLTestBase.groovy
index d3165dc..cea28b1 100644
--- 
a/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloSSLTestBase.groovy
+++ 
b/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloSSLTestBase.groovy
@@ -85,7 +85,6 @@ class AccumuloSSLTestBase extends AccumuloBasicIT {
     String provider = tree.global.get(PROVIDER_PROPERTY)
     provider = provider.replace("hdfs/user",
       conf.get("fs.defaultFS").replace("://", "@") + "/user")
-    System.out.println("provider after "+provider)
     File rootKeyStoreFile = new File(TEST_APP_PKG_DIR, "root.jks")
 
     if (!rootKeyStoreFile.exists() && !trustStoreFile.exists()) {

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/477f18de/app-packages/accumulo/src/test/resources/test_password_file
----------------------------------------------------------------------
diff --git a/app-packages/accumulo/src/test/resources/test_password_file 
b/app-packages/accumulo/src/test/resources/test_password_file
new file mode 100644
index 0000000..1fff8af
--- /dev/null
+++ b/app-packages/accumulo/src/test/resources/test_password_file
@@ -0,0 +1,4 @@
+secret_password
+secret_password
+secret_password
+secret_password

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/477f18de/slider-assembly/src/main/scripts/slider.py
----------------------------------------------------------------------
diff --git a/slider-assembly/src/main/scripts/slider.py 
b/slider-assembly/src/main/scripts/slider.py
index 26c9adc..e1112eb 100644
--- a/slider-assembly/src/main/scripts/slider.py
+++ b/slider-assembly/src/main/scripts/slider.py
@@ -21,6 +21,7 @@ import subprocess
 import time
 import platform
 from threading import Thread
+import getpass
 
 CONF = "conf"
 IS_WINDOWS = platform.system() == "Windows"
@@ -40,6 +41,7 @@ DEFAULT_JVM_OPTS = "-Djava.net.preferIPv4Stack=true 
-Djava.awt.headless=true -Xm
 ON_POSIX = 'posix' in sys.builtin_module_names
 
 finished = False
+needPassword = False
 DEBUG = False
 
 """
@@ -162,6 +164,7 @@ def print_output(name, src, toStdErr):
   :return:
   """
 
+  global needPassword
   debug ("starting printer for %s" % name )
   line = ""
   while not finished:
@@ -169,6 +172,8 @@ def print_output(name, src, toStdErr):
     if done:
       out(toStdErr, line + "\n")
       flush(toStdErr)
+      if line.find("Enter password for") >= 0:
+        needPassword = True
       line = ""
   out(toStdErr, line)
   # closedown: read remainder of stream
@@ -182,6 +187,23 @@ def print_output(name, src, toStdErr):
   flush(toStdErr)
   src.close()
 
+def read_input(name, exe):
+  """
+  Read input from stdin and send to process
+  :param name:
+  :param process: process to send input to
+  :return:
+  """
+  global needPassword
+  debug ("starting reader for %s" % name )
+  while not finished:
+    if needPassword:
+      needPassword = False
+      if sys.stdin.isatty():
+        cred = getpass.getpass()
+      else:
+        cred = sys.stdin.readline().rstrip()
+      exe.stdin.write(cred + "\n")
 
 def runProcess(commandline):
   """
@@ -192,7 +214,7 @@ def runProcess(commandline):
   global finished
   debug ("Executing : %s" % commandline)
   exe = subprocess.Popen(commandline,
-                         stdin=None,
+                         stdin=subprocess.PIPE,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          shell=False,
@@ -205,6 +227,9 @@ def runProcess(commandline):
   t2 = Thread(target=print_output, args=("stderr", exe.stderr, True))
   t2.daemon = True 
   t2.start()
+  t3 = Thread(target=read_input, args=("stdin", exe))
+  t3.daemon = True
+  t3.start()
 
   debug("Waiting for completion")
   while exe.poll() is None:
@@ -214,6 +239,7 @@ def runProcess(commandline):
   finished = True
   t.join()
   t2.join()
+  t3.join()
   return exe.returncode
 
 

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/477f18de/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java 
b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
index 164e2fe..ef7856d 100644
--- a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
+++ b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
@@ -153,16 +153,19 @@ import org.codehaus.jettison.json.JSONObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.PrintStream;
 import java.io.StringWriter;
 import java.io.Writer;
 import java.net.InetSocketAddress;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -628,26 +631,68 @@ public class SliderClient extends 
AbstractSliderLaunchedService implements RunSe
       return;
     }
 
-    for (Entry<String, List<String>> cred : tree.credentials.entrySet()) {
-      String provider = cred.getKey();
-      List<String> aliases = cred.getValue();
-      if (aliases == null || aliases.size()==0) {
-        continue;
-      }
-      Configuration c = new Configuration(conf);
-      c.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, provider);
-      CredentialProvider credentialProvider =
-          CredentialProviderFactory.getProviders(c).get(0);
-      Set<String> existingAliases = new 
HashSet<String>(credentialProvider.getAliases());
-      for (String alias : aliases) {
-        if (!existingAliases.contains(alias.toLowerCase(Locale.ENGLISH))) {
-          throw new IOException("Specified credentials have not been " +
-              "initialized in provider " + provider + ": " + alias);
+    BufferedReader br = null;
+    try {
+      for (Entry<String, List<String>> cred : tree.credentials.entrySet()) {
+        String provider = cred.getKey();
+        List<String> aliases = cred.getValue();
+        if (aliases == null || aliases.size() == 0) {
+          continue;
+        }
+        Configuration c = new Configuration(conf);
+        c.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, provider);
+        CredentialProvider credentialProvider =
+            CredentialProviderFactory.getProviders(c).get(0);
+        Set<String> existingAliases =
+            new HashSet<String>(credentialProvider.getAliases());
+        for (String alias : aliases) {
+          if (existingAliases.contains(alias.toLowerCase(Locale.ENGLISH))) {
+            log.info("Credentials for " + alias + " found in " + provider);
+          } else {
+            if (br == null) {
+              br = new BufferedReader(new InputStreamReader(System.in));
+            }
+            char[] pass = readPassword(alias, br);
+            if (pass == null)
+              throw new IOException("Could not read credentials for " + alias +
+                  " from stdin");
+            credentialProvider.createCredentialEntry(alias, pass);
+            credentialProvider.flush();
+            Arrays.fill(pass, ' ');
+          }
         }
       }
+    } finally {
+      if (br != null) {
+        br.close();
+      }
     }
   }
 
+  // using a normal reader instead of a secure one,
+  // because stdin is not hooked up to the command line
+  private char[] readPassword(String alias, BufferedReader br)
+      throws IOException {
+    char[] cred = null;
+
+    boolean noMatch;
+    do {
+      log.info(String.format("Enter password for %s: ", alias));
+      char[] newPassword1 = br.readLine().toCharArray();
+      log.info(String.format("Enter password for %s again: ", alias));
+      char[] newPassword2 = br.readLine().toCharArray();
+      noMatch = !Arrays.equals(newPassword1, newPassword2);
+      if (noMatch) {
+        if (newPassword1 != null) Arrays.fill(newPassword1, ' ');
+        log.info(String.format("Passwords don't match. Try again."));
+      } else {
+        cred = newPassword1;
+      }
+      if (newPassword2 != null) Arrays.fill(newPassword2, ' ');
+    } while (noMatch);
+    return cred;
+  }
+
   @Override
   public int actionBuild(String clustername,
       AbstractClusterBuildingActionArgs buildInfo) throws

Reply via email to