ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rle...@apache.org
Subject ambari git commit: AMBARI-12604. When regenerating Kerberos principals, ensure Kerberos Descriptor changes are applied to services (rlevas)
Date Wed, 05 Aug 2015 16:17:40 GMT
Repository: ambari
Updated Branches:
  refs/heads/branch-2.1 e6d1ff8a4 -> d0e384d3d


AMBARI-12604. When regenerating Kerberos principals, ensure Kerberos Descriptor changes are
applied to services (rlevas)


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

Branch: refs/heads/branch-2.1
Commit: d0e384d3d84dbc7be409fd521dfad7885663b07a
Parents: e6d1ff8
Author: Robert Levas <rlevas@hortonworks.com>
Authored: Wed Aug 5 12:17:19 2015 -0400
Committer: Robert Levas <rlevas@hortonworks.com>
Committed: Wed Aug 5 12:17:19 2015 -0400

----------------------------------------------------------------------
 .../server/controller/KerberosHelperImpl.java   | 105 ++++++++----
 .../kerberos/KerberosServerAction.java          |  13 ++
 .../PrepareEnableKerberosServerAction.java      |  91 +----------
 .../PrepareKerberosIdentitiesServerAction.java  | 161 +++++++++++++++++--
 .../UpdateKerberosConfigsServerAction.java      |  10 +-
 .../server/controller/KerberosHelperTest.java   |   5 +
 6 files changed, 249 insertions(+), 136 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e384d3/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
