Browse Source

AMBARI-1490: Implement initial layout for "Add security" wizard. (jaimin)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1449945 13f79535-47bb-0310-9956-ffa450edef68
Jaimin Jetly 12 years ago
parent
commit
b0067a4aa5
40 changed files with 3518 additions and 374 deletions
  1. 2 0
      CHANGES.txt
  2. 1 1
      ambari-web/app/assets/data/wizard/deploy/5_hosts/poll_5.json
  3. 8 1
      ambari-web/app/controllers.js
  4. 80 3
      ambari-web/app/controllers/main/admin.js
  5. 71 0
      ambari-web/app/controllers/main/admin/security.js
  6. 146 0
      ambari-web/app/controllers/main/admin/security/add/addSecurity_controller.js
  7. 23 0
      ambari-web/app/controllers/main/admin/security/add/step1.js
  8. 126 0
      ambari-web/app/controllers/main/admin/security/add/step2.js
  9. 502 0
      ambari-web/app/controllers/main/admin/security/add/step3.js
  10. 351 0
      ambari-web/app/controllers/main/admin/security/disable.js
  11. 3 2
      ambari-web/app/controllers/wizard/step8_controller.js
  12. 120 0
      ambari-web/app/data/secure_configs.js
  13. 225 0
      ambari-web/app/data/secure_mapping.js
  14. 390 0
      ambari-web/app/data/secure_properties.js
  15. 27 3
      ambari-web/app/messages.js
  16. 1 1
      ambari-web/app/models/host_component.js
  17. 129 0
      ambari-web/app/routes/add_security.js
  18. 239 138
      ambari-web/app/routes/main.js
  19. 294 203
      ambari-web/app/styles/application.less
  20. 1 1
      ambari-web/app/templates/application.hbs
  21. 11 1
      ambari-web/app/templates/main/admin.hbs
  22. 40 0
      ambari-web/app/templates/main/admin/security.hbs
  23. 41 0
      ambari-web/app/templates/main/admin/security/add/menu.hbs
  24. 34 0
      ambari-web/app/templates/main/admin/security/add/step1.hbs
  25. 15 0
      ambari-web/app/templates/main/admin/security/add/step2.hbs
  26. 30 0
      ambari-web/app/templates/main/admin/security/add/step3.hbs
  27. 47 0
      ambari-web/app/templates/main/service/reconfigure.hbs
  28. 36 4
      ambari-web/app/utils/db.js
  29. 214 0
      ambari-web/app/utils/polling.js
  30. 7 0
      ambari-web/app/views.js
  31. 2 0
      ambari-web/app/views/common/modal_popup.js
  32. 11 2
      ambari-web/app/views/main/admin.js
  33. 32 14
      ambari-web/app/views/main/admin/menu.js
  34. 24 0
      ambari-web/app/views/main/admin/security.js
  35. 39 0
      ambari-web/app/views/main/admin/security/add/menu.js
  36. 28 0
      ambari-web/app/views/main/admin/security/add/step1.js
  37. 25 0
      ambari-web/app/views/main/admin/security/add/step2.js
  38. 57 0
      ambari-web/app/views/main/admin/security/add/step3.js
  39. 28 0
      ambari-web/app/views/main/admin/security/disable.js
  40. 58 0
      ambari-web/app/views/main/service/reconfigure.js

+ 2 - 0
CHANGES.txt

@@ -12,6 +12,8 @@ Trunk (unreleased changes):
 
  NEW FEATURES
 
+ AMBARI-1490. Implement initial layout for "Add security" wizard. (jaimin)
+
  AMBARI-1483. Reassign Master Wizard - Step 2. (yusaku)
 
  AMBARI-1482. Reassign Master Wizard - Step 1. (yusaku)

+ 1 - 1
ambari-web/app/assets/data/wizard/deploy/5_hosts/poll_5.json

