You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by js...@apache.org on 2014/12/16 18:45:25 UTC

ambari git commit: AMBARI-8725. Inject Clusters object into KerberosServerAction

Repository: ambari
Updated Branches:
  refs/heads/trunk 828dc79fa -> 254280c3c


AMBARI-8725. Inject Clusters object into KerberosServerAction


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/254280c3
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/254280c3
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/254280c3

Branch: refs/heads/trunk
Commit: 254280c3cf6f0f78bc178ad10b8c7ec563e656b3
Parents: 828dc79
Author: Robert Levas <rl...@hortonworks.com>
Authored: Tue Dec 16 12:42:39 2014 -0500
Committer: John Speidel <js...@hortonworks.com>
Committed: Tue Dec 16 12:45:16 2014 -0500

----------------------------------------------------------------------
 .../kerberos/KerberosServerAction.java          | 68 +++++++-------
 .../kerberos/KerberosServerActionTest.java      | 96 ++++++++++++--------
 2 files changed, 92 insertions(+), 72 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/254280c3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
index 832602f..a3a1b5b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
@@ -18,10 +18,13 @@
 
 package org.apache.ambari.server.serveraction.kerberos;
 
+import com.google.inject.Inject;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.agent.CommandReport;
 import org.apache.ambari.server.serveraction.AbstractServerAction;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -49,23 +52,10 @@ public abstract class KerberosServerAction extends AbstractServerAction {
   public static final String DATA_DIRECTORY = "data_directory";
 
   /**
-   * A (command parameter) property name used to hold the KDC administrator's principal value.
-   * TODO (rlevas): For security purposes, this data should be moved to an encrypted storage facility.
+   * A (command parameter) property name used to hold encrypted data representing the KDC
+   * administrator credentials
    */
-  public static final String ADMINISTRATOR_PRINCIPAL = "admin_principal";
-
-  /**
-   * A (command parameter) property name used to hold the KDC administrator's password value.
-   * TODO (rlevas): For security purposes, this data should be moved to an encrypted storage facility.
-   */
-  public static final String ADMINISTRATOR_PASSWORD = "admin_password";
-
-  /**
-   * A (command parameter) property name used to hold the KDC administrator's (base64-encoded) keytab
-   * value.
-   * TODO (rlevas): For security purposes, this data should be moved to an encrypted storage facility.
-   */
-  public static final String ADMINISTRATOR_KEYTAB = "admin_keytab";
+  public static final String ADMINISTRATOR_CREDENTIAL = "kerberos_admin_credential";
 
   /**
    * A (command parameter) property name used to hold the default Kerberos realm value.
@@ -86,6 +76,12 @@ public abstract class KerberosServerAction extends AbstractServerAction {
   private static final Logger LOG = LoggerFactory.getLogger(KerberosServerAction.class);
 
   /**
+   * The Cluster that this ServerAction implementation is executing on
+   */
+  @Inject
+  private Clusters clusters = null;
+
+  /**
    * Given a (command parameter) Map and a property name, attempts to safely retrieve the requested
    * data.
    *
@@ -135,25 +131,6 @@ public abstract class KerberosServerAction extends AbstractServerAction {
   }
 
   /**
-   * Given a (command parameter) Map, attempts to safely retrieve the data needed to create a
-   * {@link org.apache.ambari.server.serveraction.kerberos.KerberosCredential} representing a KDC
-   * administrator.
-   * <p/>
-   * TODO (rlevas): For security purposes, this data should be moved to an encrypted storage facility.
-   *
-   * @param commandParameters a Map containing the dictionary of data to interrogate
-   * @return a KerberosCredential or null if commandParameters is null
-   */
-  protected static KerberosCredential getAdministratorCredential(Map<String, String> commandParameters) {
-    return (commandParameters == null)
-        ? null
-        : new KerberosCredential(
-        commandParameters.get(ADMINISTRATOR_PRINCIPAL),
-        commandParameters.get(ADMINISTRATOR_PASSWORD),
-        commandParameters.get(ADMINISTRATOR_KEYTAB));
-  }
-
-  /**
    * Sets the shared principal-to-password Map used to store principals and generated password for
    * use within the current request context.
    *
@@ -195,6 +172,23 @@ public abstract class KerberosServerAction extends AbstractServerAction {
   }
 
   /**
+   * Given a (command parameter) Map, attempts to safely retrieve the "data_directory" property.
+   *
+   * @param commandParameters a Map containing the dictionary of data to interrogate
+   * @return a String indicating the data directory or null (if not found or set)
+   */
+  protected KerberosCredential getAdministratorCredential(Map<String, String> commandParameters) throws AmbariException {
+    Cluster cluster = clusters.getCluster(getExecutionCommand().getClusterName());
+
+    if(cluster == null)
+      throw new AmbariException("Failed get the Cluster object");
+
+    // Create the key like we did when we encrypted the data, based on the Cluster objects hashcode.
+    byte[] key = Integer.toHexString(cluster.hashCode()).getBytes();
+    return KerberosCredential.decrypt(getCommandParameterValue(commandParameters, ADMINISTRATOR_CREDENTIAL), key);
+  }
+
+  /**
    * Attempts to safely retrieve a property with the specified name from the this action's relevant
    * command parameters Map.
    *
@@ -285,6 +279,10 @@ public abstract class KerberosServerAction extends AbstractServerAction {
               break;
             }
           }
+        } catch (AmbariException e) {
+          // Catch this separately from IOException since the reason it was thrown was not the same
+          // Note: AmbariException is an IOException, so there may be some confusion
+          throw new AmbariException(e.getMessage(), e);
         } catch (IOException e) {
           String message = String.format("Failed to process the identities, cannot read the index file: %s",
               indexFile.getAbsolutePath());

http://git-wip-us.apache.org/repos/asf/ambari/blob/254280c3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
index 65e5cd6..fd1017b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
@@ -18,12 +18,17 @@
 
 package org.apache.ambari.server.serveraction.kerberos;
 
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
 import junit.framework.Assert;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.HostRoleCommand;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.agent.CommandReport;
 import org.apache.ambari.server.agent.ExecutionCommand;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -34,20 +39,60 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 public class KerberosServerActionTest {
 
+
   Map<String, String> commandParams = new HashMap<String, String>();
   File temporaryDirectory;
+  private Injector injector;
   private KerberosServerAction action;
 
   @Before
   public void setUp() throws Exception {
+    final Cluster cluster = mock(Cluster.class);
+
+    final Clusters clusters = mock(Clusters.class);
+    when(clusters.getCluster(anyString())).thenReturn(cluster);
+
     final ExecutionCommand mockExecutionCommand = mock(ExecutionCommand.class);
     final HostRoleCommand mockHostRoleCommand = mock(HostRoleCommand.class);
 
+    injector = Guice.createInjector(new AbstractModule() {
+
+      @Override
+      protected void configure() {
+        bind(KerberosServerAction.class).toInstance(new KerberosServerAction() {
+
+          @Override
+          protected CommandReport processIdentity(Map<String, String> identityRecord, String evaluatedPrincipal,
+                                                  KerberosOperationHandler operationHandler,
+                                                  Map<String, Object> requestSharedDataContext)
+              throws AmbariException {
+            Assert.assertNotNull(requestSharedDataContext);
+
+            if (requestSharedDataContext.get("FAIL") != null) {
+              return createCommandReport(1, HostRoleStatus.FAILED, "{}", "ERROR", "ERROR");
+            } else {
+              requestSharedDataContext.put(identityRecord.get(KerberosActionDataFile.PRINCIPAL), evaluatedPrincipal);
+              return null;
+            }
+          }
+
+          @Override
+          public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
+              throws AmbariException, InterruptedException {
+            return processIdentities(requestSharedDataContext);
+          }
+        });
+
+        bind(Clusters.class).toInstance(clusters);
+      }
+    });
+
     temporaryDirectory = File.createTempFile("ambari_ut_", ".d");
 
     Assert.assertTrue(temporaryDirectory.delete());
@@ -65,39 +110,17 @@ public class KerberosServerActionTest {
     }
     builder.close();
 
+
     commandParams.put(KerberosServerAction.DATA_DIRECTORY, temporaryDirectory.getAbsolutePath());
     commandParams.put(KerberosServerAction.DEFAULT_REALM, "REALM.COM");
     commandParams.put(KerberosServerAction.KDC_TYPE, KDCType.MIT_KDC.toString());
-    commandParams.put(KerberosServerAction.ADMINISTRATOR_PRINCIPAL, "principal");
-    commandParams.put(KerberosServerAction.ADMINISTRATOR_PASSWORD, "password");
-    commandParams.put(KerberosServerAction.ADMINISTRATOR_KEYTAB, "keytab");
+    commandParams.put(KerberosServerAction.ADMINISTRATOR_CREDENTIAL,
+        new KerberosCredential("principal", "password", "keytab")
+            .encrypt(Integer.toHexString(cluster.hashCode()).getBytes()));
 
     when(mockExecutionCommand.getCommandParams()).thenReturn(commandParams);
 
-    action = new KerberosServerAction() {
-
-      @Override
-      protected CommandReport processIdentity(Map<String, String> identityRecord, String evaluatedPrincipal,
-                                              KerberosOperationHandler operationHandler,
-                                              Map<String, Object> requestSharedDataContext)
-          throws AmbariException {
-        Assert.assertNotNull(requestSharedDataContext);
-
-        if (requestSharedDataContext.get("FAIL") != null) {
-          return createCommandReport(1, HostRoleStatus.FAILED, "{}", "ERROR", "ERROR");
-        } else {
-          requestSharedDataContext.put(identityRecord.get(KerberosActionDataFile.PRINCIPAL), evaluatedPrincipal);
-          return null;
-        }
-      }
-
-      @Override
-      public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext)
-          throws AmbariException, InterruptedException {
-        return processIdentities(requestSharedDataContext);
-      }
-    };
-
+    action = injector.getInstance(KerberosServerAction.class);
 
     action.setExecutionCommand(mockExecutionCommand);
     action.setHostRoleCommand(mockHostRoleCommand);
@@ -134,16 +157,6 @@ public class KerberosServerActionTest {
   }
 
   @Test
-  public void testCreateAdministratorCredentialStatic() throws Exception {
-    KerberosCredential credential1 = new KerberosCredential("principal", "password", "keytab");
-    KerberosCredential credential2 = KerberosServerAction.getAdministratorCredential(commandParams);
-
-    Assert.assertEquals(credential1.getPrincipal(), credential2.getPrincipal());
-    Assert.assertEquals(credential1.getPassword(), credential2.getPassword());
-    Assert.assertEquals(credential1.getKeytab(), credential2.getKeytab());
-  }
-
-  @Test
   public void testSetPrincipalPasswordMapStatic() throws Exception {
     ConcurrentMap<String, Object> sharedMap = new ConcurrentHashMap<String, Object>();
     Map<String, String> dataMap = new HashMap<String, String>();
@@ -192,4 +205,13 @@ public class KerberosServerActionTest {
     Assert.assertNotNull(report);
     Assert.assertEquals(HostRoleStatus.FAILED.toString(), report.getStatus());
   }
+
+  @Test
+  public void testGetAdministrativeCredentials() throws AmbariException {
+    KerberosCredential credentials = action.getAdministratorCredential(commandParams);
+    Assert.assertNotNull(credentials);
+    Assert.assertEquals("principal", credentials.getPrincipal());
+    Assert.assertEquals("password", credentials.getPassword());
+    Assert.assertEquals("keytab", credentials.getKeytab());
+  }
 }
\ No newline at end of file