You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2018/06/28 11:36:16 UTC

[ambari] branch trunk updated: [AMBARI-24202] - Allow Conditional Upgrade Elements Based on KDC Type (#1634)

This is an automated email from the ASF dual-hosted git repository.

jonathanhurley pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new c2400f8  [AMBARI-24202] - Allow Conditional Upgrade Elements Based on KDC Type (#1634)
c2400f8 is described below

commit c2400f824209d0c5f54e095cf41738bae089d999
Author: Jonathan Hurley <jo...@apache.org>
AuthorDate: Thu Jun 28 07:36:14 2018 -0400

    [AMBARI-24202] - Allow Conditional Upgrade Elements Based on KDC Type (#1634)
---
 .../ambari/server/controller/KerberosDetails.java  |  89 +++++++++++++++
 .../ambari/server/controller/KerberosHelper.java   |  14 +++
 .../server/controller/KerberosHelperImpl.java      | 100 +++--------------
 .../server/serveraction/kerberos/KDCType.java      |   8 ++
 .../apache/ambari/server/state/UpgradeContext.java |  31 +++++-
 .../state/stack/upgrade/SecurityCondition.java     |  53 ++++++++-
 ambari-server/src/main/resources/upgrade-pack.xsd  |  12 +++
 .../ambari/server/agent/AgentResourceTest.java     |   2 +
 .../KerberosAdminPersistedCredentialCheckTest.java |   1 +
 .../upgrades/KerberosKeytabsActionTest.java        |   4 +-
 .../ambari/server/state/UpgradeHelperTest.java     | 119 +++++++++++++++++++--
 .../KerberosDescriptorUpdateHelperTest.java        |   2 +
 .../server/testutils/PartialNiceMockBinder.java    |  18 ++--
 .../ambari/server/update/HostUpdateHelperTest.java |   2 +
 .../HDP/2.2.0/upgrades/upgrade_test_conditions.xml |   9 ++
 15 files changed, 355 insertions(+), 109 deletions(-)

diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosDetails.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosDetails.java
new file mode 100644
index 0000000..43881cd
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosDetails.java
@@ -0,0 +1,89 @@
+/**
+ * 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.controller;
+
+import java.util.Map;
+
+import org.apache.ambari.server.serveraction.kerberos.KDCType;
+import org.apache.ambari.server.state.SecurityType;
+
+/**
+ * KerberosDetails is a helper class to hold the details of the relevant Kerberos-specific
+ * configurations so they may be passed around more easily.
+ */
+public class KerberosDetails {
+  private String defaultRealm;
+  private KDCType kdcType;
+  private Map<String, String> kerberosEnvProperties;
+  private SecurityType securityType;
+  private Boolean manageIdentities;
+
+  public void setDefaultRealm(String defaultRealm) {
+    this.defaultRealm = defaultRealm;
+  }
+
+  public String getDefaultRealm() {
+    return defaultRealm;
+  }
+
+  public void setKdcType(KDCType kdcType) {
+    this.kdcType = kdcType;
+  }
+
+  public KDCType getKdcType() {
+    return kdcType;
+  }
+
+  public void setKerberosEnvProperties(Map<String, String> kerberosEnvProperties) {
+    this.kerberosEnvProperties = kerberosEnvProperties;
+  }
+
+  public Map<String, String> getKerberosEnvProperties() {
+    return kerberosEnvProperties;
+  }
+
+  public void setSecurityType(SecurityType securityType) {
+    this.securityType = securityType;
+  }
+
+  public SecurityType getSecurityType() {
+    return securityType;
+  }
+
+  public boolean manageIdentities() {
+    if (manageIdentities == null) {
+      return (kerberosEnvProperties == null) ||
+        !"false".equalsIgnoreCase(kerberosEnvProperties.get(KerberosHelper.MANAGE_IDENTITIES));
+    } else {
+      return manageIdentities;
+    }
+  }
+
+  public void setManageIdentities(Boolean manageIdentities) {
+    this.manageIdentities = manageIdentities;
+  }
+
+  public boolean createAmbariPrincipal() {
+    return (kerberosEnvProperties == null) ||
+      !"false".equalsIgnoreCase(kerberosEnvProperties.get(KerberosHelper.CREATE_AMBARI_PRINCIPAL));
+  }
+
+  public String getPreconfigureServices() {
+    return (kerberosEnvProperties == null) ? "" : kerberosEnvProperties.get(KerberosHelper.PRECONFIGURE_SERVICES);
+  }
+}
\ No newline at end of file
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
index 38701e2..79b2269 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
@@ -798,6 +798,20 @@ public interface KerberosHelper {
    * @return a map of configuration types to sets of property names
    */
   Map<String, Set<String>> translateConfigurationSpecifications(Collection<String> configurationSpecifications);
+  
+  /**
+   * Gathers the Kerberos-related data from configurations and stores it in a new KerberosDetails
+   * instance.
+   *
+   * @param cluster          the relevant Cluster
+   * @param manageIdentities a Boolean value indicating how to override the configured behavior
+   *                         of managing Kerberos identities; if null the configured behavior
+   *                         will not be overridden
+   * @return a new KerberosDetails with the collected configuration data
+   * @throws AmbariException
+   */
+  KerberosDetails getKerberosDetails(Cluster cluster, Boolean manageIdentities)
+    throws KerberosInvalidConfigurationException, AmbariException;  
 
   /**
    * Types of Kerberos descriptors related to where the data is stored.
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 5dc9f37..ba9ed59 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
@@ -2452,19 +2452,11 @@ public class KerberosHelperImpl implements KerberosHelper {
     return requestStageContainer;
   }
 
-
   /**
-   * Gathers the Kerberos-related data from configurations and stores it in a new KerberosDetails
-   * instance.
-   *
-   * @param cluster          the relevant Cluster
-   * @param manageIdentities a Boolean value indicating how to override the configured behavior
-   *                         of managing Kerberos identities; if null the configured behavior
-   *                         will not be overridden
-   * @return a new KerberosDetails with the collected configuration data
-   * @throws AmbariException
+   * {@inheritDoc}
    */
-  private KerberosDetails getKerberosDetails(Cluster cluster, Boolean manageIdentities)
+  @Override
+  public KerberosDetails getKerberosDetails(Cluster cluster, Boolean manageIdentities)
     throws KerberosInvalidConfigurationException, AmbariException {
 
     KerberosDetails kerberosDetails = new KerberosDetails();
@@ -3542,13 +3534,13 @@ public class KerberosHelperImpl implements KerberosHelper {
 
       if (!hosts.isEmpty()) {
         Map<String, String> requestParams = new HashMap<>();
-       
+
         ActionExecutionContext actionExecContext = createActionExecutionContext(
-            cluster.getClusterName(), 
-            SET_KEYTAB, 
+            cluster.getClusterName(),
+            SET_KEYTAB,
             createRequestResourceFilters(hosts),
-            requestParams, 
-            retryAllowed);        
+            requestParams,
+            retryAllowed);
 
         customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage,
           requestParams, null);
@@ -3582,11 +3574,11 @@ public class KerberosHelperImpl implements KerberosHelper {
         Map<String, String> requestParams = new HashMap<>();
 
         ActionExecutionContext actionExecContext = createActionExecutionContext(
-            cluster.getClusterName(), 
-            CHECK_KEYTABS, 
+            cluster.getClusterName(),
+            CHECK_KEYTABS,
             createRequestResourceFilters(hostsToInclude),
-            requestParams, 
-            retryAllowed);        
+            requestParams,
+            retryAllowed);
 
         customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, requestParams, null);
       }
@@ -3832,7 +3824,7 @@ public class KerberosHelperImpl implements KerberosHelper {
 
     /**
      * Creates an {@link ActionExecutionContext} where some of the common values are pre-initialized.
-     * 
+     *
      * @param clusterName
      * @param commandName
      * @param resourceFilters
@@ -4376,70 +4368,4 @@ public class KerberosHelperImpl implements KerberosHelper {
       return requestStageContainer.getLastStageId();
     }
   }
-
-  /**
-   * KerberosDetails is a helper class to hold the details of the relevant Kerberos-specific
-   * configurations so they may be passed around more easily.
-   */
-  private static class KerberosDetails {
-    private String defaultRealm;
-    private KDCType kdcType;
-    private Map<String, String> kerberosEnvProperties;
-    private SecurityType securityType;
-    private Boolean manageIdentities;
-
-    public void setDefaultRealm(String defaultRealm) {
-      this.defaultRealm = defaultRealm;
-    }
-
-    public String getDefaultRealm() {
-      return defaultRealm;
-    }
-
-    public void setKdcType(KDCType kdcType) {
-      this.kdcType = kdcType;
-    }
-
-    public KDCType getKdcType() {
-      return kdcType;
-    }
-
-    public void setKerberosEnvProperties(Map<String, String> kerberosEnvProperties) {
-      this.kerberosEnvProperties = kerberosEnvProperties;
-    }
-
-    public Map<String, String> getKerberosEnvProperties() {
-      return kerberosEnvProperties;
-    }
-
-    public void setSecurityType(SecurityType securityType) {
-      this.securityType = securityType;
-    }
-
-    public SecurityType getSecurityType() {
-      return securityType;
-    }
-
-    public boolean manageIdentities() {
-      if (manageIdentities == null) {
-        return (kerberosEnvProperties == null) ||
-          !"false".equalsIgnoreCase(kerberosEnvProperties.get(MANAGE_IDENTITIES));
-      } else {
-        return manageIdentities;
-      }
-    }
-
-    public void setManageIdentities(Boolean manageIdentities) {
-      this.manageIdentities = manageIdentities;
-    }
-
-    public boolean createAmbariPrincipal() {
-      return (kerberosEnvProperties == null) ||
-        !"false".equalsIgnoreCase(kerberosEnvProperties.get(CREATE_AMBARI_PRINCIPAL));
-    }
-
-    public String getPreconfigureServices() {
-      return (kerberosEnvProperties == null) ? "" : kerberosEnvProperties.get(PRECONFIGURE_SERVICES);
-    }
-  }
 }
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCType.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCType.java
index 631b353..13ff9c5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCType.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KDCType.java
@@ -18,28 +18,36 @@
 
 package org.apache.ambari.server.serveraction.kerberos;
 
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlEnumValue;
+
 /**
  * Enumerates the supported KDC types
  */
+@XmlEnum
 public enum KDCType {
   /**
    * Indicates not KDC type is relevant. This is expected when Ambari is not managing Kerberos identities.
    */
+  @XmlEnumValue("none")
   NONE,
 
   /**
    * Indicates an MIT KDC (or similar)
    */
+  @XmlEnumValue("mit-kdc")
   MIT_KDC,
 
   /**
    * Indicates a Microsoft Active Directory
    */
+  @XmlEnumValue("active-directory")
   ACTIVE_DIRECTORY,
 
   /**
    * Indicates an IPA KDC
    */
+  @XmlEnumValue("ipa")
   IPA;
 
   /**
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java
index b13aaf9..8ef648c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UpgradeContext.java
@@ -48,6 +48,8 @@ import org.apache.ambari.server.actionmanager.HostRoleCommandFactory;
 import org.apache.ambari.server.agent.ExecutionCommand.KeyNames;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.KerberosDetails;
+import org.apache.ambari.server.controller.KerberosHelper;
 import org.apache.ambari.server.controller.internal.AbstractControllerResourceProvider;
 import org.apache.ambari.server.controller.internal.PreUpgradeCheckResourceProvider;
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
@@ -64,6 +66,7 @@ import org.apache.ambari.server.orm.dao.UpgradeDAO;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.UpgradeEntity;
 import org.apache.ambari.server.orm.entities.UpgradeHistoryEntity;
+import org.apache.ambari.server.serveraction.kerberos.KerberosInvalidConfigurationException;
 import org.apache.ambari.server.stack.MasterHostResolver;
 import org.apache.ambari.server.stageplanner.RoleGraphFactory;
 import org.apache.ambari.server.state.repository.ClusterVersionSummary;
@@ -82,7 +85,7 @@ import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.gson.Gson;
 import com.google.gson.JsonElement;
 import com.google.gson.annotations.SerializedName;
@@ -248,6 +251,13 @@ public class UpgradeContext {
   private UpgradeDAO m_upgradeDAO;
 
   /**
+   * Providers information about the Kerberization of a cluster, such as
+   * {@link KerberosDetails}.
+   */
+  @Inject
+  private KerberosHelper m_kerberosHelper;
+
+  /**
    * Used as a quick way to tell if the upgrade is to revert a patch.
    */
   private final boolean m_isRevert;
@@ -917,7 +927,7 @@ public class UpgradeContext {
    */
   @Override
   public String toString() {
-    return Objects.toStringHelper(this)
+    return MoreObjects.toStringHelper(this)
         .add("direction", m_direction)
         .add("type", m_type)
         .add("target", m_repositoryVersion).toString();
@@ -1033,6 +1043,23 @@ public class UpgradeContext {
   }
 
   /**
+   * Gets Kerberos information about a cluster. It should only be invoked if the
+   * cluster's security type is set to {@link SecurityType#KERBEROS}, otherwise
+   * it will throw an {@link AmbariException}.
+   *
+   * @return the Kerberos related details of a cluster.
+   * @throws KerberosInvalidConfigurationException
+   *           if the {@code kerberos-env} or {@code krb5-conf}} configurations
+   *           can't be parsed.
+   * @throws AmbariException
+   *           if the cluster is not Kerberized.
+   */
+  public KerberosDetails getKerberosDetails()
+      throws KerberosInvalidConfigurationException, AmbariException {
+    return m_kerberosHelper.getKerberosDetails(m_cluster, null);
+  }
+
+  /**
    * Gets the set of services which will participate in the upgrade. The
    * services available in the repository are comapred against those installed
    * in the cluster to arrive at the final subset.
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/SecurityCondition.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/SecurityCondition.java
index 878019f..be73050 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/SecurityCondition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/upgrade/SecurityCondition.java
@@ -22,11 +22,17 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlType;
 
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.KerberosDetails;
+import org.apache.ambari.server.serveraction.kerberos.KDCType;
+import org.apache.ambari.server.serveraction.kerberos.KerberosInvalidConfigurationException;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.SecurityType;
 import org.apache.ambari.server.state.UpgradeContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 
 /**
  * The {@link SecurityCondition} class is used to represent that the cluster has
@@ -38,6 +44,8 @@ import com.google.common.base.Objects;
 @XmlAccessorType(XmlAccessType.FIELD)
 public final class SecurityCondition extends Condition {
 
+  private static final Logger LOG = LoggerFactory.getLogger(SecurityCondition.class);
+
   /**
    * The type of security which much be enabled.
    */
@@ -45,11 +53,21 @@ public final class SecurityCondition extends Condition {
   public SecurityType securityType;
 
   /**
+   * The type of Kerberos when the type of security is
+   * {@link SecurityType#KERBEROS}.
+   */
+  @XmlAttribute(name = "kdc-type", required = false)
+  public KDCType kdctype;
+
+  /**
    * {@inheritDoc}
    */
   @Override
   public String toString() {
-    return Objects.toStringHelper(this).add("type", securityType).omitNullValues().toString();
+    return MoreObjects.toStringHelper(this)
+        .add("type", securityType)
+        .add("kdcType", kdctype)
+        .omitNullValues().toString();
   }
 
   /**
@@ -58,7 +76,36 @@ public final class SecurityCondition extends Condition {
   @Override
   public boolean isSatisfied(UpgradeContext upgradeContext) {
     Cluster cluster = upgradeContext.getCluster();
-    return cluster.getSecurityType() == securityType;
+
+    // if the security types don't match, then don't process any further
+    if (cluster.getSecurityType() != securityType) {
+      return false;
+    }
+
+    switch( securityType ) {
+      case KERBEROS:
+        // if KDC type is specified, then match on it
+        if( null != kdctype ) {
+          try {
+            KerberosDetails kerberosDetails = upgradeContext.getKerberosDetails();
+            return kerberosDetails.getKdcType() == kdctype;
+          } catch (AmbariException | KerberosInvalidConfigurationException kerberosException) {
+            LOG.error(
+                "Unable to determine if this upgrade condition is met because there was a problem parsing the Kerberos configruations for the KDC Type",
+                kerberosException);
+            return false;
+          }
+        }
+
+        // security type matches Kerberos, return true
+        return true;
+      case NONE:
+        // nothing to do here is the security type is NONE
+        return true;
+      default:
+        // nothing to do here if it's an unknown type
+        return true;
+    }
   }
 }
 
diff --git a/ambari-server/src/main/resources/upgrade-pack.xsd b/ambari-server/src/main/resources/upgrade-pack.xsd
index f9e6b37..5dbadc8 100644
--- a/ambari-server/src/main/resources/upgrade-pack.xsd
+++ b/ambari-server/src/main/resources/upgrade-pack.xsd
@@ -56,6 +56,7 @@
     </xs:restriction>
   </xs:simpleType>
   
+  <!-- Corresponds to the SecurityType enumeration -->
   <xs:simpleType name="security-type">
     <xs:restriction base="xs:string">
       <xs:enumeration value="none" />
@@ -63,6 +64,16 @@
     </xs:restriction>
   </xs:simpleType>
 
+  <!-- Corresponds to the KDCType enumeration -->
+  <xs:simpleType name="kdc-type">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="none" />
+      <xs:enumeration value="mit-kdc" />
+      <xs:enumeration value="active-directory" />
+      <xs:enumeration value="ipa" />
+    </xs:restriction>
+  </xs:simpleType>
+
   <xs:simpleType name="config-condition-comparison-type">
     <xs:restriction base="xs:string">
       <xs:enumeration value="equals" />
@@ -92,6 +103,7 @@
     <xs:complexContent>
       <xs:extension base="abstract-condition-type">  
         <xs:attribute name="type" type="security-type" use="required"/>
+        <xs:attribute name="kdc-type" type="kdc-type" use="optional"/>
       </xs:extension>
     </xs:complexContent>
   </xs:complexType>
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/AgentResourceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/AgentResourceTest.java
index 0117f4d..ba1626f 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/agent/AgentResourceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/AgentResourceTest.java
@@ -38,6 +38,7 @@ import org.apache.ambari.server.agent.rest.AgentResource;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AbstractRootServiceResponseFactory;
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.KerberosHelper;
 import org.apache.ambari.server.controller.RootServiceResponseFactory;
 import org.apache.ambari.server.events.AmbariEvent;
 import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
@@ -348,6 +349,7 @@ public class AgentResourceTest extends RandomPortJerseyTest {
       bind(PersistedState.class).toInstance(createNiceMock(PersistedState.class));
       bind(RoleCommandOrderProvider.class).to(CachedRoleCommandOrderProvider.class);
       bind(AmbariManagementController.class).toInstance(createNiceMock(AmbariManagementController.class));
+      bind(KerberosHelper.class).toInstance(createNiceMock(KerberosHelper.class));
     }
 
     private void installDependencies() {
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/checks/KerberosAdminPersistedCredentialCheckTest.java b/ambari-server/src/test/java/org/apache/ambari/server/checks/KerberosAdminPersistedCredentialCheckTest.java
index 0a6888a..69d1332 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/checks/KerberosAdminPersistedCredentialCheckTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/checks/KerberosAdminPersistedCredentialCheckTest.java
@@ -245,6 +245,7 @@ public class KerberosAdminPersistedCredentialCheckTest extends EasyMockSupport {
         bind(ArtifactDAO.class).toInstance(createNiceMock(ArtifactDAO.class));
         bind(RoleCommandOrderProvider.class).to(CachedRoleCommandOrderProvider.class);
         bind(UpgradeHelper.class).toInstance(upgradeHelper);
+        bind(KerberosHelper.class).toInstance(createNiceMock(KerberosHelper.class));
 
         bind(CredentialStoreService.class).toInstance(createMock(CredentialStoreService.class));
       }
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/KerberosKeytabsActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/KerberosKeytabsActionTest.java
index 9c55eec..5a19c75 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/KerberosKeytabsActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/KerberosKeytabsActionTest.java
@@ -71,7 +71,6 @@ public class KerberosKeytabsActionTest {
   public void setup() throws Exception {
 
     m_clusters = EasyMock.createMock(Clusters.class);
-    m_kerberosHelper = EasyMock.createMock(KerberosHelper.class);
     UnitOfWork unitOfWork = EasyMock.createMock(UnitOfWork.class);
 
     Map<String, String> mockProperties = new HashMap<String, String>() {{
@@ -97,7 +96,6 @@ public class KerberosKeytabsActionTest {
         PartialNiceMockBinder.newBuilder().addClustersBinding().build().configure(binder());
 
         bind(Clusters.class).toInstance(m_clusters);
-        bind(KerberosHelper.class).toInstance(m_kerberosHelper);
         bind(OsFamily.class).toInstance(EasyMock.createNiceMock(OsFamily.class));
         bind(UpgradeHelper.class).toInstance(EasyMock.createNiceMock(UpgradeHelper.class));
         bind(StackManagerFactory.class).toInstance(EasyMock.createNiceMock(StackManagerFactory.class));
@@ -107,6 +105,8 @@ public class KerberosKeytabsActionTest {
         bind(AmbariMetaInfo.class).toInstance(EasyMock.createNiceMock(AmbariMetaInfo.class));
       }
     });
+
+    m_kerberosHelper = m_injector.getInstance(KerberosHelper.class);
   }
 
   @Test
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java
index 2cc2010..e1b93de 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/UpgradeHelperTest.java
@@ -57,6 +57,7 @@ import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.AmbariManagementController;
 import org.apache.ambari.server.controller.ClusterRequest;
 import org.apache.ambari.server.controller.ConfigurationRequest;
+import org.apache.ambari.server.controller.KerberosDetails;
 import org.apache.ambari.server.controller.internal.DeleteHostComponentStatusMetaData;
 import org.apache.ambari.server.controller.internal.UpgradeResourceProvider;
 import org.apache.ambari.server.events.AgentConfigsUpdateEvent;
@@ -69,6 +70,7 @@ import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
 import org.apache.ambari.server.security.TestAuthenticationFactory;
 import org.apache.ambari.server.security.authorization.AuthorizationException;
+import org.apache.ambari.server.serveraction.kerberos.KDCType;
 import org.apache.ambari.server.stack.HostsType;
 import org.apache.ambari.server.stack.MasterHostResolver;
 import org.apache.ambari.server.stack.StackManagerMock;
@@ -2342,7 +2344,13 @@ public class UpgradeHelperTest extends EasyMockSupport {
 
     Cluster cluster = makeCluster();
 
-    UpgradeContext context = getMockUpgradeContext(cluster, Direction.UPGRADE, UpgradeType.ROLLING);
+    KerberosDetails kerberosDetails = createNiceMock(KerberosDetails.class);
+    expect(kerberosDetails.getKdcType()).andReturn(KDCType.NONE).atLeastOnce();
+    replay(kerberosDetails);
+
+    UpgradeContext context = getMockUpgradeContext(cluster, Direction.UPGRADE, UpgradeType.ROLLING, false);
+    expect(context.getKerberosDetails()).andReturn(kerberosDetails).atLeastOnce();
+    replay(context);
 
     // initially, no conditions should be met, so only 1 group should be
     // available
@@ -2378,7 +2386,9 @@ public class UpgradeHelperTest extends EasyMockSupport {
     cluster.setSecurityType(SecurityType.KERBEROS);
 
     groups = m_upgradeHelper.createSequence(upgrade, context);
-    assertEquals(4, groups.size());
+    assertEquals(5, groups.size());
+
+    EasyMock.verify(kerberosDetails);
   }
 
   /**
@@ -2778,20 +2788,70 @@ public class UpgradeHelperTest extends EasyMockSupport {
   }
 
   /**
+   * Builds a mock upgrade context using the following parameters:
+   * <ul>
+   * <li>{@link #repositoryVersion2110}
+   * <li>{@link RepositoryType#STANDARD}
+   * <li>All cluster services
+   * <li>The mock master host resolve, {@link #m_masterHostResolver}
+   * </ul>
+   *
    * @param cluster
+   *          the cluster for the upgrade
    * @param direction
+   *          the upgrade direction
    * @param type
-   * @return
+   *          the type of upgrade
+   * @return a mock {@link UpgradeContext} which has already been replayed and
+   *         is ready to use.
    */
   private UpgradeContext getMockUpgradeContext(Cluster cluster, Direction direction, UpgradeType type){
     return getMockUpgradeContext(cluster, direction, type, repositoryVersion2210);
   }
 
   /**
+   * Builds a mock upgrade context using the following parameters:
+   * <ul>
+   * <li>{@link #repositoryVersion2110}
+   * <li>{@link RepositoryType#STANDARD}
+   * <li>All cluster services
+   * <li>The mock master host resolve, {@link #m_masterHostResolver}
+   * </ul>
+   *
    * @param cluster
+   *          the cluster for the upgrade
    * @param direction
+   *          the upgrade direction
    * @param type
-   * @return
+   *          the type of upgrade
+   * @param replay
+   *          {@code true} to replay the mock object before returning it,
+   *          {@code false} otherwise.
+   * @return a mock {@link UpgradeContext}
+   */
+  private UpgradeContext getMockUpgradeContext(Cluster cluster, Direction direction, UpgradeType type, boolean replay){
+    return getMockUpgradeContext(cluster, direction, type, repositoryVersion2210,
+        RepositoryType.STANDARD, cluster.getServices().keySet(), m_masterHostResolver, replay);
+  }
+
+  /**
+   * Builds a mock upgrade context using the following parameters:
+   * <ul>
+   * <li>{@link RepositoryType#STANDARD}
+   * <li>All cluster services
+   * <li>The mock master host resolve, {@link #m_masterHostResolver}
+   * </ul>
+   *
+   * @param cluster
+   *          the cluster for the upgrade
+   * @param direction
+   *          the upgrade direction
+   * @param type
+   *          the type of upgrade
+   * @param repositoryVersion
+   *          the repository version to use for the upgrade or downgrade.
+   * @return a mock {@link UpgradeContext} which has already been replayed and
+   *         is ready to use.
    */
   private UpgradeContext getMockUpgradeContext(Cluster cluster, Direction direction,
       UpgradeType type, RepositoryVersionEntity repositoryVersion) {
@@ -2801,10 +2861,26 @@ public class UpgradeHelperTest extends EasyMockSupport {
   }
 
   /**
+   * Builds a mock upgrade context using the following parameters:
+   * <ul>
+   * <li>The mock master host resolve, {@link #m_masterHostResolver}
+   * </ul>
+   *
    * @param cluster
+   *          the cluster for the upgrade
    * @param direction
+   *          the upgrade direction
    * @param type
-   * @return
+   *          the type of upgrade
+   * @param repositoryVersion
+   *          the repository version to use for the upgrade or downgrade.
+   * @param repositoryType
+   *          the type of repository for the upgrade (patch, standard, etc).
+   * @param services
+   *          the services participating in the upgrade. This should typically
+   *          be all services, unless the {@link RepositoryType#PATCH} is used.
+   * @return a mock {@link UpgradeContext} which has already been replayed and
+   *         is ready to use.
    */
   private UpgradeContext getMockUpgradeContext(Cluster cluster, Direction direction,
       UpgradeType type, RepositoryVersionEntity repositoryVersion, RepositoryType repositoryType,
@@ -2814,10 +2890,22 @@ public class UpgradeHelperTest extends EasyMockSupport {
   }
 
   /**
+   * Builds a mock upgrade context using the following parameters:
+   * <ul>
+   * <li>{@link RepositoryType#STANDARD}
+   * <li>All cluster services
+   * </ul>
+   *
    * @param cluster
+   *          the cluster for the upgrade
    * @param direction
+   *          the upgrade direction
    * @param type
-   * @return
+   *          the type of upgrade
+   * @param repositoryVersion
+   *          the repository version to use for the upgrade or downgrade.
+   * @return a mock {@link UpgradeContext} which has already been replayed and
+   *         is ready to use.
    */
   private UpgradeContext getMockUpgradeContextNoReplay(Cluster cluster, Direction direction,
       UpgradeType type, RepositoryVersionEntity repositoryVersion) {
@@ -2828,12 +2916,29 @@ public class UpgradeHelperTest extends EasyMockSupport {
   }
 
   /**
+   * Builds a mock upgrade context using only the supplied method arguments.
+   *
    * @param cluster
+   *          the cluster for the upgrade
    * @param direction
+   *          the upgrade direction
    * @param type
+   *          the type of upgrade
+   * @param repositoryVersion
+   *          the repository version to use for the upgrade or downgrade.
    * @param repositoryType
+   *          the type of repository for the upgrade (patch, standard, etc).
    * @param services
-   * @return
+   *          the services participating in the upgrade. This should typically
+   *          be all services, unless the {@link RepositoryType#PATCH} is used
+   * @param resolver
+   *          the master hsot resolver to use when determining how to
+   *          orchestrate hosts.
+   * @param replay
+   *          {@code true} to replay the mock object before returning it,
+   *          {@code false} otherwise.
+   * @return a mock {@link UpgradeContext} which has already been replayed and
+   *         is ready to use.
    */
   private UpgradeContext getMockUpgradeContext(Cluster cluster, Direction direction,
       UpgradeType type, RepositoryVersionEntity repositoryVersion, final RepositoryType repositoryType,
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorUpdateHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorUpdateHelperTest.java
index 1550452..225c610 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorUpdateHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorUpdateHelperTest.java
@@ -40,6 +40,7 @@ import org.apache.ambari.server.audit.AuditLoggerDefaultImpl;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.AbstractRootServiceResponseFactory;
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.KerberosHelper;
 import org.apache.ambari.server.controller.RootServiceResponseFactory;
 import org.apache.ambari.server.hooks.HookService;
 import org.apache.ambari.server.hooks.users.UserHookService;
@@ -118,6 +119,7 @@ public class KerberosDescriptorUpdateHelperTest extends EasyMockSupport {
         bind(CredentialStoreService.class).toInstance(createNiceMock(CredentialStoreService.class));
         bind(AmbariManagementController.class).toInstance(createNiceMock(AmbariManagementController.class));
         bind(ExecutionScheduler.class).to(ExecutionSchedulerImpl.class);
+        bind(KerberosHelper.class).toInstance(createNiceMock(KerberosHelper.class));
       }
     });
 
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/testutils/PartialNiceMockBinder.java b/ambari-server/src/test/java/org/apache/ambari/server/testutils/PartialNiceMockBinder.java
index fd7ca49..ad214e1 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/testutils/PartialNiceMockBinder.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/testutils/PartialNiceMockBinder.java
@@ -35,6 +35,7 @@ import org.apache.ambari.server.audit.AuditLogger;
 import org.apache.ambari.server.audit.AuditLoggerDefaultImpl;
 import org.apache.ambari.server.controller.AbstractRootServiceResponseFactory;
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.KerberosHelper;
 import org.apache.ambari.server.controller.RootServiceResponseFactory;
 import org.apache.ambari.server.events.AmbariEvent;
 import org.apache.ambari.server.hooks.AmbariEventFactory;
@@ -121,7 +122,7 @@ public class PartialNiceMockBinder implements Module {
     }
 
     public Builder addAlertDefinitionBinding() {
-      PartialNiceMockBinder.this.configurers.add((Binder binder) -> {
+      configurers.add((Binder binder) -> {
           binder.bind(Cluster.class).toInstance(createNiceMock(Cluster.class));
           binder.bind(DaoUtils.class).toInstance(createNiceMock(DaoUtils.class));
           binder.bind(AlertDefinitionDAO.class).toInstance(createNiceMock(AlertDefinitionDAO.class));
@@ -132,7 +133,7 @@ public class PartialNiceMockBinder implements Module {
     }
 
     public Builder addAmbariMetaInfoBinding(AmbariManagementController ambariManagementController) {
-      PartialNiceMockBinder.this.configurers.add((Binder binder) -> {
+      configurers.add((Binder binder) -> {
           binder.bind(PersistedState.class).toInstance(easyMockSupport.createNiceMock(PersistedState.class));
           binder.bind(HostRoleCommandFactory.class).to(HostRoleCommandFactoryImpl.class);
           binder.bind(ActionDBAccessor.class).to(ActionDBAccessorImpl.class);
@@ -147,6 +148,7 @@ public class PartialNiceMockBinder implements Module {
           binder.bind(CredentialStoreService.class).toInstance(easyMockSupport.createNiceMock(CredentialStoreService.class));
           binder.bind(AmbariManagementController.class).toInstance(ambariManagementController);
           binder.bind(ExecutionScheduler.class).to(ExecutionSchedulerImpl.class);
+          binder.bind(KerberosHelper.class).toInstance(easyMockSupport.createNiceMock(KerberosHelper.class));
       });
       addConfigsBindings();
       addFactoriesInstallBinding();
@@ -173,7 +175,7 @@ public class PartialNiceMockBinder implements Module {
     }
 
     public Builder addDBAccessorBinding(DBAccessor dbAccessor) {
-      PartialNiceMockBinder.this.configurers.add((Binder binder) -> {
+      configurers.add((Binder binder) -> {
           binder.bind(StackManagerFactory.class).toInstance(easyMockSupport.createNiceMock(StackManagerFactory.class));
           binder.bind(EntityManager.class).toInstance(easyMockSupport.createNiceMock(EntityManager.class));
           binder.bind(DBAccessor.class).toInstance(dbAccessor);
@@ -184,7 +186,7 @@ public class PartialNiceMockBinder implements Module {
     }
 
     public Builder addDBAccessorBinding() {
-      PartialNiceMockBinder.this.configurers.add((Binder binder) -> {
+      configurers.add((Binder binder) -> {
           binder.bind(StackManagerFactory.class).toInstance(easyMockSupport.createNiceMock(StackManagerFactory.class));
           binder.bind(EntityManager.class).toInstance(easyMockSupport.createNiceMock(EntityManager.class));
           binder.bind(DBAccessor.class).toInstance(easyMockSupport.createNiceMock(DBAccessor.class));
@@ -202,7 +204,7 @@ public class PartialNiceMockBinder implements Module {
     }
 
     public Builder addHostRoleCommandsConfigsBindings() {
-      PartialNiceMockBinder.this.configurers.add((Binder binder) -> {
+      configurers.add((Binder binder) -> {
           binder.bindConstant().annotatedWith(Names.named(HostRoleCommandDAO.HRC_STATUS_SUMMARY_CACHE_ENABLED)).to(true);
           binder.bindConstant().annotatedWith(Names.named(HostRoleCommandDAO.HRC_STATUS_SUMMARY_CACHE_SIZE)).to(10000L);
           binder.bindConstant().annotatedWith(Names.named(HostRoleCommandDAO.HRC_STATUS_SUMMARY_CACHE_EXPIRY_DURATION_MINUTES)).to(30L);
@@ -211,7 +213,7 @@ public class PartialNiceMockBinder implements Module {
     }
 
     public Builder addActionSchedulerConfigsBindings() {
-      PartialNiceMockBinder.this.configurers.add((Binder binder) -> {
+      configurers.add((Binder binder) -> {
           binder.bindConstant().annotatedWith(Names.named("actionTimeout")).to(600000L);
           binder.bindConstant().annotatedWith(Names.named("schedulerSleeptime")).to(1L);
       });
@@ -219,14 +221,14 @@ public class PartialNiceMockBinder implements Module {
     }
 
     public Builder addActionDBAccessorConfigsBindings() {
-      PartialNiceMockBinder.this.configurers.add((Binder binder) ->
+      configurers.add((Binder binder) ->
           binder.bindConstant().annotatedWith(Names.named("executionCommandCacheSize")).to(10000L)
       );
       return this;
     }
 
     public Builder addFactoriesInstallBinding() {
-      PartialNiceMockBinder.this.configurers.add((Binder binder) -> {
+      configurers.add((Binder binder) -> {
           binder.install(new FactoryModuleBuilder().build(ConfigureClusterTaskFactory.class));
           binder.install(new FactoryModuleBuilder().implement(Config.class, ConfigImpl.class).build(ConfigFactory.class));
           binder.install(new FactoryModuleBuilder().build(RequestFactory.class));
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/update/HostUpdateHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/update/HostUpdateHelperTest.java
index 17f3b12..42fcac8 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/update/HostUpdateHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/update/HostUpdateHelperTest.java
@@ -44,6 +44,7 @@ import org.apache.ambari.server.audit.AuditLoggerDefaultImpl;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.AbstractRootServiceResponseFactory;
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.KerberosHelper;
 import org.apache.ambari.server.controller.RootServiceResponseFactory;
 import org.apache.ambari.server.hooks.HookService;
 import org.apache.ambari.server.hooks.users.UserHookService;
@@ -517,6 +518,7 @@ public class HostUpdateHelperTest {
         bind(AbstractRootServiceResponseFactory.class).to(RootServiceResponseFactory.class);
         bind(CredentialStoreService.class).toInstance(createNiceMock(CredentialStoreService.class));
         bind(ExecutionScheduler.class).to(ExecutionSchedulerImpl.class);
+        bind(KerberosHelper.class).toInstance(createNiceMock(KerberosHelper.class));
       }
     });
 
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_conditions.xml b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_conditions.xml
index b4b9c63..229141c 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_conditions.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/2.2.0/upgrades/upgrade_test_conditions.xml
@@ -30,6 +30,15 @@
       </execute-stage>
     </group>
 
+    <group xsi:type="cluster" name="CLUSTER_SECURITY_CONDITION_TEST_WITH_KDC" title="Cluster Security Condition Test With KDC Type">
+      <condition xsi:type="security" type="kerberos" kdc-type="none"/>
+      <execute-stage title="Confirm 1">
+        <task xsi:type="manual">
+          <message>Foo</message>
+        </task>
+      </execute-stage>
+    </group>
+
     <group name="ZOOKEEPER_CONFIG_CONDITION_TEST" title="ZooKeeper Config Condition Test">
       <condition xsi:type="config" type="foo-site" property="foo-property" value="foo-value" comparison="equals"/>
       <skippable>true</skippable>