http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterKerberosDescriptorResourceProvider.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterKerberosDescriptorResourceProvider.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterKerberosDescriptorResourceProvider.java
index d00751e..c8f7e8c 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterKerberosDescriptorResourceProvider.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterKerberosDescriptorResourceProvider.java
@@ -158,7 +158,8 @@ public class ClusterKerberosDescriptorResourceProvider 
extends ReadOnlyResourceP
           kerberosDescriptor = 
kerberosHelper.getKerberosDescriptor(kerberosDescriptorType,
               cluster,
               getEvaluateWhen(requestInfoProperties),
-              getAdditionalServices(requestInfoProperties));
+               getAdditionalServices(requestInfoProperties),
+              false);
         } catch (AmbariException e) {
           throw new SystemException("An unexpected error occurred building the 
cluster's composite Kerberos Descriptor", e);
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
index f826d6d..8fd71bf 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -19,16 +19,12 @@
 
 package org.apache.ambari.server.controller.internal;
 
-import java.io.File;
-import java.io.IOException;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
-import com.google.inject.Inject;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.StaticallyInject;
 import org.apache.ambari.server.controller.AmbariManagementController;
@@ -43,10 +39,6 @@ import org.apache.ambari.server.controller.spi.Resource.Type;
 import org.apache.ambari.server.controller.spi.SystemException;
 import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
-import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory;
-import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor;
-import 
org.apache.ambari.server.state.kerberos.KerberosServiceDescriptorFactory;
 
 @StaticallyInject
 public class StackVersionResourceProvider extends ReadOnlyResourceProvider {
@@ -66,18 +58,6 @@ public class StackVersionResourceProvider extends 
ReadOnlyResourceProvider {
   private static Set<String> pkPropertyIds = new HashSet<String>(
       Arrays.asList(new String[] { STACK_NAME_PROPERTY_ID, 
STACK_VERSION_PROPERTY_ID }));
 
-  /**
-   * KerberosDescriptorFactory used to create KerberosDescriptor instances
-   */
-  @Inject
-  private static KerberosDescriptorFactory kerberosDescriptorFactory;
-
-  /**
-   * KerberosServiceDescriptorFactory used to create KerberosServiceDescriptor 
instances
-   */
-  @Inject
-  private static KerberosServiceDescriptorFactory 
kerberosServiceDescriptorFactory;
-
   protected StackVersionResourceProvider(Set<String> propertyIds,
       Map<Type, String> keyPropertyIds,
       AmbariManagementController managementController) {
@@ -152,51 +132,6 @@ public class StackVersionResourceProvider extends 
ReadOnlyResourceProvider {
     return resources;
   }
 
-  /**
-   * Given data from a StackVersionResponse build a complete Kerberos 
descriptor hierarchy.
-   *
-   * @param stackVersionResponse the StackVersionResponse instance containing 
the details of the
-   *                             stack and the relevant Kerberos descriptor 
files
-   * @return a KerberosDescriptor containing the complete hierarchy for the 
stack
-   * @throws IOException     if the specified File is not found or not a 
readable
-   * @throws AmbariException if the specified File does not contain valid 
JSON-encoded Kerberos
-   *                         descriptor
-   */
-  private KerberosDescriptor buildKerberosDescriptor(StackVersionResponse 
stackVersionResponse)
-      throws IOException {
-    KerberosDescriptor kerberosDescriptor = null;
-
-    // Process the stack-level Kerberos descriptor file
-    File stackKerberosDescriptorFile = 
stackVersionResponse.getStackKerberosDescriptorFile();
-    if (stackKerberosDescriptorFile != null) {
-      kerberosDescriptor = 
kerberosDescriptorFactory.createInstance(stackKerberosDescriptorFile);
-    }
-
-    // Process the service-level Kerberos descriptor files
-    Collection<File> serviceDescriptorFiles = 
stackVersionResponse.getServiceKerberosDescriptorFiles();
-    if ((serviceDescriptorFiles != null) && !serviceDescriptorFiles.isEmpty()) 
{
-      // Make sure kerberosDescriptor is not null. This will be the case if 
there is no stack-level
-      // Kerberos descriptor file.
-      if (kerberosDescriptor == null) {
-        kerberosDescriptor = new KerberosDescriptor();
-      }
-
-      // For each service-level Kerberos descriptor file, parse into an array 
of KerberosServiceDescriptors
-      // and then append each to the KerberosDescriptor hierarchy.
-      for (File file : serviceDescriptorFiles) {
-        KerberosServiceDescriptor[] serviceDescriptors = 
kerberosServiceDescriptorFactory.createInstances(file);
-
-        if (serviceDescriptors != null) {
-          for (KerberosServiceDescriptor serviceDescriptor : 
serviceDescriptors) {
-            kerberosDescriptor.putService(serviceDescriptor);
-          }
-        }
-      }
-    }
-
-    return kerberosDescriptor;
-  }
-
   private StackVersionRequest getRequest(Map<String, Object> properties) {
     return new StackVersionRequest(
         (String) properties.get(STACK_NAME_PROPERTY_ID),

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
index 637471f..efb950c 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java
@@ -20,8 +20,8 @@ package org.apache.ambari.server.customactions;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.ActionType;
 import org.apache.ambari.server.actionmanager.TargetHostType;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.security.authorization.RoleAuthorization;
+import org.apache.ambari.server.stack.StackDirectory;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -92,7 +92,7 @@ public class ActionDefinitionManager {
     }
 
     File[] customActionDefinitionFiles
-        = customActionDefinitionRoot.listFiles(AmbariMetaInfo.FILENAME_FILTER);
+        = customActionDefinitionRoot.listFiles(StackDirectory.FILENAME_FILTER);
 
     if (customActionDefinitionFiles != null) {
       for (File definitionFile : customActionDefinitionFiles) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java
index 7824019..3ad40b6 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java
@@ -137,7 +137,7 @@ public abstract class AbstractPrepareKerberosServerAction 
extends KerberosServer
               // Calculate the set of configurations to update and replace any 
variables
               // using the previously calculated Map of configurations for the 
host.
               kerberosHelper.mergeConfigurations(kerberosConfigurations,
-                  componentDescriptor.getConfigurations(true), 
currentConfigurations);
+                  componentDescriptor.getConfigurations(true), 
currentConfigurations, null);
 
               // Add component-level principals (and keytabs)
               kerberosHelper.addIdentities(kerberosIdentityDataFileWriter, 
componentIdentities,

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/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 9755bd6..9a3c4ed 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
@@ -131,6 +131,12 @@ public abstract class KerberosServerAction extends 
AbstractServerAction {
   */
   public static final String INCLUDE_AMBARI_IDENTITY = 
"include_ambari_identity";
 
+  /**
+   * Keys used in CommandParams from ExecutionCommand to declare how to 
pre-configure services.
+   * Expected values are, "ALL", "DEFAULT", and "NONE".
+   */
+  public static final String PRECONFIGURE_SERVICES = "preconfigure_services";
+
   private static final Logger LOG = 
LoggerFactory.getLogger(KerberosServerAction.class);
 
   /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PreconfigureServiceType.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PreconfigureServiceType.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PreconfigureServiceType.java
new file mode 100644
index 0000000..c843b14
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PreconfigureServiceType.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.serveraction.kerberos;
+
+/**
+ * PreconfigureServiceType enumerates the ways in which services may be 
pre-configured.
+ */
+public enum PreconfigureServiceType {
+  /**
+   * Preconfigure services that have been explicitly flagged.
+   * <p>
+   * For example, in the Kerberos descriptor using
+   * <code>
+   * "preconfigure" : true
+   * </code>
+   * <p>
+   * For example, declared in the stack-specific kerberos_preconfigure.json 
file
+   */
+  DEFAULT,
+
+  /**
+   * Preconfigure all services, flagged or not.
+   */
+  ALL,
+
+  /**
+   * Do not preconfiure any services, even if flagged.
+   */
+  NONE
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareDisableKerberosServerAction.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareDisableKerberosServerAction.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareDisableKerberosServerAction.java
index 54ba784..a392aae 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareDisableKerberosServerAction.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareDisableKerberosServerAction.java
@@ -78,7 +78,7 @@ public class PrepareDisableKerberosServerAction extends 
AbstractPrepareKerberosS
 
     KerberosHelper kerberosHelper = getKerberosHelper();
 
-    KerberosDescriptor kerberosDescriptor = 
kerberosHelper.getKerberosDescriptor(cluster);
+    KerberosDescriptor kerberosDescriptor = 
kerberosHelper.getKerberosDescriptor(cluster, false);
     Collection<String> identityFilter = getIdentityFilter();
     List<ServiceComponentHost> schToProcess = 
kerberosHelper.getServiceComponentHostsToProcess(cluster,
         kerberosDescriptor,

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/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 ed01633..e3c6197 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
@@ -32,6 +32,10 @@ import org.apache.ambari.server.controller.KerberosHelper;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
+import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * PrepareEnableKerberosServerAction is a ServerAction implementation that 
prepares metadata needed
@@ -39,6 +43,8 @@ import 
org.apache.ambari.server.state.kerberos.KerberosDescriptor;
  */
 public class PrepareEnableKerberosServerAction extends 
PrepareKerberosIdentitiesServerAction {
 
+  private final static Logger LOG = 
LoggerFactory.getLogger(PrepareEnableKerberosServerAction.class);
+
   /**
    * Called to execute this action.  Upon invocation, calls
    * {@link KerberosServerAction#processIdentities(Map)}
@@ -62,11 +68,33 @@ public class PrepareEnableKerberosServerAction extends 
PrepareKerberosIdentities
       throw new AmbariException("Missing cluster object");
     }
 
-    KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster);
+    Map<String, String> commandParameters = getCommandParameters();
+
+    String preconfigureServices = getCommandParameterValue(commandParameters, 
PRECONFIGURE_SERVICES);
+    PreconfigureServiceType type = null;
+    if (!StringUtils.isEmpty(preconfigureServices)) {
+      try {
+        type = 
PreconfigureServiceType.valueOf(preconfigureServices.toUpperCase());
+      } catch (Throwable t) {
+        LOG.warn("Invalid preconfigure_services value, assuming DEFAULT: {}", 
preconfigureServices);
+        type = PreconfigureServiceType.DEFAULT;
+      }
+    }
+
+    KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster, 
type != PreconfigureServiceType.NONE);
+    if (type == PreconfigureServiceType.ALL) {
+      // Force all services to be flagged for pre-configuration...
+      Map<String, KerberosServiceDescriptor> serviceDescriptors = 
kerberosDescriptor.getServices();
+      if (serviceDescriptors != null) {
+        for (KerberosServiceDescriptor serviceDescriptor : 
serviceDescriptors.values()) {
+          serviceDescriptor.setPreconfigure(true);
+        }
+      }
+    }
+
     Collection<String> identityFilter = getIdentityFilter();
     List<ServiceComponentHost> schToProcess = 
getServiceComponentHostsToProcess(cluster, kerberosDescriptor, identityFilter);
 
-    Map<String, String> commandParameters = getCommandParameters();
     String dataDirectory = getCommandParameterValue(commandParameters, 
DATA_DIRECTORY);
     Map<String, Map<String, String>> kerberosConfigurations = new 
HashMap<String, Map<String, String>>();
 
@@ -92,10 +120,14 @@ public class PrepareEnableKerberosServerAction extends 
PrepareKerberosIdentities
     processServiceComponentHosts(cluster, kerberosDescriptor, schToProcess, 
identityFilter, dataDirectory,
         configurations, kerberosConfigurations, true, propertiesToIgnore);
 
+    // Calculate the set of configurations to update and replace any variables
+    // using the previously calculated Map of configurations for the host.
+    kerberosConfigurations = 
kerberosHelper.processPreconfiguredServiceConfigurations(kerberosConfigurations,
 configurations, cluster, kerberosDescriptor);
+
     kerberosHelper.applyStackAdvisorUpdates(cluster, services, configurations, 
kerberosConfigurations,
-          propertiesToIgnore, propertiesToRemove, true);
+        propertiesToIgnore, propertiesToRemove, true);
 
-    processAuthToLocalRules(cluster, kerberosDescriptor, schToProcess, 
kerberosConfigurations, getDefaultRealm(commandParameters));
+    processAuthToLocalRules(cluster, configurations, kerberosDescriptor, 
schToProcess, kerberosConfigurations, getDefaultRealm(commandParameters), true);
 
     // Ensure the cluster-env/security_enabled flag is set properly
     Map<String, String> clusterEnvProperties = 
kerberosConfigurations.get(KerberosHelper.SECURITY_ENABLED_CONFIG_TYPE);

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/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 9935844..b587e2c 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
@@ -66,7 +66,7 @@ public class PrepareKerberosIdentitiesServerAction extends 
AbstractPrepareKerber
       throw new AmbariException("Missing cluster object");
     }
 
-    KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster);
+    KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster, 
false);
     Collection<String> identityFilter = getIdentityFilter();
     List<ServiceComponentHost> schToProcess = 
getServiceComponentHostsToProcess(cluster, kerberosDescriptor, identityFilter);
 
@@ -98,10 +98,11 @@ public class PrepareKerberosIdentitiesServerAction extends 
AbstractPrepareKerber
         configurations, kerberosConfigurations, includeAmbariIdentity, 
propertiesToIgnore);
 
     kerberosHelper.applyStackAdvisorUpdates(cluster, services, configurations, 
kerberosConfigurations,
-        propertiesToIgnore,  propertiesToRemove, true);
+        propertiesToIgnore, propertiesToRemove, true);
 
     if ("true".equalsIgnoreCase(getCommandParameterValue(commandParameters, 
UPDATE_CONFIGURATIONS))) {
-      processAuthToLocalRules(cluster, kerberosDescriptor, schToProcess, 
kerberosConfigurations, getDefaultRealm(commandParameters));
+      Map<String, Map<String, String>> calculatedConfigurations = 
kerberosHelper.calculateConfigurations(cluster, null, 
kerberosDescriptor.getProperties());
+      processAuthToLocalRules(cluster, calculatedConfigurations, 
kerberosDescriptor, schToProcess, kerberosConfigurations, 
getDefaultRealm(commandParameters), false);
       processConfigurationChanges(dataDirectory, kerberosConfigurations, 
propertiesToRemove);
     }
 
@@ -147,43 +148,47 @@ public class PrepareKerberosIdentitiesServerAction 
extends AbstractPrepareKerber
   }
 
   /**
-   * Calls {@link KerberosHelper#getKerberosDescriptor(Cluster)}
+   * Calls {@link KerberosHelper#getKerberosDescriptor(Cluster, boolean)}
    *
-   * @param cluster cluster instance
+   * @param cluster                 cluster instance
+   * @param includePreconfigureData <code>true</code> to include the 
preconfigure data; <code>false</code> otherwise
    * @return the kerberos descriptor associated with the specified cluster
    * @throws AmbariException if unable to obtain the descriptor
-   * @see KerberosHelper#getKerberosDescriptor(Cluster)
+   * @see KerberosHelper#getKerberosDescriptor(Cluster, boolean)
    */
-  protected KerberosDescriptor getKerberosDescriptor(Cluster cluster)
+  protected KerberosDescriptor getKerberosDescriptor(Cluster cluster, boolean 
includePreconfigureData)
       throws AmbariException {
-    return getKerberosHelper().getKerberosDescriptor(cluster);
+    return getKerberosHelper().getKerberosDescriptor(cluster, 
includePreconfigureData);
   }
 
   /**
-   * Conditionally calls {@link 
KerberosHelper#setAuthToLocalRules(KerberosDescriptor, String, Map, Map, Map)}
+   * Conditionally calls {@link KerberosHelper#setAuthToLocalRules(Cluster, 
KerberosDescriptor, String, Map, Map, Map, boolean)}
    * 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
+   * @param cluster                  the cluster
+   * @param calculatedConfiguration  the configurations for the current 
cluster, used for replacements
+   * @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
+   * @param includePreconfiguredData true to include services flagged to be 
pre-configured; false otherwise
    * @throws AmbariException
-   * @see KerberosHelper#setAuthToLocalRules(KerberosDescriptor, String, Map, 
Map, Map)
+   * @see KerberosHelper#setAuthToLocalRules(Cluster, KerberosDescriptor, 
String, Map, Map, Map, boolean)
    */
-  protected void processAuthToLocalRules(Cluster cluster, KerberosDescriptor 
kerberosDescriptor,
-                                         List<ServiceComponentHost> 
schToProcess,
-                                         Map<String, Map<String, String>> 
kerberosConfigurations,
-                                         String defaultRealm)
+  void processAuthToLocalRules(Cluster cluster, Map<String, Map<String, 
String>> calculatedConfiguration,
+                               KerberosDescriptor kerberosDescriptor,
+                               List<ServiceComponentHost> schToProcess,
+                               Map<String, Map<String, String>> 
kerberosConfigurations,
+                               String defaultRealm, boolean 
includePreconfiguredData)
       throws AmbariException {
     if (!schToProcess.isEmpty()) {
       actionLog.writeStdOut("Creating auth-to-local rules");
 
-      Map<String, Set<String>> services = new HashMap<String, Set<String>>();
+      Map<String, Set<String>> services = new HashMap<>();
       for (ServiceComponentHost sch : schToProcess) {
         Set<String> components = services.get(sch.getServiceName());
         if (components == null) {
-          components = new HashSet<String>();
+          components = new HashSet<>();
           services.put(sch.getServiceName(), components);
         }
 
@@ -191,9 +196,8 @@ public class PrepareKerberosIdentitiesServerAction extends 
AbstractPrepareKerber
       }
 
       KerberosHelper kerberosHelper = getKerberosHelper();
-      kerberosHelper.setAuthToLocalRules(kerberosDescriptor, defaultRealm, 
services,
-          kerberosHelper.calculateConfigurations(cluster, null, 
kerberosDescriptor.getProperties()),
-          kerberosConfigurations);
+      kerberosHelper.setAuthToLocalRules(cluster, kerberosDescriptor, 
defaultRealm, services,
+          calculatedConfiguration, kerberosConfigurations, 
includePreconfiguredData);
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FixAuthToLocalMappingAction.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FixAuthToLocalMappingAction.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FixAuthToLocalMappingAction.java
index e62f2db..2f61bce 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FixAuthToLocalMappingAction.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FixAuthToLocalMappingAction.java
@@ -62,7 +62,7 @@ public class FixAuthToLocalMappingAction  extends 
AbstractServerAction {
     String clusterName = getExecutionCommand().getClusterName();
     Cluster cluster = clusters.getCluster(clusterName);
 
-    KerberosDescriptor kd = kerberosHelper.getKerberosDescriptor(cluster);
+    KerberosDescriptor kd = kerberosHelper.getKerberosDescriptor(cluster, 
false);
     if (kd == null) {
       return null;
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptor.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptor.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptor.java
index 842da95..a8c254a 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptor.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/UpgradeUserKerberosDescriptor.java
@@ -115,7 +115,7 @@ public class UpgradeUserKerberosDescriptor extends 
AbstractServerAction {
             logErrorMessage(messages, errorMessages, "The new stack version 
information was not found.");
           } else {
             logMessage(messages, String.format("Obtaining new stack Kerberos 
descriptor for %s.", targetStackId.toString()));
-            newDescriptor = 
ambariMetaInfo.getKerberosDescriptor(targetStackId.getStackName(), 
targetStackId.getStackVersion());
+            newDescriptor = 
ambariMetaInfo.getKerberosDescriptor(targetStackId.getStackName(), 
targetStackId.getStackVersion(), false);
 
             if (newDescriptor == null) {
               logErrorMessage(messages, errorMessages, String.format("The 
Kerberos descriptor for the new stack version, %s, was not found.", 
targetStackId.toString()));
@@ -126,7 +126,7 @@ public class UpgradeUserKerberosDescriptor extends 
AbstractServerAction {
             logErrorMessage(messages, errorMessages, "The previous stack 
version information was not found.");
           } else {
             logMessage(messages, String.format("Obtaining previous stack 
Kerberos descriptor for %s.", originalStackId.toString()));
-            previousDescriptor = 
ambariMetaInfo.getKerberosDescriptor(originalStackId.getStackName(), 
originalStackId.getStackVersion());
+            previousDescriptor = 
ambariMetaInfo.getKerberosDescriptor(originalStackId.getStackName(), 
originalStackId.getStackVersion(), false);
 
             if (newDescriptor == null) {
               logErrorMessage(messages, errorMessages, String.format("The 
Kerberos descriptor for the previous stack version, %s, was not found.", 
originalStackId.toString()));

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/stack/ConfigurationDirectory.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/ConfigurationDirectory.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/ConfigurationDirectory.java
index cfdf9fc..06c0523 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/ConfigurationDirectory.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/ConfigurationDirectory.java
@@ -18,7 +18,6 @@
 
 package org.apache.ambari.server.stack;
 
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.PropertyInfo;
 import org.apache.ambari.server.state.stack.ConfigurationXml;
@@ -93,10 +92,10 @@ public class ConfigurationDirectory extends 
StackDefinitionDirectory {
    * Parse the configuration directory.
    */
   private void parsePath() {
-    File[] configFiles = directory.listFiles(AmbariMetaInfo.FILENAME_FILTER);
+    File[] configFiles = directory.listFiles(StackDirectory.FILENAME_FILTER);
     if (configFiles != null) {
       for (File configFile : configFiles) {
-        if 
(configFile.getName().endsWith(AmbariMetaInfo.SERVICE_CONFIG_FILE_NAME_POSTFIX))
 {
+        if 
(configFile.getName().endsWith(StackDirectory.SERVICE_CONFIG_FILE_NAME_POSTFIX))
 {
           String configType = 
ConfigHelper.fileNameToConfigType(configFile.getName());
           ConfigurationXml config = null;
           try {

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/stack/ExtensionDirectory.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/ExtensionDirectory.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/ExtensionDirectory.java
index 7b31925..adcc889 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/ExtensionDirectory.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/ExtensionDirectory.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.HashSet;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.state.stack.ExtensionMetainfoXml;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -158,7 +157,7 @@ public class ExtensionDirectory extends 
StackDefinitionDirectory {
     if (subDirs.contains(ServiceDirectory.SERVICES_FOLDER_NAME)) {
       String servicesDir = getAbsolutePath() + File.separator + 
ServiceDirectory.SERVICES_FOLDER_NAME;
       File baseServiceDir = new File(servicesDir);
-      File[] serviceFolders = 
baseServiceDir.listFiles(AmbariMetaInfo.FILENAME_FILTER);
+      File[] serviceFolders = 
baseServiceDir.listFiles(StackDirectory.FILENAME_FILTER);
       if (serviceFolders != null) {
         for (File d : serviceFolders) {
           if (d.isDirectory()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
index 00dc046..abef459 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceDirectory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -24,7 +24,6 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.stack.ServiceMetainfoXml;
 import org.apache.ambari.server.state.stack.StackRoleCommandOrder;
@@ -257,13 +256,13 @@ public abstract class ServiceDirectory extends 
StackDefinitionDirectory {
     calculateDirectories(getStack(), getService());
     parseMetaInfoFile();
 
-    File af = new File(directory, AmbariMetaInfo.SERVICE_ALERT_FILE_NAME);
+    File af = new File(directory, StackDirectory.SERVICE_ALERT_FILE_NAME);
     alertsFile = af.exists() ? af : null;
 
-    File kdf = new File(directory, 
AmbariMetaInfo.KERBEROS_DESCRIPTOR_FILE_NAME);
+    File kdf = new File(directory, 
StackDirectory.KERBEROS_DESCRIPTOR_FILE_NAME);
     kerberosDescriptorFile = kdf.exists() ? kdf : null;
 
-    File rco = new File(directory, AmbariMetaInfo.RCO_FILE_NAME);
+    File rco = new File(directory, StackDirectory.RCO_FILE_NAME);
     if (rco.exists()) {
       rcoFile = rco;
       parseRoleCommandOrder();
@@ -279,13 +278,10 @@ public abstract class ServiceDirectory extends 
StackDefinitionDirectory {
       }
     }
 
-    File advFile = new File(directory, 
AmbariMetaInfo.SERVICE_ADVISOR_FILE_NAME);
+    File advFile = new File(directory, 
StackDirectory.SERVICE_ADVISOR_FILE_NAME);
     advisorFile = advFile.exists() ? advFile : null;
 
-    File themeFile = new File(directory, 
AmbariMetaInfo.SERVICE_THEME_FILE_NAME);
-    this.themeFile = themeFile.exists() ? themeFile : null;
-
-    File checksFile = new File(directory, 
AmbariMetaInfo.SERVICE_THEME_FILE_NAME);
+    File themeFile = new File(directory, 
StackDirectory.SERVICE_THEME_FILE_NAME);
     this.themeFile = themeFile.exists() ? themeFile : null;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
index 8103850..6699e0e 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java
@@ -391,7 +391,7 @@ public class ServiceModule extends 
BaseModule<ServiceModule, ServiceInfo> implem
    */
   private void populateConfigurationModules() {
     ConfigurationDirectory configDirectory = 
serviceDirectory.getConfigurationDirectory(
-        serviceInfo.getConfigDir(), 
AmbariMetaInfo.SERVICE_PROPERTIES_FOLDER_NAME);
+        serviceInfo.getConfigDir(), 
StackDirectory.SERVICE_PROPERTIES_FOLDER_NAME);
 
     if (configDirectory != null) {
       for (ConfigurationModule config : 
configDirectory.getConfigurationModules()) {
@@ -424,7 +424,7 @@ public class ServiceModule extends 
BaseModule<ServiceModule, ServiceInfo> implem
   private void populateThemeModules() {
 
     if (serviceInfo.getThemesDir() == null) {
-      serviceInfo.setThemesDir(AmbariMetaInfo.SERVICE_THEMES_FOLDER_NAME);
+      serviceInfo.setThemesDir(StackDirectory.SERVICE_THEMES_FOLDER_NAME);
     }
 
     String themesDir = serviceDirectory.getAbsolutePath() + File.separator + 
serviceInfo.getThemesDir();
@@ -468,7 +468,7 @@ public class ServiceModule extends 
BaseModule<ServiceModule, ServiceInfo> implem
 
   private void populateQuickLinksConfigurationModules(){
     if (serviceInfo.getQuickLinksConfigurationsDir() == null) {
-      
serviceInfo.setQuickLinksConfigurationsDir(AmbariMetaInfo.SERVICE_QUICKLINKS_CONFIGURATIONS_FOLDER_NAME);
+      
serviceInfo.setQuickLinksConfigurationsDir(StackDirectory.SERVICE_QUICKLINKS_CONFIGURATIONS_FOLDER_NAME);
     }
 
     String quickLinksConfigurationsDir = serviceDirectory.getAbsolutePath() + 
File.separator + serviceInfo.getQuickLinksConfigurationsDir();

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
index 40139c6..ed9e0a5 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackDirectory.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -19,6 +19,7 @@
 package org.apache.ambari.server.stack;
 
 import java.io.File;
+import java.io.FilenameFilter;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -28,7 +29,6 @@ import java.util.HashSet;
 import java.util.Map;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.state.stack.ConfigUpgradePack;
 import org.apache.ambari.server.state.stack.RepositoryXml;
 import org.apache.ambari.server.state.stack.StackMetainfoXml;
@@ -47,6 +47,36 @@ import org.slf4j.LoggerFactory;
 //todo: Currently some are relative and some are absolute.
 //todo: Current values were dictated by the StackInfo expectations.
 public class StackDirectory extends StackDefinitionDirectory {
+  public static final String RCO_FILE_NAME = "role_command_order.json";
+  public static final String SERVICE_METRIC_FILE_NAME = "metrics.json";
+  public static final String SERVICE_ALERT_FILE_NAME = "alerts.json";
+  public static final String SERVICE_ADVISOR_FILE_NAME = "service_advisor.py";
+
+  /**
+   * The filename for a Kerberos descriptor file at either the stack or 
service level
+   */
+  public static final String KERBEROS_DESCRIPTOR_FILE_NAME = "kerberos.json";
+
+  /**
+   * The filename for a Kerberos descriptor preconfigure file at either the 
stack or service level
+   */
+  public static final String KERBEROS_DESCRIPTOR_PRECONFIGURE_FILE_NAME = 
"kerberos_preconfigure.json";
+
+  /**
+   * The filename for a Widgets descriptor file at either the stack or service 
level
+   */
+  public static final String WIDGETS_DESCRIPTOR_FILE_NAME = "widgets.json";
+
+  /**
+   * Filename for theme file at service layer
+   */
+  public static final String SERVICE_THEME_FILE_NAME = "theme.json";
+  public static final String SERVICE_CONFIG_FOLDER_NAME = "configuration";
+  public static final String SERVICE_PROPERTIES_FOLDER_NAME = "properties";
+  public static final String SERVICE_THEMES_FOLDER_NAME = "themes";
+  public static final String SERVICE_QUICKLINKS_CONFIGURATIONS_FOLDER_NAME = 
"quicklinks";
+  public static final String SERVICE_CONFIG_FILE_NAME_POSTFIX = ".xml";
+
   /**
    * hooks directory path
    */
@@ -70,6 +100,11 @@ public class StackDirectory extends 
StackDefinitionDirectory {
   /**
    * kerberos descriptor file path
    */
+  private String kerberosDescriptorPreconfigureFilePath;
+
+  /**
+   * kerberos descriptor file path
+   */
   private String widgetsDescriptorFilePath;
 
   /**
@@ -117,6 +152,14 @@ public class StackDirectory extends 
StackDefinitionDirectory {
    */
   public static final String HOOKS_FOLDER_NAME = "hooks";
 
+  public static final FilenameFilter FILENAME_FILTER = new FilenameFilter() {
+    @Override
+    public boolean accept(File dir, String s) {
+      return !(s.equals(".svn") || s.equals(".git") ||
+          s.equals(HOOKS_FOLDER_NAME));
+    }
+  };
+
   /**
    * repository directory name
    */
@@ -205,6 +248,15 @@ public class StackDirectory extends 
StackDefinitionDirectory {
   }
 
   /**
+   * Obtain the path to the (stack-level) Kerberos descriptor 
pre-configuration file
+   *
+   * @return the path to the (stack-level) Kerberos descriptor 
pre-configuration file
+   */
+  public String getKerberosDescriptorPreconfigureFilePath() {
+    return kerberosDescriptorPreconfigureFilePath;
+  }
+
+  /**
    * Obtain the path to the (stack-level) widgets descriptor file
    *
    * @return the path to the (stack-level) widgets descriptor file
@@ -290,19 +342,24 @@ public class StackDirectory extends 
StackDefinitionDirectory {
           HOOKS_FOLDER_NAME + " does not exist");
     }
 
-    if (subDirs.contains(AmbariMetaInfo.RCO_FILE_NAME)) {
+    if (subDirs.contains(RCO_FILE_NAME)) {
       // rcoFile is expected to be absolute
-      rcoFilePath = getAbsolutePath() + File.separator + 
AmbariMetaInfo.RCO_FILE_NAME;
+      rcoFilePath = getAbsolutePath() + File.separator + RCO_FILE_NAME;
     }
 
 
-    if (subDirs.contains(AmbariMetaInfo.KERBEROS_DESCRIPTOR_FILE_NAME)) {
+    if (subDirs.contains(KERBEROS_DESCRIPTOR_FILE_NAME)) {
       // kerberosDescriptorFilePath is expected to be absolute
-      kerberosDescriptorFilePath = getAbsolutePath() + File.separator + 
AmbariMetaInfo.KERBEROS_DESCRIPTOR_FILE_NAME;
+      kerberosDescriptorFilePath = getAbsolutePath() + File.separator + 
KERBEROS_DESCRIPTOR_FILE_NAME;
+    }
+
+    if (subDirs.contains(KERBEROS_DESCRIPTOR_PRECONFIGURE_FILE_NAME)) {
+      // kerberosDescriptorPreconfigureFilePath is expected to be absolute
+      kerberosDescriptorPreconfigureFilePath = getAbsolutePath() + 
File.separator + KERBEROS_DESCRIPTOR_PRECONFIGURE_FILE_NAME;
     }
 
-    if (subDirs.contains(AmbariMetaInfo.WIDGETS_DESCRIPTOR_FILE_NAME)) {
-      widgetsDescriptorFilePath = getAbsolutePath() + File.separator + 
AmbariMetaInfo.WIDGETS_DESCRIPTOR_FILE_NAME;
+    if (subDirs.contains(WIDGETS_DESCRIPTOR_FILE_NAME)) {
+      widgetsDescriptorFilePath = getAbsolutePath() + File.separator + 
WIDGETS_DESCRIPTOR_FILE_NAME;
     }
 
     parseUpgradePacks(subDirs);
@@ -371,7 +428,7 @@ public class StackDirectory extends 
StackDefinitionDirectory {
     if (subDirs.contains(ServiceDirectory.SERVICES_FOLDER_NAME)) {
       String servicesDir = getAbsolutePath() + File.separator + 
ServiceDirectory.SERVICES_FOLDER_NAME;
       File baseServiceDir = new File(servicesDir);
-      File[] serviceFolders = 
baseServiceDir.listFiles(AmbariMetaInfo.FILENAME_FILTER);
+      File[] serviceFolders = baseServiceDir.listFiles(FILENAME_FILTER);
       if (serviceFolders != null) {
         for (File d : serviceFolders) {
           if (d.isDirectory()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
index b8de740..749a95e 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackManager.java
@@ -34,7 +34,6 @@ import javax.xml.validation.SchemaFactory;
 import javax.xml.validation.Validator;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.metadata.ActionMetadata;
 import org.apache.ambari.server.orm.dao.ExtensionDAO;
@@ -510,12 +509,12 @@ public class StackManager {
     Map<String, ServiceModule> commonServiceModules = new HashMap<String, 
ServiceModule>();
 
     if(commonServicesRoot != null) {
-      File[] commonServiceFiles = 
commonServicesRoot.listFiles(AmbariMetaInfo.FILENAME_FILTER);
+      File[] commonServiceFiles = 
commonServicesRoot.listFiles(StackDirectory.FILENAME_FILTER);
       for (File commonService : commonServiceFiles) {
         if (commonService.isFile()) {
           continue;
         }
-        for (File serviceFolder : 
commonService.listFiles(AmbariMetaInfo.FILENAME_FILTER)) {
+        for (File serviceFolder : 
commonService.listFiles(StackDirectory.FILENAME_FILTER)) {
           String serviceName = serviceFolder.getParentFile().getName();
           String serviceVersion = serviceFolder.getName();
           ServiceDirectory serviceDirectory = new 
CommonServiceDirectory(serviceFolder.getPath());
@@ -552,12 +551,12 @@ public class StackManager {
   private Map<String, StackModule> parseStackDirectory(File stackRoot) throws 
AmbariException {
     Map<String, StackModule> stackModules = new HashMap<String, StackModule>();
 
-    File[] stackFiles = stackRoot.listFiles(AmbariMetaInfo.FILENAME_FILTER);
+    File[] stackFiles = stackRoot.listFiles(StackDirectory.FILENAME_FILTER);
     for (File stack : stackFiles) {
       if (stack.isFile()) {
         continue;
       }
-      for (File stackFolder : stack.listFiles(AmbariMetaInfo.FILENAME_FILTER)) 
{
+      for (File stackFolder : stack.listFiles(StackDirectory.FILENAME_FILTER)) 
{
         if (stackFolder.isFile()) {
           continue;
         }
@@ -596,12 +595,12 @@ public class StackManager {
     if (extensionRoot == null || !extensionRoot.exists())
       return extensionModules;
 
-    File[] extensionFiles = 
extensionRoot.listFiles(AmbariMetaInfo.FILENAME_FILTER);
+    File[] extensionFiles = 
extensionRoot.listFiles(StackDirectory.FILENAME_FILTER);
     for (File extensionNameFolder : extensionFiles) {
       if (extensionNameFolder.isFile()) {
         continue;
       }
-      for (File extensionVersionFolder : 
extensionNameFolder.listFiles(AmbariMetaInfo.FILENAME_FILTER)) {
+      for (File extensionVersionFolder : 
extensionNameFolder.listFiles(StackDirectory.FILENAME_FILTER)) {
         if (extensionVersionFolder.isFile()) {
           continue;
         }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
index f19464f..cbbe92e 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
@@ -30,7 +30,6 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.state.ConfigHelper;
 import org.apache.ambari.server.state.ExtensionInfo;
 import org.apache.ambari.server.state.PropertyDependencyInfo;
@@ -280,6 +279,11 @@ public class StackModule extends BaseModule<StackModule, 
StackInfo> implements V
       
stackInfo.setKerberosDescriptorFileLocation(parentStack.getModuleInfo().getKerberosDescriptorFileLocation());
     }
 
+    // grab stack level kerberos_preconfigure.json from parent stack
+    if (stackInfo.getKerberosDescriptorPreConfigurationFileLocation() == null) 
{
+      
stackInfo.setKerberosDescriptorPreConfigurationFileLocation(parentStack.getModuleInfo().getKerberosDescriptorPreConfigurationFileLocation());
+    }
+
     if (stackInfo.getWidgetsDescriptorFileLocation() == null) {
       
stackInfo.setWidgetsDescriptorFileLocation(parentStack.getModuleInfo().getWidgetsDescriptorFileLocation());
     }
@@ -563,6 +567,7 @@ public class StackModule extends BaseModule<StackModule, 
StackInfo> implements V
       stackInfo.setStackHooksFolder(stackDirectory.getHooksDir());
       stackInfo.setRcoFileLocation(stackDirectory.getRcoFilePath());
       
stackInfo.setKerberosDescriptorFileLocation(stackDirectory.getKerberosDescriptorFilePath());
+      
stackInfo.setKerberosDescriptorPreConfigurationFileLocation(stackDirectory.getKerberosDescriptorPreconfigureFilePath());
       
stackInfo.setWidgetsDescriptorFileLocation(stackDirectory.getWidgetsDescriptorFilePath());
       stackInfo.setUpgradesFolder(stackDirectory.getUpgradesDir());
       stackInfo.setUpgradePacks(stackDirectory.getUpgradePacks());
@@ -644,7 +649,7 @@ public class StackModule extends BaseModule<StackModule, 
StackInfo> implements V
   private void populateConfigurationModules() {
     //todo: can't exclude types in stack config
     ConfigurationDirectory configDirectory = 
stackDirectory.getConfigurationDirectory(
-        AmbariMetaInfo.SERVICE_CONFIG_FOLDER_NAME, 
AmbariMetaInfo.SERVICE_PROPERTIES_FOLDER_NAME);
+        StackDirectory.SERVICE_CONFIG_FOLDER_NAME, 
StackDirectory.SERVICE_PROPERTIES_FOLDER_NAME);
 
     if (configDirectory != null) {
       for (ConfigurationModule config : 
configDirectory.getConfigurationModules()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
index 812fb62..987ff38 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
@@ -36,6 +36,7 @@ import 
org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.orm.dao.ClusterDAO;
 import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
 import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
+import org.apache.ambari.server.stack.StackDirectory;
 import org.apache.ambari.server.state.PropertyInfo.PropertyType;
 import org.apache.ambari.server.state.configgroup.ConfigGroup;
 import org.apache.ambari.server.utils.SecretReference;
@@ -1404,7 +1405,7 @@ public class ConfigHelper {
   }
 
   public static String fileNameToConfigType(String filename) {
-    int extIndex = 
filename.indexOf(AmbariMetaInfo.SERVICE_CONFIG_FILE_NAME_POSTFIX);
+    int extIndex = 
filename.indexOf(StackDirectory.SERVICE_CONFIG_FILE_NAME_POSTFIX);
     return filename.substring(0, extIndex);
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
index 8fe0a52..b7afe53 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
@@ -25,13 +25,12 @@ import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Multimaps;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.stack.StackDirectory;
 import org.apache.ambari.server.stack.Validable;
 import org.apache.ambari.server.state.stack.MetricDefinition;
 import org.apache.ambari.server.state.stack.StackRoleCommandOrder;
 import org.codehaus.jackson.annotate.JsonIgnore;
 import org.codehaus.jackson.map.annotate.JsonFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import javax.xml.bind.Unmarshaller;
 import javax.xml.bind.annotation.XmlAccessType;
@@ -112,10 +111,10 @@ public class ServiceInfo implements Validable{
   private String parent;
 
   @XmlElement(name = "widgetsFileName")
-  private String widgetsFileName = AmbariMetaInfo.WIDGETS_DESCRIPTOR_FILE_NAME;
+  private String widgetsFileName = StackDirectory.WIDGETS_DESCRIPTOR_FILE_NAME;
 
   @XmlElement(name = "metricsFileName")
-  private String metricsFileName = AmbariMetaInfo.SERVICE_METRIC_FILE_NAME;
+  private String metricsFileName = StackDirectory.SERVICE_METRIC_FILE_NAME;
 
   @XmlTransient
   private volatile Map<String, PropertyInfo> requiredProperties;
@@ -212,11 +211,11 @@ public class ServiceInfo implements Validable{
 
   @JsonIgnore
   @XmlElement(name="configuration-dir")
-  private String configDir = AmbariMetaInfo.SERVICE_CONFIG_FOLDER_NAME;
+  private String configDir = StackDirectory.SERVICE_CONFIG_FOLDER_NAME;
 
   @JsonIgnore
   @XmlElement(name = "themes-dir")
-  private String themesDir = AmbariMetaInfo.SERVICE_THEMES_FOLDER_NAME;
+  private String themesDir = StackDirectory.SERVICE_THEMES_FOLDER_NAME;
 
   @JsonIgnore
   @XmlElementWrapper(name = "themes")
@@ -228,7 +227,7 @@ public class ServiceInfo implements Validable{
 
   @JsonIgnore
   @XmlElement(name = "quickLinksConfigurations-dir")
-  private String quickLinksConfigurationsDir = 
AmbariMetaInfo.SERVICE_QUICKLINKS_CONFIGURATIONS_FOLDER_NAME;
+  private String quickLinksConfigurationsDir = 
StackDirectory.SERVICE_QUICKLINKS_CONFIGURATIONS_FOLDER_NAME;
 
   @JsonIgnore
   @XmlElementWrapper(name = "quickLinksConfigurations")

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java 
b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
index f09c710..f1412f5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -51,6 +51,7 @@ public class StackInfo implements Comparable<StackInfo>, 
Validable{
   private boolean active;
   private String rcoFileLocation;
   private String kerberosDescriptorFileLocation;
+  private String kerberosDescriptorPreConfigurationFileLocation;
   private String widgetsDescriptorFileLocation;
   private List<RepositoryInfo> repositories;
   private Collection<ServiceInfo> services;
@@ -385,6 +386,25 @@ public class StackInfo implements Comparable<StackInfo>, 
Validable{
     this.kerberosDescriptorFileLocation = kerberosDescriptorFileLocation;
   }
 
+  /**
+   * Gets the path to the stack-level Kerberos descriptor pre-configuration 
file
+   *
+   * @return a String containing the path to the stack-level Kerberos 
descriptor pre-configuration file
+   */
+  public String getKerberosDescriptorPreConfigurationFileLocation() {
+    return kerberosDescriptorPreConfigurationFileLocation;
+  }
+
+  /**
+   * Sets the path to the stack-level Kerberos descriptor file
+   *
+   * @param kerberosDescriptorPreConfigurationFileLocation a String containing 
the path to the stack-level Kerberos
+   *                                                       descriptor file
+   */
+  public void setKerberosDescriptorPreConfigurationFileLocation(String 
kerberosDescriptorPreConfigurationFileLocation) {
+    this.kerberosDescriptorPreConfigurationFileLocation = 
kerberosDescriptorPreConfigurationFileLocation;
+  }
+
   public String getWidgetsDescriptorFileLocation() {
     return widgetsDescriptorFileLocation;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptor.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptor.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptor.java
index 2112fcc..d3652b8 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptor.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptor.java
@@ -21,6 +21,8 @@ package org.apache.ambari.server.state.kerberos;
 import java.util.Map;
 import java.util.TreeMap;
 
+import org.apache.commons.lang.StringUtils;
+
 /**
  * AbstractKerberosDescriptor is the base class for all Kerberos*Descriptor 
and associated classes.
  * <p/>
@@ -151,6 +153,38 @@ public abstract class AbstractKerberosDescriptor {
   }
 
   /**
+   * Safely retrieves the requested value (converted to a Boolean) from the 
supplied Map
+   * <p/>
+   * The found value will be converted to a Boolean using {@link 
Boolean#valueOf(String)}.
+   * If not found, <code>null</code> will be returned
+   *
+   * @param map a Map containing the relevant data
+   * @param key a String declaring the item to retrieve
+   * @return a Boolean representing the requested data; or null if not found
+   * @see Boolean#valueOf(String)
+   * @see #getBooleanValue(Map, String, Boolean)
+   */
+  protected static Boolean getBooleanValue(Map<?, ?> map, String key) {
+    return getBooleanValue(map, key, null);
+  }
+
+  /**
+   * Safely retrieves the requested value (converted to a Boolean) from the 
supplied Map
+   * <p/>
+   * The found value will be converted to a Boolean using {@link 
Boolean#valueOf(String)}.
+   *
+   * @param map          a Map containing the relevant data
+   * @param key          a String declaring the item to retrieve
+   * @param defaultValue a Boolean value to return if the data is not found
+   * @return a Boolean representing the requested data; or the specified 
default value if not found
+   * @see Boolean#valueOf(String)
+   */
+  protected static Boolean getBooleanValue(Map<?, ?> map, String key, Boolean 
defaultValue) {
+    String value = getStringValue(map, key);
+    return (StringUtils.isEmpty(value)) ? defaultValue : 
Boolean.valueOf(value);
+  }
+
+  /**
    * Gets the requested AbstractKerberosDescriptor implementation using a type 
name and a relevant
    * descriptor name.
    * <p/>

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java
index 86a5e01..dc37405 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java
@@ -181,12 +181,13 @@ public class KerberosDescriptor extends 
AbstractKerberosDescriptorContainer {
   }
 
   /**
-   * Adds or replaces a KerberosServiceDescriptor
+   * Adds, replaces, or updates a KerberosServiceDescriptor
    * <p/>
-   * If a KerberosServiceDescriptor with the same name already exists in the 
services Map, it will
-   * be replaced; else a new entry will be made.
+   * If a KerberosServiceDescriptor with the same name does not exist in the 
services Map, a new
+   * entry will be added; else if it one already exists and 
<code>overwrite</code> is
+   * <code>true</code>, it will be replaced; else the exsting entry will be 
updated.
    *
-   * @param service the KerberosServiceDescriptor to put
+   * @param service   the KerberosServiceDescriptor to put
    */
   public void putService(KerberosServiceDescriptor service) {
     if (service != null) {
@@ -200,10 +201,14 @@ public class KerberosDescriptor extends 
AbstractKerberosDescriptorContainer {
         services = new TreeMap<String, KerberosServiceDescriptor>();
       }
 
-      services.put(name, service);
-
-      // Set the service's parent to this KerberosDescriptor
-      service.setParent(this);
+      KerberosServiceDescriptor existing = services.get(name);
+      if (existing == null) {
+        services.put(name, service);
+        // Set the service's parent to this KerberosDescriptor
+        service.setParent(this);
+      } else {
+        existing.update(service);
+      }
     }
   }
 
@@ -269,12 +274,7 @@ public class KerberosDescriptor extends 
AbstractKerberosDescriptorContainer {
       Map<String, KerberosServiceDescriptor> updatedServiceDescriptors = 
updates.getServices();
       if (updatedServiceDescriptors != null) {
         for (Map.Entry<String, KerberosServiceDescriptor> entry : 
updatedServiceDescriptors.entrySet()) {
-          KerberosServiceDescriptor existing = getService(entry.getKey());
-          if (existing == null) {
-            putService(entry.getValue());
-          } else {
-            existing.update(entry.getValue());
-          }
+          putService(entry.getValue());
         }
       }
 
@@ -425,17 +425,17 @@ public class KerberosDescriptor extends 
AbstractKerberosDescriptorContainer {
 
   /**
    * Get a map of principals, where the key is the principal path 
(SERVICE/COMPONENT/principal_name or SERVICE/principal_name) and the value is 
the principal.
-   *
+   * <p>
    * For example if the kerberos principal of the HISTORYSERVER is defined in 
the kerberos.json:
    * "name": "history_server_jhs",
-   *   "principal": {
-   *   "value": "jhs/_HOST@${realm}",
-   *   "type" : "service",
+   * "principal": {
+   * "value": "jhs/_HOST@${realm}",
+   * "type" : "service",
    * },
    * Then "jhs/[email protected]" will be put into the map under the 
"MAPREDUCE2/HISTORYSERVER/history_server_jhs" key.
    */
   public Map<String, String> principals() throws AmbariException {
-    Map<String,String> result = new HashMap<>();
+    Map<String, String> result = new HashMap<>();
     for (AbstractKerberosDescriptorContainer each : 
nullToEmpty(getChildContainers())) {
       if ((each instanceof KerberosServiceDescriptor)) {
         collectFromComponents(each.getName(), 
nullToEmpty(((KerberosServiceDescriptor) each).getComponents()).values(), 
result);
@@ -455,8 +455,8 @@ public class KerberosDescriptor extends 
AbstractKerberosDescriptorContainer {
     for (KerberosIdentityDescriptor each : identities) {
       if (each.getPrincipalDescriptor() != null && 
!each.getReferencedServiceName().isPresent() && 
!each.getName().startsWith("/")) {
         String path = StringUtils.isBlank(component)
-          ? String.format("%s/%s", service, each.getName())
-          : String.format("%s/%s/%s", service, component, each.getName());
+            ? String.format("%s/%s", service, each.getName())
+            : String.format("%s/%s/%s", service, component, each.getName());
         result.put(path, each.getPrincipalDescriptor().getName());
       }
     }
@@ -466,7 +466,7 @@ public class KerberosDescriptor extends 
AbstractKerberosDescriptorContainer {
     return collection == null ? Collections.<T>emptyList() : collection;
   }
 
-  private static <K,V> Map<K,V> nullToEmpty(Map<K,V> collection) {
-    return collection == null ? Collections.<K,V>emptyMap() : collection;
+  private static <K, V> Map<K, V> nullToEmpty(Map<K, V> collection) {
+    return collection == null ? Collections.<K, V>emptyMap() : collection;
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosServiceDescriptor.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosServiceDescriptor.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosServiceDescriptor.java
index 0f14ca6..20a2130 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosServiceDescriptor.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosServiceDescriptor.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
@@ -24,24 +24,8 @@ import java.util.TreeMap;
 import java.util.List;
 import java.util.Map;
 
-/**
- * Represents information required to configure Kerberos for a particular 
service.
- * <p/>
- * The data map is expected to have the following properties:
- * <ul>
- * <li>name</li>
- * <li>components</li>
- * <li>identities</li>
- * <li>configurations</li>
- * </ul>
- * Example:
- * <pre>
- *  "name" => "SERVICE",
- *  "identities" => Collection&lt;Map&lt;String, Object&gt;&gt;
- *  "components" => Collection&lt;Map&lt;String, Object&gt;&gt;
- *  "configurations" => Collection&lt;Map&lt;String, Object&gt;&gt;
- * </pre>
- */
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
 
 /**
  * KerberosServiceDescriptor is an implementation of an 
AbstractKerberosDescriptorContainer that
@@ -104,7 +88,12 @@ public class KerberosServiceDescriptor extends 
AbstractKerberosDescriptorContain
   /**
    * A Map of the components contained within this KerberosServiceDescriptor
    */
-  private Map<String, KerberosComponentDescriptor> components;
+  private Map<String, KerberosComponentDescriptor> components = null;
+
+  /**
+   * A Boolean value indicating whether this service should be pre-configured 
(true) or not.
+   */
+  private Boolean preconfigure = null;
 
   /**
    * Creates a new KerberosServiceDescriptor
@@ -157,6 +146,8 @@ public class KerberosServiceDescriptor extends 
AbstractKerberosDescriptorContain
           }
         }
       }
+
+      setPreconfigure(getBooleanValue(data, "preconfigure"));
     }
   }
 
@@ -230,6 +221,24 @@ public class KerberosServiceDescriptor extends 
AbstractKerberosDescriptorContain
   }
 
   /**
+   * Indicate whether this service should be preconfigured when determining 
configurations.
+   *
+   * @return true, to preconfigure; false, otherwise
+   */
+  public boolean shouldPreconfigure() {
+    return Boolean.TRUE.equals(preconfigure);
+  }
+
+  /**
+   * Sets whether this service should be preconfigured when determining 
configurations or not.
+   *
+   * @param preconfigure true, to preconfigure; false, otherwise
+   */
+  public void setPreconfigure(Boolean preconfigure) {
+    this.preconfigure = preconfigure;
+  }
+
+  /**
    * Gets the requested AbstractKerberosDescriptor implementation using a type 
name and a relevant
    * descriptor name.
    * <p/>
@@ -269,35 +278,38 @@ public class KerberosServiceDescriptor extends 
AbstractKerberosDescriptorContain
       map.put(Type.COMPONENT.getDescriptorPluralName(), list);
     }
 
+    if (preconfigure != null) {
+      map.put("preProcess", preconfigure.toString());
+    }
+
     return map;
   }
 
   @Override
   public int hashCode() {
-    return super.hashCode() +
-        ((getComponents() == null)
-            ? 0
-            : getComponents().hashCode());
+    return new HashCodeBuilder()
+        .appendSuper(super.hashCode())
+        .append(components)
+        .append(preconfigure)
+        .toHashCode();
   }
 
   @Override
   public boolean equals(Object object) {
-    if (object == null) {
-      return false;
-    } else if (object == this) {
+    if (object == this) {
       return true;
-    } else if (object.getClass() == KerberosServiceDescriptor.class) {
-      KerberosServiceDescriptor descriptor = (KerberosServiceDescriptor) 
object;
-      return super.equals(object) &&
-          (
-              (getComponents() == null)
-                  ? (descriptor.getComponents() == null)
-                  : getComponents().equals(descriptor.getComponents())
-          );
-    } else {
+    }
+
+    if (!(object instanceof KerberosServiceDescriptor)) {
       return false;
     }
-  }
 
+    KerberosServiceDescriptor that = (KerberosServiceDescriptor) object;
+    return new EqualsBuilder()
+        .appendSuper(super.equals(object))
+        .append(components, components)
+        .append(preconfigure, that.preconfigure)
+        .isEquals();
+  }
 }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java
index e1e4ef6..d7cd087 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/AbstractUpgradeCatalog.java
@@ -772,7 +772,7 @@ public abstract class AbstractUpgradeCatalog implements 
UpgradeCatalog {
     // Get the Stack-defined Kerberos Descriptor (aka default Kerberos 
Descriptor)
     AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
     StackId stackId = cluster.getCurrentStackVersion();
-    KerberosDescriptor defaultDescriptor = 
ambariMetaInfo.getKerberosDescriptor(stackId.getStackName(), 
stackId.getStackVersion());
+    KerberosDescriptor defaultDescriptor = 
ambariMetaInfo.getKerberosDescriptor(stackId.getStackName(), 
stackId.getStackVersion(), false);
 
     // Get the User-set Kerberos Descriptor
     ArtifactDAO artifactDAO = injector.getInstance(ArtifactDAO.class);

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
 
b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
index e07e28e..0a08121 100644
--- 
a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
+++ 
b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
@@ -393,4 +393,31 @@
     </value-attributes>
     <on-ambari-upgrade add="true"/>
   </property>
+  <property>
+    <name>preconfigure_services</name>
+    <display-name>Pre-configure services</display-name>
+    <description>
+      Indicates whether to pre-configure services or not. If pre-configuring 
services, indicates
+      whether to pre-configure all or those explicitly flagged to be 
pre-configured.  Possible values
+      are DEFAULT, NONE, or ALL
+    </description>
+    <value>DEFAULT</value>
+    <value-attributes>
+      <overridable>false</overridable>
+      <type>value-list</type>
+      <selection-cardinality>1</selection-cardinality>
+      <entries>
+        <entry>
+          <value>NONE</value>
+        </entry>
+        <entry>
+          <value>DEFAULT</value>
+        </entry>
+        <entry>
+          <value>ALL</value>
+        </entry>
+      </entries>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
 </configuration>

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/main/resources/stacks/HDP/2.6/kerberos_preconfigure.json
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/resources/stacks/HDP/2.6/kerberos_preconfigure.json 
b/ambari-server/src/main/resources/stacks/HDP/2.6/kerberos_preconfigure.json
new file mode 100644
index 0000000..c9d8c91
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/kerberos_preconfigure.json
@@ -0,0 +1,24 @@
+{
+  "services": [
+    {
+      "name": "KNOX",
+      "preconfigure" : true
+    },
+    {
+      "name": "BEACON",
+      "preconfigure" : true,
+      "configurations": {
+      },
+      "identities": [
+        {
+          "name": "beacon_server",
+          "principal": {
+            "value": "beacon/_HOST@${realm}",
+            "type": "service",
+            "local_username": "beacon"
+          }
+        }
+      ]
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/e6641558/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
index 4c86476..e9567f1 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
@@ -1831,8 +1831,30 @@ public class AmbariMetaInfoTest {
   }
 
   @Test
+  public void testReadKerberosDescriptorFromFile() throws AmbariException {
+    StackInfo stackInfo = metaInfo.getStack(STACK_NAME_HDP, "2.0.8");
+    String path = stackInfo.getKerberosDescriptorFileLocation();
+    KerberosDescriptor descriptor = 
metaInfo.readKerberosDescriptorFromFile(path);
+
+    Assert.assertNotNull(descriptor);
+    Assert.assertNotNull(descriptor.getProperties());
+    Assert.assertEquals(3, descriptor.getProperties().size());
+
+    Assert.assertNotNull(descriptor.getIdentities());
+    Assert.assertEquals(1, descriptor.getIdentities().size());
+    Assert.assertEquals("spnego", descriptor.getIdentities().get(0).getName());
+
+    Assert.assertNotNull(descriptor.getConfigurations());
+    Assert.assertEquals(1, descriptor.getConfigurations().size());
+    Assert.assertNotNull(descriptor.getConfigurations().get("core-site"));
+    Assert.assertNotNull(descriptor.getConfiguration("core-site"));
+
+    Assert.assertNull(descriptor.getServices());
+  }
+
+  @Test
   public void testGetKerberosDescriptor() throws AmbariException {
-    KerberosDescriptor descriptor = 
metaInfo.getKerberosDescriptor(STACK_NAME_HDP, "2.0.8");
+    KerberosDescriptor descriptor = 
metaInfo.getKerberosDescriptor(STACK_NAME_HDP, "2.0.8", false);
 
     Assert.assertNotNull(descriptor);
     Assert.assertNotNull(descriptor.getProperties());
@@ -1851,6 +1873,37 @@ public class AmbariMetaInfoTest {
     Assert.assertEquals(1, descriptor.getServices().size());
     Assert.assertNotNull(descriptor.getServices().get("HDFS"));
     Assert.assertNotNull(descriptor.getService("HDFS"));
+    Assert.assertFalse(descriptor.getService("HDFS").shouldPreconfigure());
+  }
+
+  @Test
+  public void testGetKerberosDescriptorWithPreconfigure() throws 
AmbariException {
+    KerberosDescriptor descriptor = 
metaInfo.getKerberosDescriptor(STACK_NAME_HDP, "2.0.8", true);
+
+    Assert.assertNotNull(descriptor);
+    Assert.assertNotNull(descriptor.getProperties());
+    Assert.assertEquals(3, descriptor.getProperties().size());
+
+    Assert.assertNotNull(descriptor.getIdentities());
+    Assert.assertEquals(1, descriptor.getIdentities().size());
+    Assert.assertEquals("spnego", descriptor.getIdentities().get(0).getName());
+
+    Assert.assertNotNull(descriptor.getConfigurations());
+    Assert.assertEquals(1, descriptor.getConfigurations().size());
+    Assert.assertNotNull(descriptor.getConfigurations().get("core-site"));
+    Assert.assertNotNull(descriptor.getConfiguration("core-site"));
+
+    Assert.assertNotNull(descriptor.getServices());
+    Assert.assertEquals(2, descriptor.getServices().size());
+    Assert.assertNotNull(descriptor.getServices().get("HDFS"));
+    Assert.assertNotNull(descriptor.getService("HDFS"));
+    Assert.assertTrue(descriptor.getService("HDFS").shouldPreconfigure());
+    Assert.assertNotNull(descriptor.getServices().get("HDFS"));
+    Assert.assertNotNull(descriptor.getService("HDFS"));
+    Assert.assertTrue(descriptor.getService("HDFS").shouldPreconfigure());
+    Assert.assertNotNull(descriptor.getServices().get("NEW_SERVICE"));
+    Assert.assertNotNull(descriptor.getService("NEW_SERVICE"));
+    
Assert.assertTrue(descriptor.getService("NEW_SERVICE").shouldPreconfigure());
   }
 
   private File getStackRootTmp(String buildDir) {

Reply via email to