You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2016/04/11 15:46:40 UTC

[1/2] ambari git commit: AMBARI-13240. Kerberos: Allow multiple KDC hosts to be set while enabling Kerberos (rlevas)

Repository: ambari
Updated Branches:
  refs/heads/trunk 251c741bc -> c6fa8c26f


http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/app/mixins/common/configs/toggle_isrequired.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/toggle_isrequired.js b/ambari-web/app/mixins/common/configs/toggle_isrequired.js
index cc2cc35..c29fc54 100644
--- a/ambari-web/app/mixins/common/configs/toggle_isrequired.js
+++ b/ambari-web/app/mixins/common/configs/toggle_isrequired.js
@@ -27,11 +27,11 @@ App.ToggleIsRequiredMixin = Em.Mixin.create({
     var excludeProperties = [
       {
         name: 'KERBEROS',                                                                // affected service
-        exclude: ['kdc_host', 'admin_server_host', 'admin_principal', 'admin_password'] // affected properties
+        exclude: ['kdc_hosts', 'admin_server_host', 'admin_principal', 'admin_password'] // affected properties
       },
       {
         name: 'KERBEROS_GENERAL',                                                                // affected service
-        exclude: ['kdc_host', 'admin_server_host', 'admin_principal', 'admin_password'] // affected properties
+        exclude: ['kdc_hosts', 'admin_server_host', 'admin_principal', 'admin_password'] // affected properties
       }
     ];
     var serviceName = serviceConfigs.get('serviceName'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/app/models/configs/objects/service_config_property.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/configs/objects/service_config_property.js b/ambari-web/app/models/configs/objects/service_config_property.js
index e7eaebd..77eb332 100644
--- a/ambari-web/app/models/configs/objects/service_config_property.js
+++ b/ambari-web/app/models/configs/objects/service_config_property.js
@@ -429,7 +429,7 @@ App.ServiceConfigProperty = Em.Object.extend({
           break;
         case 'supportTextConnection':
         case 'host':
-          var connectionProperties = ['kdc_host'];
+          var connectionProperties = ['kdc_hosts'];
           if ((validator.isNotTrimmed(value) && connectionProperties.contains(this.get('name')) || validator.isNotTrimmed(value))) {
             this.set('errorMessage', Em.I18n.t('host.trimspacesValidation'));
             isError = true;

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/app/views/common/controls_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/controls_view.js b/ambari-web/app/views/common/controls_view.js
index 2514d9d..1fd8dd4 100644
--- a/ambari-web/app/views/common/controls_view.js
+++ b/ambari-web/app/views/common/controls_view.js
@@ -1014,7 +1014,7 @@ App.CheckDBConnectionView = Ember.View.extend({
     if (!/wizard/i.test(this.get('controller.name')) && this.get('parentView.service.serviceName') === 'HIVE') {
       return this.get('parentView.service.serviceName').toLowerCase() + '_hostname';
     } else if (this.get('parentView.service.serviceName') === 'KERBEROS') {
-      return 'kdc_host';
+      return 'kdc_hosts';
     } else if (this.get('parentView.service.serviceName') === 'RANGER') {
       return '{0}_{1}_host'.format(this.get('parentView.service.serviceName').toLowerCase(), this.get('databaseName').toLowerCase());
     }
@@ -1027,7 +1027,7 @@ App.CheckDBConnectionView = Ember.View.extend({
     var propertiesMap = {
       OOZIE: ['oozie.db.schema.name', 'oozie.service.JPAService.jdbc.username', 'oozie.service.JPAService.jdbc.password', 'oozie.service.JPAService.jdbc.driver', 'oozie.service.JPAService.jdbc.url'],
       HIVE: ['ambari.hive.db.schema.name', 'javax.jdo.option.ConnectionUserName', 'javax.jdo.option.ConnectionPassword', 'javax.jdo.option.ConnectionDriverName', 'javax.jdo.option.ConnectionURL'],
-      KERBEROS: ['kdc_host'],
+      KERBEROS: ['kdc_hosts'],
       RANGER: App.get('isHadoop23Stack') ? ['db_user', 'db_password', 'db_name', 'ranger.jpa.jdbc.url', 'ranger.jpa.jdbc.driver'] :
           ['db_user', 'db_password', 'db_name', 'ranger_jdbc_connection_url', 'ranger_jdbc_driver']
     };
@@ -1036,7 +1036,7 @@ App.CheckDBConnectionView = Ember.View.extend({
   /** @property {Object} propertiesPattern - check pattern according to type of connection properties **/
   propertiesPattern: function() {
     var patterns = {
-      db_connection_url: /jdbc\.url|connection_url|connectionurl|kdc_host/ig
+      db_connection_url: /jdbc\.url|connection_url|connectionurl|kdc_hosts/ig
     };
     if (this.get('parentView.service.serviceName') != "KERBEROS") {
       patterns.user_name = /(username|dblogin|db_user)$/ig;
@@ -1050,7 +1050,7 @@ App.CheckDBConnectionView = Ember.View.extend({
       'OOZIE': 'oozie_server_hosts',
       'HDFS': 'hadoop_host',
       'HIVE': 'hive_metastore_hosts',
-      'KERBEROS': 'kdc_host',
+      'KERBEROS': 'kdc_hosts',
       'RANGER': 'ranger_server_hosts'
     };
     return this.get('parentView.categoryConfigsAll').findProperty('name', serviceMasterMap[this.get('parentView.service.serviceName')]).get('value');

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
index beacc63..28264e4 100644
--- a/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
@@ -65,13 +65,13 @@ describe('App.KerberosWizardStep2Controller', function() {
         stepConfigs: [
           ['realm', ' SPACES ', 'host'],
           ['admin_server_host', ' space_left', 'host'],
-          ['kdc_host', ' space_left_and_right ', 'host'],
+          ['kdc_hosts', ' space_left_and_right ', 'host'],
           ['ldap_url', 'space_right ', 'host']
         ],
         e: {
           realm: 'SPACES',
           admin_server_host: 'space_left',
-          kdc_host: 'space_left_and_right',
+          kdc_hosts: 'space_left_and_right',
           ldap_url: 'space_right'
         }
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/test/mixins/common/configs/toggle_isrequired_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mixins/common/configs/toggle_isrequired_test.js b/ambari-web/test/mixins/common/configs/toggle_isrequired_test.js
index 4672ae6..acf2dae 100644
--- a/ambari-web/test/mixins/common/configs/toggle_isrequired_test.js
+++ b/ambari-web/test/mixins/common/configs/toggle_isrequired_test.js
@@ -29,7 +29,7 @@ describe('#_overrideConfigIsRequired', function () {
     instanceObject = mixinObject.create({});
 
     configs = Em.A([
-      App.ServiceConfigProperty.create({ name: 'kdc_host', value: '', category: 'KDC', serviceName: 'KERBEROS', isRequired: true}),
+      App.ServiceConfigProperty.create({ name: 'kdc_hosts', value: '', category: 'KDC', serviceName: 'KERBEROS', isRequired: true}),
       App.ServiceConfigProperty.create({ name: 'admin_server_host', value: '', category: 'KDC', serviceName: 'KERBEROS', isRequired: true}),
       App.ServiceConfigProperty.create({ name: 'admin_principal', value: '', category: 'KDC', serviceName: 'KERBEROS', isRequired: true}),
       App.ServiceConfigProperty.create({ name: 'admin_password', value: '', category: 'KDC', serviceName: 'KERBEROS', isRequired: true})

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/test/views/common/controls_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/common/controls_view_test.js b/ambari-web/test/views/common/controls_view_test.js
index dca7911..c5c5338 100644
--- a/ambari-web/test/views/common/controls_view_test.js
+++ b/ambari-web/test/views/common/controls_view_test.js
@@ -625,7 +625,7 @@ describe('App.CheckDBConnectionView', function () {
           value: 'h0'
         }),
         Em.Object.create({
-          name: 'kdc_host',
+          name: 'kdc_hosts',
           value: 'h1'
         }),
         Em.Object.create({


[2/2] ambari git commit: AMBARI-13240. Kerberos: Allow multiple KDC hosts to be set while enabling Kerberos (rlevas)

Posted by rl...@apache.org.
AMBARI-13240. Kerberos: Allow multiple KDC hosts to be set while enabling Kerberos (rlevas)


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

Branch: refs/heads/trunk
Commit: c6fa8c26f40b8a776574b322560c94b01089f980
Parents: 251c741
Author: Robert Levas <rl...@hortonworks.com>
Authored: Mon Apr 11 09:46:18 2016 -0400
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Mon Apr 11 09:46:18 2016 -0400

----------------------------------------------------------------------
 .../api/rest/KdcServerReachabilityCheck.java    |  37 ++-
 .../BlueprintConfigurationProcessor.java        |   2 +-
 .../kerberos/KerberosOperationHandler.java      |   4 +-
 .../server/upgrade/UpgradeCatalog240.java       |  49 ++++
 .../apache/ambari/server/utils/StageUtils.java  |   2 -
 .../1.10.3-10/configuration/kerberos-env.xml    |   8 +-
 .../1.10.3-10/configuration/krb5-conf.xml       |  21 +-
 .../1.10.3-10/package/scripts/params.py         |   4 +-
 .../1.10.3-10/package/templates/krb5_conf.j2    |  23 +-
 .../server/controller/KerberosHelperTest.java   |   2 +-
 .../BlueprintConfigurationProcessorTest.java    |   8 +-
 .../IPAKerberosOperationHandlerTest.java        |   2 +-
 .../MITKerberosOperationHandlerTest.java        |   2 +-
 .../server/upgrade/UpgradeCatalog240Test.java   | 285 +++++++++++++++++++
 .../stacks/2.2/KERBEROS/test_kerberos_server.py | 266 -----------------
 .../python/stacks/2.2/KERBEROS/use_cases.py     |  34 ++-
 .../journalnode-upgrade-hdfs-secure.json        |   4 +-
 .../stacks/2.2/configs/journalnode-upgrade.json |   4 +-
 .../2.2/configs/pig-service-check-secure.json   |   4 +-
 .../2.2/configs/ranger-admin-upgrade.json       |   4 +-
 .../2.2/configs/ranger-usersync-upgrade.json    |   4 +-
 .../python/stacks/2.3/configs/hbase_secure.json |   4 +-
 .../data/stacks/HDP-2.2/configurations.json     |   8 +-
 .../wizard/stack/hdp/version2.0.1/KERBEROS.json |   8 +-
 .../main/admin/kerberos/step2_controller.js     |   2 +-
 .../main/admin/kerberos/step5_controller.js     |   6 +-
 .../controllers/main/service/info/configs.js    |   2 +-
 ambari-web/app/data/HDP2/site_properties.js     |   2 +-
 ambari-web/app/messages.js                      |   2 +-
 .../mixins/common/configs/toggle_isrequired.js  |   4 +-
 .../configs/objects/service_config_property.js  |   2 +-
 ambari-web/app/views/common/controls_view.js    |   8 +-
 .../admin/kerberos/step2_controller_test.js     |   4 +-
 .../common/configs/toggle_isrequired_test.js    |   2 +-
 .../test/views/common/controls_view_test.js     |   2 +-
 35 files changed, 464 insertions(+), 361 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/main/java/org/apache/ambari/server/api/rest/KdcServerReachabilityCheck.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/rest/KdcServerReachabilityCheck.java b/ambari-server/src/main/java/org/apache/ambari/server/api/rest/KdcServerReachabilityCheck.java
index 827b187..898e7e6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/rest/KdcServerReachabilityCheck.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/rest/KdcServerReachabilityCheck.java
@@ -45,26 +45,39 @@ public class KdcServerReachabilityCheck {
   private static KdcServerConnectionVerification kdcConnectionChecker;
 
 
-
   /**
-   * Handles: GET /kdc_check/{hostname}
-   * Checks the reachability of given KDC server
-   *
-   * @param headers             http headers
-   * @param ui                  uri info
-   * @param kdcServerHostName   HostName of KDC server. May contain port separate by a colon (:)
+   * Handles: GET /kdc_check/{hosts}
+   * Checks the reachability of the given KDC server(s). If a list of hosts is sent, checks will be
+   * performs until the first one succeeds, else a failure will be returned.
    *
+   * @param headers      http headers
+   * @param ui           uri info
+   * @param hosts A comma-delimited list of host names to check for a KDC server.
+   *                     Each entry may contain port separate by a colon (:)
    * @return status whether KDC server is reachable or not
    */
   @GET
-  @Path("{hostname}")
+  @Path("{hosts}")
   @Produces(MediaType.TEXT_PLAIN)
   public String plainTextCheck(@Context HttpHeaders headers, @Context UriInfo ui,
-      @PathParam("hostname") String kdcServerHostName) {
+                               @PathParam("hosts") String hosts) {
     String status = UNREACHABLE;
-    if (kdcConnectionChecker.isKdcReachable(kdcServerHostName)) {
-      status = REACHABLE;
-    }   	
+    if(hosts != null) {
+      String[] kdcHosts = hosts.split(",");
+      for(String kdcHost : kdcHosts) {
+        kdcHost = kdcHost.trim();
+
+        if (!kdcHost.isEmpty()) {
+          if (kdcConnectionChecker.isKdcReachable(kdcHost)) {
+            status = REACHABLE;
+
+            // We found a success, so break since we only care about at least one successful connection
+            break;
+          }
+        }
+      }
+    }
+
     return status;
   }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
index 1ba138b..1433a1b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
@@ -158,7 +158,7 @@ public class BlueprintConfigurationProcessor {
     { new PasswordPropertyFilter(),
       new SimplePropertyNameExportFilter("tez.tez-ui.history-url.base", "tez-site"),
       new SimplePropertyNameExportFilter("admin_server_host", "kerberos-env"),
-      new SimplePropertyNameExportFilter("kdc_host", "kerberos-env"),
+      new SimplePropertyNameExportFilter("kdc_hosts", "kerberos-env"),
       new SimplePropertyNameExportFilter("realm", "kerberos-env"),
       new SimplePropertyNameExportFilter("kdc_type", "kerberos-env"),
       new SimplePropertyNameExportFilter("ldap-url", "kerberos-env"),

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
index 139fd7a..f800072 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
@@ -101,9 +101,9 @@ public abstract class KerberosOperationHandler {
   public final static String KERBEROS_ENV_ENCRYPTION_TYPES = "encryption_types";
 
   /**
-   * Kerberos-env configuration property name: kdc_host
+   * Kerberos-env configuration property name: kdc_hosts
    */
-  public final static String KERBEROS_ENV_KDC_HOST = "kdc_host";
+  public final static String KERBEROS_ENV_KDC_HOSTS = "kdc_hosts";
 
   /**
    * Kerberos-env configuration property name: admin_server_host

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
index 39ccbe0..31af5e3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java
@@ -185,6 +185,7 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
     updateAMSConfigs();
     updateClusterEnv();
     updateHostRoleCommandTableDML();
+    updateKerberosConfigs();
   }
 
   private void createSettingTable() throws SQLException {
@@ -1143,4 +1144,52 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog {
           true);
     }
   }
+
+  /**
+   * Updates the Kerberos-related configurations for the clusters managed by this Ambari
+   * <p/>
+   * Performs the following updates:
+   * <ul>
+   * <li>Rename <code>kerberos-env/kdc_host</code> to
+   * <code>kerberos-env/kdc_hosts</li>
+   * <li>If krb5-conf/content was not changed from the original stack default, update it to the new
+   * stack default</li>
+   * </ul>
+   *
+   * @throws AmbariException if an error occurs while updating the configurations
+   */
+  protected void updateKerberosConfigs() throws AmbariException {
+    AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class);
+    Clusters clusters = ambariManagementController.getClusters();
+    Map<String, Cluster> clusterMap = getCheckedClusterMap(clusters);
+
+    for (final Cluster cluster : clusterMap.values()) {
+      Config config;
+
+      config = cluster.getDesiredConfigByType("kerberos-env");
+      if (config != null) {
+        // Rename kdc_host to kdc_hosts
+        String value = config.getProperties().get("kdc_host");
+        Map<String, String> updates = Collections.singletonMap("kdc_hosts", value);
+        Set<String> removes = Collections.singleton("kdc_host");
+
+        updateConfigurationPropertiesForCluster(cluster, "kerberos-env", updates, removes, true, false);
+      }
+
+      config = cluster.getDesiredConfigByType("krb5-conf");
+      if (config != null) {
+        String value = config.getProperties().get("content");
+        String oldDefault = "\n[libdefaults]\n  renew_lifetime \u003d 7d\n  forwardable \u003d true\n  default_realm \u003d {{realm}}\n  ticket_lifetime \u003d 24h\n  dns_lookup_realm \u003d false\n  dns_lookup_kdc \u003d false\n  #default_tgs_enctypes \u003d {{encryption_types}}\n  #default_tkt_enctypes \u003d {{encryption_types}}\n\n{% if domains %}\n[domain_realm]\n{% for domain in domains.split(\u0027,\u0027) %}\n  {{domain|trim}} \u003d {{realm}}\n{% endfor %}\n{% endif %}\n\n[logging]\n  default \u003d FILE:/var/log/krb5kdc.log\n  admin_server \u003d FILE:/var/log/kadmind.log\n  kdc \u003d FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} \u003d {\n    admin_server \u003d {{admin_server_host|default(kdc_host, True)}}\n    kdc \u003d {{kdc_host}}\n  }\n\n{# Append additional realm declarations below #}";
+
+        // if the content is the same as the old stack default, update to the new stack default;
+        // else leave it alone since the user may have changed it for a reason.
+        if(oldDefault.equalsIgnoreCase(value)) {
+          String newDefault ="[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n  {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',')  -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{% for kdc_host in kdc_host_list %}\n    kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n  }\n\n{# Append additional realm declarations
  below #}";
+          Map<String, String> updates = Collections.singletonMap("content", newDefault);
+          updateConfigurationPropertiesForCluster(cluster, "krb5-conf", updates, null, true, false);
+        }
+      }
+    }
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
index 69b9a43..218a42f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
@@ -152,8 +152,6 @@ public class StageUtils {
     componentToClusterInfoKeyMap.put("DATANODE", "slave_hosts");
     componentToClusterInfoKeyMap.put("TASKTRACKER", "mapred_tt_hosts");
     componentToClusterInfoKeyMap.put("HBASE_REGIONSERVER", "hbase_rs_hosts");
-    componentToClusterInfoKeyMap.put("KERBEROS_SERVER", "kdc_host");
-    componentToClusterInfoKeyMap.put("KERBEROS_ADMIN_CLIENT", "kerberos_adminclient_host");
     componentToClusterInfoKeyMap.put("ACCUMULO_MASTER", "accumulo_master_hosts");
     componentToClusterInfoKeyMap.put("ACCUMULO_MONITOR", "accumulo_monitor_hosts");
     componentToClusterInfoKeyMap.put("ACCUMULO_GC", "accumulo_gc_hosts");

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/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 bb880e2..3e9f5cc 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
@@ -133,11 +133,13 @@
   </property>
 
   <property require-input="true">
-    <name>kdc_host</name>
+    <name>kdc_hosts</name>
     <description>
-      The IP address or FQDN for the KDC host. Optionally a port number may be included.
+      A comma-delimited list of IP addresses or FQDNs declaring the KDC hosts.
+      Optionally a port number may be included in each entry by separating each host and port by a
+      colon (:). Example:  kdc1.example.com:88, kdc2.example.com:88
     </description>
-    <display-name>KDC host</display-name>
+    <display-name>KDC hosts</display-name>
     <value/>
     <value-attributes>
       <overridable>false</overridable>

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/krb5-conf.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/krb5-conf.xml b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/krb5-conf.xml
index 6780d2e..55f977d 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/krb5-conf.xml
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/krb5-conf.xml
@@ -71,14 +71,12 @@
   dns_lookup_kdc = false
   #default_tgs_enctypes = {{encryption_types}}
   #default_tkt_enctypes = {{encryption_types}}
-
 {% if domains %}
 [domain_realm]
-{% for domain in domains.split(',') %}
-  {{domain}} = {{realm}}
-{% endfor %}
+{%- for domain in domains.split(',') %}
+  {{domain|trim()}} = {{realm}}
+{%- endfor %}
 {% endif %}
-
 [logging]
   default = FILE:/var/log/krb5kdc.log
   admin_server = FILE:/var/log/kadmind.log
@@ -86,8 +84,17 @@
 
 [realms]
   {{realm}} = {
-    admin_server = {{admin_server_host|default(kdc_host, True)}}
-    kdc = {{kdc_host}}
+{%- if kdc_hosts > 0 -%}
+{%- set kdc_host_list = kdc_hosts.split(',')  -%}
+{%- if kdc_host_list and kdc_host_list|length > 0 %}
+    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}
+{%- if kdc_host_list -%}
+{% for kdc_host in kdc_host_list %}
+    kdc = {{kdc_host|trim()}}
+{%- endfor -%}
+{% endif %}
+{%- endif %}
+{%- endif %}
   }
 
 {# Append additional realm declarations below #}

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/params.py b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/params.py
index 200a212..d57b2a1 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/params.py
@@ -101,7 +101,7 @@ if config is not None:
     # ##############################################################################################
     realm = 'EXAMPLE.COM'
     domains = ''
-    kdc_host = 'localhost'
+    kdc_hosts = 'localhost'
     admin_server_host = None
     admin_principal = None
     admin_password = None
@@ -122,7 +122,7 @@ if config is not None:
       manage_identities = get_property_value(kerberos_env, "manage_identities", "true", True, "true")
       encryption_types = get_property_value(kerberos_env, "encryption_types", None, True, None)
       realm = get_property_value(kerberos_env, "realm", None, True, None)
-      kdc_host = get_property_value(kerberos_env, 'kdc_host', kdc_host)
+      kdc_hosts = get_property_value(kerberos_env, 'kdc_hosts', kdc_hosts)
       admin_server_host = get_property_value(kerberos_env, 'admin_server_host', admin_server_host)
 
     if krb5_conf_data is not None:

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/templates/krb5_conf.j2
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/templates/krb5_conf.j2 b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/templates/krb5_conf.j2
index cc6f63a..d473ede 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/templates/krb5_conf.j2
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/templates/krb5_conf.j2
@@ -18,20 +18,18 @@
 [libdefaults]
   renew_lifetime = 7d
   forwardable = true
-  default_realm = {{realm|upper()}}
+  default_realm = {{realm}}
   ticket_lifetime = 24h
   dns_lookup_realm = false
   dns_lookup_kdc = false
   #default_tgs_enctypes = {{encryption_types}}
   #default_tkt_enctypes = {{encryption_types}}
-
 {% if domains %}
 [domain_realm]
-{% for domain in domains.split(',') %}
-  {{domain}} = {{realm|upper()}}
-{% endfor %}
+{%- for domain in domains.split(',') %}
+  {{domain|trim()}} = {{realm}}
+{%- endfor %}
 {% endif %}
-
 [logging]
   default = FILE:/var/log/krb5kdc.log
   admin_server = FILE:/var/log/kadmind.log
@@ -39,8 +37,17 @@
 
 [realms]
   {{realm}} = {
-    admin_server = {{admin_server_host|default(kdc_host, True)}}
-    kdc = {{kdc_host}}
+{%- if kdc_hosts > 0 -%}
+{%- set kdc_host_list = kdc_hosts.split(',')  -%}
+{%- if kdc_host_list and kdc_host_list|length > 0 %}
+    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}
+{%- if kdc_host_list -%}
+{% for kdc_host in kdc_host_list %}
+    kdc = {{kdc_host|trim()}}
+{%- endfor -%}
+{% endif %}
+{%- endif %}
+{%- endif %}
   }
 
 {# Append additional realm declarations below #}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
index e8a2e35..7c70e5e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
@@ -277,7 +277,7 @@ public class KerberosHelperTest extends EasyMockSupport {
 
     final Map<String, String> kerberosEnvProperties = createMock(Map.class);
     expect(kerberosEnvProperties.get("realm")).andReturn("EXAMPLE.COM").once();
-    expect(kerberosEnvProperties.get("kdc_host")).andReturn("10.0.100.1").once();
+    expect(kerberosEnvProperties.get("kdc_hosts")).andReturn("10.0.100.1").once();
 
     final Map<String, String> krb5ConfProperties = createMock(Map.class);
     expect(krb5ConfProperties.get("kadmin_host")).andReturn("10.0.100.1").once();

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
index 411f966..834953b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
@@ -222,7 +222,7 @@ public class BlueprintConfigurationProcessorTest {
 
     Map<String, String> kerberosEnvProps = new HashMap<String, String>();
     kerberosEnvProps.put("admin_server_host", "test");
-    kerberosEnvProps.put("kdc_host", "test");
+    kerberosEnvProps.put("kdc_hosts", "test");
     kerberosEnvProps.put("realm", "test");
     kerberosEnvProps.put("kdc_type", "test");
     kerberosEnvProps.put("ldap-url", "test");
@@ -877,7 +877,7 @@ public class BlueprintConfigurationProcessorTest {
     // simulate the case of a Kerberized cluster, including config
     // added by the Kerberos service
     kerberosEnvProperties.put("admin_server_host", expectedHostName);
-    kerberosEnvProperties.put("kdc_host", expectedHostName);
+    kerberosEnvProperties.put("kdc_hosts", expectedHostName);
     coreSiteProperties.put("hadoop.proxyuser.yarn.hosts", expectedHostName);
 
     Configuration clusterConfig = new Configuration(configProperties,
@@ -904,8 +904,8 @@ public class BlueprintConfigurationProcessorTest {
     // verify that these properties are filtered out of the exported configuration
     assertFalse("admin_server_host should not be present in exported blueprint in kerberos-env",
       kerberosEnvProperties.containsKey("admin_server_host"));
-    assertFalse("kdc_host should not be present in exported blueprint in kerberos-env",
-      kerberosEnvProperties.containsKey("kdc_host"));
+    assertFalse("kdc_hosts should not be present in exported blueprint in kerberos-env",
+      kerberosEnvProperties.containsKey("kdc_hosts"));
     assertEquals("hadoop.proxyuser.yarn.hosts was not exported correctly",
       createExportedHostName("host_group_1"), coreSiteProperties.get("hadoop.proxyuser.yarn.hosts"));
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
index f877e85..cb420c7 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
@@ -50,7 +50,7 @@ public class IPAKerberosOperationHandlerTest extends KerberosOperationHandlerTes
   private static final Map<String, String> KERBEROS_ENV_MAP = new HashMap<String, String>() {
     {
       put(IPAKerberosOperationHandler.KERBEROS_ENV_ENCRYPTION_TYPES, null);
-      put(IPAKerberosOperationHandler.KERBEROS_ENV_KDC_HOST, "localhost");
+      put(IPAKerberosOperationHandler.KERBEROS_ENV_KDC_HOSTS, "localhost");
       put(IPAKerberosOperationHandler.KERBEROS_ENV_ADMIN_SERVER_HOST, "localhost");
       put(IPAKerberosOperationHandler.KERBEROS_ENV_USER_PRINCIPAL_GROUP, "");
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
index 5c882ba..d15db17 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandlerTest.java
@@ -58,7 +58,7 @@ public class MITKerberosOperationHandlerTest extends KerberosOperationHandlerTes
   private static final Map<String, String> KERBEROS_ENV_MAP = new HashMap<String, String>() {
     {
       put(MITKerberosOperationHandler.KERBEROS_ENV_ENCRYPTION_TYPES, null);
-      put(MITKerberosOperationHandler.KERBEROS_ENV_KDC_HOST, "localhost");
+      put(MITKerberosOperationHandler.KERBEROS_ENV_KDC_HOSTS, "localhost");
       put(MITKerberosOperationHandler.KERBEROS_ENV_ADMIN_SERVER_HOST, "localhost");
       put(MITKerberosOperationHandler.KERBEROS_ENV_AD_CREATE_ATTRIBUTES_TEMPLATE, "AD Create Template");
       put(MITKerberosOperationHandler.KERBEROS_ENV_KDC_CREATE_ATTRIBUTES, "-attr1 -attr2 foo=345");

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java
index e03f353..59f9f91 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java
@@ -42,6 +42,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -50,6 +51,7 @@ import javax.persistence.EntityManager;
 
 import com.google.common.collect.Maps;
 import com.google.gson.Gson;
+import com.google.inject.AbstractModule;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.ActionManager;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -357,6 +359,7 @@ public class UpgradeCatalog240Test {
     Method updateAmsConfigs = UpgradeCatalog240.class.getDeclaredMethod("updateAMSConfigs");
     Method updateClusterEnv = UpgradeCatalog240.class.getDeclaredMethod("updateClusterEnv");
     Method updateHostRoleCommandTableDML = UpgradeCatalog240.class.getDeclaredMethod("updateHostRoleCommandTableDML");
+    Method updateKerberosEnv = UpgradeCatalog240.class.getDeclaredMethod("updateKerberosConfigs");
 
     Capture<String> capturedStatements = newCapture(CaptureType.ALL);
 
@@ -372,6 +375,7 @@ public class UpgradeCatalog240Test {
             .addMockedMethod(updateAmsConfigs)
             .addMockedMethod(updateClusterEnv)
             .addMockedMethod(updateHostRoleCommandTableDML)
+            .addMockedMethod(updateKerberosEnv)
             .createMock();
 
     Field field = AbstractUpgradeCatalog.class.getDeclaredField("dbAccessor");
@@ -385,6 +389,7 @@ public class UpgradeCatalog240Test {
     upgradeCatalog240.updateAMSConfigs();
     upgradeCatalog240.updateClusterEnv();
     upgradeCatalog240.updateHostRoleCommandTableDML();
+    upgradeCatalog240.updateKerberosConfigs();
 
     replay(upgradeCatalog240, dbAccessor);
 
@@ -483,4 +488,284 @@ public class UpgradeCatalog240Test {
     Map<String, String> updatedProperties = propertiesCapture.getValue();
     assertTrue(Maps.difference(newPropertiesAmsHbaseEnv, updatedProperties).areEqual());
   }
+
+  @Test
+  public void testUpdateKerberosConfiguration() throws Exception {
+    final AmbariManagementController controller = createNiceMock(AmbariManagementController.class);
+    final DBAccessor dbAccessor = createNiceMock(DBAccessor.class);
+    final OsFamily osFamily = createNiceMock(OsFamily.class);
+
+    final Map<String, String> propertiesKerberosEnv = new HashMap<String, String>() {
+      {
+        put("realm", "EXAMPLE.COM");
+        put("encryption_types", "aes des3-cbc-sha1 rc4 des-cbc-md5");
+        put("kdc_host", "c6407.ambari.apache.org");
+        put("admin_server_host", "c6407.ambari.apache.org");
+        put("kdc_type", "mit-kdc");
+      }
+    };
+
+    final Map<String, String> propertiesKrb5Conf = new HashMap<String, String>() {
+      {
+        put("content", "\n" +
+            "[libdefaults]\n" +
+            "  renew_lifetime = 7d\n" +
+            "  forwardable = true\n" +
+            "  default_realm = {{realm}}\n" +
+            "  ticket_lifetime = 24h\n" +
+            "  dns_lookup_realm = false\n" +
+            "  dns_lookup_kdc = false\n" +
+            "  #default_tgs_enctypes = {{encryption_types}}\n" +
+            "  #default_tkt_enctypes = {{encryption_types}}\n" +
+            "\n" +
+            "{% if domains %}\n" +
+            "[domain_realm]\n" +
+            "{% for domain in domains.split(',') %}\n" +
+            "  {{domain|trim}} = {{realm}}\n" +
+            "{% endfor %}\n" +
+            "{% endif %}\n" +
+            "\n" +
+            "[logging]\n" +
+            "  default = FILE:/var/log/krb5kdc.log\n" +
+            "  admin_server = FILE:/var/log/kadmind.log\n" +
+            "  kdc = FILE:/var/log/krb5kdc.log\n" +
+            "\n" +
+            "[realms]\n" +
+            "  {{realm}} = {\n" +
+            "    admin_server = {{admin_server_host|default(kdc_host, True)}}\n" +
+            "    kdc = {{kdc_host}}\n" +
+            "  }\n" +
+            "\n" +
+            "{# Append additional realm declarations below #}");
+      }
+    };
+
+    final Config configKerberosEnv = createNiceMock(Config.class);
+    expect(configKerberosEnv.getProperties()).andReturn(propertiesKerberosEnv).anyTimes();
+    expect(configKerberosEnv.getTag()).andReturn("tag1").anyTimes();
+
+    final Config configKrb5Conf = createNiceMock(Config.class);
+    expect(configKrb5Conf.getProperties()).andReturn(propertiesKrb5Conf).anyTimes();
+    expect(configKrb5Conf.getTag()).andReturn("tag1").anyTimes();
+
+    final Cluster cluster = createNiceMock(Cluster.class);
+    expect(cluster.getDesiredConfigByType("kerberos-env")).andReturn(configKerberosEnv).once();
+    expect(cluster.getDesiredConfigByType("krb5-conf")).andReturn(configKrb5Conf).once();
+
+    final Clusters clusters = createNiceMock(Clusters.class);
+    expect(clusters.getClusters()).andReturn(Collections.singletonMap("c1", cluster));
+
+    expect(controller.getClusters()).andReturn(clusters).once();
+
+    expect(cluster.getConfigsByType("kerberos-env"))
+        .andReturn(Collections.singletonMap("tag1", configKerberosEnv))
+        .once();
+    expect(cluster.getConfigsByType("krb5-conf"))
+        .andReturn(Collections.singletonMap("tag1", configKerberosEnv))
+        .once();
+
+    expect(cluster.getDesiredConfigByType("kerberos-env"))
+        .andReturn(configKerberosEnv)
+        .once();
+    expect(cluster.getDesiredConfigByType("krb5-conf"))
+        .andReturn(configKerberosEnv)
+        .once();
+
+    Capture<Cluster> clusterCapture = newCapture(CaptureType.ALL);
+    Capture<String> typeCapture = newCapture(CaptureType.ALL);
+    Capture<Map> propertiesCapture = newCapture(CaptureType.ALL);
+    Capture<String> tagCapture = newCapture(CaptureType.ALL);
+    Capture<Map> attributesCapture = newCapture(CaptureType.ALL);
+
+
+    expect(controller.createConfig(capture(clusterCapture), capture(typeCapture),
+        capture(propertiesCapture), capture(tagCapture), capture(attributesCapture) ))
+        .andReturn(createNiceMock(Config.class))
+        .anyTimes();
+
+    replay(controller, dbAccessor, osFamily, cluster, configKerberosEnv, configKrb5Conf, clusters);
+
+    final Injector injector = Guice.createInjector(new AbstractModule() {
+      @Override
+      protected void configure() {
+        bind(AmbariManagementController.class).toInstance(controller);
+        bind(DBAccessor.class).toInstance(dbAccessor);
+        bind(OsFamily.class).toInstance(osFamily);
+        bind(EntityManager.class).toInstance(entityManager);
+      }
+    });
+
+    injector.getInstance(UpgradeCatalog240.class).updateKerberosConfigs();
+
+    verify(controller, dbAccessor, osFamily, cluster, configKerberosEnv, configKrb5Conf, clusters);
+
+    List<String> typeCaptureValues = typeCapture.getValues();
+    Assert.assertEquals(2, typeCaptureValues.size());
+    Assert.assertEquals("kerberos-env", typeCaptureValues.get(0));
+    Assert.assertEquals("krb5-conf", typeCaptureValues.get(1));
+
+    List<Map> propertiesCaptureValues = propertiesCapture.getValues();
+    Assert.assertEquals(2, propertiesCaptureValues.size());
+
+    Map<String, String> capturedCRProperties;
+
+    capturedCRProperties = propertiesCaptureValues.get(0);
+    Assert.assertNotNull(capturedCRProperties);
+    Assert.assertFalse(capturedCRProperties.containsKey("kdc_host"));
+    Assert.assertTrue(capturedCRProperties.containsKey("kdc_hosts"));
+
+    for (String property : propertiesKerberosEnv.keySet()) {
+      if ("kdc_host".equals(property)) {
+        Assert.assertEquals(property, propertiesKerberosEnv.get(property), capturedCRProperties.get("kdc_hosts"));
+      } else {
+        Assert.assertEquals(property, propertiesKerberosEnv.get(property), capturedCRProperties.get(property));
+      }
+    }
+
+    capturedCRProperties = propertiesCaptureValues.get(1);
+    Assert.assertNotNull(capturedCRProperties);
+    Assert.assertTrue(capturedCRProperties.containsKey("content"));
+
+    for (String property : propertiesKerberosEnv.keySet()) {
+      if ("content".equals(property)) {
+        Assert.assertEquals(property, "[libdefaults]\n" +
+            "  renew_lifetime = 7d\n" +
+            "  forwardable = true\n" +
+            "  default_realm = {{realm}}\n" +
+            "  ticket_lifetime = 24h\n" +
+            "  dns_lookup_realm = false\n" +
+            "  dns_lookup_kdc = false\n" +
+            "  #default_tgs_enctypes = {{encryption_types}}\n" +
+            "  #default_tkt_enctypes = {{encryption_types}}\n" +
+            "{% if domains %}\n" +
+            "[domain_realm]\n" +
+            "{%- for domain in domains.split(',') %}\n" +
+            "  {{domain|trim()}} = {{realm}}\n" +
+            "{%- endfor %}\n" +
+            "{% endif %}\n" +
+            "[logging]\n" +
+            "  default = FILE:/var/log/krb5kdc.log\n" +
+            "  admin_server = FILE:/var/log/kadmind.log\n" +
+            "  kdc = FILE:/var/log/krb5kdc.log\n" +
+            "\n" +
+            "[realms]\n" +
+            "  {{realm}} = {\n" +
+            "{%- if kdc_hosts > 0 -%}\n" +
+            "{%- set kdc_host_list = kdc_hosts.split(',')  -%}\n" +
+            "{%- if kdc_host_list and kdc_host_list|length > 0 %}\n" +
+            "    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n" +
+            "{%- if kdc_host_list -%}\n" +
+            "{% for kdc_host in kdc_host_list %}\n" +
+            "    kdc = {{kdc_host|trim()}}\n" +
+            "{%- endfor -%}\n" +
+            "{% endif %}\n" +
+            "{%- endif %}\n" +
+            "{%- endif %}\n" +
+            "  }\n" +
+            "\n" +
+            "{# Append additional realm declarations below #}", capturedCRProperties.get("content"));
+      } else {
+        Assert.assertEquals(property, propertiesKerberosEnv.get(property), capturedCRProperties.get(property));
+      }
+    }
+  }
+
+  @Test
+  public void testUpdateKerberosConfigurationWithChangedKrb5ConfContent() throws Exception {
+    final AmbariManagementController controller = createNiceMock(AmbariManagementController.class);
+    final DBAccessor dbAccessor = createNiceMock(DBAccessor.class);
+    final OsFamily osFamily = createNiceMock(OsFamily.class);
+
+    final Map<String, String> propertiesKerberosEnv = new HashMap<String, String>() {
+      {
+        put("realm", "EXAMPLE.COM");
+        put("encryption_types", "aes des3-cbc-sha1 rc4 des-cbc-md5");
+        put("kdc_host", "c6407.ambari.apache.org");
+        put("admin_server_host", "c6407.ambari.apache.org");
+        put("kdc_type", "mit-kdc");
+      }
+    };
+
+    final Map<String, String> propertiesKrb5Conf = new HashMap<String, String>() {
+      {
+        put("content", "CHANGED CONTENT");
+      }
+    };
+
+    final Config configKerberosEnv = createNiceMock(Config.class);
+    expect(configKerberosEnv.getProperties()).andReturn(propertiesKerberosEnv).anyTimes();
+    expect(configKerberosEnv.getTag()).andReturn("tag1").anyTimes();
+
+    final Config configKrb5Conf = createNiceMock(Config.class);
+    expect(configKrb5Conf.getProperties()).andReturn(propertiesKrb5Conf).anyTimes();
+    expect(configKrb5Conf.getTag()).andReturn("tag1").anyTimes();
+
+    final Cluster cluster = createNiceMock(Cluster.class);
+    expect(cluster.getDesiredConfigByType("kerberos-env")).andReturn(configKerberosEnv).once();
+    expect(cluster.getDesiredConfigByType("krb5-conf")).andReturn(configKrb5Conf).once();
+
+    final Clusters clusters = createNiceMock(Clusters.class);
+    expect(clusters.getClusters()).andReturn(Collections.singletonMap("c1", cluster));
+
+    expect(controller.getClusters()).andReturn(clusters).once();
+
+    expect(cluster.getConfigsByType("kerberos-env"))
+        .andReturn(Collections.singletonMap("tag1", configKerberosEnv))
+        .once();
+
+    expect(cluster.getDesiredConfigByType("kerberos-env"))
+        .andReturn(configKerberosEnv)
+        .once();
+
+    Capture<Cluster> clusterCapture = newCapture(CaptureType.ALL);
+    Capture<String> typeCapture = newCapture(CaptureType.ALL);
+    Capture<Map> propertiesCapture = newCapture(CaptureType.ALL);
+    Capture<String> tagCapture = newCapture(CaptureType.ALL);
+    Capture<Map> attributesCapture = newCapture(CaptureType.ALL);
+
+
+    expect(controller.createConfig(capture(clusterCapture), capture(typeCapture),
+        capture(propertiesCapture), capture(tagCapture), capture(attributesCapture)))
+        .andReturn(createNiceMock(Config.class))
+        .anyTimes();
+
+    replay(controller, dbAccessor, osFamily, cluster, configKerberosEnv, configKrb5Conf, clusters);
+
+    final Injector injector = Guice.createInjector(new AbstractModule() {
+      @Override
+      protected void configure() {
+        bind(AmbariManagementController.class).toInstance(controller);
+        bind(DBAccessor.class).toInstance(dbAccessor);
+        bind(OsFamily.class).toInstance(osFamily);
+        bind(EntityManager.class).toInstance(entityManager);
+      }
+    });
+
+    injector.getInstance(UpgradeCatalog240.class).updateKerberosConfigs();
+
+    verify(controller, dbAccessor, osFamily, cluster, configKerberosEnv, configKrb5Conf, clusters);
+
+    List<String> typeCaptureValues = typeCapture.getValues();
+    Assert.assertEquals(1, typeCaptureValues.size());
+    Assert.assertEquals("kerberos-env", typeCaptureValues.get(0));
+
+    List<Map> propertiesCaptureValues = propertiesCapture.getValues();
+    Assert.assertEquals(1, propertiesCaptureValues.size());
+
+    Map<String, String> capturedCRProperties;
+
+    capturedCRProperties = propertiesCaptureValues.get(0);
+    Assert.assertNotNull(capturedCRProperties);
+    Assert.assertFalse(capturedCRProperties.containsKey("kdc_host"));
+    Assert.assertTrue(capturedCRProperties.containsKey("kdc_hosts"));
+
+    for (String property : propertiesKerberosEnv.keySet()) {
+      if ("kdc_host".equals(property)) {
+        Assert.assertEquals(property, propertiesKerberosEnv.get(property), capturedCRProperties.get("kdc_hosts"));
+      } else {
+        Assert.assertEquals(property, propertiesKerberosEnv.get(property), capturedCRProperties.get(property));
+      }
+    }
+  }
 }
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/python/stacks/2.2/KERBEROS/test_kerberos_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/KERBEROS/test_kerberos_server.py b/ambari-server/src/test/python/stacks/2.2/KERBEROS/test_kerberos_server.py
deleted file mode 100644
index a11d596..0000000
--- a/ambari-server/src/test/python/stacks/2.2/KERBEROS/test_kerberos_server.py
+++ /dev/null
@@ -1,266 +0,0 @@
-"""
-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.
-
-"""
-
-import os
-import use_cases
-
-from stacks.utils.RMFTestCase import *
-
-from only_for_platform import not_for_platform, PLATFORM_WINDOWS
-
-@not_for_platform(PLATFORM_WINDOWS)
-class TestKerberosServer(RMFTestCase):
-  COMMON_SERVICES_PACKAGE_DIR = "KERBEROS/1.10.3-10/package"
-  STACK_VERSION = "2.2"
-
-  def test_configure_managed_kdc(self):
-    json_data = use_cases.get_manged_kdc_use_case()
-
-    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/kerberos_server.py",
-                       classname="KerberosServer",
-                       command="configure",
-                       config_dict=json_data,
-                       stack_version = self.STACK_VERSION,
-                       target = RMFTestCase.TARGET_COMMON_SERVICES
-    )
-
-    # Validate krb5.conf file
-    self.assertResourceCalled('Directory', use_cases.get_krb5_conf_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0755,
-                              create_parents = True)
-
-    file_path = (use_cases.get_krb5_conf_dir(json_data) +
-                 "/" +
-                 use_cases.get_krb5_conf_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=Template('krb5_conf.j2'),
-                              owner='root',
-                              group='root',
-                              mode=0644)
-
-    # Validate kdc.conf file
-    self.assertResourceCalled('Directory', use_cases.get_kdc_conf_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0700,
-                              create_parents = True)
-
-    file_path = (use_cases.get_kdc_conf_dir(json_data) +
-                 "/" +
-                 use_cases.get_kdc_conf_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=Template('kdc_conf.j2'),
-                              owner='root',
-                              group='root',
-                              mode=0600)
-
-    # Validate kadm5.acl file
-    self.assertResourceCalled('Directory', use_cases.get_kadm5_acl_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0700,
-                              create_parents = True)
-
-    file_path = (use_cases.get_kadm5_acl_dir(json_data) +
-                 "/" +
-                 use_cases.get_kadm5_acl_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=Template('kadm5_acl.j2'),
-                              owner='root',
-                              group='root',
-                              mode=0600)
-
-  def test_configure_unmanaged_kdc(self):
-    json_data = use_cases.get_unmanged_kdc_use_case()
-
-    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/kerberos_server.py",
-                       classname="KerberosServer",
-                       command="configure",
-                       config_dict=json_data,
-                       stack_version = self.STACK_VERSION,
-                       target = RMFTestCase.TARGET_COMMON_SERVICES
-    )
-
-    # Validate krb5.conf file
-    self.assertResourceCalled('Directory', use_cases.get_krb5_conf_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0755,
-                              create_parents = True)
-
-    file_path = (use_cases.get_krb5_conf_dir(json_data) +
-                 "/" +
-                 use_cases.get_krb5_conf_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=InlineTemplate(use_cases.get_krb5_conf_template(json_data)),
-                              owner='root',
-                              group='root',
-                              mode=0644)
-
-    # Validate kdc.conf file
-    self.assertResourceCalled('Directory', use_cases.get_kdc_conf_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0700,
-                              create_parents = True)
-
-    file_path = (use_cases.get_kdc_conf_dir(json_data) +
-                 "/" +
-                 use_cases.get_kdc_conf_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=InlineTemplate(use_cases.get_kdc_conf_template(json_data)),
-                              owner='root',
-                              group='root',
-                              mode=0600)
-
-    # Validate kadm5.acl file
-    self.assertResourceCalled('Directory', use_cases.get_kadm5_acl_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0700,
-                              create_parents = True)
-
-    file_path = (use_cases.get_kadm5_acl_dir(json_data) +
-                 "/" +
-                 use_cases.get_kadm5_acl_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=InlineTemplate(use_cases.get_kadm5_acl_template(json_data)),
-                              owner='root',
-                              group='root',
-                              mode=0600)
-
-  def test_configure_unmanaged_ad(self):
-    json_data = use_cases.get_unmanged_ad_use_case()
-
-    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/kerberos_server.py",
-                       classname="KerberosServer",
-                       command="configure",
-                       config_dict=json_data,
-                       stack_version = self.STACK_VERSION,
-                       target = RMFTestCase.TARGET_COMMON_SERVICES
-    )
-
-    # Validate krb5.conf file
-    self.assertResourceCalled('Directory', use_cases.get_krb5_conf_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0755,
-                              create_parents = True)
-
-    file_path = (use_cases.get_krb5_conf_dir(json_data) +
-                 "/" +
-                 use_cases.get_krb5_conf_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=InlineTemplate(use_cases.get_krb5_conf_template(json_data)),
-                              owner='root',
-                              group='root',
-                              mode=0644)
-
-    # Validate kdc.conf file
-    self.assertResourceCalled('Directory', use_cases.get_kdc_conf_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0700,
-                              create_parents = True)
-
-    file_path = (use_cases.get_kdc_conf_dir(json_data) +
-                 "/" +
-                 use_cases.get_kdc_conf_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=InlineTemplate(use_cases.get_kdc_conf_template(json_data)),
-                              owner='root',
-                              group='root',
-                              mode=0600)
-
-    # Validate kadm5.acl file
-    self.assertResourceCalled('Directory', use_cases.get_kadm5_acl_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0700,
-                              create_parents = True)
-
-    file_path = (use_cases.get_kadm5_acl_dir(json_data) +
-                 "/" +
-                 use_cases.get_kadm5_acl_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=InlineTemplate(use_cases.get_kadm5_acl_template(json_data)),
-                              owner='root',
-                              group='root',
-                              mode=0600)
-
-  def test_configure_cross_realm_trust(self):
-    json_data = use_cases.get_cross_realm_use_case()
-
-    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/kerberos_server.py",
-                       classname="KerberosServer",
-                       command="configure",
-                       config_dict=json_data,
-                       stack_version = self.STACK_VERSION,
-                       target = RMFTestCase.TARGET_COMMON_SERVICES
-    )
-
-    # Validate krb5.conf file
-    self.assertResourceCalled('Directory', use_cases.get_krb5_conf_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0755,
-                              create_parents = True)
-
-    file_path = (use_cases.get_krb5_conf_dir(json_data) +
-                 "/" +
-                 use_cases.get_krb5_conf_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=InlineTemplate(use_cases.get_krb5_conf_template(json_data)),
-                              owner='root',
-                              group='root',
-                              mode=0644)
-
-    # Validate kdc.conf file
-    self.assertResourceCalled('Directory', use_cases.get_kdc_conf_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0700,
-                              create_parents = True)
-
-    file_path = (use_cases.get_kdc_conf_dir(json_data) +
-                 "/" +
-                 use_cases.get_kdc_conf_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=InlineTemplate(use_cases.get_kdc_conf_template(json_data)),
-                              owner='root',
-                              group='root',
-                              mode=0600)
-
-    # Validate kadm5.acl file
-    self.assertResourceCalled('Directory', use_cases.get_kadm5_acl_dir(json_data),
-                              owner='root',
-                              group='root',
-                              mode=0700,
-                              create_parents = True)
-
-    file_path = (use_cases.get_kadm5_acl_dir(json_data) +
-                 "/" +
-                 use_cases.get_kadm5_acl_file(json_data))
-    self.assertResourceCalled('File', file_path,
-                              content=InlineTemplate(use_cases.get_kadm5_acl_template(json_data)),
-                              owner='root',
-                              group='root',
-                              mode=0600)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/python/stacks/2.2/KERBEROS/use_cases.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/KERBEROS/use_cases.py b/ambari-server/src/test/python/stacks/2.2/KERBEROS/use_cases.py
index 181c16d..aab01ad 100644
--- a/ambari-server/src/test/python/stacks/2.2/KERBEROS/use_cases.py
+++ b/ambari-server/src/test/python/stacks/2.2/KERBEROS/use_cases.py
@@ -23,18 +23,17 @@ krb5_conf_template = \
   '[libdefaults]\n' \
   '  renew_lifetime = 7d\n' \
   '  forwardable = true\n' \
-  '  realm = {{realm|upper()}}\n' \
+  '  realm = {{realm}}\n' \
   '  ticket_lifetime = 24h\n' \
   '  dns_lookup_realm = false\n' \
   '  dns_lookup_kdc = false\n' \
   '\n' \
   '{% if domains %}\n' \
   '[domain_realm]\n' \
-  '{% for domain in domains %}\n' \
-  '  {{domain}} = {{realm|upper()}}\n' \
-  '{% endfor %}\n' \
+  '{%- for domain in domains.split(\',\') %}\n' \
+  '  {{domain|trim()}} = {{realm}}\n' \
+  '{%- endfor %}\n' \
   '{% endif %}\n' \
-  '\n' \
   '[logging]\n' \
   '  default = FILE:/var/log/krb5kdc.log\n' \
   '  admin_server = FILE:/var/log/kadmind.log\n' \
@@ -42,9 +41,18 @@ krb5_conf_template = \
   '\n' \
   '[realms]\n' \
   '  {{realm}} = {\n' \
-  '    admin_server = {{admin_server_host|default(kdc_host, True)}}\n' \
-  '    kdc = {{kdc_host}}\n' \
-  '}\n' \
+  '{%- if kdc_hosts > 0 -%}\n' \
+  '{%- set kdc_host_list = kdc_hosts.split(\',\')  -%}\n' \
+  '{%- if kdc_host_list and kdc_host_list|length > 0 %}\n' \
+  '    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n' \
+  '{%- if kdc_host_list -%}\n' \
+  '{% for kdc_host in kdc_host_list %}\n' \
+  '    kdc = {{kdc_host|trim()}}\n' \
+  '{%- endfor -%}\n' \
+  '{% endif %}\n' \
+  '{%- endif %}\n' \
+  '{%- endif %}\n' \
+  '  }\n' \
   '\n' \
   '{# Append additional realm declarations should be placed below #}\n'
 
@@ -74,7 +82,7 @@ def get_manged_kdc_use_case():
   json_data['clusterHostInfo']['kdc_server_hosts'] = ['c6401.ambari.apache.org']
   json_data['configurations']['kerberos-env'] = {
     'kdc_type': 'mit-kdc',
-    'kdc_host': 'c6401.ambari.apache.org'
+    'kdc_hosts': 'c6401.ambari.apache.org, c6402.ambari.apache.org'
   }
   json_data['configurations']['krb5-conf'] = {
     'realm': 'MANAGED_REALM.COM',
@@ -92,7 +100,7 @@ def get_unmanged_kdc_use_case():
     json_data = json.load(f)
 
   json_data['configurations']['kerberos-env'] = {
-    'kdc_host': 'ad.oscorp_industries.com',
+    'kdc_hosts': 'c6401.ambari.apache.org, c6402.ambari.apache.org',
     'kdc_type': 'mit-kdc'
   }
   json_data['configurations']['krb5-conf'] = {
@@ -128,7 +136,7 @@ def get_unmanged_krb5conf_use_case():
     'manage_krb5_conf': "false"
   }
   json_data['configurations']['kerberos-env'] = {
-    'kdc_host': 'c6401.ambari.apache.org',
+    'kdc_hosts': 'c6401.ambari.apache.org, c6402.ambari.apache.org',
     'encryption_types' : 'aes256-cts-hmac-sha1-96'
   }
 
@@ -140,7 +148,7 @@ def get_unmanged_ad_use_case():
     json_data = json.load(f)
 
   json_data['configurations']['kerberos-env'] = {
-    'kdc_host': 'ad.oscorp_industries.com',
+    'kdc_hosts': 'c6401.ambari.apache.org, c6402.ambari.apache.org',
     'kdc_type': 'active-directory',
   }
   json_data['configurations']['krb5-conf'] = {
@@ -173,7 +181,7 @@ def get_cross_realm_use_case():
 
   json_data['clusterHostInfo']['kdc_server_hosts'] = ['c6401.ambari.apache.org']
   json_data['configurations']['kerberos-env'] = {
-    'kdc_host': 'c6401.ambari.apache.org',
+    'kdc_hosts': 'c6401.ambari.apache.org, c6402.ambari.apache.org',
     'kdc_type': 'mit-kdc'
   }
   json_data['configurations']['krb5-conf'] = {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/python/stacks/2.2/configs/journalnode-upgrade-hdfs-secure.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/configs/journalnode-upgrade-hdfs-secure.json b/ambari-server/src/test/python/stacks/2.2/configs/journalnode-upgrade-hdfs-secure.json
index c1ca3aa..7b07d87 100644
--- a/ambari-server/src/test/python/stacks/2.2/configs/journalnode-upgrade-hdfs-secure.json
+++ b/ambari-server/src/test/python/stacks/2.2/configs/journalnode-upgrade-hdfs-secure.json
@@ -169,7 +169,7 @@
         }, 
         "kerberos-env": {
             "kdc_type": "mit-kdc",
-            "kdc_host": "c6406.ambari.apache.org",
+            "kdc_hosts": "c6406.ambari.apache.org",
             "admin_server_host": "c6406.ambari.apache.org",
             "ldap_url": "",
             "ad_create_attributes_template": "\n{\n  \"objectClass\": [\"top\", \"person\", \"organizationalPerson\", \"user\"],\n  \"cn\": \"$principal_name\",\n  #if( $is_service )\n  \"servicePrincipalName\": \"$principal_name\",\n  #end\n  \"userPrincipalName\": \"$normalized_principal\",\n  \"unicodePwd\": \"$password\",\n  \"accountExpires\": \"0\",\n  \"userAccountControl\": \"66048\"\n}\n    ",
@@ -1004,7 +1004,7 @@
         "krb5-conf": {
             "realm": "EXAMPLE.COM",
             "conf_dir": "/etc",
-            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm|upper()}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n\n{% if domains %}\n[domain_realm]\n{% for domain in domains.split(',') %}\n  {{domain}} = {{realm|upper()}}\n{% endfor %}\n{% endif %}\n\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n    admin_server = {{admin_server_host|default(kdc_host, True)}}\n    kdc = {{kdc_host}}\n  }\n\n{# Append additional realm declarations below #}\n    ",
+            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n  {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',')  -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{% for kdc_host in kdc_host_list %}\n    kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n  }\n\n{# Append additional realm declarations bel
 ow #}\n    ",
             "domains": ""
         },
         "yarn-log4j": {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/python/stacks/2.2/configs/journalnode-upgrade.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/configs/journalnode-upgrade.json b/ambari-server/src/test/python/stacks/2.2/configs/journalnode-upgrade.json
index 7df0daf..cf84bb7 100644
--- a/ambari-server/src/test/python/stacks/2.2/configs/journalnode-upgrade.json
+++ b/ambari-server/src/test/python/stacks/2.2/configs/journalnode-upgrade.json
@@ -169,7 +169,7 @@
         }, 
         "kerberos-env": {
             "kdc_type": "mit-kdc",
-            "kdc_host": "c6406.ambari.apache.org",
+            "kdc_hosts": "c6406.ambari.apache.org",
             "admin_server_host": "c6406.ambari.apache.org",
             "ldap_url": "",
             "ad_create_attributes_template": "\n{\n  \"objectClass\": [\"top\", \"person\", \"organizationalPerson\", \"user\"],\n  \"cn\": \"$principal_name\",\n  #if( $is_service )\n  \"servicePrincipalName\": \"$principal_name\",\n  #end\n  \"userPrincipalName\": \"$normalized_principal\",\n  \"unicodePwd\": \"$password\",\n  \"accountExpires\": \"0\",\n  \"userAccountControl\": \"66048\"\n}\n    ",
@@ -1004,7 +1004,7 @@
         "krb5-conf": {
             "realm": "EXAMPLE.COM",
             "conf_dir": "/etc",
-            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm|upper()}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n\n{% if domains %}\n[domain_realm]\n{% for domain in domains.split(',') %}\n  {{domain}} = {{realm|upper()}}\n{% endfor %}\n{% endif %}\n\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n    admin_server = {{admin_server_host|default(kdc_host, True)}}\n    kdc = {{kdc_host}}\n  }\n\n{# Append additional realm declarations below #}\n    ",
+            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n  {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',')  -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{% for kdc_host in kdc_host_list %}\n    kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n  }\n\n{# Append additional realm declarations bel
 ow #}\n    ",
             "domains": ""
         },
         "yarn-log4j": {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/python/stacks/2.2/configs/pig-service-check-secure.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/configs/pig-service-check-secure.json b/ambari-server/src/test/python/stacks/2.2/configs/pig-service-check-secure.json
index f60fa8f..729ce78 100644
--- a/ambari-server/src/test/python/stacks/2.2/configs/pig-service-check-secure.json
+++ b/ambari-server/src/test/python/stacks/2.2/configs/pig-service-check-secure.json
@@ -146,7 +146,7 @@
             "ldap_url": "", 
             "encryption_types": "aes des3-cbc-sha1 rc4 des-cbc-md5", 
             "kdc_type": "mit-kdc",
-            "kdc_host": "c6401.ambari.apache.org",
+            "kdc_hosts": "c6401.ambari.apache.org",
             "admin_server_host": "c6401.ambari.apache.org"
         },
         "tez-site": {
@@ -285,7 +285,7 @@
         }, 
         "krb5-conf": {
             "conf_dir": "/etc",
-            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm|upper()}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n\n{% if domains %}\n[domain_realm]\n{% for domain in domains.split(',') %}\n  {{domain}} = {{realm|upper()}}\n{% endfor %}\n{% endif %}\n\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n    admin_server = {{admin_server_host|default(kdc_host, True)}}\n    kdc = {{kdc_host}}\n  }\n\n{# Append additional realm declarations below #}\n    ",
+            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n  {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',')  -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{% for kdc_host in kdc_host_list %}\n    kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n  }\n\n{# Append additional realm declarations bel
 ow #}\n    ",
             "domains": "",
             "manage_krb5_conf": "true"
         },

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/python/stacks/2.2/configs/ranger-admin-upgrade.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/configs/ranger-admin-upgrade.json b/ambari-server/src/test/python/stacks/2.2/configs/ranger-admin-upgrade.json
index a321dfb..cfff7df 100644
--- a/ambari-server/src/test/python/stacks/2.2/configs/ranger-admin-upgrade.json
+++ b/ambari-server/src/test/python/stacks/2.2/configs/ranger-admin-upgrade.json
@@ -161,7 +161,7 @@
         }, 
         "krb5-conf": {
             "conf_dir": "/etc",
-            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm|upper()}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n\n{% if domains %}\n[domain_realm]\n{% for domain in domains.split(',') %}\n  {{domain}} = {{realm|upper()}}\n{% endfor %}\n{% endif %}\n\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n    admin_server = {{admin_server_host|default(kdc_host, True)}}\n    kdc = {{kdc_host}}\n  }\n\n{# Append additional realm declarations below #}\n    ",
+            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n  {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',')  -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{% for kdc_host in kdc_host_list %}\n    kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n  }\n\n{# Append additional realm declarations bel
 ow #}\n    ",
             "domains": "",
             "manage_krb5_conf": "true"
         },
@@ -202,7 +202,7 @@
             "container_dn": "", 
             "ldap_url": "", 
             "encryption_types": "aes des3-cbc-sha1 rc4 des-cbc-md5",
-            "kdc_host": "c6407.ambari.apache.org",
+            "kdc_hosts": "c6407.ambari.apache.org",
             "admin_server_host": "c6407.ambari.apache.org",
             "kdc_type": "mit-kdc"
         }, 

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/python/stacks/2.2/configs/ranger-usersync-upgrade.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/configs/ranger-usersync-upgrade.json b/ambari-server/src/test/python/stacks/2.2/configs/ranger-usersync-upgrade.json
index db8e60b..8e886ce 100644
--- a/ambari-server/src/test/python/stacks/2.2/configs/ranger-usersync-upgrade.json
+++ b/ambari-server/src/test/python/stacks/2.2/configs/ranger-usersync-upgrade.json
@@ -156,7 +156,7 @@
         }, 
         "krb5-conf": {
             "conf_dir": "/etc",
-            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm|upper()}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n\n{% if domains %}\n[domain_realm]\n{% for domain in domains.split(',') %}\n  {{domain}} = {{realm|upper()}}\n{% endfor %}\n{% endif %}\n\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n    admin_server = {{admin_server_host|default(kdc_host, True)}}\n    kdc = {{kdc_host}}\n  }\n\n{# Append additional realm declarations below #}\n    ",
+            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n  {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',')  -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{% for kdc_host in kdc_host_list %}\n    kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n  }\n\n{# Append additional realm declarations bel
 ow #}\n    ",
             "domains": "",
             "manage_krb5_conf": "true"
         },
@@ -192,7 +192,7 @@
         }, 
         "kerberos-env": {
             "ad_create_attributes_template": "\n{\n  \"objectClass\": [\"top\", \"person\", \"organizationalPerson\", \"user\"],\n  \"cn\": \"$principal_name\",\n  #if( $is_service )\n  \"servicePrincipalName\": \"$principal_name\",\n  #end\n  \"userPrincipalName\": \"$normalized_principal\",\n  \"unicodePwd\": \"$password\",\n  \"accountExpires\": \"0\",\n  \"userAccountControl\": \"66048\"\n}\n    ",
-            "kdc_host": "c6407.ambari.apache.org",
+            "kdc_hosts": "c6407.ambari.apache.org",
             "admin_server_host": "c6407.ambari.apache.org",
             "realm": "EXAMPLE.COM",
             "container_dn": "", 

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-server/src/test/python/stacks/2.3/configs/hbase_secure.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.3/configs/hbase_secure.json b/ambari-server/src/test/python/stacks/2.3/configs/hbase_secure.json
index 8ecb91b..fd482db 100644
--- a/ambari-server/src/test/python/stacks/2.3/configs/hbase_secure.json
+++ b/ambari-server/src/test/python/stacks/2.3/configs/hbase_secure.json
@@ -138,7 +138,7 @@
             "security.client.protocol.acl": "*"
         }, 
         "kerberos-env": {
-            "kdc_host": "c6405.ambari.apache.org", 
+            "kdc_hosts": "c6405.ambari.apache.org",
             "ad_create_attributes_template": "\n{\n  \"objectClass\": [\"top\", \"person\", \"organizationalPerson\", \"user\"],\n  \"cn\": \"$principal_name\",\n  #if( $is_service )\n  \"servicePrincipalName\": \"$principal_name\",\n  #end\n  \"userPrincipalName\": \"$normalized_principal\",\n  \"unicodePwd\": \"$password\",\n  \"accountExpires\": \"0\",\n  \"userAccountControl\": \"66048\"\n}\n    ",
             "realm": "EXAMPLE.COM", 
             "container_dn": "", 
@@ -435,7 +435,7 @@
         "krb5-conf": {
             "domains": "EXAMPLE.COM", 
             "manage_krb5_conf": "true", 
-            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm|upper()}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n\n{% if domains %}\n[domain_realm]\n{% for domain in domains.split(',') %}\n  {{domain}} = {{realm|upper()}}\n{% endfor %}\n{% endif %}\n\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n    admin_server = {{admin_server_host|default(kdc_host, True)}}\n    kdc = {{kdc_host}}\n  }\n\n{# Append additional realm declarations below #}\n    ", 
+            "content": "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n  {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',')  -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{% for kdc_host in kdc_host_list %}\n    kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n  }\n\n{# Append additional realm declarations bel
 ow #}\n    ",
             "conf_dir": "/etc"
         }, 
         "ldap-log4j": {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/app/assets/data/stacks/HDP-2.2/configurations.json
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/data/stacks/HDP-2.2/configurations.json b/ambari-web/app/assets/data/stacks/HDP-2.2/configurations.json
index b82c0ee..85d4a9f 100644
--- a/ambari-web/app/assets/data/stacks/HDP-2.2/configurations.json
+++ b/ambari-web/app/assets/data/stacks/HDP-2.2/configurations.json
@@ -9464,7 +9464,7 @@
             "property_description" : "Customizable krb5.conf template (Jinja template engine)",
             "property_name" : "content",
             "property_type" : [ ],
-            "property_value" : "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm|upper()}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n\n{% if domains %}\n[domain_realm]\n{% for domain in domains.split(',') %}\n  {{domain}} = {{realm|upper()}}\n{% endfor %}\n{% endif %}\n\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n    admin_server = {{admin_server_host|default(kdc_host, True)}}\n    kdc = {{kdc_host}}\n  }\n\n{# Append additional realm declarations below #}\n    ",
+            "property_value" : "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n  {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',')  -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{% for kdc_host in kdc_host_list %}\n    kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n  }\n\n{# Append additional realm declarat
 ions below #}\n    ",
             "service_name" : "KERBEROS",
             "stack_name" : "HDP",
             "stack_version" : "2.2",
@@ -9514,11 +9514,11 @@
           }
         },
         {
-          "href" : "http://c6401:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/kdc_host",
+          "href" : "http://c6401:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/kdc_hosts",
           "StackConfigurations" : {
             "final" : "false",
-            "property_description" : "\n      The IP address or FQDN for the KDC host. Optionally a port number may be included.\n    ",
-            "property_name" : "kdc_host",
+            "property_description" : "\n            A comma-delimited list of IP addresses or FQDNs declaring the KDC hosts. Optionally a port number may be included in each entry by separating each host and port by a colon (:). Example:  kdc1.example.com:88, kdc2.example.com:88.\n",
+            "property_name" : "kdc_hosts",
             "property_type" : [ ],
             "property_value" : "",
             "service_name" : "KERBEROS",

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/app/assets/data/wizard/stack/hdp/version2.0.1/KERBEROS.json
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/data/wizard/stack/hdp/version2.0.1/KERBEROS.json b/ambari-web/app/assets/data/wizard/stack/hdp/version2.0.1/KERBEROS.json
index b34c7b4..589f58a 100644
--- a/ambari-web/app/assets/data/wizard/stack/hdp/version2.0.1/KERBEROS.json
+++ b/ambari-web/app/assets/data/wizard/stack/hdp/version2.0.1/KERBEROS.json
@@ -93,7 +93,7 @@
         "property_description" : "The jinja template for the krb5.conf file",
         "property_name" : "content",
         "property_type" : [ ],
-        "property_value" : "\n[libdefaults]\n  renew_lifetime = {{libdefaults_renew_lifetime}}\n  forwardable = {{libdefaults_forwardable}}\n  default_realm = {{realm|upper()}}\n  ticket_lifetime = {{libdefaults_ticket_lifetime}}\n  dns_lookup_realm = {{libdefaults_dns_lookup_realm}}\n  dns_lookup_kdc = {{libdefaults_dns_lookup_kdc}}\n\n{% if domains %}\n[domain_realm]\n{% for domain in domains %}\n  {{domain}} = {{realm|upper()}}\n{% endfor %}\n{% endif %}\n\n[logging]\n  default = {{logging_default}}\n{#\n# The following options are unused unless a managed KDC is installed\n  admin_server = {{logging_admin_server}}\n  kdc = {{logging_admin_kdc}}\n#}\n\n[realms]\n  {{realm}} = {\n    admin_server = {{admin_server_host|default(kdc_host, True)}}\n    kdc = {{kdc_host}}\n  }\n\n{# Append additional realm declarations should be placed below #}\n    ",
+        "property_value" : "\n[libdefaults]\n  renew_lifetime = 7d\n  forwardable = true\n  default_realm = {{realm}}\n  ticket_lifetime = 24h\n  dns_lookup_realm = false\n  dns_lookup_kdc = false\n  #default_tgs_enctypes = {{encryption_types}}\n  #default_tkt_enctypes = {{encryption_types}}\n{% if domains %}\n[domain_realm]\n{%- for domain in domains.split(',') %}\n  {{domain|trim()}} = {{realm}}\n{%- endfor %}\n{% endif %}\n[logging]\n  default = FILE:/var/log/krb5kdc.log\n  admin_server = FILE:/var/log/kadmind.log\n  kdc = FILE:/var/log/krb5kdc.log\n\n[realms]\n  {{realm}} = {\n{%- if kdc_hosts > 0 -%}\n{%- set kdc_host_list = kdc_hosts.split(',')  -%}\n{%- if kdc_host_list and kdc_host_list|length > 0 %}\n    admin_server = {{admin_server_host|default(kdc_host_list[0]|trim(), True)}}\n{%- if kdc_host_list -%}\n{% for kdc_host in kdc_host_list %}\n    kdc = {{kdc_host|trim()}}\n{%- endfor -%}\n{% endif %}\n{%- endif %}\n{%- endif %}\n  }\n\n{# Append additional realm declarations
  below #}\n    ",
         "service_name" : "KERBEROS",
         "stack_name" : "HDP",
         "stack_version" : "2.2",
@@ -115,11 +115,11 @@
       }
     },
     {
-      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/kdc_host",
+      "href" : "http://c6403.ambari.apache.org:8080/api/v1/stacks/HDP/versions/2.2/services/KERBEROS/configurations/kdc_hosts",
       "StackConfigurations" : {
         "final" : "false",
-        "property_description" : "\n      The IP address or FQDN of the KDC or Active Directory server, optionally a port number may be\n      provided\n    ",
-        "property_name" : "kdc_host",
+        "property_description" : "\n            A comma-delimited list of IP addresses or FQDNs declaring the KDC hosts. Optionally a port number may be included in each entry by separating each host and port by a colon (:). Example:  kdc1.example.com:88, kdc2.example.com:88\n    ",
+        "property_name" : "kdc_hosts",
         "property_type" : [ ],
         "property_value" : "",
         "service_name" : "KERBEROS",

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
index 7f77c38..c95823f 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
@@ -211,7 +211,7 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend(App.KDCCred
     var content = this.get('stepConfigs')[0].get('configs');
     var configs = content.filterProperty('filename', site + '.xml');
     // properties that should be formated as hosts
-    var hostProperties = ['kdc_host', 'realm'];
+    var hostProperties = ['kdc_hosts', 'realm'];
     configs.forEach(function (_configProperty) {
       // do not pass any globals whose name ends with _host or _hosts
       if (_configProperty.isRequiredByAgent !== false) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/app/controllers/main/admin/kerberos/step5_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step5_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step5_controller.js
index 38150c8..a298cf3 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step5_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step5_controller.js
@@ -123,15 +123,15 @@ App.KerberosWizardStep5Controller = App.KerberosProgressPageController.extend({
         filterObject = [
           {
             key: Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'),
-            properties: ['kdc_type', 'kdc_host', 'realm', 'executable_search_paths']
+            properties: ['kdc_type', 'kdc_hosts', 'realm', 'executable_search_paths']
           },
           {
             key: Em.I18n.t('admin.kerberos.wizard.step1.option.ad'),
-            properties: ['kdc_type', 'kdc_host', 'realm', 'ldap_url', 'container_dn', 'executable_search_paths']
+            properties: ['kdc_type', 'kdc_hosts', 'realm', 'ldap_url', 'container_dn', 'executable_search_paths']
           },
           {
             key: Em.I18n.t('admin.kerberos.wizard.step1.option.ipa'),
-            properties: ['kdc_type', 'kdc_host', 'realm', 'executable_search_paths']
+            properties: ['kdc_type', 'kdc_hosts', 'realm', 'executable_search_paths']
           },
           {
             key: Em.I18n.t('admin.kerberos.wizard.step1.option.manual'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/app/controllers/main/service/info/configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js
index 8943d7c..738d235 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -362,7 +362,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
     if (this.get('content.serviceName') === 'KERBEROS') {
       var kdc_type = configs.findProperty('name', 'kdc_type');
       if (kdc_type.get('value') === 'none') {
-        configs.findProperty('name', 'kdc_host').set('isVisible', false);
+        configs.findProperty('name', 'kdc_hosts').set('isVisible', false);
         configs.findProperty('name', 'admin_server_host').set('isVisible', false);
         configs.findProperty('name', 'domains').set('isVisible', false);
       } else if (kdc_type.get('value') === 'active-directory') {

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/app/data/HDP2/site_properties.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/data/HDP2/site_properties.js b/ambari-web/app/data/HDP2/site_properties.js
index 3586b0f..07062f7 100644
--- a/ambari-web/app/data/HDP2/site_properties.js
+++ b/ambari-web/app/data/HDP2/site_properties.js
@@ -1357,7 +1357,7 @@ var hdp2properties = [
     "index": 0
   },
   {
-    "name": "kdc_host",
+    "name": "kdc_hosts",
     "displayType": "supportTextConnection",
     "serviceName": "KERBEROS",
     "filename": "kerberos-env.xml",

http://git-wip-us.apache.org/repos/asf/ambari/blob/c6fa8c26/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 2d6ec67..2e4f648 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1165,7 +1165,7 @@ Em.I18n.translations = {
   'admin.kerberos.wizard.step5.moreInfoNonManual.body': 'Using the <b>Download CSV button</b>, you can download a csv file which contains a list of the principals and keytabs that will automatically be created by Ambari.',
   'admin.kerberos.wizard.step5.moreInfoManual.body': 'Important: Use the <b>Download CSV</b> button to obtain a list of the <b>required</b> principals and keytabs that are needed by Ambari to enable Kerberos in the cluster. <b>Do not proceed</b> until you have manually created and distributed the principals and keytabs to the cluster hosts.',
   'admin.kerberos.wizard.step5.kdc_type.label': 'KDC Type',
-  'admin.kerberos.wizard.step5.kdc_host.label': 'KDC Host',
+  'admin.kerberos.wizard.step5.kdc_hosts.label': 'KDC Hosts',
   'admin.kerberos.wizard.step5.realm.label': 'Realm Name',
   'admin.kerberos.wizard.step5.ldap_url.label': 'LDAP URL',
   'admin.kerberos.wizard.step5.container_dn.label': 'Container DN',