You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ja...@apache.org on 2014/11/21 23:04:50 UTC

[2/3] ambari git commit: AMBARI-8408. Implement the initial layout for the kerberos wizard. (jaimin)

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/controllers/wizard/step8_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step8_controller.js b/ambari-web/app/controllers/wizard/step8_controller.js
index affad0c..2254198 100644
--- a/ambari-web/app/controllers/wizard/step8_controller.js
+++ b/ambari-web/app/controllers/wizard/step8_controller.js
@@ -19,7 +19,7 @@
 var App = require('app');
 var stringUtils = require('utils/string_utils');
 
-App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
+App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wizardDeployProgressControllerMixin, {
 
   name: 'wizardStep8Controller',
 
@@ -93,6 +93,13 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
   isBackBtnDisabled: false,
 
   /**
+   * This flag when turned to true launches deploy progress bar
+   */
+  isDeployStarted: function() {
+    this.get('isSubmitDisabled');
+  }.property('isSubmitDisabled'),
+
+  /**
    * Is error appears while <code>ajaxQueue</code> executes
    * @type {bool}
    */
@@ -112,12 +119,6 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
   serviceConfigTags: [],
 
   /**
-   * Ajax-requests queue
-   * @type {App.ajaxQueue}
-   */
-  ajaxRequestsQueue: null,
-
-  /**
    * Is cluster security enabled
    * @type {bool}
    */
@@ -154,12 +155,6 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
   }.property('content.services').cacheable(),
 
   /**
-   * Ajax-requests count
-   * @type {number}
-   */
-  ajaxQueueLength: 0,
-
-  /**
    * Current cluster name
    * @type {string}
    */
@@ -964,8 +959,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
       return App.showConfirmationPopup(function () {
         self.submitProceed();
       }, Em.I18n.t('installer.step8.securityConfirmationPopupBody'));
-    }
-    else {
+    } else {
       return this.submitProceed();
     }
   },
@@ -1535,7 +1529,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
           if (service.get('serviceName') === 'MAPREDUCE' && (type === 'capacity-scheduler' || type === 'mapred-queue-acls')) {
             return;
           } else if (type === 'core-site') {
-            coreSiteObject.service_config_version_note = serviceVersionNotes
+            coreSiteObject.service_config_version_note = serviceVersionNotes;
             this.get('serviceConfigTags').pushObject(coreSiteObject);
           } else if (type === 'storm-site') {
             var obj = this.createStormSiteObj(tag);
@@ -1826,53 +1820,5 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, {
       }
     }, this);
     return {type: 'storm-site', tag: tag, properties: stormProperties};
-  },
-
-  /**
-   * Navigate to next step after all requests are sent
-   * @method ajaxQueueFinished
-   */
-  ajaxQueueFinished: function () {
-    console.log('everything is loaded');
-    App.router.send('next');
-  },
-
-  /**
-   * We need to do a lot of ajax calls async in special order. To do this,
-   * generate array of ajax objects and then send requests step by step. All
-   * ajax objects are stored in <code>ajaxRequestsQueue</code>
-   *
-   * @param {Object} params object with ajax-request parameters like url, type, data etc
-   * @method addRequestToAjaxQueue
-   */
-  addRequestToAjaxQueue: function (params) {
-    if (App.get('testMode')) return;
-
-    params = jQuery.extend({
-      sender: this,
-      error: 'ajaxQueueRequestErrorCallback'
-    }, params);
-    params.data['cluster'] = this.get('clusterName');
-
-    this.get('ajaxRequestsQueue').addRequest(params);
-  },
-
-  /**
-   * Error callback for each queued ajax-request
-   * @param {object} xhr
-   * @param {string} status
-   * @param {string} error
-   * @method ajaxQueueRequestErrorCallback
-   */
-  ajaxQueueRequestErrorCallback: function (xhr, status, error) {
-    var responseText = JSON.parse(xhr.responseText);
-    var controller = App.router.get(App.clusterStatus.wizardControllerName);
-    controller.registerErrPopup(Em.I18n.t('common.error'), responseText.message);
-    this.set('hasErrorOccurred', true);
-    // an error will break the ajax call chain and allow submission again
-    this.set('isSubmitDisabled', false);
-    this.set('isBackBtnDisabled', false);
-    App.router.get(this.get('content.controllerName')).setStepsEnable();
   }
-
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/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 2510408..0f68c61 100644
--- a/ambari-web/app/data/HDP2/site_properties.js
+++ b/ambari-web/app/data/HDP2/site_properties.js
@@ -2159,7 +2159,204 @@ module.exports =
       "index": 0
     },
 
