SLIDER-1035 check for SASL resolver, kinit command, move things up and down, 
flush stderr on every line too. Stopping work on this for now


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

Branch: refs/heads/develop
Commit: 3c5cea48007aeeea9e7b2fd586573438a318109d
Parents: 64525aa
Author: Steve Loughran <ste...@apache.org>
Authored: Fri Jan 8 13:55:22 2016 +0000
Committer: Steve Loughran <ste...@apache.org>
Committed: Fri Jan 8 13:55:22 2016 +0000

----------------------------------------------------------------------
 .../apache/hadoop/security/KerberosDiags.java   | 218 +++++++++++++------
 .../server/appmaster/SliderAppMaster.java       |   2 +-
 .../apache/slider/client/TestDiagnostics.groovy |  23 +-
 .../funtest/commands/KDiagCommandIT.groovy      |   3 +-
 4 files changed, 171 insertions(+), 75 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/3c5cea48/slider-core/src/main/java/org/apache/hadoop/security/KerberosDiags.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/hadoop/security/KerberosDiags.java 
b/slider-core/src/main/java/org/apache/hadoop/security/KerberosDiags.java
index 4c16a48..4b64e9c 100644
--- a/slider-core/src/main/java/org/apache/hadoop/security/KerberosDiags.java
+++ b/slider-core/src/main/java/org/apache/hadoop/security/KerberosDiags.java
@@ -65,6 +65,8 @@ public class KerberosDiags implements Closeable {
     = "sun.security.krb5.debug";
   public static final String SUN_SECURITY_SPNEGO_DEBUG
     = "sun.security.spnego.debug";
+  public static final String KERBEROS_KINIT_COMMAND
+    = "hadoop.kerberos.kinit.command";
 
   private final Configuration conf;
   private final List<String> services;
@@ -86,48 +88,7 @@ public class KerberosDiags implements Closeable {
 
   @Override
   public void close() throws IOException {
-    if (out != null) {
-      out.flush();
-    }
-  }
-
-  private void println(String format, Object... args) {
-    String msg = String.format(format, args);
-    if (out != null) {
-      out.println(msg);
-      out.flush();
-    } else {
-      LOG.info(msg);
-    }
-  }
-
-  private void title(String format, Object... args) {
-    println("");
-    println("");
-    println(format, args);
-    println("");
-  }
-
-  private void printSysprop(String key) {
-    println("%s = \"%s\"", key, System.getProperty(key, "(unset)"));
-  }
-
-  private void printConfOpt(String key) {
-    println("%s = \"%s\"", key, conf.get(key, "(unset)"));
-  }
-
-  private void printEnv(String key) {
-    String env = System.getenv(key);
-    println("%s = \"%s\"", key, env != null ? env : "(unset)");
-  }
-
-  private void dump(File file) throws IOException {
-    try(FileInputStream in = new FileInputStream(file)) {
-      for (String line: IOUtils.readLines(in)) {
-        println(line);
-      }
-    }
-    println("");
+    flush();
   }
 
   /**
@@ -150,7 +111,7 @@ public class KerberosDiags implements Closeable {
     println("Maximum AES encryption key length %d", aesLen);
     failif (aesLen < 256,
       "Java Cryptography Extensions are not installed on this JVM."
-        +"Kerberos is not going to work.");
+        +" Kerberos will not work.");
     boolean securityDisabled = SecurityUtil.getAuthenticationMethod(conf)
       .equals(UserGroupInformation.AuthenticationMethod.SIMPLE);
     if (securityDisabled) {
@@ -178,31 +139,54 @@ public class KerberosDiags implements Closeable {
       printEnv(env);
     }
     for (String prop : new String[]{
-      "hadoop.kerberos.kinit.command",
+      KERBEROS_KINIT_COMMAND,
       HADOOP_SECURITY_AUTHENTICATION,
       HADOOP_SECURITY_AUTHORIZATION,
+      "hadoop.kerberos.min.seconds.before.relogin",    // not in 2.6
       "hadoop.security.dns.interface",   // not in 2.6
       "hadoop.security.dns.nameserver",  // not in 2.6
-      HADOOP_SSL_ENABLED_KEY,
       HADOOP_RPC_PROTECTION,
       HADOOP_SECURITY_SASL_PROPS_RESOLVER_CLASS,
       HADOOP_SECURITY_CRYPTO_CODEC_CLASSES_KEY_PREFIX,
       HADOOP_SECURITY_GROUP_MAPPING,
+      "hadoop.security.impersonation.provider.class",    // not in 2.6
+      "dfs.data.transfer.protection" // HDFS
+
     }) {
       printConfOpt(prop);
     }
+    validateKrb5File();
+    validateSasl(HADOOP_SECURITY_SASL_PROPS_RESOLVER_CLASS);
+    validateSasl("dfs.data.transfer.saslproperties.resolver.class");
+    validateKinit();
+
+    boolean krb5Debug = getAndSet(SUN_SECURITY_KRB5_DEBUG);
+    boolean spnegoDebug = getAndSet(SUN_SECURITY_SPNEGO_DEBUG);
+
+    try {
+      title("Logging in");
+      UserGroupInformation loginUser = getLoginUser();
+      dumpUser("Log in user", loginUser);
+      println("Ticket based login: %b", isLoginTicketBased());
+      println("Keytab based login: %b", isLoginKeytabBased());
+      validateUser("Login user", loginUser);
+      loginFromKeytab();
+
+      return true;
+    } finally {
+      // restore original system properties
+      System.setProperty(SUN_SECURITY_KRB5_DEBUG,
+        Boolean.toString(krb5Debug));
+      System.setProperty(SUN_SECURITY_SPNEGO_DEBUG,
+        Boolean.toString(spnegoDebug));
+    }
+  }
 
-    System.setProperty(SUN_SECURITY_KRB5_DEBUG, "true");
-    System.setProperty(SUN_SECURITY_SPNEGO_DEBUG, "true");
-
-    title("Logging in");
-    UserGroupInformation loginUser = getLoginUser();
-    dumpUser("Log in user", loginUser);
-    println("Ticket based login: %b", isLoginTicketBased());
-    println("Keytab based login: %b", isLoginKeytabBased());
-    validateUser("Login user", loginUser);
-
-    // locate KDC and dump it
+  /**
+   * Locate the krb5.conf file and dump it. No-op on windows
+   * @throws IOException
+   */
+  private void validateKrb5File() throws IOException {
     if (!Shell.WINDOWS) {
       title("Locating Kerberos configuration file");
       String krbPath = "/etc/krb5.conf";
@@ -230,7 +214,9 @@ public class KerberosDiags implements Closeable {
         "Kerberos configuration file %s not found", krbFile);
       dump(krbFile);
     }
+  }
 
+  private void loginFromKeytab() throws IOException {
     UserGroupInformation ugi;
     String identity;
     if (keytab != null) {
@@ -253,7 +239,6 @@ public class KerberosDiags implements Closeable {
     } else {
       println("No keytab: logging is as current user");
     }
-    return true;
   }
 
   private void dumpUser(String message, UserGroupInformation ugi)
@@ -280,16 +265,7 @@ public class KerberosDiags implements Closeable {
       println("(none)");
     }
 
-    title("Tokens");
-    Collection<Token<? extends TokenIdentifier>> tokens
-      = credentials.getAllTokens();
-    if (!tokens.isEmpty()) {
-      for (Token<? extends TokenIdentifier> token : tokens) {
-        println("%s", token);
-      }
-    } else {
-      println("(none)");
-    }
+    dumpTokens(ugi);
   }
 
   private void validateUser(String message, UserGroupInformation user) {
@@ -299,9 +275,113 @@ public class KerberosDiags implements Closeable {
       "%s: Null AuthenticationMethod for %s", message, user);
   }
 
+  private void validateKinit() {
+    String kinit = conf.getTrimmed(KERBEROS_KINIT_COMMAND, "");
+    if (!kinit.isEmpty()) {
+      File kinitPath = new File(kinit);
+      println("%s = %s", KERBEROS_KINIT_COMMAND, kinitPath);
+      if (kinitPath.isAbsolute()) {
+        failif(!kinitPath.exists(), "%s executable does not exist: %s",
+          KERBEROS_KINIT_COMMAND, kinitPath);
+        failif(!kinitPath.isFile(), "%s path does not refer to a file: %s",
+          KERBEROS_KINIT_COMMAND, kinitPath);
+      } else {
+        println("Executable %s is relative -must be on the PATH", kinit);
+        printEnv("PATH");
+      }
+    }
+  }
+
+  private void validateSasl(String saslPropsResolverKey) {
+    title("Resolving SASL property %s", saslPropsResolverKey);
+    String saslPropsResolver = conf.getTrimmed(saslPropsResolverKey);
+    try {
+      Class<? extends SaslPropertiesResolver> resolverClass = conf.getClass(
+        saslPropsResolverKey,
+        SaslPropertiesResolver.class, SaslPropertiesResolver.class);
+      println("Resolver is %s", resolverClass.toString());
+    } catch (RuntimeException e) {
+      throw new KerberosDiagsFailure(e, "Failed to load %s class %s",
+        saslPropsResolverKey, saslPropsResolver);
+    }
+  }
+
+  public void dumpTokens(UserGroupInformation user) {
+    Collection<Token<? extends TokenIdentifier>> tokens
+      = user.getCredentials().getAllTokens();
+    title("Token Count: %d", tokens.size());
+    for (Token<? extends TokenIdentifier> token : tokens) {
+      println("Token %s", token.getKind());
+    }
+  }
+
+  /**
+   * Set the System property to true; return the old value for caching
+   * @param sysprop property
+   * @return the previous value
+   */
+  private boolean getAndSet(String sysprop) {
+    boolean old = Boolean.getBoolean(sysprop);
+    System.setProperty(sysprop, "true");
+    return old;
+  }
+
+  /**
+   * Flush all active output channels, including {@Code System.err},
+   * so as to stay in sync with any JRE log messages.
+   */
+  private void flush() {
+    if (out != null) {
+      out.flush();
+    } else {
+      System.out.flush();
+    }
+    System.err.flush();
+  }
+
+  private void println(String format, Object... args) {
+    String msg = String.format(format, args);
+    if (out != null) {
+      out.println(msg);
+    } else {
+      LOG.info(msg);
+    }
+    flush();
+  }
+
+  private void title(String format, Object... args) {
+    println("");
+    println("");
+    String msg = "== " + String.format(format, args) + " ==";
+    println(msg);
+    println("");
+  }
+
+  private void printSysprop(String key) {
+    println("%s = \"%s\"", key, System.getProperty(key, "(unset)"));
+  }
+
+  private void printConfOpt(String key) {
+    println("%s = \"%s\"", key, conf.get(key, "(unset)"));
+  }
+
+
+  private void printEnv(String key) {
+    String env = System.getenv(key);
+    println("%s = \"%s\"", key, env != null ? env : "(unset)");
+  }
+
+  private void dump(File file) throws IOException {
+    try (FileInputStream in = new FileInputStream(file)) {
+      for (String line : IOUtils.readLines(in)) {
+        println(line);
+      }
+    }
+    println("");
+  }
+
   /**
    * Format and raise a failure
-   * @param condition failure condition
    * @param message string formatting message
    * @param args any arguments for the formatting
    * @throws KerberosDiagsFailure containing the formatted text
@@ -327,7 +407,7 @@ public class KerberosDiags implements Closeable {
   }
 
   /**
-   * Diagnostics failures include an exit code 41, "unauth"
+   * Diagnostics failures return the exit code 41, "unauthorized"
    */
   public static class KerberosDiagsFailure extends ExitUtil.ExitException {
     public KerberosDiagsFailure( String message) {

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/3c5cea48/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
----------------------------------------------------------------------
diff --git 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
index b793bed..a01dde9 100644
--- 
a/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
+++ 
b/slider-core/src/main/java/org/apache/slider/server/appmaster/SliderAppMaster.java
@@ -1025,7 +1025,7 @@ public class SliderAppMaster extends 
AbstractSliderLaunchedService
   /**
    * Get the YARN application Attempt report as the logged in user
    * @param yarnClient client to the RM
-   * @return the appication report
+   * @return the application report
    * @throws YarnException
    * @throws IOException
    * @throws InterruptedException

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/3c5cea48/slider-core/src/test/groovy/org/apache/slider/client/TestDiagnostics.groovy
----------------------------------------------------------------------
diff --git 
a/slider-core/src/test/groovy/org/apache/slider/client/TestDiagnostics.groovy 
b/slider-core/src/test/groovy/org/apache/slider/client/TestDiagnostics.groovy
index 04f019f..ca22cbe 100644
--- 
a/slider-core/src/test/groovy/org/apache/slider/client/TestDiagnostics.groovy
+++ 
b/slider-core/src/test/groovy/org/apache/slider/client/TestDiagnostics.groovy
@@ -21,16 +21,18 @@ package org.apache.slider.client
 import groovy.transform.CompileStatic
 import groovy.util.logging.Slf4j
 import org.apache.hadoop.yarn.conf.YarnConfiguration
+import static org.apache.slider.common.Constants.SUN_SECURITY_KRB5_DEBUG
 import org.apache.slider.common.params.ActionDiagnosticArgs
 import org.apache.slider.common.params.Arguments
+import org.apache.slider.common.params.ClientArgs
 import org.apache.slider.common.params.SliderActions
+import org.apache.slider.common.tools.SliderUtils
 import org.apache.slider.core.main.ServiceLauncher
 import org.apache.slider.test.SliderTestBase
 import org.apache.slider.test.YarnMiniClusterTestBase
 import org.apache.slider.test.YarnZKMiniClusterTestBase
 import org.junit.Test
 
-@CompileStatic
 @Slf4j
 class TestDiagnostics extends YarnZKMiniClusterTestBase {
 
@@ -50,9 +52,24 @@ class TestDiagnostics extends YarnZKMiniClusterTestBase {
     diagnostics.client = true
     diagnostics.verbose = true
     describe("Verbose diagnostics")
-    
-    
     client.actionDiagnostic(diagnostics)
+  }
+
+  /**
+   * help should print out help string and then succeed
+   * @throws Throwable
+   */
+  @Test
+  public void testKDiag() throws Throwable {
+    ServiceLauncher launcher = launch(SliderClient,
+      SliderUtils.createConfiguration(),
+      [
+        ClientArgs.ACTION_KDIAG,
+        ClientArgs.ARG_FAIL,
+        ClientArgs.ARG_SYSPROP,
+        define(SUN_SECURITY_KRB5_DEBUG, "true")])
 
+    assert 0 == launcher.serviceExitCode
   }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/3c5cea48/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/KDiagCommandIT.groovy
----------------------------------------------------------------------
diff --git 
a/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/KDiagCommandIT.groovy
 
b/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/KDiagCommandIT.groovy
index 8d05df6..61325e2 100644
--- 
a/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/KDiagCommandIT.groovy
+++ 
b/slider-funtest/src/test/groovy/org/apache/slider/funtest/commands/KDiagCommandIT.groovy
@@ -35,8 +35,7 @@ public class KDiagCommandIT extends CommandTestBase 
implements Arguments {
   public void testKdiag() throws Throwable {
     SliderShell shell = new SliderShell([
       SliderActions.ACTION_KDIAG,
-      ARG_FAIL,
-      ARG_SYSPROP, define(SUN_SECURITY_KRB5_DEBUG, "true")
+      ARG_FAIL
     ],
       [(ENV_JAAS_DEBUG): "true"]
     )

Reply via email to