index 4ae1260..1edbf99 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
@@ -233,12 +233,17 @@ public class KerberosHelperImpl implements KerberosHelper {
                 throw new AmbariException(String.format("Custom operation %s can only be
requested with the security type cluster property: %s", operation.name(), SecurityType.KERBEROS.name()));
               }
 
+              CreatePrincipalsAndKeytabsHandler handler = null;
+
               if ("true".equalsIgnoreCase(value) || "all".equalsIgnoreCase(value)) {
-                requestStageContainer = handle(cluster, getKerberosDetails(cluster, manageIdentities),
null, null, null,
-                    requestStageContainer, new CreatePrincipalsAndKeytabsHandler(true));
+                handler = new CreatePrincipalsAndKeytabsHandler(true, true);
               } else if ("missing".equalsIgnoreCase(value)) {
-                requestStageContainer = handle(cluster, getKerberosDetails(cluster, manageIdentities),
null, null, null,
-                    requestStageContainer, new CreatePrincipalsAndKeytabsHandler(false));
+                handler = new CreatePrincipalsAndKeytabsHandler(false, true);
+              }
+
+              if (handler != null) {
+                requestStageContainer = handle(cluster, getKerberosDetails(cluster, manageIdentities),
+                    null, null, null, requestStageContainer, handler);
               } else {
                 throw new AmbariException(String.format("Unexpected directive value: %s",
value));
               }
@@ -262,7 +267,7 @@ public class KerberosHelperImpl implements KerberosHelper {
                                                 RequestStageContainer requestStageContainer,
Boolean manageIdentities)
       throws AmbariException, KerberosOperationException {
     return handle(cluster, getKerberosDetails(cluster, manageIdentities), serviceComponentFilter,
identityFilter,
-        hostsToForceKerberosOperations, requestStageContainer, new CreatePrincipalsAndKeytabsHandler(false));
+        hostsToForceKerberosOperations, requestStageContainer, new CreatePrincipalsAndKeytabsHandler(false,
false));
   }
 
   @Override
@@ -331,7 +336,7 @@ public class KerberosHelperImpl implements KerberosHelper {
   public RequestStageContainer createTestIdentity(Cluster cluster, Map<String, String>
commandParamsStage,
                                                   RequestStageContainer requestStageContainer)
       throws KerberosOperationException, AmbariException {
-    return handleTestIdentity(cluster, getKerberosDetails(cluster, null), commandParamsStage,
requestStageContainer, new CreatePrincipalsAndKeytabsHandler(false));
+    return handleTestIdentity(cluster, getKerberosDetails(cluster, null), commandParamsStage,
requestStageContainer, new CreatePrincipalsAndKeytabsHandler(false, false));
   }
 
   @Override
@@ -2390,10 +2395,11 @@ public class KerberosHelperImpl implements KerberosHelper {
                              Map<String, ? extends Collection<String>> serviceComponentFilter,
Collection<String> identityFilter, Set<String> hostsWithValidKerberosClient)
         throws AmbariException {
       // If there are principals, keytabs, and configurations to process, setup the following
sages:
-      //  1) generate principals
-      //  2) generate keytab files
-      //  3) distribute keytab files
-      //  4) update configurations
+      //  1) prepare identities
+      //  2) generate principals
+      //  3) generate keytab files
+      //  4) distribute keytab files
+      //  5) update configurations
 
       // If a RequestStageContainer does not already exist, create a new one...
       if (requestStageContainer == null) {
@@ -2406,6 +2412,8 @@ public class KerberosHelperImpl implements KerberosHelper {
 
       Map<String, String> commandParameters = new HashMap<String, String>();
       commandParameters.put(KerberosServerAction.AUTHENTICATED_USER_NAME, ambariManagementController.getAuthName());
+      commandParameters.put(KerberosServerAction.UPDATE_CONFIGURATION_NOTE, "Enabling Kerberos");
+      commandParameters.put(KerberosServerAction.UPDATE_CONFIGURATIONS, "true");
       commandParameters.put(KerberosServerAction.DEFAULT_REALM, kerberosDetails.getDefaultRealm());
       if (dataDirectory != null) {
         commandParameters.put(KerberosServerAction.DATA_DIRECTORY, dataDirectory.getAbsolutePath());
@@ -2511,6 +2519,8 @@ public class KerberosHelperImpl implements KerberosHelper {
 
       Map<String, String> commandParameters = new HashMap<String, String>();
       commandParameters.put(KerberosServerAction.AUTHENTICATED_USER_NAME, ambariManagementController.getAuthName());
+      commandParameters.put(KerberosServerAction.UPDATE_CONFIGURATION_NOTE, "Disabling Kerberos");
+      commandParameters.put(KerberosServerAction.UPDATE_CONFIGURATIONS, "true");
       commandParameters.put(KerberosServerAction.DEFAULT_REALM, kerberosDetails.getDefaultRealm());
       if (dataDirectory != null) {
         commandParameters.put(KerberosServerAction.DATA_DIRECTORY, dataDirectory.getAbsolutePath());
@@ -2577,15 +2587,25 @@ public class KerberosHelperImpl implements KerberosHelper {
     private boolean regenerateAllKeytabs;
 
     /**
+     * A boolean value indicating whether to update service configurations (<code>true</code>)
+     * or ignore any potential configuration changes (<code>false</code>).
+     */
+    private boolean updateConfigurations;
+
+    /**
      * CreatePrincipalsAndKeytabsHandler constructor to set whether this instance should
be used to
      * regenerate all keytabs or just the ones that have not been distributed
      *
      * @param regenerateAllKeytabs A boolean value indicating whether to create keytabs for
all
      *                             principals (<code>true</code> or only the
ones that are missing
      *                             (<code>false</code>)
+     * @param updateConfigurations A boolean value indicating whether to update service configurations
+     *                             (<code>true</code>) or ignore any potential
configuration changes
+     *                             (<code>false</code>)
      */
-    public CreatePrincipalsAndKeytabsHandler(boolean regenerateAllKeytabs) {
+    public CreatePrincipalsAndKeytabsHandler(boolean regenerateAllKeytabs, boolean updateConfigurations)
{
       this.regenerateAllKeytabs = regenerateAllKeytabs;
+      this.updateConfigurations = updateConfigurations;
     }
 
     @Override
@@ -2617,6 +2637,12 @@ public class KerberosHelperImpl implements KerberosHelper {
                              List<ServiceComponentHost> serviceComponentHosts,
                              Map<String, ? extends Collection<String>> serviceComponentFilter,
Collection<String> identityFilter, Set<String> hostsWithValidKerberosClient)
         throws AmbariException {
+      // If there are principals and keytabs to process, setup the following sages:
+      //  1) prepare identities
+      //  2) generate principals
+      //  3) generate keytab files
+      //  4) distribute keytab files
+      //  5) update configurations (optional)
 
       // If a RequestStageContainer does not already exist, create a new one...
       if (requestStageContainer == null) {
@@ -2627,34 +2653,35 @@ public class KerberosHelperImpl implements KerberosHelper {
             actionManager);
       }
 
-      if (kerberosDetails.manageIdentities()) {
-        // If there are principals and keytabs to process, setup the following sages:
-        //  1) prepare identities
-        //  2) generate principals
-        //  3) generate keytab files
-        //  4) distribute keytab files
 
-        Map<String, String> commandParameters = new HashMap<String, String>();
-        commandParameters.put(KerberosServerAction.AUTHENTICATED_USER_NAME, ambariManagementController.getAuthName());
-        commandParameters.put(KerberosServerAction.DEFAULT_REALM, kerberosDetails.getDefaultRealm());
-        if (dataDirectory != null) {
-          commandParameters.put(KerberosServerAction.DATA_DIRECTORY, dataDirectory.getAbsolutePath());
-        }
-        if (serviceComponentFilter != null) {
-          commandParameters.put(KerberosServerAction.SERVICE_COMPONENT_FILTER, StageUtils.getGson().toJson(serviceComponentFilter));
-        }
-        if (identityFilter != null) {
-          commandParameters.put(KerberosServerAction.IDENTITY_FILTER, StageUtils.getGson().toJson(identityFilter));
-        }
+      Map<String, String> commandParameters = new HashMap<String, String>();
+      commandParameters.put(KerberosServerAction.AUTHENTICATED_USER_NAME, ambariManagementController.getAuthName());
+      commandParameters.put(KerberosServerAction.DEFAULT_REALM, kerberosDetails.getDefaultRealm());
+      if (dataDirectory != null) {
+        commandParameters.put(KerberosServerAction.DATA_DIRECTORY, dataDirectory.getAbsolutePath());
+      }
+      if (serviceComponentFilter != null) {
+        commandParameters.put(KerberosServerAction.SERVICE_COMPONENT_FILTER, StageUtils.getGson().toJson(serviceComponentFilter));
+      }
+      if (identityFilter != null) {
+        commandParameters.put(KerberosServerAction.IDENTITY_FILTER, StageUtils.getGson().toJson(identityFilter));
+      }
+
+      commandParameters.put(KerberosServerAction.REGENERATE_ALL, (regenerateAllKeytabs) ?
"true" : "false");
+
+      if(updateConfigurations) {
+        commandParameters.put(KerberosServerAction.UPDATE_CONFIGURATION_NOTE, "Updated Kerberos-related
configurations");
+        commandParameters.put(KerberosServerAction.UPDATE_CONFIGURATIONS, "true");
+      }
+
+      // *****************************************************************
+      // Create stage to create principals
+      addPrepareKerberosIdentitiesStage(cluster, clusterHostInfoJson, hostParamsJson, event,
+          commandParameters, roleCommandOrder, requestStageContainer);
 
+      if (kerberosDetails.manageIdentities()) {
         commandParameters.put(KerberosServerAction.KDC_TYPE, kerberosDetails.getKdcType().name());
         commandParameters.put(KerberosServerAction.ADMINISTRATOR_CREDENTIAL, getEncryptedAdministratorCredentials(cluster));
-        commandParameters.put(KerberosServerAction.REGENERATE_ALL, (regenerateAllKeytabs)
? "true" : "false");
-
-        // *****************************************************************
-        // Create stage to create principals
-        addPrepareKerberosIdentitiesStage(cluster, clusterHostInfoJson, hostParamsJson, event,
-            commandParameters, roleCommandOrder, requestStageContainer);
 
         // *****************************************************************
         // Create stage to create principals
@@ -2666,11 +2693,19 @@ public class KerberosHelperImpl implements KerberosHelper {
         addCreateKeytabFilesStage(cluster, clusterHostInfoJson, hostParamsJson, event,
             commandParameters, roleCommandOrder, requestStageContainer);
 
+        // *****************************************************************
         // Create stage to distribute keytabs
         addDistributeKeytabFilesStage(cluster, serviceComponentHosts, clusterHostInfoJson,
             hostParamsJson, commandParameters, roleCommandOrder, requestStageContainer, hostsWithValidKerberosClient);
       }
 
+      if(updateConfigurations) {
+        // *****************************************************************
+        // Create stage to update configurations of services
+        addUpdateConfigurationsStage(cluster, clusterHostInfoJson, hostParamsJson, event,
commandParameters,
+            roleCommandOrder, requestStageContainer);
+      }
+
       return requestStageContainer.getLastStageId();
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e384d3/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 57e5527..389f1b8 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
@@ -78,6 +78,7 @@ public abstract class KerberosServerAction extends AbstractServerAction
{
    * A (command parameter) property name used to hold the (serialized) identity filter list.
    */
   public static final String IDENTITY_FILTER = "identity_filter";
+
   /**
    * A (command parameter) property name used to hold the relevant KDC type value.  See
    * {@link org.apache.ambari.server.serveraction.kerberos.KDCType} for valid values
@@ -85,6 +86,18 @@ public abstract class KerberosServerAction extends AbstractServerAction
{
   public static final String KDC_TYPE = "kdc_type";
 
   /**
+   * A (command parameter) property name used to hold a boolean value indicating whether
configurations
+   * should be process to see if they need to be updated
+   */
+  public static final String UPDATE_CONFIGURATIONS = "update_configurations";
+
+  /**
+   * A (command parameter) property name used to hold the note to set when applying any
+   * configuration changes
+   */
+  public static final String UPDATE_CONFIGURATION_NOTE = "update_configuration_note";
+
+  /**
    * The prefix to use for the data directory name.
    */
   public static final String DATA_DIRECTORY_PREFIX = ".ambari_";

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e384d3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareEnableKerberosServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareEnableKerberosServerAction.java
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareEnableKerberosServerAction.java
index 9caf7df..84248dc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareEnableKerberosServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareEnableKerberosServerAction.java
@@ -18,20 +18,14 @@
 
 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.controller.KerberosHelper;
 import org.apache.ambari.server.state.Cluster;
-import org.apache.ambari.server.state.SecurityState;
 import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-import java.io.File;
-import java.io.IOException;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
@@ -42,18 +36,7 @@ import java.util.concurrent.ConcurrentMap;
  * PrepareEnableKerberosServerAction is a ServerAction implementation that prepares metadata
needed
  * to enable Kerberos on the cluster.
  */
-public class PrepareEnableKerberosServerAction extends AbstractPrepareKerberosServerAction
{
-  private final static Logger LOG = LoggerFactory.getLogger(PrepareEnableKerberosServerAction.class);
-
-  /**
-   * KerberosHelper
-   */
-  @Inject
-  private KerberosHelper kerberosHelper;
-
-  @Inject
-  private KerberosConfigDataFileWriterFactory kerberosConfigDataFileWriterFactory;
-
+public class PrepareEnableKerberosServerAction extends PrepareKerberosIdentitiesServerAction
{
 
   /**
    * Called to execute this action.  Upon invocation, calls
@@ -78,18 +61,9 @@ public class PrepareEnableKerberosServerAction extends AbstractPrepareKerberosSe
       throw new AmbariException("Missing cluster object");
     }
 
-    KerberosDescriptor kerberosDescriptor = kerberosHelper.getKerberosDescriptor(cluster);
+    KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster);
     Collection<String> identityFilter = getIdentityFilter();
-    List<ServiceComponentHost> schToProcess = kerberosHelper.getServiceComponentHostsToProcess(cluster,
-        kerberosDescriptor,
-        getServiceComponentFilter(),
-        identityFilter,
-        new KerberosHelper.Command<Boolean, ServiceComponentHost>() {
-          @Override
-          public Boolean invoke(ServiceComponentHost sch) throws AmbariException {
-            return (sch.getDesiredSecurityState() == SecurityState.SECURED_KERBEROS) &&
(sch.getSecurityState() != SecurityState.SECURED_KERBEROS);
-          }
-        });
+    List<ServiceComponentHost> schToProcess = getServiceComponentHostsToProcess(cluster,
kerberosDescriptor, identityFilter);
 
     Map<String, String> commandParameters = getCommandParameters();
     String dataDirectory = getCommandParameterValue(commandParameters, DATA_DIRECTORY);
@@ -105,16 +79,8 @@ public class PrepareEnableKerberosServerAction extends AbstractPrepareKerberosSe
     }
 
     processServiceComponentHosts(cluster, kerberosDescriptor, schToProcess, identityFilter,
dataDirectory, kerberosConfigurations);
+    processAuthToLocalRules(cluster, kerberosDescriptor, schToProcess, kerberosConfigurations,
getDefaultRealm(commandParameters));
 
-    if (!schToProcess.isEmpty()) {
-      actionLog.writeStdOut("Creating auth-to-local rules");
-      kerberosHelper.setAuthToLocalRules(kerberosDescriptor, cluster, getDefaultRealm(commandParameters),
-          kerberosHelper.calculateConfigurations(cluster, null, kerberosDescriptor.getProperties()),
-          kerberosConfigurations);
-    }
-
-
-    actionLog.writeStdOut("Determining configuration changes");
     // Ensure the cluster-env/security_enabled flag is set properly
     Map<String, String> clusterEnvProperties = kerberosConfigurations.get(KerberosHelper.SECURITY_ENABLED_CONFIG_TYPE);
     if (clusterEnvProperties == null) {
@@ -123,54 +89,7 @@ public class PrepareEnableKerberosServerAction extends AbstractPrepareKerberosSe
     }
     clusterEnvProperties.put(KerberosHelper.SECURITY_ENABLED_PROPERTY_NAME, "true");
 
-    // If there are configurations to set, create a (temporary) data file to store the configuration
-    // updates and fill it will the relevant configurations.
-    if (!kerberosConfigurations.isEmpty()) {
-      if(dataDirectory == null) {
-        String message = "The data directory has not been set.  Generated data can not be
stored.";
-        LOG.error(message);
-        throw new AmbariException(message);
-      }
-
-      File configFile = new File(dataDirectory, KerberosConfigDataFileWriter.DATA_FILE_NAME);
-      KerberosConfigDataFileWriter kerberosConfDataFileWriter = null;
-
-      actionLog.writeStdOut(String.format("Writing configuration changes metadata file to
%s", configFile.getAbsolutePath()));
-      try {
-        kerberosConfDataFileWriter = kerberosConfigDataFileWriterFactory.createKerberosConfigDataFileWriter(configFile);
-
-        for (Map.Entry<String, Map<String, String>> entry : kerberosConfigurations.entrySet())
{
-          String type = entry.getKey();
-          Map<String, String> properties = entry.getValue();
-
-          if (properties != null) {
-            for (Map.Entry<String, String> configTypeEntry : properties.entrySet())
{
-              kerberosConfDataFileWriter.addRecord(type,
-                  configTypeEntry.getKey(),
-                  configTypeEntry.getValue(),
-                  KerberosConfigDataFileWriter.OPERATION_TYPE_SET);
-            }
-          }
-        }
-      } catch (IOException e) {
-        String message = String.format("Failed to write kerberos configurations file - %s",
configFile.getAbsolutePath());
-        LOG.error(message, e);
-        actionLog.writeStdOut(message);
-        actionLog.writeStdErr(message + "\n" + e.getLocalizedMessage());
-        throw new AmbariException(message, e);
-      } finally {
-        if (kerberosConfDataFileWriter != null) {
-          try {
-            kerberosConfDataFileWriter.close();
-          } catch (IOException e) {
-            String message = "Failed to close the kerberos configurations file writer";
-            LOG.warn(message, e);
-            actionLog.writeStdOut(message);
-            actionLog.writeStdErr(message + "\n" + e.getLocalizedMessage());
-          }
-        }
-      }
-    }
+    processConfigurationChanges(dataDirectory, kerberosConfigurations);
 
     return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", actionLog.getStdOut(),
actionLog.getStdErr());
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e384d3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareKerberosIdentitiesServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareKerberosIdentitiesServerAction.java
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareKerberosIdentitiesServerAction.java
index 55f75ad..5f067ec 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareKerberosIdentitiesServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareKerberosIdentitiesServerAction.java
@@ -29,6 +29,8 @@ import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
@@ -48,6 +50,9 @@ public class PrepareKerberosIdentitiesServerAction extends AbstractPrepareKerber
   @Inject
   private KerberosHelper kerberosHelper;
 
+  @Inject
+  private KerberosConfigDataFileWriterFactory kerberosConfigDataFileWriterFactory;
+
   /**
    * Called to execute this action.  Upon invocation, calls
    * {@link KerberosServerAction#processIdentities(Map)}
@@ -71,18 +76,9 @@ public class PrepareKerberosIdentitiesServerAction extends AbstractPrepareKerber
       throw new AmbariException("Missing cluster object");
     }
 
-    KerberosDescriptor kerberosDescriptor = kerberosHelper.getKerberosDescriptor(cluster);
+    KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster);
     Collection<String> identityFilter = getIdentityFilter();
-    List<ServiceComponentHost> schToProcess = kerberosHelper.getServiceComponentHostsToProcess(cluster,
-        kerberosDescriptor,
-        getServiceComponentFilter(),
-        identityFilter,
-        new KerberosHelper.Command<Boolean, ServiceComponentHost>() {
-          @Override
-          public Boolean invoke(ServiceComponentHost sch) throws AmbariException {
-            return true;
-          }
-        });
+    List<ServiceComponentHost> schToProcess = getServiceComponentHostsToProcess(cluster,
kerberosDescriptor, identityFilter);
 
     Map<String, String> commandParameters = getCommandParameters();
     String dataDirectory = getCommandParameterValue(commandParameters, DATA_DIRECTORY);
@@ -99,13 +95,154 @@ public class PrepareKerberosIdentitiesServerAction extends AbstractPrepareKerber
 
     processServiceComponentHosts(cluster, kerberosDescriptor, schToProcess, identityFilter,
dataDirectory, kerberosConfigurations);
 
+    if("true".equalsIgnoreCase(getCommandParameterValue(commandParameters, UPDATE_CONFIGURATIONS)))
{
+      processAuthToLocalRules(cluster, kerberosDescriptor, schToProcess, kerberosConfigurations,
getDefaultRealm(commandParameters));
+      processConfigurationChanges(dataDirectory, kerberosConfigurations);
+    }
 
     return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", actionLog.getStdOut(),
actionLog.getStdErr());
   }
 
   @Override
-  protected CommandReport processIdentity(Map<String, String> identityRecord, String
evaluatedPrincipal, KerberosOperationHandler operationHandler, Map<String, String> kerberosConfiguration,
Map<String, Object> requestSharedDataContext) throws AmbariException {
+  protected CommandReport processIdentity(Map<String, String> identityRecord, String
evaluatedPrincipal,
+                                          KerberosOperationHandler operationHandler,
+                                          Map<String, String> kerberosConfiguration,
+                                          Map<String, Object> requestSharedDataContext)
+      throws AmbariException {
     throw new UnsupportedOperationException();
   }
+
+  /**
+   * Calls {@link KerberosHelper#getServiceComponentHostsToProcess(Cluster, KerberosDescriptor,
Map, Collection, KerberosHelper.Command)}
+   * with no filter on ServiceComponentHosts
+   * <p/>
+   * The <code>shouldProcessCommand</code> implementation passed to KerberosHelper#getServiceComponentHostsToProcess
+   * always returns true, indicating to process all ServiceComponentHosts.
+   *
+   * @param cluster            the cluster
+   * @param kerberosDescriptor the current Kerberos descriptor
+   * @param identityFilter     a list of identities to include, or all if null
+   * @return the list of ServiceComponentHosts to process
+   * @throws AmbariException
+   * @see KerberosHelper#getServiceComponentHostsToProcess(Cluster, KerberosDescriptor, Map,
Collection, KerberosHelper.Command)
+   */
+  protected List<ServiceComponentHost> getServiceComponentHostsToProcess(Cluster cluster,
+                                                                         KerberosDescriptor
kerberosDescriptor,
+                                                                         Collection<String>
identityFilter)
+      throws AmbariException {
+    return kerberosHelper.getServiceComponentHostsToProcess(cluster,
+        kerberosDescriptor,
+        getServiceComponentFilter(),
+        identityFilter,
+        new KerberosHelper.Command<Boolean, ServiceComponentHost>() {
+          @Override
+          public Boolean invoke(ServiceComponentHost sch) throws AmbariException {
+            return true;
+          }
+        });
+  }
+
+  /**
+   * Calls {@link KerberosHelper#getKerberosDescriptor(Cluster)}
+   *
+   * @param cluster cluster instance
+   * @return the kerberos descriptor associated with the specified cluster
+   * @throws AmbariException if unable to obtain the descriptor
+   * @see KerberosHelper#getKerberosDescriptor(Cluster)
+   */
+  protected KerberosDescriptor getKerberosDescriptor(Cluster cluster)
+      throws AmbariException {
+    return kerberosHelper.getKerberosDescriptor(cluster);
+  }
+
+  /**
+   * Conditionally calls {@link KerberosHelper#setAuthToLocalRules(KerberosDescriptor, Cluster,
String, Map, Map)}
+   * if there are ServiceComponentHosts to process
+   *
+   * @param cluster                cluster instance
+   * @param kerberosDescriptor     the current Kerberos descriptor
+   * @param schToProcess           a list of ServiceComponentHosts to process
+   * @param kerberosConfigurations the Kerberos-specific configuration map
+   * @param defaultRealm           the default realm
+   * @throws AmbariException
+   * @see KerberosHelper#setAuthToLocalRules(KerberosDescriptor, Cluster, String, Map, Map)
+   */
+  protected void processAuthToLocalRules(Cluster cluster, KerberosDescriptor kerberosDescriptor,
+                                         List<ServiceComponentHost> schToProcess,
+                                         Map<String, Map<String, String>> kerberosConfigurations,
+                                         String defaultRealm)
+      throws AmbariException {
+    if (!schToProcess.isEmpty()) {
+      actionLog.writeStdOut("Creating auth-to-local rules");
+      kerberosHelper.setAuthToLocalRules(kerberosDescriptor, cluster, defaultRealm,
+          kerberosHelper.calculateConfigurations(cluster, null, kerberosDescriptor.getProperties()),
+          kerberosConfigurations);
+    }
+  }
+
+  /**
+   * Processes configuration changes to determine if any work needs to be done.
+   * <p/>
+   * If work is to be done, a data file containing the details is created so it they changes
may be
+   * processed in the appropriate stage.
+   *
+   * @param dataDirectory          the directory in which to write the configuration changes
data file
+   * @param kerberosConfigurations the Kerberos-specific configuration map
+   * @throws AmbariException
+   */
+  protected void processConfigurationChanges(String dataDirectory,
+                                             Map<String, Map<String, String>>
kerberosConfigurations)
+      throws AmbariException {
+    actionLog.writeStdOut("Determining configuration changes");
+
+    // If there are configurations to set, create a (temporary) data file to store the configuration
+    // updates and fill it will the relevant configurations.
+    if (!kerberosConfigurations.isEmpty()) {
+      if (dataDirectory == null) {
+        String message = "The data directory has not been set.  Generated data can not be
stored.";
+        LOG.error(message);
+        throw new AmbariException(message);
+      }
+
+      File configFile = new File(dataDirectory, KerberosConfigDataFileWriter.DATA_FILE_NAME);
+      KerberosConfigDataFileWriter kerberosConfDataFileWriter = null;
+
+      actionLog.writeStdOut(String.format("Writing configuration changes metadata file to
%s", configFile.getAbsolutePath()));
+      try {
+        kerberosConfDataFileWriter = kerberosConfigDataFileWriterFactory.createKerberosConfigDataFileWriter(configFile);
+
+        for (Map.Entry<String, Map<String, String>> entry : kerberosConfigurations.entrySet())
{
+          String type = entry.getKey();
+          Map<String, String> properties = entry.getValue();
+
+          if (properties != null) {
+            for (Map.Entry<String, String> configTypeEntry : properties.entrySet())
{
+              kerberosConfDataFileWriter.addRecord(type,
+                  configTypeEntry.getKey(),
+                  configTypeEntry.getValue(),
+                  KerberosConfigDataFileWriter.OPERATION_TYPE_SET);
+            }
+          }
+        }
+      } catch (IOException e) {
+        String message = String.format("Failed to write kerberos configurations file - %s",
configFile.getAbsolutePath());
+        LOG.error(message, e);
+        actionLog.writeStdOut(message);
+        actionLog.writeStdErr(message + "\n" + e.getLocalizedMessage());
+        throw new AmbariException(message, e);
+      } finally {
+        if (kerberosConfDataFileWriter != null) {
+          try {
+            kerberosConfDataFileWriter.close();
+          } catch (IOException e) {
+            String message = "Failed to close the kerberos configurations file writer";
+            LOG.warn(message, e);
+            actionLog.writeStdOut(message);
+            actionLog.writeStdErr(message + "\n" + e.getLocalizedMessage());
+          }
+        }
+      }
+    }
+  }
 }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e384d3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/UpdateKerberosConfigsServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/UpdateKerberosConfigsServerAction.java
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/UpdateKerberosConfigsServerAction.java
index f2484e6..931806d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/UpdateKerberosConfigsServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/UpdateKerberosConfigsServerAction.java
@@ -120,9 +120,13 @@ public class UpdateKerberosConfigsServerAction extends AbstractServerAction
{
           }
 
           if (!configTypes.isEmpty()) {
-            String configNote = cluster.getSecurityType() == SecurityType.KERBEROS
-                ? "Enabling Kerberos"
-                : "Disabling Kerberos";
+            String configNote = getCommandParameterValue(getCommandParameters(), KerberosServerAction.UPDATE_CONFIGURATION_NOTE);
+
+            if((configNote == null) || configNote.isEmpty()) {
+              configNote = cluster.getSecurityType() == SecurityType.KERBEROS
+                  ? "Enabling Kerberos"
+                  : "Disabling Kerberos";
+            }
 
             for (String configType : configTypes) {
               configHelper.updateConfigType(cluster, controller, configType,

http://git-wip-us.apache.org/repos/asf/ambari/blob/d0e384d3/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
index 467c3ac..5d84fbc 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
@@ -1483,6 +1483,11 @@ public class KerberosHelperTest extends EasyMockSupport {
       expect(requestStageContainer.getId()).andReturn(1L).once();
       requestStageContainer.addStages(anyObject(List.class));
       expectLastCall().once();
+      // Update Configurations Stage
+      expect(requestStageContainer.getLastStageId()).andReturn(1L).anyTimes();
+      expect(requestStageContainer.getId()).andReturn(1L).once();
+      requestStageContainer.addStages(anyObject(List.class));
+      expectLastCall().once();
       // Clean-up/Finalize Stage
       expect(requestStageContainer.getLastStageId()).andReturn(3L).anyTimes();
       expect(requestStageContainer.getId()).andReturn(1L).once();


Mime
View raw message