-
+  /********************************************* kerberos ********************************/
+    {
+      "id": "puppet var",
+      "name": "kdc_type",
+      "displayName": "KDC type",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "masterHost",
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 0
+    },
+    {
+      "id": "puppet var",
+      "name": "kdc_host",
+      "displayName": "KDC host",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 0
+    },
+    {
+      "id": "puppet var",
+      "name": "admin_server_host",
+      "displayName": "Kadmin host",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 1
+    },
+    {
+      "id": "puppet var",
+      "name": "realm",
+      "displayName": "Realm name",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 2
+    },
+    {
+      "id": "puppet var",
+      "name": "domains",
+      "displayName": "Domains",
+      "isRequired": false,
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 3
+    },
+    {
+      "id": "puppet var",
+      "name": "test_principal",
+      "displayName": "Test principal",
+      "isRequired": false,
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 4
+    },
+    {
+      "id": "puppet var",
+      "name": "test_password",
+      "displayName": "Test password",
+      "isRequired": false,
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 5
+    },
+    {
+      "id": "puppet var",
+      "name": "test_keytab",
+      "displayName": "Test keytab",
+      "isRequired": false,
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "KDC",
+      "index": 5
+    },
+    {
+      "id": "puppet var",
+      "name": "conf_dir",
+      "displayName": "krb5-conf directory path",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "directory",
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "Advanced krb5-conf",
+      "index": 0
+    },
+    {
+      "id": "puppet var",
+      "name": "content",
+      "displayName": "krb5-conf template",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "content",
+      "serviceName": "KERBEROS",
+      "filename": "krb5-conf.xml",
+      "category": "Advanced krb5-conf",
+      "index": 1
+    },
+    {
+      "id": "puppet var",
+      "name": "conf_dir",
+      "displayName": "kadm5-acl directory path",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "directory",
+      "serviceName": "KERBEROS",
+      "filename": "kadm5-acl.xml",
+      "category": "Advanced kadm5-acl",
+      "index": 0
+    },
+    {
+      "id": "puppet var",
+      "name": "content",
+      "displayName": "kadm5-conf template",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "content",
+      "serviceName": "KERBEROS",
+      "filename": "kadm5-acl.xml",
+      "category": "Advanced kadm5-acl",
+      "index": 1
+    },
+    {
+      "id": "puppet var",
+      "name": "conf_dir",
+      "displayName": "kdc-conf directory path",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "directory",
+      "serviceName": "KERBEROS",
+      "filename": "kdc-conf.xml",
+      "category": "Advanced kdc-conf",
+      "index": 0
+    },
+    {
+      "id": "puppet var",
+      "name": "content",
+      "displayName": "kdc-conf template",
+      "value": "",
+      "defaultValue": "",
+      "description": "",
+      "isOverridable": false,
+      "isVisible": true,
+      "isRequiredByAgent": true,
+      "displayType": "content",
+      "serviceName": "KERBEROS",
+      "filename": "kdc-conf.xml",
+      "category": "Advanced kdc-conf",
+      "index": 1
+    },
   /********************************************* flume-agent *****************************/
     {
       "id": "site property",

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 9943582..5c53cd6 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -154,6 +154,7 @@ Em.I18n.translations = {
   'common.upgrade': 'Upgrade',
   'common.reUpgrade': 'Retry Upgrade',
   'common.security':'Security',
+  'common.kerberos':'Kerberos',
   'common.cluster':'Cluster',
   'common.repositories':'Repositories',
   'common.stack.versions':'Stack Versions',
@@ -237,6 +238,7 @@ Em.I18n.translations = {
   'common.unknown': "Unknown",
   'common.install': "Install",
   'common.alertDefinition': "Alert Definition",
+  'common.prerequisites': 'Prerequisites',
 
   'passiveState.turnOn':'Turn On Maintenance Mode',
   'passiveState.turnOff':'Turn Off Maintenance Mode',
@@ -861,6 +863,10 @@ Em.I18n.translations = {
   'alerts.definition.details.notification': 'Notification',
   'alerts.definition.details.noAlerts': 'No alert instances to show',
 
+
+  'wizard.progressPage.notice.completed':'Please proceed to the next step.',
+  'wizard.progressPage.notice.failed':'You can click on the Retry button to retry failed tasks.',
+
   'admin.advanced.caution':'This section is for advanced user only.<br/>Proceed with caution.',
   'admin.advanced.button.uninstallIncludingData':'Uninstall cluster including all data.',
   'admin.advanced.button.uninstallKeepData':'Uninstall cluster but keep data.',
@@ -893,6 +899,34 @@ Em.I18n.translations = {
   'admin.authentication.form.test.success':'The configuration passes the test',
   'admin.authentication.form.test.fail':'The configuration fails the test',
 
+  'admin.kerberos.wizard.configuration.note': 'This is the initial configuration created by Enable Kerberos wizard.',
+  'admin.kerberos.wizard.header':'Enable Kerberos Wizard',
+  'admin.kerberos.button.enable': 'Enable Kerberos',
+  'admin.kerberos.wizard.step1.header': 'Get Started',
+  'admin.kerberos.wizard.step2.header': 'Configure Kerberos',
+  'admin.kerberos.wizard.step3.header': 'Install and Test Kerberos',
+  'admin.kerberos.wizard.step4.header': 'Configure Identities',
+  'admin.kerberos.wizard.step5.header': 'Kerberize Cluster',
+  'admin.kerberos.wizard.step6.header': 'Test Services',
+  'admin.kerberos.wizard.step1.info.body': 'Welcome to the Ambari Security Wizard. Use this wizard to enable kerberos security in your cluster. </br>Let\'s get started.',
+  'admin.kerberos.wizard.step1.alert.body': 'Note: This process requires services to be restarted and cluster downtime. As well, depending on the options you select, might require support from your Security administrators. Please plan accordingly.',
+  'admin.kerberos.wizard.step1.body.text': 'What type of KDC do you plan on using?',
+  'admin.kerberos.wizard.step1.option.kdc': 'Existing MIT KDC',
+  'admin.kerberos.wizard.step1.option.kdc.condition.1': 'An administrative principal is created in the MIT KDC to be shared with Ambari when prompted.',
+  'admin.kerberos.wizard.step1.option.kdc.condition.2': 'Java Cryptography Extension (JCE) is installed on all hosts.',
+  'admin.kerberos.wizard.step1.option.ad': 'Existing Active Directory',
+  'admin.kerberos.wizard.step1.option.ad.condition.1': 'An administrative principal is created in the Active Directory to be shared with Ambari when prompted.',
+  'admin.kerberos.wizard.step1.option.ad.condition.2': 'Java Cryptography Extension (JCE) is installed on all hosts.',
+  'admin.kerberos.wizard.step1.prerequisites.label': 'Following prerequisites needs to be checked to progress ahead in the wizard.',
+  'admin.kerberos.wizard.step2.info.body': 'Please configure kerberos related properties.',
+  'admin.kerberos.wizard.step3.task0.title': 'Install Kerberos',
+  'admin.kerberos.wizard.step3.task1.title': 'Test Kerberos',
+  'admin.kerberos.wizard.step3.notice.inProgress': 'Please wait while kerberos service is being installed and tested.',
+  'admin.kerberos.wizard.step3.notice.completed': 'Kerberos service has been installed and tested successfully.',
+  'admin.kerberos.wizard.progressPage.notice.inProgress': 'Please wait while cluster is being kerberized',
+  'admin.kerberos.wizard.step4.info.body': 'Configure principal name and keytab location for service users and hadoop service components.',
+  'admin.kerberos.wizard.step6.notice.completed': 'Cluster has been successfully kerberized.',
+
   'admin.highAvailability':' High Availability',
   'admin.highAvailability.button.enable':'Enable NameNode HA',
   'admin.highAvailability.button.disable':'Disable NameNode HA',
@@ -915,8 +949,6 @@ Em.I18n.translations = {
 
   'admin.highAvailability.wizard.header':'Enable NameNode HA Wizard',
   'admin.highAvailability.wizard.progressPage.notice.inProgress':'Please wait while NameNode HA is being deployed.',
-  'admin.highAvailability.wizard.progressPage.notice.completed':'Please proceed to the next step.',
-  'admin.highAvailability.wizard.progressPage.notice.failed':'You can click on the Retry button to retry failed tasks.',
   'admin.highAvailability.wizard.progressPage.header':'Deploy',
   'admin.highAvailability.wizard.step1.header':'Get Started',
   'admin.highAvailability.wizard.step1.nameserviceid.tooltip.title':'Nameservice ID',

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/mixins.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins.js b/ambari-web/app/mixins.js
index 27c9c03..a1016b3 100644
--- a/ambari-web/app/mixins.js
+++ b/ambari-web/app/mixins.js
@@ -26,5 +26,9 @@ require('mixins/common/serverValidator');
 require('mixins/common/table_server_view_mixin');
 require('mixins/common/table_server_mixin');
 require('mixins/main/host/details/host_components/decommissionable');
+require('mixins/wizard/wizardProgressPageController');
+require('mixins/wizard/wizardDeployProgressController');
+require('mixins/wizard/wizardProgressPageView');
+require('mixins/wizard/wizardDeployProgressView');
 require('mixins/wizard/selectHost');
 require('mixins/wizard/addSecurityConfigs');

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/mixins/wizard/wizardDeployProgressController.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/wizard/wizardDeployProgressController.js b/ambari-web/app/mixins/wizard/wizardDeployProgressController.js
new file mode 100644
index 0000000..3c9ccf1
--- /dev/null
+++ b/ambari-web/app/mixins/wizard/wizardDeployProgressController.js
@@ -0,0 +1,94 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * Mixin for wizard controller for showing command progress on wizard pages
+ * This should
+ * @type {Ember.Mixin}
+ */
+App.wizardDeployProgressControllerMixin = Em.Mixin.create({
+
+  /**
+   * Ajax-requests count
+   * @type {number}
+   */
+  ajaxQueueLength: 0,
+
+  /**
+   * Ajax-requests queue
+   * @type {App.ajaxQueue}
+   */
+  ajaxRequestsQueue: null,
+
+  /**
+   * This flag when turned to true launches deploy progress bar
+   */
+  isDeployStarted: '',
+
+
+  /**
+   * We need to do a lot of ajax calls async in special order. To do this,
+   * generate array of ajax objects and then send requests step by step. All
+   * ajax objects are stored in <code>ajaxRequestsQueue</code>
+   *
+   * @param {Object} params object with ajax-request parameters like url, type, data etc
+   * @method addRequestToAjaxQueue
+   */
+  addRequestToAjaxQueue: function (params) {
+    if (App.get('testMode')) return;
+
+    params = jQuery.extend({
+      sender: this,
+      error: 'ajaxQueueRequestErrorCallback'
+    }, params);
+    params.data['cluster'] = this.get('clusterName');
+
+    this.get('ajaxRequestsQueue').addRequest(params);
+  },
+
+  /**
+   * Navigate to next step after all requests are sent
+   * @method ajaxQueueFinished
+   */
+  ajaxQueueFinished: function () {
+    console.log('everything is loaded');
+    App.router.send('next');
+  },
+
+  /**
+   * Error callback for each queued ajax-request
+   * @param {object} xhr
+   * @param {string} status
+   * @param {string} error
+   * @method ajaxQueueRequestErrorCallback
+   */
+  ajaxQueueRequestErrorCallback: function (xhr, status, error) {
+    var responseText = JSON.parse(xhr.responseText);
+    var controller = App.router.get(App.clusterStatus.wizardControllerName);
+    controller.registerErrPopup(Em.I18n.t('common.error'), responseText.message);
+    this.set('hasErrorOccurred', true);
+    // an error will break the ajax call chain and allow submission again
+    this.set('isSubmitDisabled', false);
+    this.set('isBackBtnDisabled', false);
+    App.router.get(this.get('content.controllerName')).setStepsEnable();
+  }
+});
+
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/mixins/wizard/wizardDeployProgressView.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/wizard/wizardDeployProgressView.js b/ambari-web/app/mixins/wizard/wizardDeployProgressView.js
new file mode 100644
index 0000000..50d70c0
--- /dev/null
+++ b/ambari-web/app/mixins/wizard/wizardDeployProgressView.js
@@ -0,0 +1,96 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * Mixin for wizard view for showing command progress on wizard pages
+ * This should
+ * @type {Ember.Mixin}
+ */
+App.wizardDeployProgressViewMixin = Em.Mixin.create({
+
+  /**
+   * Should ajax-queue progress bar be displayed
+   * @method showLoadingIndicator
+   */
+  showLoadingIndicator: function () {
+    if (!this.get('controller.isSubmitDisabled') || App.get('testMode')) {
+      if (this.get('modalPopup')) {
+        this.get('modalPopup').hide();
+        this.set('modalPopup', null);
+      }
+      return;
+    }
+    // don't create popup if it already exists
+    if (this.get('modalPopup')) {
+      return;
+    }
+    this.set('modalPopup', App.ModalPopup.show({
+
+      header: '',
+
+      showFooter: false,
+
+      showCloseButton: false,
+
+      bodyClass: Em.View.extend({
+
+        templateName: require('templates/wizard/step8/step8_log_popup'),
+
+        controllerBinding: 'App.router.wizardStep8Controller',
+
+        /**
+         * Css-property for progress-bar
+         * @type {string}
+         */
+        barWidth: '',
+
+        /**
+         * Popup-message
+         * @type {string}
+         */
+        message: '',
+
+        /**
+         * Set progress bar width and popup message when ajax-queue requests are proccessed
+         * @method ajaxQueueChangeObs
+         */
+        ajaxQueueChangeObs: function () {
+          var length = this.get('controller.ajaxQueueLength');
+          var left = this.get('controller.ajaxRequestsQueue.queue.length');
+          this.set('barWidth', 'width: ' + ((length - left) / length * 100) + '%;');
+          this.set('message', Em.I18n.t('installer.step8.deployPopup.message').format((length - left), length));
+        }.observes('controller.ajaxQueueLength', 'controller.ajaxRequestsQueue.queue.length'),
+
+        /**
+         * Hide popup when ajax-queue is finished
+         * @method autoHide
+         */
+        autoHide: function () {
+          if (this.get('controller.servicesInstalled')) {
+            this.get('parentView').hide();
+          }
+        }.observes('controller.servicesInstalled')
+      })
+
+    }));
+  }.observes('controller.isDeployStarted')
+
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/mixins/wizard/wizardProgressPageController.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/wizard/wizardProgressPageController.js b/ambari-web/app/mixins/wizard/wizardProgressPageController.js
new file mode 100644
index 0000000..074d249
--- /dev/null
+++ b/ambari-web/app/mixins/wizard/wizardProgressPageController.js
@@ -0,0 +1,364 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * Mixin for wizard controller for showing command progress on wizard pages
+ * This should
+ * @type {Ember.Mixin}
+ */
+App.wizardProgressPageControllerMixin = Em.Mixin.create({
+  controllerName: '',
+  clusterDeployState: 'WIZARD_DEPLOY',
+  status: 'IN_PROGRESS',
+  tasks: [],
+  commands: [],
+  currentRequestIds: [], //todo: replace with using requestIds from tasks
+  logs: [],
+  currentTaskId: null,
+  POLL_INTERVAL: 4000,
+  isSubmitDisabled: true,
+  isBackButtonDisabled: true,
+  /**
+   *  tasksMessagesPrefix should be overloaded by any controller including the mixin
+   */
+  tasksMessagesPrefix: '',
+
+  loadStep: function () {
+    this.clearStep();
+    this.initializeTasks();
+    this.loadTasks();
+    this.addObserver('tasks.@each.status', this, 'onTaskStatusChange');
+    this.onTaskStatusChange();
+  },
+
+  clearStep: function () {
+    this.set('isSubmitDisabled', true);
+    this.set('isBackButtonDisabled', true);
+    this.set('tasks', []);
+    this.set('currentRequestIds', []);
+  },
+
+  initializeTasks: function () {
+    var commands = this.get('commands');
+    var currentStep = App.router.get(this.get('content.controllerName') + '.currentStep');
+    var tasksMessagesPrefix = this.get('tasksMessagesPrefix');
+    for (var i = 0; i < commands.length; i++) {
+      this.get('tasks').pushObject(Ember.Object.create({
+        title: Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
+        status: 'PENDING',
+        id: i,
+        command: commands[i],
+        showRetry: false,
+        showRollback: false,
+        name: Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
+        displayName: Em.I18n.t(tasksMessagesPrefix + currentStep + '.task' + i + '.title'),
+        progress: 0,
+        isRunning: false,
+        requestIds: []
+      }));
+    }
+  },
+
+  loadTasks: function () {
+    var self = this;
+    var loadedStatuses = this.get('content.tasksStatuses');
+    var loadedRequestIds = this.get('content.tasksRequestIds');
+    if (loadedStatuses && loadedStatuses.length === this.get('tasks').length) {
+      this.get('tasks').forEach(function (task, i) {
+        self.setTaskStatus(task.get('id'), loadedStatuses[i]);
+        self.setRequestIds(task.get('id'), loadedRequestIds[i]);
+      });
+      if (loadedStatuses.contains('IN_PROGRESS')) {
+        var curTaskId = this.get('tasks')[loadedStatuses.indexOf('IN_PROGRESS')].get('id');
+        this.set('currentRequestIds', this.get('content.requestIds'));
+        this.set('currentTaskId', curTaskId);
+        this.doPolling();
+      } else if (loadedStatuses.contains('QUEUED')) {
+        var curTaskId = this.get('tasks')[loadedStatuses.indexOf('QUEUED')].get('id');
+        this.set('currentTaskId', curTaskId);
+        this.runTask(curTaskId);
+      }
+    }
+  },
+
+  setTaskStatus: function (taskId, status) {
+    this.get('tasks').findProperty('id', taskId).set('status', status);
+  },
+
+  setRequestIds: function (taskId, requestIds) {
+    this.get('tasks').findProperty('id', taskId).set('requestIds', requestIds);
+  },
+
+  retryTask: function () {
+    var task = this.get('tasks').findProperty('status', 'FAILED');
+    task.set('showRetry', false);
+    task.set('showRollback', false);
+    task.set('status', 'PENDING');
+  },
+
+  onTaskStatusChange: function () {
+    var statuses = this.get('tasks').mapProperty('status');
+    var tasksRequestIds = this.get('tasks').mapProperty('requestIds');
+    var requestIds = this.get('currentRequestIds');
+    // save task info
+    App.router.get(this.get('content.controllerName')).saveTasksStatuses(statuses);
+    App.router.get(this.get('content.controllerName')).saveTasksRequestIds(tasksRequestIds);
+    App.router.get(this.get('content.controllerName')).saveRequestIds(requestIds);
+    // call saving of cluster status asynchronous
+    // synchronous executing cause problems in Firefox
+    App.clusterStatus.setClusterStatus({
+      clusterName: App.router.getClusterName(),
+      clusterState: this.get('clusterDeployState'),
+      wizardControllerName: this.get('content.controllerName'),
+      localdb: App.db.data
+    }, {successCallback: this.statusChangeCallback, sender: this});
+  },
+
+  /**
+   * Method that called after saving persist data to server.
+   * Switch task according its status.
+   */
+  statusChangeCallback: function () {
+    if (!this.get('tasks').someProperty('status', 'IN_PROGRESS') && !this.get('tasks').someProperty('status', 'QUEUED') && !this.get('tasks').someProperty('status', 'FAILED')) {
+      var nextTask = this.get('tasks').findProperty('status', 'PENDING');
+      if (nextTask) {
+        this.set('status', 'IN_PROGRESS');
+        this.setTaskStatus(nextTask.get('id'), 'QUEUED');
+        this.set('currentTaskId', nextTask.get('id'));
+        this.runTask(nextTask.get('id'));
+      } else {
+        this.set('status', 'COMPLETED');
+        this.set('isSubmitDisabled', false);
+        this.set('isBackButtonDisabled', false);
+      }
+    } else if (this.get('tasks').someProperty('status', 'FAILED')) {
+      this.set('status', 'FAILED');
+      this.set('isBackButtonDisabled', false);
+      this.get('tasks').findProperty('status', 'FAILED').set('showRetry', true);
+      if (App.supports.autoRollbackHA) {
+        this.get('tasks').findProperty('status', 'FAILED').set('showRollback', true);
+      }
+    }
+    this.get('tasks').filterProperty('status', 'COMPLETED').setEach('showRetry', false);
+    this.get('tasks').filterProperty('status', 'COMPLETED').setEach('showRollback', false);
+  },
+
+  /**
+   * Run command of appropriate task
+   */
+  runTask: function (taskId) {
+    this[this.get('tasks').findProperty('id', taskId).get('command')]();
+  },
+
+  onTaskError: function () {
+    this.setTaskStatus(this.get('currentTaskId'), 'FAILED');
+  },
+
+  onTaskCompleted: function () {
+    this.setTaskStatus(this.get('currentTaskId'), 'COMPLETED');
+  },
+
+  /**
+   * check whether component installed on specified hosts
+   * @param componentName
+   * @param hostNames
+   * @return {$.ajax}
+   */
+  checkInstalledComponents: function (componentName, hostNames) {
+    return App.ajax.send({
+      name: 'host_component.installed.on_hosts',
+      sender: this,
+      data: {
+        componentName: componentName,
+        hostNames: hostNames.join(',')
+      },
+      success: 'checkInstalledComponentsSuccessCallback'
+    });
+  },
+
+  checkInstalledComponentsSuccessCallback: function (data, opt, params) {
+    installedComponents = data.items;
+  },
+
+  createComponent: function (componentName, hostName, serviceName) {
+    var hostNames = (Array.isArray(hostName)) ? hostName : [hostName];
+    var self = this;
+
+    this.checkInstalledComponents(componentName, hostNames).complete(function () {
+      var result = [];
+
+      hostNames.forEach(function (hostName) {
+        result.push({
+          componentName: componentName,
+          hostName: hostName,
+          hasComponent: installedComponents.someProperty('HostRoles.host_name', hostName)
+        });
+      });
+
+      result.forEach(function (host, index, array) {
+        if (!host.hasComponent) {
+          App.ajax.send({
+            name: 'admin.high_availability.create_component',
+            sender: this,
+            data: {
+              hostName: host.hostName,
+              componentName: host.componentName,
+              serviceName: serviceName,
+              taskNum: array.length
+            },
+            success: 'onCreateComponent',
+            error: 'onCreateComponentError'
+          });
+        } else {
+          // Simulates format returned from ajax.send
+          this.onCreateComponent(null, null, {hostName: host.hostName, componentName: host.componentName, taskNum: array.length});
+        }
+      }, self)
+    });
+  },
+
+  onCreateComponent: function () {
+    var hostName = arguments[2].hostName;
+    var componentName = arguments[2].componentName;
+    var taskNum = arguments[2].taskNum;
+    var serviceName = arguments[2].serviceName;
+    this.updateComponent(componentName, hostName, serviceName, "Install", taskNum);
+  },
+
+  onCreateComponentError: function (error) {
+    if (error.responseText.indexOf('org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException') !== -1) {
+      this.onCreateComponent();
+    } else {
+      this.onTaskError();
+    }
+  },
+
+  updateComponent: function (componentName, hostName, serviceName, context, taskNum) {
+    if (!(hostName instanceof Array)) {
+      hostName = [hostName];
+    }
+    var state = context.toLowerCase() == "start" ? "STARTED" : "INSTALLED";
+    for (var i = 0; i < hostName.length; i++) {
+      App.ajax.send({
+        name: 'common.host.host_component.update',
+        sender: this,
+        data: {
+          context: context + " " + App.format.role(componentName),
+          hostName: hostName[i],
+          serviceName: serviceName,
+          componentName: componentName,
+          taskNum: taskNum || hostName.length,
+          HostRoles: {
+            state: state
+          }
+        },
+        success: 'startPolling',
+        error: 'onTaskError'
+      });
+    }
+  },
+
+  startPolling: function (data) {
+    if (data) {
+      this.get('currentRequestIds').push(data.Requests.id);
+      var tasksCount = arguments[2].taskNum || 1;
+      if (tasksCount === this.get('currentRequestIds').length) {
+        this.setRequestIds(this.get('currentTaskId'), this.get('currentRequestIds'));
+        this.doPolling();
+      }
+    } else {
+      this.onTaskCompleted();
+    }
+  },
+
+  doPolling: function () {
+    this.setTaskStatus(this.get('currentTaskId'), 'IN_PROGRESS');
+    var requestIds = this.get('currentRequestIds');
+    this.set('logs', []);
+    for (var i = 0; i < requestIds.length; i++) {
+      App.ajax.send({
+        name: 'admin.high_availability.polling',
+        sender: this,
+        data: {
+          requestId: requestIds[i]
+        },
+        success: 'parseLogs',
+        error: 'onTaskError'
+      });
+    }
+  },
+
+  parseLogs: function (logs) {
+    this.get('logs').pushObject(logs.tasks);
+    if (this.get('currentRequestIds').length === this.get('logs').length) {
+      var tasks = [];
+      this.get('logs').forEach(function (logs) {
+        tasks.pushObjects(logs);
+      }, this);
+      var self = this;
+      var currentTaskId = this.get('currentTaskId');
+      if (!tasks.someProperty('Tasks.status', 'PENDING') && !tasks.someProperty('Tasks.status', 'QUEUED') && !tasks.someProperty('Tasks.status', 'IN_PROGRESS')) {
+        this.set('currentRequestIds', []);
+        if (tasks.someProperty('Tasks.status', 'FAILED') || tasks.someProperty('Tasks.status', 'TIMEDOUT') || tasks.someProperty('Tasks.status', 'ABORTED')) {
+          this.setTaskStatus(currentTaskId, 'FAILED');
+        } else {
+          this.setTaskStatus(currentTaskId, 'COMPLETED');
+        }
+      } else {
+        var actionsPerHost = tasks.length;
+        var completedActions = tasks.filterProperty('Tasks.status', 'COMPLETED').length
+          + tasks.filterProperty('Tasks.status', 'FAILED').length
+          + tasks.filterProperty('Tasks.status', 'ABORTED').length
+          + tasks.filterProperty('Tasks.status', 'TIMEDOUT').length;
+        var queuedActions = tasks.filterProperty('Tasks.status', 'QUEUED').length;
+        var inProgressActions = tasks.filterProperty('Tasks.status', 'IN_PROGRESS').length;
+        var progress = Math.ceil(((queuedActions * 0.09) + (inProgressActions * 0.35) + completedActions ) / actionsPerHost * 100);
+        this.get('tasks').findProperty('id', currentTaskId).set('progress', progress);
+        window.setTimeout(function () {
+          self.doPolling()
+        }, self.POLL_INTERVAL);
+      }
+    }
+  },
+
+  showHostProgressPopup: function (event) {
+    var popupTitle = event.contexts[0].title;
+    var requestIds = event.contexts[0].requestIds;
+    var hostProgressPopupController = App.router.get('highAvailabilityProgressPopupController');
+    hostProgressPopupController.initPopup(popupTitle, requestIds, this, true);
+  },
+
+  done: function () {
+    if (!this.get('isSubmitDisabled')) {
+      this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
+      App.router.send('next');
+    }
+  },
+
+  back: function () {
+    if (!this.get('isBackButtonDisabled')) {
+      this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
+      App.router.send('back');
+    }
+  }
+
+});
+
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/mixins/wizard/wizardProgressPageView.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/wizard/wizardProgressPageView.js b/ambari-web/app/mixins/wizard/wizardProgressPageView.js
new file mode 100644
index 0000000..bbb6420
--- /dev/null
+++ b/ambari-web/app/mixins/wizard/wizardProgressPageView.js
@@ -0,0 +1,121 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+/**
+ * Mixin for wizard view for showing command progress on wizard pages
+ * This should
+ * @type {Ember.Mixin}
+ */
+App.wizardProgressPageViewMixin = Em.Mixin.create({
+
+  /**
+   * Following computed property needs to be overridden by the view implementing this mixin
+   */
+
+  currentStep: '',
+
+  /**
+   * Following computed property needs to be overridden by the view implementing this mixin
+   */
+
+  headerTitle: function () {
+
+  }.property(),
+
+  submitButtonText: Em.I18n.t('common.next'),
+
+  noticeCompleted: Em.I18n.t('wizard.progressPage.notice.completed'),
+
+  noticeFailed: Em.I18n.t('wizard.progressPage.notice.failed'),
+
+  /**
+   * @noticeInProgress: Following computed property needs to be overridden to show the label text while the commands
+   * on the page are progressing
+   */
+  noticeInProgress: function () {
+
+  }.property(),
+
+  /**
+   * @showBackButton: Override this property to show back button on the wizard progress page
+   */
+  showBackButton: false,
+
+  /**
+   * Following computed property needs to be overridden by the view implementing this mixin
+   */
+  notice: '',
+
+  noticeClass: 'alert alert-info',
+
+  onStatusChange: function () {
+    var status = this.get('controller.status');
+    if (status === 'COMPLETED') {
+      this.set('notice', this.get('noticeCompleted'));
+      this.set('noticeClass', 'alert alert-success');
+    } else if (status === 'FAILED') {
+      this.set('notice', this.get('noticeFailed'));
+      this.set('noticeClass', 'alert alert-error');
+    } else {
+      this.set('notice', this.get('noticeInProgress'));
+      this.set('noticeClass', 'alert alert-info');
+    }
+  }.observes('controller.status'),
+
+  taskView: Em.View.extend({
+    icon: '',
+    iconColor: '',
+    linkClass: '',
+
+    didInsertElement: function () {
+      this.onStatus();
+    },
+
+    barWidth: function () {
+      return 'width: ' + this.get('content.progress') + '%;';
+    }.property('content.progress'),
+
+    onStatus: function () {
+      var linkClass = !!this.get('content.requestIds.length') ? 'active-link' : 'active-text';
+      this.set('linkClass', linkClass);
+      if (this.get('content.status') === 'IN_PROGRESS') {
+        this.set('icon', 'icon-cog');
+        this.set('iconColor', 'text-info');
+      } else if (this.get('content.status') === 'FAILED') {
+        this.set('icon', 'icon-exclamation-sign');
+        this.set('iconColor', 'text-error');
+      } else if (this.get('content.status') === 'COMPLETED') {
+        this.set('icon', 'icon-ok');
+        this.set('iconColor', 'text-success');
+      } else {
+        this.set('icon', 'icon-cog');
+        this.set('iconColor', '');
+        this.set('linkClass', 'not-active-link');
+      }
+    }.observes('content.status', 'content.hosts.length'),
+
+    showProgressBar: function () {
+      return this.get('content.status') === "IN_PROGRESS";
+    }.property('content.status')
+  })
+
+});
+
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/models/stack_service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/stack_service.js b/ambari-web/app/models/stack_service.js
index d28da98..91dab9b 100644
--- a/ambari-web/app/models/stack_service.js
+++ b/ambari-web/app/models/stack_service.js
@@ -153,7 +153,7 @@ App.StackService = DS.Model.extend({
     var configTypes = this.get('configTypes');
     var serviceComponents = this.get('serviceComponents');
     if (configTypes && Object.keys(configTypes).length) {
-      var pattern = ["MetricsSink", "General", "CapacityScheduler", "FaultTolerance", "Isolation", "Performance", "^Advanced", "Env$", "^Custom", "Falcon - Oozie integration", "FalconStartupSite", "FalconRuntimeSite"];
+      var pattern = ["MetricsSink", "General", "CapacityScheduler", "FaultTolerance", "Isolation", "Performance", "KDC","^Advanced", "Env$", "^Custom", "Falcon - Oozie integration", "FalconStartupSite", "FalconRuntimeSite"];
       configCategories = App.StackService.configCategories.call(this).filter(function (_configCategory) {
         var serviceComponentName = _configCategory.get('name');
         var isServiceComponent = serviceComponents.someProperty('componentName', serviceComponentName);
@@ -335,6 +335,11 @@ App.StackService.configCategories = function () {
         App.ServiceConfigCategory.create({ name: 'KAFKA_BROKER', displayName: 'Kafka Broker'})
       ]);
       break;
+    case 'KERBEROS':
+      serviceConfigCategories.pushObjects([
+        App.ServiceConfigCategory.create({ name: 'KDC', displayName: 'KDC and Kadmin'})
+      ]);
+      break;
     case 'PIG':
       break;
     case 'SQOOP':

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/router.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/router.js b/ambari-web/app/router.js
index 50297f2..d6791f5 100644
--- a/ambari-web/app/router.js
+++ b/ambari-web/app/router.js
@@ -322,6 +322,9 @@ App.Router = Em.Router.extend({
           } else if (clusterStatusOnServer && (clusterStatusOnServer.wizardControllerName === App.router.get('addSecurityController.name') || clusterStatusOnServer.wizardControllerName === App.router.get('mainAdminSecurityDisableController.name'))) {
             // if wizardControllerName == "addSecurityController", then it means someone closed the browser or the browser was crashed when we were last in Add Security wizard
             route = 'main.admin.adminSecurity';
+          } else if (clusterStatusOnServer && (clusterStatusOnServer.wizardControllerName === App.router.get('kerberosWizardController.name'))) {
+            // if wizardControllerName == "adminKerberosController", then it means someone closed the browser or the browser was crashed when we were last in Add Kerberos wizard
+            route = 'main.admin.adminKerberos';
           } else if (clusterStatusOnServer && clusterStatusOnServer.wizardControllerName === App.router.get('addServiceController.name')) {
             // if wizardControllerName == "addHostController", then it means someone closed the browser or the browser was crashed when we were last in Add Hosts wizard
             route = 'main.serviceAdd';

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/routes/add_kerberos_routes.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/add_kerberos_routes.js b/ambari-web/app/routes/add_kerberos_routes.js
new file mode 100644
index 0000000..028e11d
--- /dev/null
+++ b/ambari-web/app/routes/add_kerberos_routes.js
@@ -0,0 +1,255 @@
+/**
+ * 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.
+ */
+var App = require('app');
+
+module.exports = App.WizardRoute.extend({
+  route: '/enable',
+  enter: function (router) {
+    Em.run.next(function () {
+      var kerberosWizardController = router.get('kerberosWizardController');
+      App.router.get('updateController').set('isWorking', false);
+      var popup = App.ModalPopup.show({
+        classNames: ['full-width-modal'],
+        header: Em.I18n.t('admin.kerberos.wizard.header'),
+        bodyClass: App.KerberosWizardView.extend({
+          controller: kerberosWizardController
+        }),
+        primary: Em.I18n.t('form.cancel'),
+        showFooter: false,
+        secondary: null,
+
+        onClose: function () {
+          var self = this;
+          var kerberosProgressPageController = App.router.get('kerberosProgressPageController');
+          var controller = App.router.get('kerberosWizardController');
+          controller.clearTasksData();
+          controller.finish();
+          App.router.get('updateController').set('isWorking', true);
+          if(App.get('testMode')){
+            App.router.transitionTo('adminKerberos.index');
+            location.reload();
+          }
+          App.clusterStatus.setClusterStatus({
+            clusterName: App.router.getClusterName(),
+            clusterState: 'DEFAULT',
+            localdb: App.db.data
+          }, {alwaysCallback: function () {
+            self.hide();
+            App.router.transitionTo('adminKerberos.index');
+          }});
+
+        },
+        didInsertElement: function () {
+          this.fitHeight();
+        }
+      });
+      kerberosWizardController.set('popup', popup);
+      var currentClusterStatus = App.clusterStatus.get('value');
+      if (currentClusterStatus) {
+        if (App.testMode) {
+          kerberosWizardController.setCurrentStep(App.db.data.KerberosWizard.currentStep);
+        } else {
+          switch (currentClusterStatus.clusterState) {
+            case 'KERBEROS_DEPLOY' :
+              kerberosWizardController.setCurrentStep(currentClusterStatus.localdb.KerberosWizard.currentStep);
+              break;
+            default:
+              var currStep = App.router.get('kerberosWizardController.currentStep');
+              kerberosWizardController.setCurrentStep(currStep);
+              break;
+          }
+        }
+
+      }
+      router.transitionTo('step' + kerberosWizardController.get('currentStep'));
+    });
+  },
+
+  step1: Em.Route.extend({
+    route: '/step1',
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('1');
+    },
+
+    connectOutlets: function (router) {
+      console.log('in addSecurity.step1:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('kerberosWizardStep1', controller.get('content'));
+      })
+    },
+
+    unroutePath: function () {
+      return false;
+    },
+
+    next: function (router) {
+      var kerberosWizardController = router.get('kerberosWizardController');
+      var kerberosStep1controller = router.get('kerberosWizardStep1Controller');
+      kerberosWizardController.saveKerberosOption(kerberosStep1controller);
+      kerberosWizardController.setDBProperty('serviceConfigProperties', null);
+      kerberosWizardController.setDBProperty('advancedServiceConfig', null);
+      router.transitionTo('step2');
+    }
+  }),
+
+  step2: Em.Route.extend({
+    route: '/step2',
+
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('2');
+    },
+    connectOutlets: function (router) {
+      console.log('in kerberosWizardController.step2:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        var kerberosWizardStep2Controller = router.get('kerberosWizardStep2Controller');
+        kerberosWizardStep2Controller.set('wizardController', controller);
+        controller.connectOutlet('kerberosWizardStep2', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    back: Em.Router.transitionTo('step1'),
+    next: function (router) {
+      var kerberosWizardController = router.get('kerberosWizardController');
+      var kerberosWizardStep2Controller = router.get('kerberosWizardStep2Controller');
+      kerberosWizardController.saveServiceConfigProperties(kerberosWizardStep2Controller);
+      kerberosWizardController.clearTasksData();
+      router.transitionTo('step3');
+    }
+  }),
+  step3: Em.Route.extend({
+    route: '/step3',
+
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('3');
+    },
+    connectOutlets: function (router) {
+      console.log('in kerberosWizardController.step3:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('kerberosWizardStep3', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    back: Em.Router.transitionTo('step2'),
+    next: function (router) {
+      // load kerberos descriptor for all services
+      router.transitionTo('step4');
+    }
+  }),
+
+  step4: Em.Route.extend({
+    route: '/step4',
+
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('4');
+    },
+    connectOutlets: function (router) {
+      console.log('in kerberosWizardController.step4:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('kerberosWizardStep4', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    back: Em.Router.transitionTo('step3'),
+    next: function (router) {
+      router.transitionTo('step5');
+    }
+  }),
+
+  step5: Em.Route.extend({
+    route: '/step5',
+
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('5');
+    },
+    connectOutlets: function (router) {
+      console.log('in kerberosWizardController.step5:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('kerberosWizardStep5', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    back: Em.Router.transitionTo('step4'),
+    next: function (router) {
+      router.transitionTo('step6');
+    }
+  }),
+
+  step6: Em.Route.extend({
+    route: '/step6',
+
+    enter: function (router) {
+      router.get('kerberosWizardController').setCurrentStep('6');
+    },
+    connectOutlets: function (router) {
+      console.log('in kerberosWizardController.step6:connectOutlets');
+      var controller = router.get('kerberosWizardController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('kerberosWizardStep5', controller.get('content'));
+      })
+    },
+    unroutePath: function () {
+      return false;
+    },
+    next: function (router) {
+      var controller = router.get('kerberosWizardController');
+      controller.finish();
+      App.clusterStatus.setClusterStatus({
+        clusterName: App.router.getClusterName(),
+        clusterState: 'DEFAULT',
+        localdb: App.db.data
+      }, {alwaysCallback: function () {
+        self.hide();
+        App.router.transitionTo('adminKerberos.index');
+      }});
+
+    }
+  }),
+
+
+  gotoStep1: Em.Router.transitionTo('step1'),
+
+  gotoStep2: Em.Router.transitionTo('step2'),
+
+  gotoStep3: Em.Router.transitionTo('step3'),
+
+  gotoStep4: Em.Router.transitionTo('step4'),
+
+  gotoStep5: Em.Router.transitionTo('step5'),
+
+  gotoStep6: Em.Router.transitionTo('step6')
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/routes/main.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js
index 86c01eb..37c9fea 100644
--- a/ambari-web/app/routes/main.js
+++ b/ambari-web/app/routes/main.js
@@ -408,7 +408,7 @@ module.exports = Em.Route.extend({
         }
       },
 
-      index: Ember.Route.extend({
+      index: Em.Route.extend({
         route: '/',
         connectOutlets: function (router, context) {
           var controller = router.get('mainAdminController');
@@ -499,6 +499,18 @@ module.exports = Em.Route.extend({
       adminAddSecurity: require('routes/add_security')
     }),
 
+    adminKerberos: Em.Route.extend({
+      route: '/kerberos',
+      index: Em.Route.extend({
+        route: '/',
+        connectOutlets: function (router, context) {
+          router.set('mainAdminController.category', "kerberos");
+          router.get('mainAdminController').connectOutlet('mainAdminKerberos');
+        }
+      }),
+      adminAddKerberos:  require('routes/add_kerberos_routes')
+    }),
+
     stackAndUpgrade: Em.Route.extend({
       route: '/stack',
       connectOutlets: function (router) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/templates/main/admin/highAvailability/progress.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/highAvailability/progress.hbs b/ambari-web/app/templates/main/admin/highAvailability/progress.hbs
index b80650d..f543554 100644
--- a/ambari-web/app/templates/main/admin/highAvailability/progress.hbs
+++ b/ambari-web/app/templates/main/admin/highAvailability/progress.hbs
@@ -22,7 +22,7 @@
   {{#each task in controller.tasks}}
   {{#view view.taskView contentBinding="task"}}
     <div class="item">
-      <div {{bindAttr class=":pull-left view.linkClass controller.isHA:span4 controller.isRMHA:span5 controller.isRollback:span3 controller.isReassign:span5"}}>
+      <div {{bindAttr class=":pull-left view.linkClass isKerberosWizard:span4 controller.isHA:span4 controller.isRMHA:span5 controller.isRollback:span3 controller.isReassign:span5"}}>
         <i {{bindAttr class="view.icon view.iconColor"}}></i>
         <a {{action "showHostProgressPopup" task target="controller"}} >{{task.title}}</a>
       </div>
@@ -58,6 +58,9 @@
   {{/view}}
   {{/each}}
   <div class="btn-area">
+    {{#if view.showBackButton}}
+       <button class="btn pull-left" {{bindAttr disabled="controller.isBackButtonDisabled"}} {{action back target="controller"}}>&larr; {{t common.back}}</button>
+    {{/if}}
     <button class="btn btn-success pull-right" {{bindAttr disabled="controller.isSubmitDisabled"}} {{action done target="controller"}}>{{view.submitButtonText}}</button>
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/templates/main/admin/kerberos.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos.hbs b/ambari-web/app/templates/main/admin/kerberos.hbs
new file mode 100644
index 0000000..b2d90a2
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/kerberos.hbs
@@ -0,0 +1,36 @@
+{{!
+* 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.
+}}
+{{#if dataIsLoaded}}
+  {{#if securityEnabled}}
+    <div>
+      <p class="text-success">{{t admin.security.enabled}}
+        <a class="btn btn-padding btn-warning" {{bindAttr disabled="isSubmitDisabled"}} {{action notifySecurityOffPopup target="controller"}}>{{t admin.security.button.disable}} </a>
+        <br/>
+      </p>
+    </div>
+  {{else}}
+    <div>
+      <p class="muted">{{t admin.security.disabled}}
+        <a class="btn btn-padding btn-success" {{action startKerberosWizard target="controller"}}>{{t admin.kerberos.button.enable}} </a>
+        <br/>
+      </p>
+    </div>
+  {{/if}}
+{{else}}
+  <div class="spinner"></div>
+{{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/templates/main/admin/kerberos/step1.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step1.hbs b/ambari-web/app/templates/main/admin/kerberos/step1.hbs
new file mode 100644
index 0000000..9f04342
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/kerberos/step1.hbs
@@ -0,0 +1,47 @@
+{{!
+* 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.
+}}
+
+<h2>{{t admin.kerberos.wizard.step1.header}}</h2>
+<p class="alert alert-info">
+  {{t admin.kerberos.wizard.step1.info.body}}
+</p>
+<div class="alert">
+  {{t admin.kerberos.wizard.step1.alert.body}}
+</div>
+
+<div class="step1-options-body">
+  {{t admin.kerberos.wizard.step1.body.text}}
+  {{#each option in options}}
+    <label>
+      {{view Ember.RadioButton name="option.displayName" selectionBinding="selectedItem" valueBinding="option.value"}}  {{option.displayName}}
+    </label>
+  {{/each}}
+  <br/>
+</div>
+<div class="alert alert-info step1-prerequisites-body">
+  <h5>{{selectedOption.displayName}}:</h5>
+  <b>{{t admin.kerberos.wizard.step1.prerequisites.label}}</b> <br/> <br/>
+  {{#each condition in selectedOption.preConditions}}
+    <label class="checkbox"> {{view Ember.Checkbox  checkedBinding="condition.checked"}} {{condition.displayText}} </label>
+  {{/each}}
+</div>
+
+
+<div class="btn-area">
+  <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action "next" target="controller"}}>{{t common.next}} &rarr;</a>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/templates/main/admin/kerberos/step2.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step2.hbs b/ambari-web/app/templates/main/admin/kerberos/step2.hbs
new file mode 100644
index 0000000..2fdf55b
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/kerberos/step2.hbs
@@ -0,0 +1,35 @@
+{{!
+* 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.
+}}
+
+<div id="serviceConfig">
+  <h2>{{t admin.kerberos.wizard.step2.header}}</h2>
+  <div class="alert alert-info">
+    {{t admin.kerberos.wizard.step2.info.body}}
+  </div>
+  {{#if isConfigsLoaded}}
+    {{view App.ServicesConfigView}}
+  {{else}}
+    <div class="spinner"></div>
+  {{/if}}
+
+  <div class="btn-area">
+    <a class="btn" {{action back}}>&larr; {{t common.back}}</a>
+    <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
+      {{action submit target="controller"}}>{{t common.next}} &rarr;</a>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/templates/main/admin/kerberos/step3.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step3.hbs b/ambari-web/app/templates/main/admin/kerberos/step3.hbs
new file mode 100644
index 0000000..defea53
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/kerberos/step3.hbs
@@ -0,0 +1,18 @@
+{{!
+* 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.
+}}
+{{template "templates/main/admin/highAvailability/progress"}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/templates/main/admin/kerberos/step4.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step4.hbs b/ambari-web/app/templates/main/admin/kerberos/step4.hbs
new file mode 100644
index 0000000..bbf50d3
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/kerberos/step4.hbs
@@ -0,0 +1,21 @@
+{{!
+* 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.
+}}
+<h2>{{t admin.kerberos.wizard.step4.header}}</h2>
+<p class="alert alert-info">
+  {{t admin.kerberos.wizard.step4.info.body}}
+</p>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/templates/main/admin/kerberos/step5.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step5.hbs b/ambari-web/app/templates/main/admin/kerberos/step5.hbs
new file mode 100644
index 0000000..eadc752
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/kerberos/step5.hbs
@@ -0,0 +1,18 @@
+{{!
+* 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.
+}}
+<h2>{{t admin.kerberos.wizard.step5.header}}</h2>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/templates/main/admin/kerberos/step6.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/step6.hbs b/ambari-web/app/templates/main/admin/kerberos/step6.hbs
new file mode 100644
index 0000000..defea53
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/kerberos/step6.hbs
@@ -0,0 +1,18 @@
+{{!
+* 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.
+}}
+{{template "templates/main/admin/highAvailability/progress"}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/templates/main/admin/kerberos/wizard.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos/wizard.hbs b/ambari-web/app/templates/main/admin/kerberos/wizard.hbs
new file mode 100644
index 0000000..e842565
--- /dev/null
+++ b/ambari-web/app/templates/main/admin/kerberos/wizard.hbs
@@ -0,0 +1,47 @@
+{{!
+* 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.
+}}
+
+<div class="wizard">
+  <div class="container">
+    <div class="container-fluid">
+      <div class="row-fluid">
+        <div class="span3">
+          <!--Sidebar content-->
+          <div class="well">
+            <ul class="nav nav-pills nav-stacked">
+              <li class="nav-header"> <i class="icon-lock"></i>&nbsp;{{t admin.kerberos.wizard.header}}</li>
+              <li {{bindAttr class="isStep1:active view.isStep1Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep1 target="controller"}}>{{t admin.kerberos.wizard.step1.header}}</a></li>
+              <li {{bindAttr class="isStep2:active view.isStep2Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep2 target="controller"}}>{{t admin.kerberos.wizard.step2.header}}</a></li>
+              <li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep3 target="controller"}}>{{t admin.kerberos.wizard.step3.header}}</a></li>
+              <li {{bindAttr class="isStep4:active view.isStep4Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep4 target="controller"}}>{{t admin.kerberos.wizard.step4.header}}</a></li>
+              <li {{bindAttr class="isStep5:active view.isStep5Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep5 target="controller"}}>{{t admin.kerberos.wizard.step5.header}}</a></li>
+              <li {{bindAttr class="isStep6:active view.isStep6Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep6 target="controller"}}>{{t admin.kerberos.wizard.step6.header}}</a></li>
+            </ul>
+          </div>
+        </div>
+        <div class="wizard-content well span9">
+          {{#if view.isLoaded}}
+            {{outlet}}
+          {{else}}
+            <div class="spinner"></div>
+          {{/if}}
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 773746e..2454216 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -121,7 +121,7 @@ var urls = {
 
   'common.host.host_component.update': {
     'real': '/clusters/{clusterName}/hosts/{hostName}/host_components/{componentName}?{urlParams}',
-    'mock': '/data/wizard/deploy/poll_1.json',
+    'mock': '/data/wizard/deploy/2_hosts/poll_9.json',
     'type': 'PUT',
     'format': function (data) {
       return {
@@ -159,11 +159,11 @@ var urls = {
   },
 
   'common.across.services.configurations': {
+    'type': 'PUT',
     'real':'/clusters/{clusterName}',
-    'mock':'',
+    'mock':'/data/services/ambari.json',
     'format': function(data) {
       return {
-        type: 'PUT',
         dataType: 'text',
         data: data.data
       }
@@ -290,6 +290,11 @@ var urls = {
     'real': '/clusters/{name}',
     'type': 'DELETE'
   },
+  'common.delete.service': {
+    'real': '/clusters/{clusterName}/services/{serviceName}',
+    'mock': '/data/services/ambari.json',
+    'type': 'DELETE'
+  },
   'common.delete.request_schedule': {
     'real': '/clusters/{clusterName}/request_schedules/{request_schedule_id}',
     'type': 'DELETE'
@@ -1145,6 +1150,24 @@ var urls = {
       }
     }
   },
+  'common.create_component': {
+    'real': '/clusters/{clusterName}/services?ServiceInfo/service_name={serviceName}',
+    'mock': '',
+    'type': 'POST',
+    'format': function(data) {
+      return {
+        data: JSON.stringify({
+          "components": [
+            {
+              "ServiceComponentInfo": {
+                "component_name": data.componentName
+              }
+            }
+          ]
+        })
+      }
+    }
+  },
   'admin.high_availability.create_zkfc': {
     'real': '/clusters/{clusterName}/services?ServiceInfo/service_name=HDFS',
     'mock': '',
@@ -1321,11 +1344,11 @@ var urls = {
   },
 
   'wizard.step8.create_selected_services': {
+    'type': 'POST',
     'real':'/clusters/{cluster}/services',
-    'mock':'',
+    'mock':'/data/stacks/HDP-2.1/recommendations.json',
     'format': function(data) {
       return {
-        type: 'POST',
         dataType: 'text',
         data: data.data
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index 01ac3b9..838d2cc 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -72,20 +72,24 @@ App.config = Em.Object.create({
     return fileName.endsWith('.xml') ? fileName.slice(0, -4) : fileName;
   },
 
-  setPreDefinedServiceConfigs: function () {
+  setPreDefinedServiceConfigs: function (isMiscTabToBeAdded) {
     var configs = this.get('preDefinedSiteProperties');
     var services = [];
-    var nonServiceTab = require('data/service_configs');
     var stackServices = App.StackService.find().filterProperty('id');
     // Only include services that has configTypes related to them for service configuration page
-    // Also Remove HCatalog from this list. HCatalog has hive-site affiliated to it but none of the properties of it should be exposed under HCatalog Service
-    // HCatalog should be eventually made a part of Hive Service. See AMBARI-6302 description for further details
     var servicesWithConfigTypes = stackServices.filter(function (service) {
       var configtypes = service.get('configTypes');
       return configtypes && !!Object.keys(configtypes).length;
     }, this);
 
-    var allTabs = servicesWithConfigTypes.concat(nonServiceTab);
+    var allTabs;
+    if (isMiscTabToBeAdded) {
+      var nonServiceTab = require('data/service_configs');
+      allTabs = servicesWithConfigTypes.concat(nonServiceTab);
+    } else {
+      allTabs = servicesWithConfigTypes;
+    }
+
     allTabs.forEach(function (service) {
       var serviceConfigs = configs.filterProperty('serviceName', service.get('serviceName'));
       service.set('configs', serviceConfigs);

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/utils/db.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/db.js b/ambari-web/app/utils/db.js
index 1530718..707dc42 100644
--- a/ambari-web/app/utils/db.js
+++ b/ambari-web/app/utils/db.js
@@ -34,6 +34,7 @@ var InitialData =  {
   'Installer' : {},
   'AddHost' : {},
   'AddService' : {},
+  'KerberosWizard': {},
   'StackUpgrade' : {},
   'ReassignMaster' : {},
   'AddSecurity': {},
@@ -526,6 +527,12 @@ App.db.setReassignMasterWizardReassignHosts = function (reassignHosts) {
   localStorage.setObject('ambari', App.db.data);
 };
 
+App.db.setKerberosWizardConfigTag = function (tag) {
+  App.db.data = localStorage.getObject('ambari');
+  App.db.data.KerberosWizard[tag.name] = tag.value;
+  localStorage.setObject('ambari', App.db.data);
+};
+
 /*
  *  getter methods
  */
@@ -842,4 +849,9 @@ App.db.getReassignMasterWizardReassignHosts = function () {
   return App.db.data.ReassignMaster.reassignHosts;
 };
 
+App.db.getKerberosWizardConfigTag = function (tag) {
+  App.db.data = localStorage.getObject('ambari');
+  return App.db.data.KerberosWizard[tag];
+};
+
 module.exports = App.db;

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/utils/ember_reopen.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ember_reopen.js b/ambari-web/app/utils/ember_reopen.js
index d6a535f..8acebe5 100644
--- a/ambari-web/app/utils/ember_reopen.js
+++ b/ambari-web/app/utils/ember_reopen.js
@@ -114,6 +114,23 @@ Ember.isBlank = function(obj) {
   return Ember.isEmpty(obj) || (typeof obj === 'string' && obj.match(/\S/) === null);
 };
 
+/**
+ *
+ */
+Ember.RadioButton = Ember.Checkbox.extend({
+  tagName : "input",
+  type : "radio",
+  attributeBindings : [ "type", "name", "value", "checked", "style" ],
+  style: "vertical-align: middle; margin: 0px;" ,
+  click : function() {
+    this.set("selection", this.$().val())
+  },
+  checked : function() {
+    return this.get("value") == this.get("selection");
+  }.property('value','selection')
+});
+
+
 Em.View.reopen({
   /**
    * overwritten set method of Ember.View to avoid uncaught errors
@@ -126,4 +143,4 @@ Em.View.reopen({
       console.debug('Calling set on destroyed view');
     }
   }
-});
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 586064f..d31c5b9 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -107,6 +107,17 @@ require('views/main/admin/advanced');
 require('views/main/admin/advanced/password');
 require('views/main/admin/audit');
 require('views/main/admin/authentication');
+
+require('views/main/admin/kerberos');
+require('views/main/admin/kerberos/wizard_view');
+require('views/main/admin/kerberos/progress_view');
+require('views/main/admin/kerberos/step1_view');
+require('views/main/admin/kerberos/step2_view');
+require('views/main/admin/kerberos/step3_view');
+require('views/main/admin/kerberos/step4_view');
+require('views/main/admin/kerberos/step5_view');
+require('views/main/admin/kerberos/step6_view');
+
 require('views/main/admin/security');
 require('views/main/admin/security/disable');
 require('views/main/admin/security/add/menu');

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/views/main/admin.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin.js b/ambari-web/app/views/main/admin.js
index 41d6cbf..949d74c 100644
--- a/ambari-web/app/views/main/admin.js
+++ b/ambari-web/app/views/main/admin.js
@@ -41,11 +41,19 @@ App.MainAdminView = Em.View.extend({
       label: Em.I18n.t('common.serviceAccounts')
     });
     if (!App.get('isHadoopWindowsStack')) {
-      items.push({
-        name: 'security',
-        url: 'adminSecurity.index',
-        label: Em.I18n.t('common.security')
-      });
+      if (App.get('supports.automatedKerberos')) {
+        items.push({
+          name: 'kerberos',
+          url: 'adminKerberos.index',
+          label: Em.I18n.t('common.kerberos')
+        });
+      } else {
+        items.push({
+          name: 'security',
+          url: 'adminSecurity.index',
+          label: Em.I18n.t('common.security')
+        });
+      }
     }
     return items;
   }.property(''),

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/views/main/admin/highAvailability/progress_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/highAvailability/progress_view.js b/ambari-web/app/views/main/admin/highAvailability/progress_view.js
index eaf8dda..45cb00f 100644
--- a/ambari-web/app/views/main/admin/highAvailability/progress_view.js
+++ b/ambari-web/app/views/main/admin/highAvailability/progress_view.js
@@ -19,7 +19,7 @@
 
 var App = require('app');
 
-App.HighAvailabilityProgressPageView = Em.View.extend({
+App.HighAvailabilityProgressPageView = Em.View.extend(App.wizardProgressPageViewMixin, {
 
   didInsertElement: function () {
     this.get('controller').loadStep();
@@ -34,12 +34,6 @@ App.HighAvailabilityProgressPageView = Em.View.extend({
     }
   }.property(),
 
-  submitButtonText: Em.I18n.t('common.next'),
-
-  noticeCompleted: Em.I18n.t('admin.highAvailability.wizard.progressPage.notice.completed'),
-
-  noticeFailed: Em.I18n.t('admin.highAvailability.wizard.progressPage.notice.failed'),
-
   noticeInProgress: function () {
     var currentStep = App.router.get('highAvailabilityWizardController.currentStep');
     if (currentStep == 1) {
@@ -49,58 +43,5 @@ App.HighAvailabilityProgressPageView = Em.View.extend({
     }
   }.property(),
 
-  notice: Em.I18n.t('admin.highAvailability.wizard.progressPage.notice.inProgress'),
-
-  noticeClass: 'alert alert-info',
-
-  onStatusChange: function () {
-    var status = this.get('controller.status');
-    if (status === 'COMPLETED') {
-      this.set('notice', this.get('noticeCompleted'));
-      this.set('noticeClass', 'alert alert-success');
-    } else if (status === 'FAILED') {
-      this.set('notice', this.get('noticeFailed'));
-      this.set('noticeClass', 'alert alert-error');
-    } else {
-      this.set('notice', this.get('noticeInProgress'));
-      this.set('noticeClass', 'alert alert-info');
-    }
-  }.observes('controller.status'),
-
-  taskView: Em.View.extend({
-    icon: '',
-    iconColor: '',
-    linkClass: '',
-
-    didInsertElement: function () {
-      this.onStatus();
-    },
-
-    barWidth: function () {
-      return 'width: ' + this.get('content.progress') + '%;';
-    }.property('content.progress'),
-
-    onStatus: function () {
-      var linkClass = !!this.get('content.requestIds.length') ? 'active-link' : 'active-text';
-      this.set('linkClass', linkClass);
-      if (this.get('content.status') === 'IN_PROGRESS') {
-        this.set('icon', 'icon-cog');
-        this.set('iconColor', 'text-info');
-      } else if (this.get('content.status') === 'FAILED') {
-        this.set('icon', 'icon-exclamation-sign');
-        this.set('iconColor', 'text-error');
-      } else if (this.get('content.status') === 'COMPLETED') {
-        this.set('icon', 'icon-ok');
-        this.set('iconColor', 'text-success');
-      } else {
-        this.set('icon', 'icon-cog');
-        this.set('iconColor', '');
-        this.set('linkClass', 'not-active-link');
-      }
-    }.observes('content.status', 'content.hosts.length'),
-
-    showProgressBar: function () {
-      return this.get('content.status') === "IN_PROGRESS";
-    }.property('content.status')
-  })
+  notice: Em.I18n.t('admin.highAvailability.wizard.progressPage.notice.inProgress')
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/views/main/admin/kerberos.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/kerberos.js b/ambari-web/app/views/main/admin/kerberos.js
new file mode 100644
index 0000000..87639d3
--- /dev/null
+++ b/ambari-web/app/views/main/admin/kerberos.js
@@ -0,0 +1,28 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+
+App.MainAdminKerberosView = Em.View.extend({
+  templateName: require('templates/main/admin/kerberos'),
+  didInsertElement: function() {
+    var controller = this.get('controller');
+    controller.set('dataIsLoaded',false);
+    controller.loadSecurityStatusFromServer();
+  }
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/dd87511e/ambari-web/app/views/main/admin/kerberos/progress_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/kerberos/progress_view.js b/ambari-web/app/views/main/admin/kerberos/progress_view.js
new file mode 100644
index 0000000..b2251de
--- /dev/null
+++ b/ambari-web/app/views/main/admin/kerberos/progress_view.js
@@ -0,0 +1,39 @@
+/**
+ * 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.
+ */
+
+
+var App = require('app');
+
+App.KerberosProgressPageView = Em.View.extend(App.wizardProgressPageViewMixin, {
+
+  didInsertElement: function () {
+    this.get('controller').loadStep();
+  },
+
+  headerTitle: function () {
+    var currentStep = App.router.get('kerberosWizardController.currentStep');
+    return  Em.I18n.t('admin.kerberos.wizard.step' + currentStep + '.header');
+  }.property(),
+
+  noticeInProgress: function () {
+    var currentStep = App.router.get('kerberosWizardController.currentStep');
+    return  Em.I18n.t('admin.kerberos.wizard.step' + currentStep + '.notice.inProgress');
+  }.property(),
+
+  notice: Em.I18n.t('admin.kerberos.wizard.progressPage.notice.inProgress')
+});