@@ -388,7 +388,7 @@
       "Tasks" : {
         "exit_code" : 999,
         "stdout" : "",
-        "status" : "QUEUED",
+        "status" : "COMPLETED",
         "stderr" : "",
         "host_name" : "host5",
         "id" : 11,

+ 8 - 1
ambari-web/app/controllers.js

@@ -32,6 +32,13 @@ require('controllers/main/admin/user');
 require('controllers/main/admin/user/edit');
 require('controllers/main/admin/user/create');
 require('controllers/main/admin/advanced');
+require('utils/polling');
+require('controllers/main/admin/security');
+require('controllers/main/admin/security/disable');
+require('controllers/main/admin/security/add/addSecurity_controller');
+require('controllers/main/admin/security/add/step1');
+require('controllers/main/admin/security/add/step2');
+require('controllers/main/admin/security/add/step3');
 require('controllers/main/admin/authentication');
 require('controllers/main/service');
 require('controllers/main/service/item');
@@ -76,4 +83,4 @@ require('controllers/wizard/step11_controller');
 require('controllers/wizard/stack_upgrade/step1_controller');
 require('controllers/wizard/stack_upgrade/step2_controller');
 require('controllers/global/cluster_controller');
-require('controllers/global/update_controller');
+require('controllers/global/update_controller');

+ 80 - 3
ambari-web/app/controllers/main/admin.js

@@ -19,6 +19,83 @@
 var App = require('app');
 
 App.MainAdminController = Em.Controller.extend({
-  name:'mainAdminController',
-  category:'user'
-})
+  name: 'mainAdminController',
+  category: 'user',
+  securityEnabled: false,
+
+  /**
+   * return true if security status is loaded and false otherwise
+   */
+  securityStatusLoading: function () {
+    var dfd = $.Deferred();
+    this.connectOutlet('loading');
+    if (App.testMode) {
+      window.setTimeout(function () {
+        dfd.resolve();
+      }, 50);
+    } else {
+      this.getHDFSDetailsFromServer(dfd);
+    }
+    return dfd.promise();
+  },
+
+  /**
+   * return true if security status is loaded and false otherwise
+   */
+  getHDFSDetailsFromServer: function (dfd) { //TODO: this should be obtain from cluster level config rather than HDFS global config
+    var self = this;
+    var url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/services/HDFS';
+    $.ajax({
+      type: 'GET',
+      url: url,
+      timeout: 10000,
+      dataType: 'text',
+      success: function (data) {
+        console.log("TRACE: The url is: " + url);
+        var jsonData = jQuery.parseJSON(data);
+        var configs = jsonData.ServiceInfo.desired_configs;
+        if ('global' in configs) {
+          self.getServiceConfigsFromServer(dfd, 'global', configs['global']);
+        } else {
+          dfd.reject();
+        }
+      },
+
+      error: function (request, ajaxOptions, error) {
+        dfd.reject();
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+  },
+
+  getServiceConfigsFromServer: function (dfd, siteName, tagName) {
+    var self = this;
+    var url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/configurations/?type=' + siteName + '&tag=' + tagName;
+    $.ajax({
+      type: 'GET',
+      url: url,
+      async: true,
+      timeout: 10000,
+      dataType: 'json',
+      success: function (data) {
+        console.log("TRACE: In success function for the GET getServiceConfigsFromServer call");
+        console.log("TRACE: The url is: " + url);
+        var configs = data.items.findProperty('tag', tagName).properties;
+        if (configs && configs['security_enabled'] === 'true') {
+          self.set('securityEnabled', true);
+        } else {
+          self.set('securityEnabled', false);
+        }
+        dfd.resolve();
+      },
+
+      error: function (request, ajaxOptions, error) {
+        dfd.reject();
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+  }
+
+});

+ 71 - 0
ambari-web/app/controllers/main/admin/security.js

@@ -0,0 +1,71 @@
+/**
+ * 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.MainAdminSecurityController = Em.Controller.extend({
+  name: 'mainAdminSecurityController',
+  securityEnabledBinding: 'App.router.mainAdminController.securityEnabled',
+  isSubmitDisabled: false,
+  getAddSecurityWizardStatus: function () {
+    return App.db.getSecurityWizardStatus();
+  },
+  setAddSecurityWizardStatus: function (status) {
+    App.db.setSecurityWizardStatus(status);
+  },
+  notifySecurityOff: false,
+  notifySecurityAdd: false,
+
+  notifySecurityOffPopup: function () {
+    var self = this;
+    if (!this.get('isSubmitDisabled')) {
+      App.ModalPopup.show({
+        header: Em.I18n.t('admin.security.disable.popup.header'),
+        primary: 'OK',
+        secondary: null,
+        onPrimary: function () {
+          App.router.transitionTo('disableSecurity');
+          self.set('isSubmitDisabled', true);
+          this.hide();
+        },
+        bodyClass: Ember.View.extend({
+          template: Ember.Handlebars.compile('<h5>{{t admin.security.disable.popup.body}}</h5>')
+        })
+      });
+    }
+  },
+
+  notifySecurityAddPopup: function () {
+    var self = this;
+
+    App.ModalPopup.show({
+      header: Em.I18n.t('admin.security.enable.popup.header'),
+      primary: 'OK',
+      secondary: null,
+      onPrimary: function () {
+        App.router.send('addSecurity');
+        this.hide();
+      },
+      bodyClass: Ember.View.extend({
+        template: Ember.Handlebars.compile('<h5>{{t admin.security.enable.popup.body}}</h5>')
+      })
+    });
+  }
+
+});
+
+

+ 146 - 0
ambari-web/app/controllers/main/admin/security/add/addSecurity_controller.js

@@ -0,0 +1,146 @@
+/**
+ * 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.AddSecurityController = App.WizardController.extend({
+
+  name: 'addSecurityController',
+  securityEnabled: false,
+
+  totalSteps: 3,
+
+  content: Em.Object.create({
+    services: [],
+    serviceConfigProperties: null,
+    controllerName: 'addSecurityController',
+
+    saveCurrentStage: function(stage) {
+      App.db.setSecurityStage(stage);
+    },
+
+    loadCurrentStage: function() {
+      return App.db.getSecurityStage();
+    }
+  }),
+
+  /**
+   * Loads all prior steps on refresh
+   */
+  loadAllPriorSteps: function () {
+    var step = this.get('currentStep');
+    switch (step) {
+      case '3':
+        this.loadStages();
+      case '2':
+        this.loadServiceConfigs();
+      case '1':
+        this.loadServices();
+    }
+  },
+
+  clearServices: function () {
+    if (this.get('content.services')) {
+      this.get('content.services').clear();
+    }
+  },
+
+  /**
+   * loads the status of stages of step3 from localDb
+   */
+
+  loadStages: function() {
+
+  },
+
+  /**
+   * return true if cluster data is loaded and false otherwise
+   */
+  dataLoading: function () {
+    var dfd = $.Deferred();
+    this.connectOutlet('loading');
+    var interval = setInterval(function () {
+      if (App.router.get('clusterController.isLoaded')) {
+        dfd.resolve();
+        clearInterval(interval);
+      }
+    }, 50);
+    return dfd.promise();
+  },
+
+
+
+
+  /**
+   * Loads all installed services
+   */
+  loadServices: function () {
+    this.clearServices();
+    var secureServices = require('data/secure_configs');
+    var installedServices = App.Service.find().mapProperty('serviceName');
+    //General (only non service tab) tab is always displayed
+    this.get('content.services').push(secureServices.findProperty('serviceName', 'GENERAL'));
+    installedServices.forEach(function (_service) {
+      var secureService = secureServices.findProperty('serviceName', _service);
+      if (secureService) {
+        this.get('content.services').push(secureService);
+      }
+    }, this);
+
+  },
+
+  /**
+   * Loads all service config properties
+   */
+
+  loadServiceConfigs: function () {
+    var serviceConfigProperties = App.db.getServiceConfigProperties();
+    this.set('content.serviceConfigProperties', serviceConfigProperties);
+  },
+
+  /**
+   * Save config properties
+   * @param stepController Step2AddSecurityController
+   */
+  saveServiceConfigProperties: function (stepController) {
+    var serviceConfigProperties = [];
+    stepController.get('stepConfigs').forEach(function (_content) {
+      _content.get('configs').forEach(function (_configProperties) {
+        var displayType = _configProperties.get('displayType');
+        if (displayType === 'directories' || displayType === 'directory') {
+          var value = _configProperties.get('value').trim().split(/\s+/g).join(',');
+          _configProperties.set('value', value);
+        }
+        var configProperty = {
+          id: _configProperties.get('id'),
+          name: _configProperties.get('name'),
+          value: _configProperties.get('value'),
+          defaultValue: _configProperties.get('defaultValue'),
+          service: _configProperties.get('serviceName'),
+          filename: _configProperties.get('filename')
+        };
+        serviceConfigProperties.push(configProperty);
+      }, this);
+
+    }, this);
+
+    App.db.setServiceConfigProperties(serviceConfigProperties);
+    this.set('content.serviceConfigProperties', serviceConfigProperties);
+  }
+
+});
+

+ 23 - 0
ambari-web/app/controllers/main/admin/security/add/step1.js

@@ -0,0 +1,23 @@
+/**
+ * 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.MainAdminSecurityAddStep1Controller = Em.Controller.extend({
+
+  name: 'mainAdminSecurityAddStep1Controller'
+});

+ 126 - 0
ambari-web/app/controllers/main/admin/security/add/step2.js

@@ -0,0 +1,126 @@
+/**
+ * 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.MainAdminSecurityAddStep2Controller = Em.Controller.extend({
+
+  name: 'mainAdminSecurityAddStep2Controller',
+  stepConfigs: [],
+  installedServices: [],
+  serviceConfigs: require('data/secure_configs'),
+  selectedService: null,
+
+  isSubmitDisabled: function () {
+    return !this.stepConfigs.everyProperty('errorCount', 0);
+  }.property('stepConfigs.@each.errorCount'),
+
+  clearStep: function () {
+    this.get('stepConfigs').clear();
+  },
+
+
+  /**
+   *  Function is called whenever the step is loaded
+   */
+  loadStep: function () {
+    console.log("TRACE: Loading addSecurity step2: Configure Services");
+    this.clearStep();
+    var serviceConfigs = this.get('serviceConfigs');
+    this.renderServiceConfigs(this.get('content.services'));
+    var storedServices = this.get('content.serviceConfigProperties');
+    if (storedServices) {
+      var configs = new Ember.Set();
+
+      // for all services`
+      this.get('stepConfigs').forEach(function (_content) {
+        //for all components
+        _content.get('configs').forEach(function (_config) {
+
+          var componentVal = storedServices.findProperty('name', _config.get('name'));
+          //if we have config for specified component
+          if (componentVal) {
+            //set it
+            _config.set('value', componentVal.value)
+          }
+
+        }, this);
+      }, this);
+
+    }
+    //
+    this.set('installedServices', App.Service.find().mapProperty('serviceName'));
+    this.set('selectedService', 'HDFS');
+    console.log("The services are: " + this.get('installedServices'));
+    //
+  },
+
+  /**
+   * Render configs for active services
+   * @param serviceConfigs
+   */
+  renderServiceConfigs: function (serviceConfigs) {
+    serviceConfigs.forEach(function (_serviceConfig) {
+
+      var serviceConfig = App.ServiceConfig.create({
+        filename: _serviceConfig.filename,
+        serviceName: _serviceConfig.serviceName,
+        displayName: _serviceConfig.displayName,
+        configCategories: _serviceConfig.configCategories,
+        showConfig: true,
+        configs: []
+      });
+
+      this.loadComponentConfigs(_serviceConfig, serviceConfig);
+
+      console.log('pushing ' + serviceConfig.serviceName, serviceConfig);
+
+      this.get('stepConfigs').pushObject(serviceConfig);
+
+
+    }, this);
+
+    this.set('selectedService', this.get('stepConfigs').filterProperty('showConfig', true).objectAt(0));
+  },
+
+  /**
+   * Load child components to service config object
+   * @param _componentConfig
+   * @param componentConfig
+   */
+  loadComponentConfigs: function (_componentConfig, componentConfig) {
+    _componentConfig.configs.forEach(function (_serviceConfigProperty) {
+      var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
+      //serviceConfigProperty.serviceConfig = componentConfig;
+      //serviceConfigProperty.initialValue();
+      componentConfig.configs.pushObject(serviceConfigProperty);
+      serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
+      serviceConfigProperty.validate();
+    }, this);
+  },
+
+  /**
+   *  submit and move to step3
+   */
+
+  submit: function () {
+    if (!this.get('isSubmitDisabled')) {
+      App.router.send('next');
+    }
+  }
+
+});

+ 502 - 0
ambari-web/app/controllers/main/admin/security/add/step3.js

@@ -0,0 +1,502 @@
+/**
+ * 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.MainAdminSecurityAddStep3Controller = Em.Controller.extend({
+
+  name: 'mainAdminSecurityAddStep3Controller',
+  configMapping: require('data/secure_mapping'),
+  stages: [],
+  configs: [],
+  noOfWaitingAjaxCalls: 0,
+  secureServices: [],
+  serviceConfigTags: [],
+  globalProperties: [],
+
+  clearStep: function () {
+    this.get('stages').clear();
+  },
+
+  loadStep: function () {
+    this.clearStep();
+    this.loadStages();
+    this.addInfoToStages();
+    this.prepareSecureConfigs();
+    // this.populateSuccededStages();
+    this.moveToNextStage();
+  },
+
+
+  loadStages: function () {
+    this.get('stages').pushObjects([
+      App.Poll.create({stage: 'stage2', label: Em.I18n.translations['admin.addSecurity.apply.stage2'], isPolling: true}),
+      App.Poll.create({stage: 'stage3', label: Em.I18n.translations['admin.addSecurity.apply.stage3'], isPolling: false}),
+      App.Poll.create({stage: 'stage4', label: Em.I18n.translations['admin.addSecurity.apply.stage4'], isPolling: true})
+    ]);
+  },
+
+  populateSuccededStages: function () {
+    var currentStage = 'stage' + this.get('content').loadCurrentStage();
+    var inc = 1;
+    while (inc < currentStage) {
+      var stage = 'stage' + inc;
+      this.get('stages').findProperty('stage', stage).setProperties({ isStarted: true, isCompleted: true });
+    }
+  },
+
+  startStage: function () {
+    var startedStages = this.get('stages').filterProperty('isStarted', true);
+    if (startedStages.length) {
+      var currentStage = startedStages.findProperty('isCompleted', false);
+      if (currentStage && currentStage.get('isPolling') === true) {
+        currentStage.start();
+      } else if (currentStage && currentStage.get('stage') === 'stage3') {
+        if (App.testMode) {
+          currentStage.set('isSuccess', true);
+          currentStage.set('isCompleted', true);
+          this.moveToNextStage();
+        } else {
+          this.loadConfigsForAllServices();
+        }
+      }
+    }
+  }.observes('stages.@each.isStarted'),
+
+  onCompleteStage: function () {
+    var index = this.get('stages').filterProperty('isSuccess', true).length;
+    if (index > 0) {
+      this.moveToNextStage();
+    }
+  }.observes('stages.@each.isSuccess'),
+
+  addInfoToStages: function () {
+    // this.addInfoToStage1();
+    this.addInfoToStage2();
+    this.addInfoToStage3();
+    this.addInfoToStage4();
+  },
+
+  addInfoToStage1: function () {
+    var stage1 = this.get('stages').findProperty('stage', 'stage1');
+    if (App.testMode) {
+      stage1.set('isSucces', true);
+      stage1.set('isStarted', true);
+      stage1.set('isCompleted', true);
+    }
+  },
+
+  addInfoToStage2: function () {
+    var stage2 = this.get('stages').findProperty('stage', 'stage2');
+    var url = (App.testMode) ? '/data/wizard/deploy/2_hosts/poll_1.json' : App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/services';
+    var data = '{"ServiceInfo": {"state": "INSTALLED"}}';
+    stage2.set('url', url);
+    stage2.set('data', data);
+  },
+
+  addInfoToStage3: function () {
+
+  },
+
+  addInfoToStage4: function () {
+    var stage4 = this.get('stages').findProperty('stage', 'stage4');
+    var url = (App.testMode) ? '/data/wizard/deploy/2_hosts/poll_1.json' : App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/services';
+    var data = '{"ServiceInfo": {"state": "STARTED"}}';
+    stage4.set('url', url);
+    stage4.set('data', data);
+  },
+
+  loadUiSideConfigs: function () {
+    var uiConfig = [];
+    var configs = this.get('configMapping').filterProperty('foreignKey', null);
+    configs.forEach(function (_config) {
+      var value = this.getGlobConfigValue(_config.templateName, _config.value, _config.name);
+      uiConfig.pushObject({
+        "id": "site property",
+        "name": _config.name,
+        "value": value,
+        "filename": _config.filename
+      });
+    }, this);
+    var dependentConfig = this.get('configMapping').filterProperty('foreignKey');
+    dependentConfig.forEach(function (_config) {
+      this.setConfigValue(uiConfig, _config);
+      uiConfig.pushObject({
+        "id": "site property",
+        "name": _config.name,
+        "value": _config.value,
+        "filename": _config.filename
+      });
+    }, this);
+    return uiConfig;
+  },
+
+
+  /**
+   * Set all site property that are derived from other puppet-variable
+   */
+
+  getGlobConfigValue: function (templateName, expression, name) {
+    var express = expression.match(/<(.*?)>/g);
+    var value = expression;
+    if (express == null) {
+      return expression;
+    }
+    express.forEach(function (_express) {
+      console.log("The value of template is: " + _express);
+      if (_express.match(/\[([\d]*)(?=\])/ === null)) {
+      }
+      var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
+      if (this.get('globalProperties').someProperty('name', templateName[index])) {
+        //console.log("The name of the variable is: " + this.get('content.serviceConfigProperties').findProperty('name', templateName[index]).name);
+        var globValue = this.get('globalProperties').findProperty('name', templateName[index]).value;
+        if (value !== null) {   // if the property depends on more than one template name like <templateName[0]>/<templateName[1]> then don't proceed to the next if the prior is null or not found in the global configs
+          value = value.replace(_express, globValue);
+        }
+      } else {
+        /*
+         console.log("ERROR: The variable name is: " + templateName[index]);
+         console.log("ERROR: mapped config from configMapping file has no corresponding variable in " +
+         "content.serviceConfigProperties. Two possible reasons for the error could be: 1) The service is not selected. " +
+         "and/OR 2) The service_config metadata file has no corresponding global var for the site property variable");
+         */
+        value = null;
+      }
+    }, this);
+    return value;
+  },
+  /**
+   * Set all site property that are derived from other site-properties
+   */
+  setConfigValue: function (uiConfig, config) {
+    if (config.value == null) {
+      return;
+    }
+    var fkValue = config.value.match(/<(foreignKey.*?)>/g);
+    if (fkValue) {
+      fkValue.forEach(function (_fkValue) {
+        var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]);
+        if (uiConfig.someProperty('name', config.foreignKey[index])) {
+          var globalValue = uiConfig.findProperty('name', config.foreignKey[index]).value;
+          config.value = config.value.replace(_fkValue, globalValue);
+        } else if (this.get('content.serviceConfigProperties').someProperty('name', config.foreignKey[index])) {
+          var globalValue;
+          if (this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value === '') {
+            globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).defaultValue;
+          } else {
+            globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value;
+          }
+          config.value = config.value.replace(_fkValue, globalValue);
+        }
+      }, this);
+    }
+    if (fkValue = config.name.match(/<(foreignKey.*?)>/g)) {
+      fkValue.forEach(function (_fkValue) {
+        var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]);
+        if (uiConfig.someProperty('name', config.foreignKey[index])) {
+          var globalValue = uiConfig.findProperty('name', config.foreignKey[index]).value;
+          config.name = config.name.replace(_fkValue, globalValue);
+        } else if (this.get('content.serviceConfigProperties').someProperty('name', config.foreignKey[index])) {
+          var globalValue;
+          if (this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value === '') {
+            globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).defaultValue;
+          } else {
+            globalValue = this.get('content.serviceConfigProperties').findProperty('name', config.foreignKey[index]).value;
+          }
+          config.name = config.name.replace(_fkValue, globalValue);
+        }
+      }, this);
+    }
+    //For properties in the configMapping file having foreignKey and templateName properties.
+
+    var templateValue = config.value.match(/<(templateName.*?)>/g);
+    if (templateValue) {
+      templateValue.forEach(function (_value) {
+        var index = parseInt(_value.match(/\[([\d]*)(?=\])/)[1]);
+        if (this.get('globalProperties').someProperty('name', config.templateName[index])) {
+          var globalValue = this.get('globalProperties').findProperty('name', config.templateName[index]).value;
+          config.value = config.value.replace(_value, globalValue);
+        } else {
+          config.value = null;
+        }
+      }, this);
+    }
+  },
+
+
+  prepareSecureConfigs: function () {
+    this.loadGlobals();
+    this.loadInstanceName();
+    var storedConfigs = this.get('content.serviceConfigProperties').filterProperty('id', 'site property');
+    var uiConfigs = this.loadUiSideConfigs();
+    this.set('configs', storedConfigs.concat(uiConfigs));
+  },
+
+  loadGlobals: function () {
+    var globals = this.get('content.serviceConfigProperties').filterProperty('id', 'puppet var');
+    this.set('globalProperties', globals);
+  },
+
+  loadInstanceName: function () {
+    var isInstanceName = this.get('globalProperties').findProperty('name', 'instance_name');
+    if (isInstanceName) {
+      this.get('globalProperties').forEach(function (_globalProperty) {
+        if (/primary_name?$/.test(_globalProperty.name)) {
+          if (!/_HOST?$/.test(_globalProperty.value)) {
+            _globalProperty.value = _globalProperty.value + "/_HOST";
+          }
+        }
+      }, this);
+    }
+  },
+
+  loadConfigsForAllServices: function () {
+    this.set('noOfWaitingAjaxCalls', this.get('content.services').length - 2);
+    this.get('content.services').forEach(function (_secureService, index) {
+      if (_secureService.serviceName !== 'GENERAL' && _secureService.serviceName !== 'NAGIOS') {
+        this.getConfigDetailsFromServer(_secureService, index);
+      }
+    }, this);
+  },
+
+  getConfigDetailsFromServer: function (secureService, id) {
+    var self = this;
+    var url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/services/' + secureService.serviceName;
+    $.ajax({
+      type: 'GET',
+      url: url,
+      timeout: 10000,
+      dataType: 'text',
+      success: function (data) {
+        console.log("TRACE: In success function for the GET getServciceConfigs call");
+        console.log("TRACE: The url is: " + url);
+        var jsonData = jQuery.parseJSON(data);
+
+        //prepare tags to fetch all configuration for a service
+        self.setServiceTagNames(secureService.serviceName, jsonData.ServiceInfo.desired_configs);
+        self.set('noOfWaitingAjaxCalls', self.get('noOfWaitingAjaxCalls') - 1);
+
+        if (self.get('noOfWaitingAjaxCalls') == 0) {
+          self.getAllConfigsFromServer();
+        }
+      },
+
+      error: function (request, ajaxOptions, error) {
+        self.get('stages').findProperty('stage', 'stage3').set('isError', true);
+        console.log("TRACE: In error function for the getServciceConfigs call");
+        console.log("TRACE: value of the url is: " + url);
+        console.log("TRACE: error code status is: " + request.status);
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+  },
+
+  /**
+   * set tagnames for configuration of the *-site.xml
+   */
+  setServiceTagNames: function (secureServiceName, configs) {
+    console.log("TRACE: In setServiceTagNames function:");
+    //var serviceConfigTags = this.get('serviceConfigTags');
+    for (var index in configs) {
+      var serviceConfigObj = {
+        serviceName: secureServiceName,
+        siteName: index,
+        tagName: configs[index],
+        newTagName: null,
+        configs: {}
+      };
+      console.log("The value of serviceConfigTags[index]: " + configs[index]);
+      this.get('serviceConfigTags').pushObject(serviceConfigObj);
+    }
+    return serviceConfigObj;
+  },
+
+
+  getAllConfigsFromServer: function () {
+    this.set('noOfWaitingAjaxCalls', this.get('serviceConfigTags').length - 1);
+    this.get('serviceConfigTags').forEach(function (_serviceConfigTags) {
+      if (_serviceConfigTags.serviceName !== 'MAPREDUCE' || _serviceConfigTags.siteName !== 'core-site') {   //skip MapReduce core-site configuration
+        this.getServiceConfigsFromServer(_serviceConfigTags);
+      }
+    }, this);
+  },
+
+
+  createConfigurations: function () {
+    this.set('noOfWaitingAjaxCalls', this.get('serviceConfigTags').length - 1);
+    this.get('serviceConfigTags').forEach(function (_serviceConfigTags) {
+      if (_serviceConfigTags.serviceName !== 'MAPREDUCE' || _serviceConfigTags.siteName !== 'core-site') {   //skip MapReduce core-site configuration
+        this.createConfiguration(_serviceConfigTags);
+      }
+    }, this);
+  },
+
+  createConfiguration: function (serviceConfigTags) {
+    var self = this;
+    var clusterName = App.router.getClusterName();
+    var url = App.apiPrefix + '/clusters/' + clusterName + '/configurations';
+    var data = this.createConfigurationData(serviceConfigTags);
+    $.ajax({
+      type: 'POST',
+      url: url,
+      data: JSON.stringify(data),
+      dataType: 'text',
+      timeout: 5000,
+      success: function (data) {
+        var jsonData = jQuery.parseJSON(data);
+        self.set('noOfWaitingAjaxCalls', self.get('noOfWaitingAjaxCalls') - 1);
+        if (self.get('noOfWaitingAjaxCalls') == 0) {
+          self.applyConfigurationToServices();
+        }
+      },
+
+      error: function (request, ajaxOptions, error) {
+        self.get('stages').findProperty('stage', 'stage3').set('isError', true);
+        console.log('TRACE: In Error ');
+        console.log('TRACE: Error message is: ' + request.responseText);
+        console.log("TRACE: value of the url is: " + url);
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+
+  },
+
+  createConfigurationData: function (serviceConfigTags) {
+    return {"type": serviceConfigTags.siteName, "tag": serviceConfigTags.newTagName, "properties": serviceConfigTags.configs};
+  },
+
+  applyConfigurationToServices: function () {
+    this.applyHdfsCoretoMaprCore();
+    this.set('noOfWaitingAjaxCalls', this.get('content.services').length-2);
+    this.get('content.services').forEach(function (_service) {
+      if (_service.serviceName !== 'GENERAL' && _service.serviceName !== 'NAGIOS') {
+        var data = {config: {}};
+        this.get('serviceConfigTags').filterProperty('serviceName', _service.serviceName).forEach(function (_serviceConfig) {
+          data.config[_serviceConfig.siteName] = _serviceConfig.newTagName;
+        }, this);
+        this.applyConfToService(_service.serviceName, data);
+      }
+    }, this);
+  },
+
+  applyHdfsCoretoMaprCore: function () {
+    this.get('serviceConfigTags').filterProperty('serviceName', 'MAPREDUCE').findProperty('siteName', 'core-site').newTagName = this.get('serviceConfigTags').filterProperty('serviceName', 'HDFS').findProperty('siteName', 'core-site').newTagName;
+  },
+
+  applyConfToService: function (serviceName, data) {
+    var self = this;
+    var clusterName = App.router.getClusterName();
+    var url = App.apiPrefix + '/clusters/' + clusterName + '/services/' + serviceName;
+    $.ajax({
+      type: 'PUT',
+      url: url,
+      async: false,
+      dataType: 'text',
+      data: JSON.stringify(data),
+      timeout: 5000,
+      success: function (data) {
+        var jsonData = jQuery.parseJSON(data);
+        console.log("TRACE: In success function for the applyCreatedConfToService call");
+        console.log("TRACE: value of the url is: " + url);
+        self.set('noOfWaitingAjaxCalls', self.get('noOfWaitingAjaxCalls') - 1);
+        if (self.get('noOfWaitingAjaxCalls') == 0) {
+          var currentStage = self.get('stages').findProperty('stage', 'stage3');
+          currentStage.set('isSuccess', true);
+          currentStage.set('isCompleted', true);
+        }
+      },
+
+      error: function (request, ajaxOptions, error) {
+        self.get('stages').findProperty('stage', 'stage3').set('isError', true);
+        console.log('Error: In Error of apply');
+        console.log('Error: Error message is: ' + request.responseText);
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+    console.log("Exiting applyCreatedConfToService");
+
+  },
+
+  moveToNextStage: function () {
+    var nextStage = this.get('stages').findProperty('isStarted', false);
+    if (nextStage) {
+      // this.get('content').saveCurrentStage(nextStage.get('stage').charAt(nextStage.get('stage').length - 1));
+      nextStage.set('isStarted', true);
+    } else {
+      this.set('isSubmitDisabled', false);
+    }
+  },
+
+  /**
+   * gets site config properties from server and sets it for every configuration
+   * @param serviceConfigTags
+   */
+
+  getServiceConfigsFromServer: function (serviceConfigTags) {
+    var self = this;
+    var properties = {};
+    var url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/configurations/?type=' + serviceConfigTags.siteName + '&tag=' + serviceConfigTags.tagName;
+    $.ajax({
+      type: 'GET',
+      url: url,
+      async: true,
+      timeout: 10000,
+      dataType: 'json',
+      success: function (data) {
+        console.log("TRACE: In success function for the GET getServiceConfigsFromServer call");
+        console.log("TRACE: The url is: " + url);
+        serviceConfigTags.configs = data.items.findProperty('tag', serviceConfigTags.tagName).properties;
+        self.set('noOfWaitingAjaxCalls', self.get('noOfWaitingAjaxCalls') - 1);
+
+        if (self.get('noOfWaitingAjaxCalls') == 0) {
+          self.addSecureConfigs();
+          self.createConfigurations();
+        }
+      },
+
+      error: function (request, ajaxOptions, error) {
+        self.get('stages').findProperty('stage', 'stage3').set('isError', true);
+        console.log("TRACE: In error function for the getServiceConfigsFromServer call");
+        console.log("TRACE: value of the url is: " + url);
+        console.log("TRACE: error code status is: " + request.status);
+
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+  },
+
+
+  addSecureConfigs: function () {
+    this.get('serviceConfigTags').forEach(function (_serviceConfigTags, index) {
+      if (_serviceConfigTags.siteName === 'global') {
+        _serviceConfigTags.newTagName = 'version' + (new Date).getTime() + index;
+        this.get('globalProperties').forEach(function (_globalProperty) {
+          _serviceConfigTags.configs[_globalProperty.name] = _globalProperty.value;
+        }, this);
+      } else {
+        _serviceConfigTags.newTagName = 'version' + (new Date).getTime();
+        this.get('configs').filterProperty('id', 'site property').filterProperty('filename', _serviceConfigTags.siteName + '.xml').forEach(function (_config) {
+          _serviceConfigTags.configs[_config.name] = _config.value;
+        }, this);
+      }
+    }, this);
+  }
+});

+ 351 - 0
ambari-web/app/controllers/main/admin/security/disable.js

@@ -0,0 +1,351 @@
+/**
+ * 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.MainAdminSecurityDisableController = Em.Controller.extend({
+
+  name: 'mainAdminSecurityDisableController',
+  configMapping: require('data/secure_mapping').slice(0),
+  stages: [],
+  configs: [],
+  noOfWaitingAjaxCalls: 0,
+  secureServices: [],
+  serviceConfigTags: [],
+  globalProperties: [],
+
+  clearStep: function () {
+    this.get('stages').clear();
+    this.get('secureServices').clear();
+  },
+
+  loadStep: function () {
+    this.clearStep();
+    this.loadStages();
+    this.loadSecureServices();
+    this.addInfoToStages();
+    this.moveToNextStage();
+  },
+
+
+  loadStages: function () {
+    this.get('stages').pushObjects([
+      App.Poll.create({stage: 'stage2', label: Em.I18n.translations['admin.addSecurity.apply.stage2'], isPolling: true}),
+      App.Poll.create({stage: 'stage3', label: Em.I18n.translations['admin.addSecurity.apply.stage3'], isPolling: false}),
+      App.Poll.create({stage: 'stage4', label: Em.I18n.translations['admin.addSecurity.apply.stage4'], isPolling: true})
+    ]);
+  },
+
+  startStage: function () {
+    var startedStages = this.get('stages').filterProperty('isStarted', true);
+    if (startedStages.length) {
+      var currentStage = startedStages.findProperty('isCompleted', false);
+      if (currentStage && currentStage.get('isPolling') === true) {
+        currentStage.start();
+      } else if (currentStage && currentStage.get('stage') === 'stage3') {
+        if (App.testMode) {
+          currentStage.set('isSuccess', true);
+          currentStage.set('isCompleted', true);
+          this.moveToNextStage();
+        } else {
+          this.loadConfigsForAllServices();
+        }
+      }
+    }
+  }.observes('stages.@each.isStarted'),
+
+  onCompleteStage: function () {
+    var index = this.get('stages').filterProperty('isSuccess', true).length;
+    if (index > 0) {
+      this.moveToNextStage();
+    }
+  }.observes('stages.@each.isSuccess'),
+
+  addInfoToStages: function () {
+    this.addInfoToStage2();
+    this.addInfoToStage3();
+    this.addInfoToStage4();
+  },
+
+  addInfoToStage1: function () {
+    var stage1 = this.get('stages').findProperty('stage', 'stage1');
+    if (App.testMode) {
+      stage1.set('isSucces', true);
+      stage1.set('isStarted', true);
+      stage1.set('isCompleted', true);
+    }
+  },
+
+  addInfoToStage2: function () {
+    var stage2 = this.get('stages').findProperty('stage', 'stage2');
+    var url = (App.testMode) ? '/data/wizard/deploy/2_hosts/poll_1.json' : App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/services';
+    var data = '{"ServiceInfo": {"state": "INSTALLED"}}';
+    stage2.set('url', url);
+    stage2.set('data', data);
+  },
+
+  addInfoToStage3: function () {
+
+  },
+
+  addInfoToStage4: function () {
+    var stage4 = this.get('stages').findProperty('stage', 'stage4');
+    var url = (App.testMode) ? '/data/wizard/deploy/2_hosts/poll_1.json' : App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/services';
+    var data = '{"ServiceInfo": {"state": "STARTED"}}';
+    stage4.set('url', url);
+    stage4.set('data', data);
+  },
+
+  loadSecureServices: function() {
+    var secureServices = require('data/secure_configs');
+    var installedServices = App.Service.find().mapProperty('serviceName');
+    //General (only non service tab) tab is always displayed
+    installedServices.forEach(function (_service) {
+      var secureService = secureServices.findProperty('serviceName', _service);
+      if (secureService) {
+        this.get('secureServices').push(secureService);
+      }
+    }, this);
+  },
+
+  /**
+   * gets site config properties from server and sets it for every configuration
+   * @param serviceConfigTags
+   */
+
+  getServiceConfigsFromServer: function (serviceConfigTags) {
+    var self = this;
+    var properties = {};
+    var url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/configurations/?type=' + serviceConfigTags.siteName + '&tag=' + serviceConfigTags.tagName;
+    $.ajax({
+      type: 'GET',
+      url: url,
+      async: true,
+      timeout: 10000,
+      dataType: 'json',
+      success: function (data) {
+        console.log("TRACE: In success function for the GET getServiceConfigsFromServer call");
+        console.log("TRACE: The url is: " + url);
+        serviceConfigTags.configs = data.items.findProperty('tag', serviceConfigTags.tagName).properties;
+        self.set('noOfWaitingAjaxCalls', self.get('noOfWaitingAjaxCalls') - 1);
+
+        if (self.get('noOfWaitingAjaxCalls') == 0) {
+          self.removeSecureConfigs();
+          self.createConfigurations();
+        }
+      },
+
+      error: function (request, ajaxOptions, error) {
+        self.get('stages').findProperty('stage', 'stage3').set('isError', true);
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+  },
+  loadConfigsForAllServices: function () {
+    this.set('noOfWaitingAjaxCalls', this.get('secureServices').length - 1);
+    this.get('secureServices').forEach(function (_secureService, index) {
+      if (_secureService.serviceName !== 'GENERAL' && _secureService.serviceName !== 'NAGIOS') {
+        this.getConfigDetailsFromServer(_secureService, index);
+      }
+    }, this);
+  },
+
+  getConfigDetailsFromServer: function (secureService, id) {
+    var self = this;
+    var url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/services/' + secureService.serviceName;
+    $.ajax({
+      type: 'GET',
+      url: url,
+      timeout: 10000,
+      dataType: 'text',
+      success: function (data) {
+        console.log("TRACE: In success function for the GET getServciceConfigs call");
+        console.log("TRACE: The url is: " + url);
+        var jsonData = jQuery.parseJSON(data);
+
+        //prepare tags to fetch all configuration for a service
+        self.setServiceTagNames(secureService.serviceName, jsonData.ServiceInfo.desired_configs);
+        self.set('noOfWaitingAjaxCalls', self.get('noOfWaitingAjaxCalls') - 1);
+
+        if (self.get('noOfWaitingAjaxCalls') == 0) {
+          self.getAllConfigsFromServer();
+        }
+      },
+
+      error: function (request, ajaxOptions, error) {
+        self.get('stages').findProperty('stage', 'stage3').set('isError', true);
+        console.log("TRACE: In error function for the getServciceConfigs call");
+        console.log("TRACE: value of the url is: " + url);
+        console.log("TRACE: error code status is: " + request.status);
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+  },
+
+  /**
+   * set tagnames for configuration of the *-site.xml
+   */
+  setServiceTagNames: function (secureServiceName, configs) {
+    console.log("TRACE: In setServiceTagNames function:");
+    //var serviceConfigTags = this.get('serviceConfigTags');
+    for (var index in configs) {
+      var serviceConfigObj = {
+        serviceName: secureServiceName,
+        siteName: index,
+        tagName: configs[index],
+        newTagName: null,
+        configs: {}
+      };
+      console.log("The value of serviceConfigTags[index]: " + configs[index]);
+      this.get('serviceConfigTags').pushObject(serviceConfigObj);
+    }
+    return serviceConfigObj;
+  },
+
+
+  getAllConfigsFromServer: function () {
+    this.set('noOfWaitingAjaxCalls', this.get('serviceConfigTags').length - 1);
+    this.get('serviceConfigTags').forEach(function (_serviceConfigTags) {
+      if (_serviceConfigTags.serviceName !== 'MAPREDUCE' || _serviceConfigTags.siteName !== 'core-site') {   //skip MapReduce core-site configuration
+        this.getServiceConfigsFromServer(_serviceConfigTags);
+      }
+    }, this);
+  },
+
+
+  createConfigurations: function () {
+    this.set('noOfWaitingAjaxCalls', this.get('serviceConfigTags').length - 1);
+    this.get('serviceConfigTags').forEach(function (_serviceConfigTags) {
+      if (_serviceConfigTags.serviceName !== 'MAPREDUCE' || _serviceConfigTags.siteName !== 'core-site') {   //skip MapReduce core-site configuration
+        this.createConfiguration(_serviceConfigTags);
+      }
+    }, this);
+  },
+
+  createConfiguration: function (serviceConfigTags) {
+    var self = this;
+    var clusterName = App.router.getClusterName();
+    var url = App.apiPrefix + '/clusters/' + clusterName + '/configurations';
+    var data = this.createConfigurationData(serviceConfigTags);
+    $.ajax({
+      type: 'POST',
+      url: url,
+      data: JSON.stringify(data),
+      dataType: 'text',
+      timeout: 5000,
+      success: function (data) {
+        var jsonData = jQuery.parseJSON(data);
+        self.set('noOfWaitingAjaxCalls', self.get('noOfWaitingAjaxCalls') - 1);
+        if (self.get('noOfWaitingAjaxCalls') == 0) {
+          self.applyConfigurationToServices();
+        }
+      },
+
+      error: function (request, ajaxOptions, error) {
+        self.get('stages').findProperty('stage', 'stage3').set('isError', true);
+        console.log('TRACE: In Error ');
+        console.log('TRACE: Error message is: ' + request.responseText);
+        console.log("TRACE: value of the url is: " + url);
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+
+  },
+
+  createConfigurationData: function (serviceConfigTags) {
+    return {"type": serviceConfigTags.siteName, "tag": serviceConfigTags.newTagName, "properties": serviceConfigTags.configs};
+  },
+
+  applyConfigurationToServices: function () {
+    this.applyHdfsCoretoMaprCore();
+    this.set('noOfWaitingAjaxCalls', this.get('secureServices').length-1);
+    this.get('secureServices').forEach(function (_service) {
+      if (_service.serviceName !== 'GENERAL' && _service.serviceName !== 'NAGIOS') {
+        var data = {config: {}};
+        this.get('serviceConfigTags').filterProperty('serviceName', _service.serviceName).forEach(function (_serviceConfig) {
+          data.config[_serviceConfig.siteName] = _serviceConfig.newTagName;
+        }, this);
+        this.applyConfToService(_service.serviceName, data);
+      }
+    }, this);
+  },
+
+  applyHdfsCoretoMaprCore: function () {
+    this.get('serviceConfigTags').filterProperty('serviceName', 'MAPREDUCE').findProperty('siteName', 'core-site').newTagName = this.get('serviceConfigTags').filterProperty('serviceName', 'HDFS').findProperty('siteName', 'core-site').newTagName;
+  },
+
+  applyConfToService: function (serviceName, data) {
+    var self = this;
+    var clusterName = App.router.getClusterName();
+    var url = App.apiPrefix + '/clusters/' + clusterName + '/services/' + serviceName;
+    $.ajax({
+      type: 'PUT',
+      url: url,
+      async: false,
+      dataType: 'text',
+      data: JSON.stringify(data),
+      timeout: 5000,
+      success: function (data) {
+        self.set('noOfWaitingAjaxCalls', self.get('noOfWaitingAjaxCalls') - 1);
+        if (self.get('noOfWaitingAjaxCalls') == 0) {
+          var currentStage = self.get('stages').findProperty('stage', 'stage3');
+          currentStage.set('isSuccess', true);
+          currentStage.set('isCompleted', true);
+        }
+      },
+
+      error: function (request, ajaxOptions, error) {
+        self.get('stages').findProperty('stage', 'stage3').set('isError', true);
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+    console.log("Exiting applyCreatedConfToService");
+
+  },
+
+  moveToNextStage: function () {
+    var nextStage = this.get('stages').findProperty('isStarted', false);
+    if (nextStage) {
+      nextStage.set('isStarted', true);
+    } else {
+      this.set('isSubmitDisabled', false);
+    }
+  },
+
+  removeSecureConfigs: function () {
+    this.get('serviceConfigTags').forEach(function (_serviceConfigTags, index) {
+      if (_serviceConfigTags.siteName === 'global') {
+        _serviceConfigTags.newTagName = 'version' + (new Date).getTime() + index;
+        if ('security_enabled' in _serviceConfigTags.configs) {
+          _serviceConfigTags.configs.security_enabled = false;
+        }
+      } else {
+        _serviceConfigTags.newTagName = 'version' + (new Date).getTime();
+        this.get('configMapping').filterProperty('filename', _serviceConfigTags.siteName + '.xml').forEach(function (_config) {
+          if (_config.name in _serviceConfigTags.configs) {
+            delete _serviceConfigTags.configs[_config.name];
+          }
+          console.log("*******Not Deleted" +  _config.name);
+        }, this);
+      }
+    }, this);
+  }
+});

+ 3 - 2
ambari-web/app/controllers/wizard/step8_controller.js

@@ -26,6 +26,7 @@ App.WizardStep8Controller = Em.Controller.extend({
   services: [],
   configs: [],
   globals: [],
+  ajaxQueue: [],
   configMapping: require('data/config_mapping'),
   slaveComponentConfig: null,
   isSubmitDisabled: false,
@@ -799,7 +800,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     this.createAllHostComponents();
 
     this.ajaxQueueFinished = function () {
-      console.log('everything is loaded')
+      console.log('everything is loaded');
       App.router.send('next');
     };
     this.doNextAjaxCall();
@@ -1473,7 +1474,7 @@ App.WizardStep8Controller = Em.Controller.extend({
     }
   },
 
-  ajaxQueue: [],
+
 
   ajaxQueueFinished: function () {
     //do something

+ 120 - 0
ambari-web/app/data/secure_configs.js

@@ -0,0 +1,120 @@
+/**
+ * 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.SecureConfigProperties = Ember.ArrayProxy.extend({
+  content: require('data/secure_properties').configProperties
+});
+require('models/service_config');
+
+var configProperties = App.SecureConfigProperties.create();
+
+module.exports = [
+  {
+    serviceName: 'GENERAL',
+    displayName: 'CLUSTER',
+    filename: 'hdfs-site',
+    configCategories: [
+      App.ServiceConfigCategory.create({ name: 'KERBEROS'})
+    ],
+    configs: configProperties.filterProperty('serviceName', 'GENERAL')
+  },
+  {
+    serviceName: 'HDFS',
+    displayName: 'HDFS',
+    filename: 'hdfs-site',
+    configCategories: [
+      App.ServiceConfigCategory.create({ name: 'General'}),
+      App.ServiceConfigCategory.create({ name: 'NameNode'}),
+      App.ServiceConfigCategory.create({ name: 'SNameNode'}),
+      App.ServiceConfigCategory.create({ name: 'DataNode'})
+    ],
+    configs: configProperties.filterProperty('serviceName', 'HDFS')
+  },
+
+  {
+    serviceName: 'MAPREDUCE',
+    displayName: 'MapReduce',
+    filename: 'mapred-site',
+    configCategories: [
+      App.ServiceConfigCategory.create({ name: 'JobTracker'}),
+      App.ServiceConfigCategory.create({ name: 'TaskTracker'})
+    ],
+    configs: configProperties.filterProperty('serviceName', 'MAPREDUCE')
+  },
+
+  {
+    serviceName: 'HIVE',
+    displayName: 'Hive/HCat',
+    filename: 'hive-site',
+    configCategories: [
+      App.ServiceConfigCategory.create({ name: 'Hive Metastore'})
+    ],
+    configs: configProperties.filterProperty('serviceName', 'HIVE')
+  },
+
+  {
+    serviceName: 'WEBHCAT',
+    displayName: 'WebHCat',
+    filename: 'webhcat-site',
+    configCategories: [
+      App.ServiceConfigCategory.create({ name: 'WebHCat'})
+    ],
+    configs: configProperties.filterProperty('serviceName', 'WEBHCAT')
+  },
+
+  {
+    serviceName: 'HBASE',
+    displayName: 'HBase',
+    filename: 'hbase-site',
+    configCategories: [
+      App.ServiceConfigCategory.create({ name: 'HBase Master'}),
+      App.ServiceConfigCategory.create({ name: 'RegionServer'})
+    ],
+    configs: configProperties.filterProperty('serviceName', 'HBASE')
+  },
+  /*
+  {
+    serviceName: 'ZOOKEEPER',
+    displayName: 'ZooKeeper',
+    configCategories: [
+      App.ServiceConfigCategory.create({ name: 'ZooKeeper'})
+    ],
+    configs: configProperties.filterProperty('serviceName', 'ZOOKEEPER')
+
+  },
+
+
+  {
+    serviceName: 'OOZIE',
+    displayName: 'Oozie',
+    filename: 'oozie-site',
+    configCategories: [
+      App.ServiceConfigCategory.create({ name: 'Oozie Server'})
+    ],
+    configs: configProperties.filterProperty('serviceName', 'OOZIE')
+  },
+  */
+  {
+    serviceName: 'NAGIOS',
+    displayName: 'Nagios',
+    configCategories: [
+      App.ServiceConfigCategory.create({ name: 'General'})
+    ],
+    configs: configProperties.filterProperty('serviceName', 'NAGIOS')
+  }
+];

+ 225 - 0
ambari-web/app/data/secure_mapping.js

@@ -0,0 +1,225 @@
+/**
+ * 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.
+ */
+
+module.exports = [
+  {
+    "name": "hadoop.security.authentication",
+    "templateName": [],
+    "foreignKey": null,
+    "value": "kerberos",
+    "filename": "core-site.xml"
+  },
+  {
+    "name": "hadoop.security.authorization",
+    "templateName": [],
+    "foreignKey": null,
+    "value": "true",
+    "filename": "core-site.xml"
+  },
+ // {
+   // "name": "hadoop.security.auth_to_local",
+   // "templateName": [""],
+   //"foreignKey": null,
+   // "value": "RULE:[2:$1@$0]([<templateName[0]>]t@.*<templateName[1]>)s/.*/$MAPRED_USER/ RULE:[2:$1@$0]([<templateName[2]>]n@.*<templateName[1]>)s/.*/$HDFS_USER/ RULE:[2:$1@$0](<templateName[3]>@.*<templateName[1]>)s/.*/$HBASE_USER/ RULE:[2:$1@$0](<templateName[4]>@.*<templateName[1]>)s/.*/$HABSE_USER/ DEFAULT",
+   // "filename": "core-site.xml"
+ // },
+
+  {
+    "name": "dfs.namenode.kerberos.principal",
+    "templateName": ["namenode_primary_name","realm_name"],
+    "foreignKey": null,
+    "value": "<templateName[0]>@<templateName[1]>",
+    "filename": "hdfs-site.xml"
+  },
+  {
+    "name": "dfs.namenode.keytab.file",
+    "templateName": ["namenode_keytab"],
+    "foreignKey": null,
+    "value": "<templateName[0]>",
+    "filename": "hdfs-site.xml"
+  },
+  {
+    "name": "dfs.secondary.namenode.kerberos.principal",
+    "templateName": ["snamenode_primary_name","realm_name"],
+    "foreignKey": null,
+    "value": "<templateName[0]>@<templateName[1]>",
+    "filename": "hdfs-site.xml"
+  },
+  {
+    "name": "dfs.secondary.namenode.keytab.file",
+    "templateName": ["snamenode_keytab"],
+    "foreignKey": null,
+    "value": "<templateName[0]>",
+    "filename": "hdfs-site.xml"
+  },
+  {
+    "name": "dfs.web.authentication.kerberos.principal",
+    "templateName": ["hadoop_http_primary_name","realm_name"],
+    "foreignKey": null,
+    "value": "<templateName[0]>@<templateName[1]>",
+    "filename": "hdfs-site.xml"
+  },
+  {
+    "name": "dfs.web.authentication.kerberos.keytab",
+    "templateName": ["hadoop_http_keytab"],
+    "foreignKey": null,
+    "value": "<templateName[0]>",
+    "filename": "hdfs-site.xml"
+  },
+  {
+    "name": "dfs.datanode.kerberos.principal",
+    "templateName": ["datanode_primary_name","realm_name"],
+    "foreignKey": null,
+    "value": "<templateName[0]>@<templateName[1]>",
+    "filename": "hdfs-site.xml"
+  },
+  {
+    "name": "dfs.datanode.keytab.file",
+    "templateName": ["datanode_keytab"],
+    "foreignKey": null,
+    "value": "<templateName[0]>",
+    "filename": "hdfs-site.xml"
+  },
+  {
+    "name": "dfs.namenode.kerberos.internal.spnego.principal",
+    "templateName": [],
+    "foreignKey": null,
+    "value": "${dfs.web.authentication.kerberos.principal}",
+    "filename": "hdfs-site.xml"
+  },
+  {
+    "name": "dfs.secondary.namenode.kerberos.internal.spnego.principal",
+    "templateName": [],
+    "foreignKey": null,
+    "value": "${dfs.web.authentication.kerberos.principal}",
+    "filename": "hdfs-site.xml"
+  },
+  {
+    "name": "mapreduce.jobtracker.kerberos.principal",
+    "templateName": ["jobtracker_primary_name","realm_name"],
+    "foreignKey": null,
+    "value": "<templateName[0]>@<templateName[1]>",
+    "filename": "mapred-site.xml"
+  },
+  {
+    "name": "mapreduce.jobtracker.keytab.file",
+    "templateName": ["jobtracker_keytab"],
+    "foreignKey": null,
+    "value": "<templateName[0]>",
+    "filename": "mapred-site.xml"
+  },
+  {
+    "name": "mapreduce.tasktracker.kerberos.principal",
+    "templateName": ["tasktracker_primary_name","realm_name"],
+    "foreignKey": null,
+    "value": "<templateName[0]>@<templateName[1]>",
+    "filename": "mapred-site.xml"
+  },
+  {
+    "name": "mapreduce.tasktracker.keytab.file",
+    "templateName": ["tasktracker_keytab"],
+    "foreignKey": null,
+    "value": "<templateName[0]>",
+    "filename": "mapred-site.xml"
+  },
+  {
+    "name": "hbase.master.kerberos.principal",
+    "templateName": ["hbase_master_primary_name","realm_name"],
+    "foreignKey": null,
+    "value": "<templateName[0]>@<templateName[1]>",
+    "filename": "hbase-site.xml"
+  },
+  {
+    "name": "hbase.master.keytab.file",
+    "templateName": ["hbase_master_keytab"],
+    "foreignKey": null,
+    "value": "<templateName[0]>",
+    "filename": "hbase-site.xml"
+  },
+  {
+    "name": "hbase.regionserver.kerberos.principal",
+    "templateName": ["regionserver_primary_name","realm_name"],
+    "foreignKey": null,
+    "value": "<templateName[0]>@<templateName[1]>",
+    "filename": "hbase-site.xml"
+  },
+  {
+    "name": "hbase.regionserver.keytab.file",
+    "templateName": ["regionserver_keytab"],
+    "foreignKey": null,
+    "value": "<templateName[0]>",
+    "filename": "hbase-site.xml"
+  },
+  {
+    "name": "hive.metastore.sasl.enabled",
+    "templateName": [],
+    "foreignKey": null,
+    "value": "true",
+    "filename": "hive-site.xml"
+  },
+  {
+    "name": "hive.server2.authentication",
+    "templateName": [],
+    "foreignKey": null,
+    "value": "KERBEROS",
+    "filename": "hive-site.xml"
+  },
+  {
+    "name": "hive.metastore.kerberos.principal",
+    "templateName": ["hive_metastore_primary_name","realm_name"],
+    "foreignKey": null,
+    "value": "<templateName[0]>@<templateName[1]>",
+    "filename": "hive-site.xml"
+  },
+  {
+    "name": "hive.metastore.kerberos.keytab.file",
+    "templateName": ["hive_metastore__keytab"],
+    "foreignKey": null,
+    "value": "<templateName[0]>",
+    "filename": "hive-site.xml"
+  },
+  {
+    "name": "hive.server2.authentication.kerberos.principal",
+    "templateName": ["hive_metastore_primary_name","realm_name"],
+    "foreignKey": null,
+    "value": "<templateName[0]>@<templateName[1]>",
+    "filename": "hive-site.xml"
+  },
+  {
+    "name": "hive.server2.authentication.kerberos.keytab",
+    "templateName": ["hive_metastore__keytab"],
+    "foreignKey": null,
+    "value": "<templateName[0]>",
+    "filename": "hive-site.xml"
+  },
+  {
+    "name": "templeton.kerberos.principal",
+    "templateName": ["webhcat_http_primary_name","realm_name"],
+    "foreignKey": null,
+    "value": "<templateName[0]>@<templateName[1]>",
+    "filename": "hive-site.xml"
+  },
+  {
+    "name": "templeton.kerberos.keytab",
+    "templateName": ["webhcat_http_keytab"],
+    "foreignKey": null,
+    "value": "<templateName[0]>",
+    "filename": "hive-site.xml"
+  }
+];
+

+ 390 - 0
ambari-web/app/data/secure_properties.js

@@ -0,0 +1,390 @@
+/**
+ * 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.
+ */
+module.exports =
+{
+  "configProperties": [
+    //GENERAL
+    {
+      "id": "puppet var",
+      "name": "security_enabled",
+      "displayName": "Enable security",
+      "value": "",
+      "defaultValue": "true",
+      "description": "Enable kerberos security for the cluster",
+      "displayType": "principal",
+      "isVisible": false,
+      "serviceName": "GENERAL",
+      "category": "KERBEROS"
+    },
+    {
+      "id": "puppet var",
+      "name": "realm_name",
+      "displayName": "Realm name",
+      "value": "",
+      "defaultValue": "EXAMPLE",
+      "description": "Realm name to be used for all principal names",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "GENERAL",
+      "category": "KERBEROS"
+    },
+    {
+      "id": "puppet var",
+      "name": "instance_name",
+      "displayName": "Instance name",
+      "value": "",
+      "defaultValue": "EXAMPLE",
+      "description": "Whether to use instance name for creating principals across cluster",
+      "displayType": "checkbox",
+      "isVisible": true,
+      "serviceName": "GENERAL",
+      "category": "KERBEROS"
+    },
+    //HDFS
+    {
+      "id": "puppet var",
+      "name": "namenode_primary_name",
+      "displayName": "primary name",
+      "value": "",
+      "defaultValue": "nn",
+      "description": "Primary name for NameNode",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "HDFS",
+      "category": "NameNode"
+    },
+    {
+      "id": "puppet var",
+      "name": "namenode_keytab",
+      "displayName": "Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "Keytab for NameNode",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "HDFS",
+      "category": "NameNode"
+    },
+    {
+      "id": "puppet var",
+      "name": "hadoop_http_primary_name",
+      "displayName": "HTTP primary name",
+      "value": "",
+      "defaultValue": "HTTP",
+      "isReconfigurable": false,
+      "description": "Primary name for spnego access for NameNode",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "HDFS",
+      "category": "General"
+    },
+    {
+      "id": "puppet var",
+      "name": "hadoop_http_keytab",
+      "displayName": "HTTP Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "Keytab for http NameNode and SNameNode",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "HDFS",
+      "category": "General"
+    },
+    {
+      "id": "puppet var",
+      "name": "snamenode_primary_name",
+      "displayName": "primary name",
+      "value": "",
+      "defaultValue": "sn",
+      "description": "Primary name for SecondaryNameNode",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "HDFS",
+      "category": "SNameNode"
+    },
+    {
+      "id": "puppet var",
+      "name": "snamenode_keytab",
+      "displayName": "Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "Keytab for SecondaryNameNode",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "HDFS",
+      "category": "SNameNode"
+    },
+    {
+      "id": "puppet var",
+      "name": "datanode_primary_name",
+      "displayName": "primary name",
+      "value": "",
+      "defaultValue": "dn",
+      "description": "Primary name for DataNode",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "HDFS",
+      "category": "DataNode"
+    },
+    {
+      "id": "puppet var",
+      "name": "datanode_keytab",
+      "displayName": "Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "Keytab for DataNode",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "HDFS",
+      "category": "DataNode"
+    },
+    //MAPREDUCE
+    {
+      "id": "puppet var",
+      "name": "jobtracker_primary_name",
+      "displayName": "primary name",
+      "value": "",
+      "defaultValue": "jt",
+      "description": "Primary name for JobTracker",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "MAPREDUCE",
+      "category": "JobTracker"
+    },
+    {
+      "id": "puppet var",
+      "name": "jobtracker_keytab",
+      "displayName": "Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "keytab for JobTracker",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "MAPREDUCE",
+      "category": "JobTracker"
+    },
+    {
+      "id": "puppet var",
+      "name": "tasktracker_primary_name",
+      "displayName": "primary name",
+      "value": "",
+      "defaultValue": "tt",
+      "description": "Primary name for TaskTracker",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "MAPREDUCE",
+      "category": "TaskTracker"
+    },
+    {
+      "id": "puppet var",
+      "name": "tasktracker_keytab",
+      "displayName": "Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "keytab for TaskTracker",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "MAPREDUCE",
+      "category": "TaskTracker"
+    },
+
+    //HBASE
+    {
+      "id": "puppet var",
+      "name": "hbase_master_primary_name",
+      "displayName": "primary name",
+      "value": "",
+      "defaultValue": "hm",
+      "description": "Primary name for HBase master",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "HBASE",
+      "category": "HBase Master"
+    },
+    {
+      "id": "puppet var",
+      "name": "hbase_master_keytab",
+      "displayName": "Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "keytab for HBase master",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "HBASE",
+      "category": "HBase Master"
+    },
+    {
+      "id": "puppet var",
+      "name": "regionserver_primary_name",
+      "displayName": "primary name",
+      "value": "",
+      "defaultValue": "rs",
+      "description": "Primary name for regionServer",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "HBASE",
+      "category": "RegionServer"
+    },
+    {
+      "id": "puppet var",
+      "name": "regionserver_keytab",
+      "displayName": "Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "keytab for RegionServer",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "HBASE",
+      "category": "RegionServer"
+    },
+
+    //HIVE
+    {
+      "id": "puppet var",
+      "name": "hive_metastore_primary_name",
+      "displayName": "primary name",
+      "value": "",
+      "defaultValue": "hive",
+      "description": "Primary name for Hive Metastore",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "HIVE",
+      "category": "Hive Metastore"
+    },
+    {
+      "id": "puppet var",
+      "name": "hive_metastore__keytab",
+      "displayName": "Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "keytab for Hive Metastore",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "HIVE",
+      "category": "Hive Metastore"
+
+    },
+
+    //OOZIE
+    {
+      "id": "puppet var",
+      "name": "oozie_primary_name",
+      "displayName": "primary name",
+      "value": "",
+      "defaultValue": "oozie",
+      "description": "Primary name for Oozie server",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "OOZIE",
+      "category": "Oozie Server"
+    },
+    {
+      "id": "puppet var",
+      "name": "oozie_keytab",
+      "displayName": "Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "Keytab for Oozie server",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "OOZIE",
+      "category": "Oozie Server"
+    },
+    {
+      "id": "puppet var",
+      "name": "oozie_http_primary_name",
+      "displayName": "HTTP primary name",
+      "value": "",
+      "defaultValue": "HTTP",
+      "description": "Primary name for spnego access for Oozie server",
+      "isReconfigurable": false,
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "OOZIE",
+      "category": "Oozie Server"
+    },
+    {
+      "id": "puppet var",
+      "name": "oozie_http_keytab",
+      "displayName": "HTTP Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "Keytab for http Oozie server",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "OOZIE",
+      "category": "Oozie Server"
+    },
+
+
+    //WEBHCAT
+    {
+      "id": "puppet var",
+      "name": "webhcat_http_primary_name",
+      "displayName": "HTTP primary name",
+      "value": "",
+      "defaultValue": "HTTP",
+      "description": "Primary name for spnego access for webHCat",
+      "displayType": "principal",
+      "isReconfigurable": false,
+      "isVisible": true,
+      "serviceName": "WEBHCAT",
+      "category": "WebHCat"
+    },
+    {
+      "id": "puppet var",
+      "name": "webhcat_http_keytab",
+      "displayName": "HTTP Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "Keytab for http webHCat",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "WEBHCAT",
+      "category": "WebHCat"
+    },
+    //HUE
+
+    //NAGIOS
+    {
+      "id": "puppet var",
+      "name": "nagios_primary_name",
+      "displayName": "primary name",
+      "value": "",
+      "defaultValue": "nagios",
+      "description": "Primary name for Nagios server",
+      "displayType": "principal",
+      "isVisible": true,
+      "serviceName": "NAGIOS",
+      "category": "General"
+    },
+    {
+      "id": "puppet var",
+      "name": "nagios_keytab",
+      "displayName": "Keytab Path",
+      "value": "",
+      "defaultValue": "",
+      "description": "Keytab for nagios",
+      "displayType": "directory",
+      "isVisible": true,
+      "serviceName": "NAGIOS",
+      "category": "General"
+    }
+
+  ]
+};

+ 27 - 3
ambari-web/app/messages.js

@@ -24,7 +24,7 @@ Em.I18n.translations = {
   'app.reloadPopup.header': 'Reload Page',
 
   'app.loadingPlaceholder': 'Loading...',
-  'app.sighout':'Sign out',
+  'app.signout':'Sign out',
 
   'apply':'apply',
   'and':'and',
@@ -56,6 +56,7 @@ Em.I18n.translations = {
   'common.hide':'Hide',
   'common.cancel':'Cancel',
   'common.apply':'Apply',
+  'common.done':'Done',
   'common.service': 'Service',
   'common.version':'Version',
   'common.description':'Description',
@@ -453,8 +454,31 @@ Em.I18n.translations = {
   'admin.authentication.form.test.fail':'The configuration fails the test',
 
   'admin.security.title':'Kerberos Security has not been enabled on this cluster.',
-  'admin.security.button.enable':'Enable Kerberos Security on this cluster',
-
+  'admin.security.enabled': 'Kerberos security is enabled on the cluster',
+  'admin.security.disabled': 'Kerberos security is disabled on the cluster',
+  'admin.security.button.enable':'Enable Security',
+  'admin.security.button.disable':'Disable Security',
+  'admin.security.enable.popup.body': 'We will walk you through add security wizard',
+  'admin.security.enable.popup.header': 'Add security',
+  'admin.security.disable.popup.header': 'Remove security',
+  'admin.security.disable.popup.body': 'Kerberos security will be disabled on the cluster',
+  'admin.security.recommend.enable': 'Enabling security is highly recommended',
+  'admin.addSecurity.header': 'Add security wizard',
+  'admin.security.step1.header': 'Start',
+  'admin.security.step2.header': 'Configure',
+  'admin.security.step3.header': 'Apply',
+  'admin.security.step1.body.header': 'Important: Before configuring your cluster to use Kerberos security, you must perform the following manual steps on your cluster.',
+  'admin.security.step1.body.instruction1': 'Install, configure and start KDC',
+  'admin.security.step1.body.instruction2': 'Install, configure and start kadmin',
+  'admin.security.step1.body.instruction3': 'Install and start clients on all machines',
+  'admin.security.step2.body.header': 'Configure Kerberos security properties',
+  'admin.security.step3.body.header': 'Applying kerberos security to the cluster',
+  'admin.addSecurity.apply.stage1': '1. Checking KDC',
+  'admin.addSecurity.apply.stage2': '1. Stopping Services',
+  'admin.addSecurity.apply.stage3': '2. Saving Configurations',
+  'admin.addSecurity.apply.stage4': '3. Starting Services',
+  'admin.addSecurity.apply.stage5': '5. Smoke Test',
+  'admin.security.status.error' : 'Error in retrieving cluster security status from server',
   'admin.users.ldapAuthentionUsed':'LDAP Authentication is being used to authenticate users',
   'admin.users.delete.yourself.message':'You can\'t delete yourself',
   'admin.users.delete.yourself.header':'Deleting warning',

+ 1 - 1
ambari-web/app/models/host_component.js

@@ -117,5 +117,5 @@ App.HostComponentStatus = {
     }
     return 'none';
   }
-}
+};
 

+ 129 - 0
ambari-web/app/routes/add_security.js

@@ -0,0 +1,129 @@
+/**
+ * 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.
+ */
+
+module.exports = Em.Route.extend({
+  route: '/addSecurity',
+  App: require('app'),
+  enter: function (router) {
+    console.log('in /hosts/add:enter');
+    router.get('mainAdminSecurityController').setAddSecurityWizardStatus('RUNNING');
+
+    Ember.run.next(function () {
+      var mainAdminSecurityController = router.get('mainAdminSecurityController');
+      var addSecurityController = router.get('addSecurityController');
+      var currentStep = router.get('addSecurityController').get('currentStep');
+      App.router.get('updateController').set('isWorking', false);
+      App.ModalPopup.show({
+        classNames: ['full-width-modal'],
+        header: Em.I18n.t('admin.addSecurity.header'),
+        bodyClass: App.MainAdminSecurityAddMenuView.extend({
+          controllerBinding: 'App.router.addSecurityController'
+        }),
+        primary: Em.I18n.t('form.cancel'),
+        secondary: null,
+        showFooter: false,
+
+        onPrimary: function () {
+          this.hide();
+          App.router.get('updateController').set('isWorking', true);
+          router.transitionTo('adminSecurity.index');
+        },
+        onClose: function () {
+          this.hide();
+          App.router.get('updateController').set('isWorking', true);
+          mainAdminSecurityController.setAddSecurityWizardStatus(null);
+          router.get('addSecurityController').setCurrentStep(1);
+          router.get('addSecurityController.content').saveCurrentStage(2);
+          router.transitionTo('adminSecurity.index');
+        },
+        didInsertElement: function () {
+          this.fitHeight();
+        }
+      });
+      App.router.transitionTo('step' + currentStep);
+    });
+
+  },
+
+  step1: Em.Route.extend({
+    route: '/start',
+    connectOutlets: function (router) {
+      console.log('in addSecurity.step1:connectOutlets');
+      var controller = router.get('addSecurityController');
+      controller.dataLoading().done(function () {
+        controller.setCurrentStep('1');
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('mainAdminSecurityAddStep1', controller.get('content'));
+      })
+    },
+
+    next: function (router) {
+      var addSecurityController = router.get('addSecurityController');
+      addSecurityController.get('content').set('serviceConfigProperties', null);
+      router.transitionTo('step2');
+    }
+  }),
+
+  step2: Em.Route.extend({
+    route: '/configure',
+    connectOutlets: function (router) {
+      console.log('in addSecurity.step2:connectOutlets');
+      var controller = router.get('addSecurityController');
+      controller.dataLoading().done(function () {
+        controller.setCurrentStep('2');
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('mainAdminSecurityAddStep2', controller.get('content'));
+      })
+    },
+    back: Em.Router.transitionTo('step1'),
+    next: function (router) {
+      var addSecurityController = router.get('addSecurityController');
+      var addSecurityStep2Controller = router.get('mainAdminSecurityAddStep2Controller');
+      addSecurityController.saveServiceConfigProperties(addSecurityStep2Controller);
+      addSecurityController.get('content').saveCurrentStage('2');
+      router.transitionTo('step3');
+    }
+  }),
+
+  step3: Em.Route.extend({
+    route: '/apply',
+    connectOutlets: function (router) {
+      console.log('in addSecurity.step3:connectOutlets');
+      var controller = router.get('addSecurityController');
+      controller.dataLoading().done(function () {
+        controller.setCurrentStep('3');
+        controller.loadAllPriorSteps();
+        controller.connectOutlet('mainAdminSecurityAddStep3', controller.get('content'));
+      })
+    },
+    back: Em.Router.transitionTo('step2'),
+    done: function (router, context) {
+      //Logic on completion of the wizard
+      //set stage to stage2 of step3
+      router.setAddSecurityWizardStatus(null);
+    }
+  }),
+
+  gotoStep1: Em.Router.transitionTo('step1'),
+
+  gotoStep2: Em.Router.transitionTo('step2'),
+
+  gotoStep3: Em.Router.transitionTo('step3')
+
+});
+

+ 239 - 138
ambari-web/app/routes/main.js

@@ -17,8 +17,8 @@
  */
 
 module.exports = Em.Route.extend({
-  route:'/main',
-  enter:function (router) {
+  route: '/main',
+  enter: function (router) {
     console.log('in /main:enter');
     if (router.getAuthenticated()) {
       App.router.get('clusterController').loadClusterName(false);
@@ -30,107 +30,118 @@ module.exports = Em.Route.extend({
       });
     }
   },
-
-  index:Ember.Route.extend({
-    route:'/',
-    redirectsTo:'dashboard'
+  /*routePath: function(router,event) {
+   if (router.getAuthenticated()) {
+   App.router.get('clusterController').loadClusterName(false);
+   router.get('mainController').initialize();
+   // TODO: redirect to last known state
+   } else {
+   Ember.run.next(function () {
+   router.transitionTo('login');
+   });
+   }
+   }, */
+
+  index: Ember.Route.extend({
+    route: '/',
+    redirectsTo: 'dashboard'
   }),
 
-  test:Em.Route.extend({
-    route:'/test',
-    connectOutlets:function (router, context) {
+  test: Em.Route.extend({
+    route: '/test',
+    connectOutlets: function (router, context) {
       router.get('mainController').connectOutlet('mainTest');
     }
   }),
 
-  connectOutlets:function (router, context) {
+  connectOutlets: function (router, context) {
     router.get('applicationController').connectOutlet('main');
   },
 
-  charts:Em.Route.extend({
-    route:'/charts',
-    connectOutlets:function (router, context) {
+  charts: Em.Route.extend({
+    route: '/charts',
+    connectOutlets: function (router, context) {
       router.get('mainController').connectOutlet('mainCharts');
     },
-    enter:function (router) {
+    enter: function (router) {
       Em.run.next(function () {
         router.transitionTo('heatmap');
       });
     },
-    index:Ember.Route.extend({
-      route:'/',
-      redirectsTo:'heatmap'
+    index: Ember.Route.extend({
+      route: '/',
+      redirectsTo: 'heatmap'
     }),
-    heatmap:Em.Route.extend({
-      route:'/heatmap',
-      connectOutlets:function (router, context) {
+    heatmap: Em.Route.extend({
+      route: '/heatmap',
+      connectOutlets: function (router, context) {
         router.get('mainChartsController').connectOutlet('mainChartsHeatmap');
       }
     }),
-    horizon_chart:Em.Route.extend({
-      route:'/horizon_chart',
-      connectOutlets:function (router, context) {
+    horizon_chart: Em.Route.extend({
+      route: '/horizon_chart',
+      connectOutlets: function (router, context) {
         router.get('mainChartsController').connectOutlet('mainChartsHorizon');
       }
     }),
-    showChart:function (router, event) {
+    showChart: function (router, event) {
       var parent = event.view._parentView;
       parent.deactivateChildViews();
       event.view.set('active', "active");
       router.transitionTo(event.context);
     }
   }),
-  apps:Em.Route.extend({
-    route:'/apps',
-    connectOutlets:function (router) {
+  apps: Em.Route.extend({
+    route: '/apps',
+    connectOutlets: function (router) {
       //router.get('clusterController').loadRuns();
       router.get('mainAppsController').loadRuns();
       router.get('mainController').connectOutlet('mainApps');
     }
   }),
 
-  hosts:Em.Route.extend({
-    route:'/hosts',
-    index:Ember.Route.extend({
-      route:'/',
-      connectOutlets:function (router, context) {
+  hosts: Em.Route.extend({
+    route: '/hosts',
+    index: Ember.Route.extend({
+      route: '/',
+      connectOutlets: function (router, context) {
         router.get('mainController').connectOutlet('mainHost');
       }
     }),
 
-    hostDetails:Em.Route.extend({
-      route:'/:host_id',
-      connectOutlets:function (router, host) {
+    hostDetails: Em.Route.extend({
+      route: '/:host_id',
+      connectOutlets: function (router, host) {
         router.get('mainController').connectOutlet('mainHostDetails', host);
       },
 
-      index:Ember.Route.extend({
-        route:'/',
-        redirectsTo:'summary'
+      index: Ember.Route.extend({
+        route: '/',
+        redirectsTo: 'summary'
       }),
 
-      summary:Em.Route.extend({
-        route:'/summary',
-        connectOutlets:function (router, context) {
+      summary: Em.Route.extend({
+        route: '/summary',
+        connectOutlets: function (router, context) {
           router.get('mainHostDetailsController').connectOutlet('mainHostSummary');
         }
       }),
 
-      metrics:Em.Route.extend({
-        route:'/metrics',
-        connectOutlets:function (router, context) {
+      metrics: Em.Route.extend({
+        route: '/metrics',
+        connectOutlets: function (router, context) {
           router.get('mainHostDetailsController').connectOutlet('mainHostMetrics');
         }
       }),
 
-      audit:Em.Route.extend({
-        route:'/audit',
-        connectOutlets:function (router, context) {
+      audit: Em.Route.extend({
+        route: '/audit',
+        connectOutlets: function (router, context) {
           router.get('mainHostDetailsController').connectOutlet('mainHostAudit');
         }
       }),
 
-      hostNavigate:function (router, event) {
+      hostNavigate: function (router, event) {
         var parent = event.view._parentView;
         parent.deactivateChildViews();
         event.view.set('active', "active");
@@ -138,20 +149,20 @@ module.exports = Em.Route.extend({
       }
     }),
 
-    backToHostsList:function (router, event) {
+    backToHostsList: function (router, event) {
       router.transitionTo('hosts.index');
     },
 
-    showDetails:function (router, event) {
+    showDetails: function (router, event) {
       router.get('mainHostDetailsController').setBack(true);
       router.transitionTo('hostDetails.summary', event.context)
     },
 
-    addHost:function (router) {
-      if(App.clusterStatus){
+    addHost: function (router) {
+      if (App.clusterStatus) {
         App.clusterStatus.updateFromServer();
         var currentClusterStatus = App.clusterStatus.get('value');
-        if(currentClusterStatus && currentClusterStatus.clusterState=="ADD_HOSTS_COMPLETED_5"){
+        if (currentClusterStatus && currentClusterStatus.clusterState == "ADD_HOSTS_COMPLETED_5") {
           // The last time add hosts ran, it left the status
           // in this state. We need to clear any previous status
           // so that the hosts page starts from fresh.
@@ -163,133 +174,222 @@ module.exports = Em.Route.extend({
 
   }),
 
-  hostAdd:require('routes/add_host_routes'),
+  hostAdd: require('routes/add_host_routes'),
+
+  admin: Em.Route.extend({
+    route: '/admin',
+    enter: function (router, transition) {
+      var controller = router.get('mainAdminController');
+      if (!App.db.getUser().admin) {
+        Em.run.next(function () {
+          router.transitionTo('main.dashboard');
+        });
+      } else {
+        // Em.run.next(function () {
+        // router.transitionTo('admin' + controller.get('category').capitalize());
+        //});
+      }
+    },
 
-  admin:Em.Route.extend({
-    route:'/admin',
-    enter: function(){
-      if(!App.db.getUser().admin){
+    routePath: function (router, event) {
+      if (!App.db.getUser().admin) {
         Em.run.next(function () {
           App.router.transitionTo('main.dashboard');
         });
+      } else {
+        // var controller = router.get('mainAdminController');
+        //router.transitionTo('admin' + controller.get('category').capitalize());
       }
     },
-    connectOutlets:function (router, context) {
+    connectOutlets: function (router, context) {
       router.get('mainController').connectOutlet('mainAdmin');
     },
 
-    index:Ember.Route.extend({
-      route:'/',
-      redirectsTo:'adminUser'
+    index: Em.Route.extend({
+      /* enter: function(router, transition){
+       var controller = router.get('mainAdminController');
+       router.transitionTo('admin' + controller.get('category').capitalize());
+       }, */
+      route: '/',
+      redirectsTo: 'adminUser'
     }),
 
-    adminUser:Em.Route.extend({
-      route:'/user',
-      enter:function (router) {
+
+    adminUser: Em.Route.extend({
+      route: '/user',
+      index: Em.Route.extend({
+        route: '/',
+        redirectsTo: 'allUsers'
+      }),
+      enter: function (router) {
         router.set('mainAdminController.category', "user");
         Em.run.next(function () {
           router.transitionTo('allUsers');
         });
       },
-
+      routePath: function (router, event) {
+        router.set('mainAdminController.category', "user");
+        router.transitionTo('allUsers');
+        Em.run.next(function () {
+          router.transitionTo('allUsers');
+        });
+      },
       // events
-      gotoUsers:Em.Router.transitionTo("allUsers"),
-      gotoCreateUser:Em.Router.transitionTo("createUser"),
-      gotoEditUser:function (router, event) {
+      gotoUsers: Em.Router.transitionTo("allUsers"),
+      gotoCreateUser: Em.Router.transitionTo("createUser"),
+      gotoEditUser: function (router, event) {
         router.transitionTo("editUser", event.context)
       },
 
       // states
-      allUsers:Em.Route.extend({
-        route:'/',
-        connectOutlets:function (router) {
+      allUsers: Em.Route.extend({
+        route: '/allUsers',
+        // index: Ember.Route.extend({
+        //route: '/',
+        connectOutlets: function (router) {
           router.get('mainAdminController').connectOutlet('mainAdminUser');
         }
+        //})
       }),
 
-      createUser:Em.Route.extend({
-        route:'/create',
-        connectOutlets:function (router) {
+      createUser: Em.Route.extend({
+        route: '/create',
+        connectOutlets: function (router) {
           router.get('mainAdminController').connectOutlet('mainAdminUserCreate', {});
         }
       }),
 
-      editUser:Em.Route.extend({
-        route:'/edit/:user_id',
-        connectOutlets:function (router, user) {
+      editUser: Em.Route.extend({
+        route: '/edit/:user_id',
+        connectOutlets: function (router, user) {
           router.get('mainAdminController').connectOutlet('mainAdminUserEdit', user);
         }
       })
     }),
 
-    adminCluster:Em.Route.extend({
-      route:'/cluster',
-      connectOutlets:function (router) {
-        router.set('mainAdminController.category', "cluster");
-        router.get('mainAdminController').connectOutlet('mainAdminCluster');
-      }
-    }),
 
-    adminAuthentication:Em.Route.extend({
-      route:'/authentication',
-      connectOutlets:function (router) {
+    adminAuthentication: Em.Route.extend({
+      route: '/authentication',
+      connectOutlets: function (router, context) {
         router.set('mainAdminController.category', "authentication");
         router.get('mainAdminController').connectOutlet('mainAdminAuthentication');
       }
     }),
 
-    adminSecurity:Em.Route.extend({
-      route:'/security',
-      connectOutlets:function (router) {
+
+    adminSecurity: Em.Route.extend({
+      route: '/security',
+      enter: function (router) {
+        //alert("1.. I am in enter path");
         router.set('mainAdminController.category', "security");
-        router.get('mainAdminController').connectOutlet('mainAdminSecurity');
-      }
+        var controller = router.get('mainAdminSecurityController');
+        if (!(controller.getAddSecurityWizardStatus() === 'RUNNING')) {
+          Em.run.next(function () {
+            router.transitionTo('adminSecurity.index');
+          });
+        } else {
+          Em.run.next(function () {
+            router.transitionTo('adminAddSecurity');
+          });
+        }
+      },
+
+      index: Ember.Route.extend({
+        route: '/',
+        connectOutlets: function (router, context) {
+          var controller = router.get('mainAdminController');
+          controller.set('category', "security");
+          var securityStatus = controller.securityStatusLoading();
+          securityStatus.done(function () {
+            controller.connectOutlet('mainAdminSecurity');
+          });
+          securityStatus.fail(function () {
+            App.ModalPopup.show({
+              header: Em.I18n.translations['common.error'],
+              secondary: false,
+              onPrimary: function () {
+                this.hide();
+              },
+              bodyClass: Ember.View.extend({
+                template: Ember.Handlebars.compile(['<p>{{t admin.security.status.error}}</p>'])
+              })
+            });
+          });
+        }
+      }),
+
+      addSecurity: function (router, object) {
+        router.transitionTo('adminAddSecurity');
+      },
+
+      disableSecurity: Ember.Route.extend({
+        route: '/',
+        connectOutlets: function (router, context) {
+          router.get('mainAdminSecurityController').connectOutlet('mainAdminSecurityDisable');
+        }
+      }),
+
+      adminAddSecurity: require('routes/add_security')
     }),
 
-    adminAdvanced:Em.Route.extend({
-      route:'/advanced',
-      connectOutlets:function (router) {
+    adminCluster: Em.Route.extend({
+      route: '/cluster',
+      connectOutlets: function (router) {
+        router.set('mainAdminController.category', "cluster");
+        router.get('mainAdminController').connectOutlet('mainAdminCluster');
+      }
+    }),
+    adminAdvanced: Em.Route.extend({
+      route: '/advanced',
+      connectOutlets: function (router) {
         router.set('mainAdminController.category', "advanced");
         router.get('mainAdminController').connectOutlet('mainAdminAdvanced');
       }
     }),
 
-    adminAudit:Em.Route.extend({
-      route:'/audit',
-      connectOutlets:function (router) {
+    adminAudit: Em.Route.extend({
+      route: '/audit',
+      connectOutlets: function (router) {
         router.set('mainAdminController.category', "audit");
         router.get('mainAdminController').connectOutlet('mainAdminAudit');
       }
     }),
-    upgradeStack:function (router, event) {
-      if(!$(event.currentTarget).hasClass('inactive')){
+    upgradeStack: function (router, event) {
+      if (!$(event.currentTarget).hasClass('inactive')) {
         router.transitionTo('stackUpgrade');
       }
     },
 
-    adminNavigate:function (router, object) {
+
+    adminNavigate: function (router, object) {
       router.transitionTo('admin' + object.context.capitalize());
-    }
+    },
+
+    //events
+    goToAdminUser: Em.Router.transitionTo('adminUser'),
+    goToAdminSecurity: Em.Router.transitionTo('adminSecurity.index'),
+    goToAdminCluster: Em.Router.transitionTo('adminCluster')
+
   }),
-  stackUpgrade:require('routes/stack_upgrade'),
+  stackUpgrade: require('routes/stack_upgrade'),
 
-  dashboard:Em.Route.extend({
-    route:'/dashboard',
-    connectOutlets:function (router, context) {
+  dashboard: Em.Route.extend({
+    route: '/dashboard',
+    connectOutlets: function (router, context) {
       router.get('mainController').connectOutlet('mainDashboard');
     },
-    showDetails:function (router, event) {
+    showDetails: function (router, event) {
       router.get('mainHostDetailsController').setBack(true);
       router.transitionTo('hosts.hostDetails.summary', event.context);
     }
   }),
 
-  services:Em.Route.extend({
-    route:'/services',
-    index:Ember.Route.extend({
-      route:'/'
+  services: Em.Route.extend({
+    route: '/services',
+    index: Ember.Route.extend({
+      route: '/'
     }),
-    enter:function (router) {
+    enter: function (router) {
       Ember.run.next(function () {
         var service = router.get('mainServiceItemController.content');
         if (!service) {
@@ -298,72 +398,73 @@ module.exports = Em.Route.extend({
         router.transitionTo('service.summary', service);
       });
     },
-    connectOutlets:function (router, context) {
+    connectOutlets: function (router, context) {
       router.get('mainController').connectOutlet('mainService');
     },
-    service:Em.Route.extend({
-      route:'/:service_id',
-      connectOutlets:function (router, service) {
+    service: Em.Route.extend({
+      route: '/:service_id',
+      connectOutlets: function (router, service) {
         router.get('mainServiceController').connectOutlet('mainServiceItem', service);
         router.transitionTo('summary');
       },
-      index:Ember.Route.extend({
-        route:'/'
+      index: Ember.Route.extend({
+        route: '/'
       }),
-      summary:Em.Route.extend({
-        route:'/summary',
-        connectOutlets:function (router, context) {
+      summary: Em.Route.extend({
+        route: '/summary',
+        connectOutlets: function (router, context) {
           var item = router.get('mainServiceItemController.content');
           var viewName = 'mainServiceInfoSummary';
           router.get('mainServiceItemController').connectOutlet('mainServiceInfoSummary', item);
         }
       }),
-      metrics:Em.Route.extend({
-        route:'/metrics',
-        connectOutlets:function (router, context) {
+      metrics: Em.Route.extend({
+        route: '/metrics',
+        connectOutlets: function (router, context) {
           var item = router.get('mainServiceItemController.content');
           router.get('mainServiceItemController').connectOutlet('mainServiceInfoMetrics', item);
         }
       }),
-      configs:Em.Route.extend({
-        route:'/configs',
-        connectOutlets:function (router, context) {
+      configs: Em.Route.extend({
+        route: '/configs',
+        connectOutlets: function (router, context) {
           var item = router.get('mainServiceItemController.content');
           router.get('mainServiceItemController').connectOutlet('mainServiceInfoConfigs', item);
         }
       }),
-      audit:Em.Route.extend({
-        route:'/audit',
-        connectOutlets:function (router, context) {
+      audit: Em.Route.extend({
+        route: '/audit',
+        connectOutlets: function (router, context) {
           var item = router.get('mainServiceItemController.content');
           router.get('mainServiceItemController').connectOutlet('mainServiceInfoAudit', item);
         }
       }),
-      showInfo:function (router, event) {
+      showInfo: function (router, event) {
         var parent = event.view._parentView;
         parent.deactivateChildViews();
         event.view.set('active', "active");
         router.transitionTo(event.context);
       },
-      showDetails:function (router, event) {
+      showDetails: function (router, event) {
         router.get('mainHostDetailsController').setBack(true);
         router.transitionTo('hosts.hostDetails.summary', event.context);
       }
     }),
-    showService:Em.Router.transitionTo('service'),
-    addService:Em.Router.transitionTo('serviceAdd')
+    showService: Em.Router.transitionTo('service'),
+    addService: Em.Router.transitionTo('serviceAdd')
   }),
 
+
   serviceAdd:require('routes/add_service_routes'),
   reassignMaster:require('routes/reassign_master_routes'),
 
 
-  selectService:Em.Route.transitionTo('services.service'),
-  selectHost:function (router, event) {
+  selectService: Em.Route.transitionTo('services.service'),
+  selectHost: function (router, event) {
     router.get('mainHostDetailsController').setBack(false);
     router.transitionTo('hosts.hostDetails.index', event.context);
   },
-  filterHosts:function (router, component) {
+  filterHosts: function (router, component) {
     router.get('mainHostController').filterByComponent(component.context);
     router.transitionTo('hosts.index');
   }

File diff suppressed because it is too large
+ 294 - 203
ambari-web/app/styles/application.less


+ 1 - 1
ambari-web/app/templates/application.hbs

@@ -43,7 +43,7 @@
                 {{App.router.loginName}}&nbsp;<span class="caret"></span>
               </button>
               <ul class="dropdown-menu">
-                <li><a href="" {{action logoff}}>{{t app.sighout}}</a></li>
+                <li><a href="" {{action logoff}}>{{t app.signout}}</a></li>
               </ul>
             </div>
           {{/if}}

+ 11 - 1
ambari-web/app/templates/main/admin.hbs

@@ -18,7 +18,17 @@
 
 <div class="row-fluid">
   <div id="main-admin-menu" class="well span2">
-  {{view App.MainAdminMenuView}}
+      <ul>
+        {{#view view.NavItemView item="user" }}
+            <a class="text-center" href="javascript:void(null);" {{action goToAdminUser}} > Users</a>
+        {{/view}}
+        {{#view view.NavItemView item="security" }}
+            <a class="text-center" href="javascript:void(null);" {{action goToAdminSecurity}} > Security</a>
+        {{/view}}
+        {{#view view.NavItemView item="cluster" }}
+          <a class="text-center" href="javascript:void(null);" {{action goToAdminCluster}} > Cluster</a>
+        {{/view}}
+      </ul>
   </div>
   <div class="span10">
     <div class="row-fluid">

+ 40 - 0
ambari-web/app/templates/main/admin/security.hbs

@@ -0,0 +1,40 @@
+{{!
+* 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 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>
+  <div>
+    {{outlet}}
+  </div>
+{{else}}
+  <div>
+    <p class="text-error">{{t admin.security.disabled}}
+      <a
+              class="btn btn-padding btn-success" {{action notifySecurityAddPopup target="controller"}}>{{t admin.security.button.enable}}
+      </a> <br/>
+    </p>
+
+    <p class="alert alert-info">{{t admin.security.recommend.enable}}</p>
+  </div>
+{{/if}}

+ 41 - 0
ambari-web/app/templates/main/admin/security/add/menu.hbs

@@ -0,0 +1,41 @@
+{{!
+* 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="addSecurity">
+    <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">{{t admin.addSecurity.header}}</li>
+                            <li {{bindAttr class="isStep1:active view.isStep1Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep1}}>{{t admin.security.step1.header}}</a></li>
+                            <li {{bindAttr class="isStep2:active view.isStep2Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep2}}>{{t admin.security.step2.header}}</a></li>
+                            <li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep3}}>{{t admin.security.step3.header}}</a></li>
+                        </ul>
+                    </div>
+                </div>
+                <div id="addSecurity-content" class="well span9">
+                  {{outlet}}
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

+ 34 - 0
ambari-web/app/templates/main/admin/security/add/step1.hbs

@@ -0,0 +1,34 @@
+{{!
+* 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.security.step1.header}}</h2>
+<p class="alert">
+  {{t admin.security.step1.body.header}}
+</p>
+<div class="alert alert-info">
+    <ol>
+        <li>{{t admin.security.step1.body.instruction1}}</li>
+        <li>{{t admin.security.step1.body.instruction2}}</li>
+        <li>{{t admin.security.step1.body.instruction3}}</li>
+    </ol>
+</div>
+
+
+<div class="btn-area">
+    <a class="btn btn-success pull-right" {{action "next"}}>Next &rarr;</a>
+</div>

+ 15 - 0
ambari-web/app/templates/main/admin/security/add/step2.hbs

@@ -0,0 +1,15 @@
+<div id="serviceConfig">
+  <h2>{{t admin.security.step2.header}}</h2>
+
+  <p class="alert alert-info">
+    {{t admin.security.step2.body.header}}
+  </p>
+  {{view App.ServicesConfigView}}
+
+  <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>

+ 30 - 0
ambari-web/app/templates/main/admin/security/add/step3.hbs

@@ -0,0 +1,30 @@
+{{!
+* 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.security.step3.header}}</h2>
+<p class="alert alert-info">
+  {{t admin.security.step3.body.header}}
+</p>
+
+{{view App.MainServiceReconfigureView}}
+
+<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 done}}>{{t common.done}} </a>
+</div>

+ 47 - 0
ambari-web/app/templates/main/service/reconfigure.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.
+}}
+
+<table id="security-stages" class="table no-borders">
+  <tbody>
+    {{#each stage in controller.stages}}
+      {{#view App.StageStatusView}}
+      <td>
+        <p {{bindAttr class="stage.hasStarted::faintText"}}>{{stage.label}}</p>
+      </td>
+      <td>
+        {{#if stage.isCompleted}}
+          {{#if stage.isSuccess}}
+            {{view App.StageSuccessView}}
+          {{else}}
+            {{view App.StageFailureView}}
+          {{/if}}
+        {{else}}
+          {{#if stage.isStarted}}
+            {{#if stage.isPolling}}
+              <div class="progress-bar pull-left">
+                {{view App.StageInProgressView stageBinding=stage}}
+              </div>
+              <div class="progress-percentage pull-left">{{stage.progress}}%</div>
+            {{/if}}
+          {{/if}}
+        {{/if}}
+      </td>
+      {{/view}}
+    {{/each}}
+  </tbody>
+</table>

+ 36 - 4
ambari-web/app/utils/db.js

@@ -51,11 +51,14 @@ App.db.cleanUp = function () {
       'loginName': '',
       'authenticated': false
     },
+
     'Installer' : {},
     'AddHost' : {},
     'AddService' : {},
     'StackUpgrade' : {},
-    'ReassignMaster' : {}
+    'ReassignMaster' : {},
+    'AddSecurity': {}
+
   };
   console.log("In cleanup./..");
   localStorage.setObject('ambari', App.db.data);
@@ -129,7 +132,7 @@ App.db.setHosts = function (hostInfo) {
   localStorage.setObject('ambari', App.db.data);
 };
 
-App.db.setInstallOptions = function(installOptions){
+App.db.setInstallOptions = function (installOptions) {
   console.log('TRACE: Entering db:setInstallOptions function');
   App.db.data = localStorage.getObject('ambari');
   App.db.data.Installer.installOptions = installOptions;
@@ -195,7 +198,7 @@ App.db.setServiceConfigs = function (serviceConfigs) {
   localStorage.setObject('ambari', App.db.data);
 };
 
-App.db.setAdvancedServiceConfig = function(serviceConfigs) {
+App.db.setAdvancedServiceConfig = function (serviceConfigs) {
   App.db.data = localStorage.getObject('ambari');
   App.db.data.Installer.advanceServiceConfigs = serviceConfigs;
   localStorage.setObject('ambari', App.db.data);
@@ -246,6 +249,21 @@ App.db.setWizardCurrentStep = function (wizardType, currentStep) {
   localStorage.setObject('ambari', App.db.data);
 };
 
+App.db.setSecurityWizardStatus = function (status) {
+  App.db.data = localStorage.getObject('ambari');
+  if (!App.db.data.AddSecurity) {
+    App.db.data.AddSecurity = {};
+  }
+  App.db.data.AddSecurity.status = status;
+  localStorage.setObject('ambari', App.db.data);
+};
+
+App.db.setSecurityStage = function (securityStage) {
+  App.db.data = localStorage.getObject('ambari');
+  App.db.data.AddSecurity.securityStage = securityStage;
+  localStorage.setObject('ambari', App.db.data);
+};
+
 
 /*
  *  getter methods
@@ -356,7 +374,7 @@ App.db.getServiceConfigs = function () {
   return App.db.data.Installer.serviceConfigs;
 };
 
-App.db.getAdvancedServiceConfig = function() {
+App.db.getAdvancedServiceConfig = function () {
   App.db.data = localStorage.getObject('ambari');
   return App.db.data.Installer.advanceServiceConfigs;
 };
@@ -386,6 +404,20 @@ App.db.getUpgradeOptions = function () {
   console.log('TRACE: Entering db:getUpgradeOptions function');
   App.db.data = localStorage.getObject('ambari');
   return App.db.data.StackUpgrade.upgradeOptions;
+}
+
+App.db.getSecurityWizardStatus = function () {
+  App.db.data = localStorage.getObject('ambari');
+  if (!App.db.data.AddSecurity) {
+    App.db.data.AddSecurity = {};
+  }
+  return App.db.data.AddSecurity.status;
+};
+
+App.db.getSecurityStage = function () {
+  App.db.data = localStorage.getObject('ambari');
+  return App.db.data.AddSecurity.securityStage;
+
 };
 
 module.exports = App.db;

+ 214 - 0
ambari-web/app/utils/polling.js

@@ -0,0 +1,214 @@
+/**
+ * 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.Poll = Em.Object.extend({
+  stage: '',
+  label: '',
+  isStarted: false,
+  isPolling: true,
+  clusterName: null,
+  requestId: null,
+  temp: false,
+  progress: 0,
+  url: null,
+  testUrl: null,
+  data: null,
+  isError: false,
+  isSuccess: false,
+  POLL_INTERVAL: 4000,
+  polledData: [],
+  numPolls: 0,
+  mockDataPrefix: '/data/wizard/deploy/5_hosts',
+
+  barWidth: function () {
+    var barWidth = 'width: ' + this.get('progress') + '%;';
+    return barWidth;
+  }.property('progress'),
+
+  isCompleted: function () {
+    return (this.get('isError') || this.get('isSuccess'));
+  }.property('isError', 'isSuccess'),
+
+  start: function () {
+    if (App.testMode) {
+      this.startPolling();
+      return;
+    }
+    var self = this;
+    var url = this.get('url');
+    var method;
+    var data = this.get('data');
+    if (App.testMode) {
+      method = 'GET';
+    } else {
+      method = 'PUT';
+    }
+
+    $.ajax({
+      type: method,
+      url: url,
+      async: false,
+      data: data,
+      dataType: 'text',
+      timeout: App.timeout,
+      success: function (data) {
+        var jsonData = jQuery.parseJSON(data);
+        console.log("TRACE: Polling -> value of the url is: " + url);
+        console.log("TRACE: Polling-> value of the sent data is: " + self.get('data'));
+        console.log("TRACE: Polling-> value of the received data is: " + jsonData);
+        if (jsonData === null) {
+          self.set('isSuccess', true);
+        } else {
+          var requestId = jsonData.Requests.id;
+          self.set('requestId', requestId);
+          console.log('requestId is: ' + requestId);
+        }
+      },
+
+      error: function () {
+        console.log("ERROR");
+        self.set('isError', true);
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+  },
+
+  doPolling: function () {
+    if (this.get('requestId')) {
+      this.startPolling();
+    }
+  }.observes('requestId'),
+
+  startPolling: function () {
+    var self = this;
+    var url = App.apiPrefix + '/clusters/' + App.router.getClusterName() + '/requests/' + this.get('requestId') + '?fields=tasks/*';
+    if (App.testMode) {
+      this.set('POLL_INTERVAL', 1);
+      this.numPolls++;
+      url = this.get('mockDataPrefix') + '/poll_' + this.get('numPolls') + '.json';
+      debugger;
+    }
+
+    $.ajax({
+      type: 'GET',
+      url: url,
+      async: true,
+      dataType: 'text',
+      timeout: App.timeout,
+      success: function (data) {
+        console.log("TRACE: In success function for the GET logs data");
+        console.log("TRACE: The value is: ", jQuery.parseJSON(data));
+        var result = self.parseInfo(jQuery.parseJSON(data));
+        if (result !== true) {
+          window.setTimeout(function () {
+            self.startPolling();
+          }, self.POLL_INTERVAL);
+        }
+      },
+
+      error: function (request, ajaxOptions, error) {
+        console.log("TRACE: In error function for the GET data");
+        console.log("TRACE: value of the url is: " + url);
+        console.log("TRACE: error code status is: " + request.status);
+        self.set('isError', true);
+      },
+
+      statusCode: require('data/statusCodes')
+    }).retry({times: App.maxRetries, timeout: App.timeout}).then(null,
+      function () {
+        App.showReloadPopup();
+        console.log('Install services all retries failed');
+      }
+    );
+  },
+
+  stopPolling: function () {
+    //this.set('isSuccess', true);
+  },
+
+  replacePolledData: function (polledData) {
+    this.polledData.clear();
+    this.set('polledData', polledData);
+  },
+
+
+  getExecutedTasks: function (tasksData) {
+    var succededTasks = tasksData.filterProperty('Tasks.status', 'COMPLETED');
+    var failedTasks = tasksData.filterProperty('Tasks.status', 'FAILED');
+    var abortedTasks = tasksData.filterProperty('Tasks.status', 'ABORTED');
+    var timedoutTasks = tasksData.filterProperty('Tasks.status', 'TIMEDOUT');
+    var inProgressTasks = tasksData.filterProperty('Tasks.status', 'IN_PROGRESS');
+    return (succededTasks.length + failedTasks.length + abortedTasks.length + timedoutTasks.length + inProgressTasks.length);
+  },
+
+  isPollingFinished: function (polledData) {
+    if (polledData.everyProperty('Tasks.status', 'COMPLETED')) {
+      this.set('isSuccess', true);
+      return true;
+    } else if (polledData.someProperty('Tasks.status', 'FAILED') || polledData.someProperty('Tasks.status', 'TIMEDOUT') || polledData.someProperty('Tasks.status', 'ABORTED')) {
+      this.set('isError', true);
+      return true;
+    } else {
+      return false;
+    }
+  },
+
+
+  parseInfo: function (polledData) {
+    console.log('TRACE: Entering task info function');
+    var self = this;
+    var totalProgress = 0;
+    var tasksData = polledData.tasks;
+    console.log("The value of tasksData is: ", tasksData);
+    if (!tasksData) {
+      console.log("ERROR: NO tasks available to process");
+    }
+    var requestId = this.get('requestId');
+    if (!App.testMode && polledData.Requests && polledData.Requests.id && polledData.Requests.id != requestId) {
+      // We dont want to use non-current requestId's tasks data to
+      // determine the current install status.
+      // Also, we dont want to keep polling if it is not the
+      // current requestId.
+      return false;
+    }
+    this.replacePolledData(tasksData);
+    /* this.hosts.forEach(function (_host) {
+     var actionsPerHost = tasksData.filterProperty('Tasks.host_name', _host.name); // retrieved from polled Data
+     if (actionsPerHost.length === 0) {
+     _host.set('message', this.t('installer.step9.host.status.nothingToInstall'));
+     console.log("INFO: No task is hosted on the host");
+     }
+     if (actionsPerHost !== null && actionsPerHost !== undefined && actionsPerHost.length !== 0) {
+     this.setLogTasksStatePerHost(actionsPerHost, _host);
+     this.onSuccessPerHost(actionsPerHost, _host);     // every action should be a success
+     this.onErrorPerHost(actionsPerHost, _host);     // any action should be a failure
+     this.onInProgressPerHost(actionsPerHost, _host);  // current running action for a host
+     totalProgress += self.progressPerHost(actionsPerHost, _host);
+     }
+     }, this); */
+    var executedTasks = this.getExecutedTasks(tasksData);
+    totalProgress = Math.floor((executedTasks / tasksData.length) * 100);
+    this.set('progress', totalProgress.toString());
+    console.log("INFO: right now the progress is: " + this.get('progress'));
+    return this.isPollingFinished(tasksData);
+  }
+
+});
+

+ 7 - 0
ambari-web/app/views.js

@@ -59,6 +59,12 @@ require('views/main/admin/user');
 require('views/main/admin/user/create');
 require('views/main/admin/user/edit');
 require('views/main/admin/user/row');
+require('views/main/admin/security');
+require('views/main/admin/security/disable');
+require('views/main/admin/security/add/menu');
+require('views/main/admin/security/add/step1');
+require('views/main/admin/security/add/step2');
+require('views/main/admin/security/add/step3');
 require('views/main/dashboard');
 require('views/main/dashboard/service');
 require('views/main/dashboard/service/hdfs');
@@ -74,6 +80,7 @@ require('views/main/dashboard/cluster_metrics/network');
 require('views/main/service');
 require('views/main/service/menu');
 require('views/main/service/item');
+require('views/main/service/reconfigure');
 require('views/main/service/info/menu');
 require('views/main/service/info/summary');
 require('views/main/service/info/configs');

+ 2 - 0
ambari-web/app/views/common/modal_popup.js

@@ -20,6 +20,8 @@ var App = require('app');
 
 App.ModalPopup = Ember.View.extend({
 
+  viewName: 'modalPopup',
+
   template: Ember.Handlebars.compile([
     '<div class="modal-backdrop"></div><div class="modal" id="modal" tabindex="-1" role="dialog" aria-labelledby="modal-label" aria-hidden="true">',
     '<div class="modal-header">',

+ 11 - 2
ambari-web/app/views/main/admin.js

@@ -19,5 +19,14 @@
 var App = require('app');
 
 App.MainAdminView = Em.View.extend({
-    templateName: require('templates/main/admin')
-});
+  templateName: require('templates/main/admin'),
+  selectedBinding: 'controller.selected',
+  NavItemView: Ember.View.extend({
+    tagName: 'li',
+    classNameBindings: 'isActive:active'.w(),
+    isActive: function () {
+      return this.get('item') === this.get('parentView.selected');
+    }.property('item', 'parentView.selected').cacheable()
+  })
+});
+

+ 32 - 14
ambari-web/app/views/main/admin/menu.js

@@ -18,12 +18,18 @@
 
 var App = require('app');
 
+// This logic is substituted by MainAdminView for now.
 App.MainAdminMenuView = Em.CollectionView.extend({
-  content:[
+  //contentBinding: 'controller',
+  /*content: [
     {
       route:'user',
       label:'Users'
     },
+    {
+      route:'security',
+      label:'Security'
+    },
     {
       route:'cluster',
       label:'Cluster'
@@ -33,30 +39,41 @@ App.MainAdminMenuView = Em.CollectionView.extend({
       route:'authentication',
       label:'Authentication'
     },
-    {
-      route:'security',
-      label:'Security'
+
+{
+      route: 'user',
+      label: 'Users'
+
     },
     {
-      route:'audit',
-      label:'Audit'
-    }*/
+      route: 'security',
+      label: 'Security'
+    }/*,
+     {
+     route:'authentication',
+     label:'Authentication'
+     },
+
+     {
+     route:'audit',
+     label:'Audit'
+     }*/
     /*,
-    {
-      route:'advanced',
-      label:'Advanced'
-    }
-    */
+     {
+     route:'advanced',
+     label:'Advanced'
+     }
+
   ],
   tagName: "ul",
   classNames: ["nav", "nav-list"],
 
-  init: function(){
+  init: function () {
     this._super();
     this.activateView(); // default selected menu
   },
 
-  activateView:function () {
+  activateView: function () {
     var route = App.get('router.mainAdminController.category');
     $.each(this._childViews, function () {
       this.set('active', (this.get('content.route') == route ? "active" : ""));
@@ -68,4 +85,5 @@ App.MainAdminMenuView = Em.CollectionView.extend({
     active:"",
     template:Ember.Handlebars.compile('<a class="text-center" {{action adminNavigate view.content.route }} href="#"> {{unbound view.content.label}}</a>')
   })
+*/
 });

+ 24 - 0
ambari-web/app/views/main/admin/security.js

@@ -0,0 +1,24 @@
+/**
+ * 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.MainAdminSecurityView = Em.View.extend({
+  templateName: require('templates/main/admin/security')
+
+});

+ 39 - 0
ambari-web/app/views/main/admin/security/add/menu.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.MainAdminSecurityAddMenuView = Em.View.extend({
+
+  templateName: require('templates/main/admin/security/add/menu'),
+
+  isStep1Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',1).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep2Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',2).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep3Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',3).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable()
+
+});
+
+

+ 28 - 0
ambari-web/app/views/main/admin/security/add/step1.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.MainAdminSecurityAddStep1View = Em.View.extend({
+
+  templateName: require('templates/main/admin/security/add/step1')
+
+});
+
+
+

+ 25 - 0
ambari-web/app/views/main/admin/security/add/step2.js

@@ -0,0 +1,25 @@
+/**
+ * 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.MainAdminSecurityAddStep2View = Em.View.extend({
+
+  templateName: require('templates/main/admin/security/add/step2')
+
+});

+ 57 - 0
ambari-web/app/views/main/admin/security/add/step3.js

@@ -0,0 +1,57 @@
+/**
+ * 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.MainAdminSecurityAddStep3View = Em.View.extend({
+
+  templateName: require('templates/main/admin/security/add/step3'),
+  didInsertElement: function () {
+    this.get('controller').loadStep();
+  }
+
+});
+
+App.StageStatusView = Em.View.extend({
+  tagName: 'tr',
+  hasStarted: null,
+  classNameBindings: ['faintText']
+});
+
+App.StageSuccessView = Em.View.extend({
+  layout: Ember.Handlebars.compile('<i class="icon-ok icon-large"></i> Done')
+});
+
+App.StageFailureView = Em.View.extend({
+  layout: Ember.Handlebars.compile('<i class="icon-remove icon-large"></i> Failed')
+});
+
+App.StageInProgressView = Em.View.extend({
+  stage: null,
+  classNames: ['progress-striped', 'active', 'progress'],
+  template: Ember.Handlebars.compile([
+    '<div class="bar" {{bindAttr style="stage.barWidth"}}>',
+    '</div>'
+  ].join('\n')),
+
+  isStageCompleted: function () {
+    return this.get('obj.progress') == 100 || this.get('controller.isStepCompleted');
+  }.property('controller.isStepCompleted', 'obj.progress')
+
+});
+

+ 28 - 0
ambari-web/app/views/main/admin/security/disable.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.MainAdminSecurityDisableView = Em.View.extend({
+
+  templateName: require('templates/main/service/reconfigure'),
+
+  didInsertElement: function () {
+    this.get('controller').loadStep();
+  }
+});

+ 58 - 0
ambari-web/app/views/main/service/reconfigure.js

@@ -0,0 +1,58 @@
+/**
+ * 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.MainServiceReconfigureView = Em.View.extend({
+
+  templateName: require('templates/main/service/reconfigure'),
+  didInsertElement: function () {
+    this.get('controller').loadStep();
+  }
+
+});
+
+App.StageStatusView = Em.View.extend({
+  tagName: 'tr',
+  hasStarted: null,
+  classNameBindings: ['faintText']
+});
+
+App.StageSuccessView = Em.View.extend({
+  layout: Ember.Handlebars.compile('<i class="icon-ok icon-large"></i> Done')
+});
+
+App.StageFailureView = Em.View.extend({
+  layout: Ember.Handlebars.compile('<i class="icon-remove icon-large"></i> Failed')
+});
+
+App.StageInProgressView = Em.View.extend({
+  stage: null,
+  classNames: ['progress-striped', 'active', 'progress'],
+  template: Ember.Handlebars.compile([
+    '<div class="bar" {{bindAttr style="stage.barWidth"}}>',
+    '</div>'
+  ].join('\n')),
+
+  isStageCompleted: function () {
+    return this.get('obj.progress') == 100 || this.get('controller.isStepCompleted');
+  }.property('controller.isStepCompleted', 'obj.progress')
+
+});
+
+
+

Some files were not shown because too many files changed in this diff