Bladeren bron

AMBARI-2555. Security Wizard: Create separate page for principal/keytab. (Andrii Tkach via yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1499803 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 jaren geleden
bovenliggende
commit
01404348d8

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

@@ -40,6 +40,7 @@ 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/security/add/step4');
 require('controllers/main/admin/authentication');
 require('controllers/main/service');
 require('controllers/main/service/item');

+ 5 - 1
ambari-web/app/controllers/main/admin/security/add/addSecurity_controller.js

@@ -22,7 +22,7 @@ App.AddSecurityController = App.WizardController.extend({
   name: 'addSecurityController',
   securityEnabled: false,
 
-  totalSteps: 3,
+  totalSteps: 4,
 
   content: Em.Object.create({
     services: [],
@@ -36,6 +36,7 @@ App.AddSecurityController = App.WizardController.extend({
   loadAllPriorSteps: function () {
     var step = this.get('currentStep');
     switch (step) {
+      case '4':
       case '3':
       case '2':
         this.loadServiceConfigs();
@@ -100,6 +101,9 @@ App.AddSecurityController = App.WizardController.extend({
           serviceName: _configProperties.get('serviceName'),
           domain:  _configProperties.get('domain'),
           filename: _configProperties.get('filename'),
+          unit: _configProperties.get('unit'),
+          components: _configProperties.get('components'),
+          component: _configProperties.get('component'),
           overrides: overridesArray
         };
         serviceConfigProperties.push(configProperty);

+ 2 - 251
ambari-web/app/controllers/main/admin/security/add/step2.js

@@ -199,263 +199,14 @@ App.MainAdminSecurityAddStep2Controller = Em.Controller.extend({
     this.setHostsToConfig(zooKeeperService, 'zookeeperserver_hosts', 'ZOOKEEPER_SERVER');
   },
 
-  showHostPrincipalKeytabList: function(){
-    App.ModalPopup.show({
-      self: this,
-      header: Em.I18n.t('admin.security.step2.popup.header'),
-      primary: Em.I18n.t('common.proceed'),
-      downloadCsv: Em.I18n.t('admin.security.step2.popup.downloadCSV'),
-      classNames: ['sixty-percent-width-modal'],
-      csvContent: [],
-      onDownloadCsv: function(){
-        var blob = new Blob([this.get('csvContent')], {type: "text/csv;charset=utf-8"});
-        saveAs(blob, "host-principal-keytab-list.csv");
-      },
-      onPrimary: function(){
-        this.hide();
-        App.router.send('next');
-      },
-      buildCsvContent: function(data){
-        this.set('csvContent', stringUtils.arrayToCSV(data));
-      },
-      bodyClass: Em.View.extend({
-        componentsToDisplay: ['NAMENODE', 'SECONDARY_NAMENODE', 'DATANODE', 'JOBTRACKER', 'ZOOKEEPER_SERVER', 'HIVE_SERVER', 'TASKTRACKER',
-        'OOZIE_SERVER', 'NAGIOS_SERVER', 'HBASE_MASTER', 'HBASE_REGIONSERVER'],
-        hostComponents: function(){
-          var componentsToDisplay = this.get('componentsToDisplay');
-          var configs = this.get('parentView.self.stepConfigs');
-          var hosts = App.Host.find();
-          var result = [];
-          hosts.forEach(function(host){
-            host.get('hostComponents').forEach(function(hostComponent){
-              if(componentsToDisplay.contains(hostComponent.get('componentName'))){
-                var serviceConfigs = configs.findProperty('serviceName', hostComponent.get('service.serviceName')).get('configs');
-                var principal, keytab;
-                serviceConfigs.forEach(function(config){
-                  if (config.get('component') && config.get('component') === hostComponent.get('componentName')) {
-                    if (config.get('name').substr(-15, 15) === '_principal_name') {
-                      principal = config.get('value').replace('_HOST', host.get('hostName')) + config.get('unit');
-                    } else if (config.get('name').substr(-7, 7) === '_keytab' || config.get('name').substr(-12, 12) === '_keytab_path') {
-                      keytab = config.get('value');
-                    }
-                  } else if (config.get('components') && config.get('components').contains(hostComponent.get('componentName'))) {
-                    if (config.get('name').substr(-15, 15) === '_principal_name') {
-                      principal = config.get('value').replace('_HOST', host.get('hostName')) + config.get('unit');
-                    } else if (config.get('name').substr(-7, 7) === '_keytab' || config.get('name').substr(-12, 12) === '_keytab_path') {
-                      keytab = config.get('value');
-                    }
-                  }
-                });
-
-                result.push({
-                  host: host.get('hostName'),
-                  component: hostComponent.get('displayName'),
-                  principal: principal,
-                  keytab: keytab
-                });
-              }
-            });
-          });
-          this.get('parentView').buildCsvContent(result);
-          return result;
-        }.property(),
-        template: Em.Handlebars.compile([
-          '<div class="alert alert-info">{{t admin.security.step2.popup.notice}}</div>',
-          '<div class="long-popup-list">',
-            '<table class="table table-bordered table-striped">',
-            '<thead>',
-              '<tr>',
-                '<th>{{t common.host}}</th>',
-                '<th>{{t common.component}}</th>',
-                '<th>{{t admin.security.step2.popup.table.principal}}</th>',
-                '<th>{{t admin.security.step2.popup.table.keytab}}</th>',
-              '</tr>',
-            '</thead>',
-            '<tbody>',
-            '{{#each hostComponent in view.hostComponents}}',
-              '<tr>',
-                '<td>{{hostComponent.host}}</td>',
-                '<td>{{hostComponent.component}}</td>',
-                '<td>{{hostComponent.principal}}</td>',
-                '<td>{{hostComponent.keytab}}</td>',
-              '</tr>',
-            '{{/each}}',
-            '</tbody>',
-            '</table>',
-          '</div>'
-        ].join(''))
-      }),
-      footerClass: Em.View.extend({
-        classNames: ['modal-footer'],
-        template: Em.Handlebars.compile([
-          '{{#if view.parentView.downloadCsv}}<a class="btn btn-info" {{action onDownloadCsv target="view.parentView"}}>{{view.parentView.downloadCsv}}</a>&nbsp;{{/if}}',
-          '{{#if view.parentView.secondary}}<a class="btn" {{action onSecondary target="view.parentView"}}>{{view.parentView.secondary}}</a>&nbsp;{{/if}}',
-          '{{#if view.parentView.primary}}<a class="btn btn-success" {{action onPrimary target="view.parentView"}}>{{view.parentView.primary}}</a>{{/if}}'
-        ].join(''))
-      })
-    });
-  },
-
   /**
    *  submit and move to step3
    */
 
   submit: function () {
     if (!this.get('isSubmitDisabled')) {
-      if (App.supports.secureClusterProceedPopup) {
-        this.showHostPrincipalKeytabList();
-      } else {
-        App.router.send('next');
-      }
+      App.router.send('next');
     }
-  },
+  }
 
-  doDownloadCsv: function(){
-      var blob = new Blob([this.buildCvsContent()], {type: "text/csv;charset=utf-8"});
-      saveAs(blob, "host-principal-keytab-list.csv");
-    },
-    
-    buildCvsContent: function() {
-      var configs = this.get('stepConfigs');
-      var hosts = App.Host.find();
-      var result = [];
-      var componentsToDisplay = ['NAMENODE', 'SECONDARY_NAMENODE', 'DATANODE', 'JOBTRACKER', 'ZOOKEEPER_SERVER', 'HIVE_SERVER', 'TASKTRACKER',
-                                 'OOZIE_SERVER', 'NAGIOS_SERVER', 'HBASE_MASTER', 'HBASE_REGIONSERVER'];
-      var securityUsers = App.router.get('mainAdminSecurityController').get('serviceUsers');
-      if (!securityUsers || securityUsers.length < 1) { // Page could be refreshed in middle
-        if (App.testMode) {
-          securityUsers.pushObject({id: 'puppet var', name: 'hdfs_user', value: 'hdfs'});
-          securityUsers.pushObject({id: 'puppet var', name: 'mapred_user', value: 'mapred'});
-          securityUsers.pushObject({id: 'puppet var', name: 'hbase_user', value: 'hbase'});
-          securityUsers.pushObject({id: 'puppet var', name: 'hive_user', value: 'hive'});
-          securityUsers.pushObject({id: 'puppet var', name: 'smokeuser', value: 'ambari-qa'});
-        } else {
-          App.router.get('mainAdminSecurityController').setSecurityStatus();
-          securityUsers = App.router.get('mainAdminSecurityController').get('serviceUsers');
-        }
-      }
-      var isHbaseInstalled = App.Service.find().findProperty('serviceName', 'HBASE');
-      var generalConfigs = configs.findProperty('serviceName', 'GENERAL').configs;
-      var realm = generalConfigs.findProperty('name', 'kerberos_domain').get('value');
-      var smokeUserId = securityUsers.findProperty('name', 'smokeuser').value;
-      var hdfsUserId = securityUsers.findProperty('name', 'hdfs_user').value;
-      var hbaseUserId = securityUsers.findProperty('name', 'hbase_user').value;
-      var mapredUserId = securityUsers.findProperty('name', 'mapred_user').value;
-      var hiveUserId = securityUsers.findProperty('name', 'hive_user').value;
-      var zkUserId = securityUsers.findProperty('name', 'zk_user').value;
-      var oozieUserId = securityUsers.findProperty('name', 'oozie_user').value;
-      var nagiosUserId = securityUsers.findProperty('name', 'nagios_user').value;
-      var hadoopGroupId = securityUsers.findProperty('name', 'user_group').value;
-      
-      var smokeUser = smokeUserId + '@' + realm;
-      var hdfsUser = hdfsUserId + '@' + realm;
-      var hbaseUser = hbaseUserId + '@' + realm;
-      var smokeUserKeytabPath = generalConfigs.findProperty('name', 'smokeuser_keytab').get('value');
-      var hdfsUserKeytabPath = generalConfigs.findProperty('name', 'keytab_path').get('value') + "/hdfs.headless.keytab";
-      var hbaseUserKeytabPath = generalConfigs.findProperty('name', 'keytab_path').get('value') + "/hbase.headless.keytab";
-      var httpPrincipal = generalConfigs.findProperty('name', 'hadoop_http_principal_name');
-      var httpKeytabPath = generalConfigs.findProperty('name', 'hadoop_http_keytab').get('value');
-      var componentToOwnerMap = {
-          'NAMENODE': hdfsUserId,
-          'SECONDARY_NAMENODE': hdfsUserId,
-          'DATANODE': hdfsUserId,
-          'TASKTRACKER': mapredUserId,
-          'JOBTRACKER': mapredUserId,
-          'ZOOKEEPER_SERVER': zkUserId,
-          'HIVE_SERVER': hiveUserId,
-          'OOZIE_SERVER': oozieUserId,
-          'NAGIOS_SERVER': nagiosUserId,
-          'HBASE_MASTER': hbaseUserId,
-          'HBASE_REGIONSERVER': hbaseUserId
-      };
-      
-      var addedPrincipalsHost = {}; //Keys = host_principal, Value = 'true'
-      
-      hosts.forEach(function(host){
-        result.push({
-          host: host.get('hostName'),
-          component: Em.I18n.t('admin.addSecurity.user.smokeUser'),
-          principal: smokeUser,
-          keytab: smokeUserKeytabPath,
-          owner: smokeUserId,
-          group: hadoopGroupId,
-          acl: '440'
-        });
-        result.push({
-          host: host.get('hostName'),
-          component: Em.I18n.t('admin.addSecurity.user.hdfsUser'),
-          principal: hdfsUser,
-          keytab: hdfsUserKeytabPath,
-          owner: hdfsUserId,
-          group: hadoopGroupId,
-          acl: '440'
-        });
-        if (isHbaseInstalled) {
-          result.push({
-            host: host.get('hostName'),
-            component: Em.I18n.t('admin.addSecurity.user.hbaseUser'),
-            principal: hbaseUser,
-            keytab: hbaseUserKeytabPath,
-            owner: hbaseUserId,
-            group: hadoopGroupId,
-            acl: '440'
-          });
-        }
-        if(host.get('hostComponents').someProperty('componentName', 'NAMENODE') || 
-          host.get('hostComponents').someProperty('componentName', 'SECONDARY_NAMENODE') ||
-          host.get('hostComponents').someProperty('componentName', 'WEBHCAT_SERVER') ||
-          host.get('hostComponents').someProperty('componentName', 'OOZIE_SERVER')){
-          result.push({
-            host: host.get('hostName'),
-            component: Em.I18n.t('admin.addSecurity.user.httpUser'),
-            principal: httpPrincipal.get('value').replace('_HOST', host.get('hostName')) + httpPrincipal.get('unit'),
-            keytab: httpKeytabPath,
-            owner: 'root',
-            group: hadoopGroupId,
-            acl: '440'
-          });
-        }
-        host.get('hostComponents').forEach(function(hostComponent){
-          if(componentsToDisplay.contains(hostComponent.get('componentName'))){
-            var serviceConfigs = configs.findProperty('serviceName', hostComponent.get('service.serviceName')).get('configs');
-            var principal, keytab;
-            serviceConfigs.forEach(function(config){
-              if (config.get('component') && config.get('component') === hostComponent.get('componentName')) {
-                if (config.get('name').endsWith('_principal_name')) {
-                  principal = config.get('value').replace('_HOST', host.get('hostName')) + config.get('unit');
-                } else if (config.get('name').endsWith('_keytab') || config.get('name').endsWith('_keytab_path')) {
-                  keytab = config.get('value');
-                }
-              } else if (config.get('components') && config.get('components').contains(hostComponent.get('componentName'))) {
-                if (config.get('name').endsWith('_principal_name')) {
-                  principal = config.get('value').replace('_HOST', host.get('hostName')) + config.get('unit');
-                } else if (config.get('name').endsWith('_keytab') || config.get('name').endsWith('_keytab_path')) {
-                  keytab = config.get('value');
-                }
-              }
-            });
-            
-   
-            var key = host.get('hostName') + "--" + principal;
-            if (!addedPrincipalsHost[key]) {
-              var owner = componentToOwnerMap[hostComponent.get('componentName')];
-              if(!owner){
-                owner = '';
-              }
-              result.push({
-                host: host.get('hostName'),
-                component: hostComponent.get('displayName'),
-                principal: principal,
-                keytab: keytab,
-                owner: owner,
-                group: hadoopGroupId,
-                acl: '400'
-              });
-              addedPrincipalsHost[key] = true;
-            }
-          }
-        });
-      });
-      return stringUtils.arrayToCSV(result);
-    }
 });

+ 142 - 599
ambari-web/app/controllers/main/admin/security/add/step3.js

@@ -17,617 +17,160 @@
  */
 
 var App = require('app');
-App.MainAdminSecurityAddStep3Controller = Em.Controller.extend({
+var stringUtils = require('utils/string_utils');
 
+App.MainAdminSecurityAddStep3Controller = Em.Controller.extend({
   name: 'mainAdminSecurityAddStep3Controller',
-  secureMapping: require('data/secure_mapping'),
-  secureProperties: require('data/secure_properties').configProperties,
-  stages: [],
-  configs: [],
-  noOfWaitingAjaxCalls: 0,
-  secureServices: [],
-  serviceConfigTags: [],
-  globalProperties: [],
-
-  isSubmitDisabled: true,
-  isBackBtnDisabled: function () {
-    return !this.get('stages').someProperty('isError', true);
-  }.property('stages.@each.isCompleted'),
-
-  isOozieSelected: function () {
-    return this.get('content.services').someProperty('serviceName', 'OOZIE');
-  }.property('content.services'),
-
-  isHiveSelected: function () {
-    return this.get('content.services').someProperty('serviceName', 'HIVE');
-  }.property('content.services'),
-
-  isNagiosSelected: function () {
-    return this.get('content.services').someProperty('serviceName', 'NAGIOS');
-  }.property('content.services'),
-
-  isZkSelected: function () {
-    return this.get('content.services').someProperty('serviceName', 'ZOOKEEPER');
-  }.property('content.services'),
-
-  isWebHcatSelected: function () {
-    var installedServices = App.Service.find().mapProperty('serviceName');
-    return installedServices.contains('WEBHCAT');
-  },
-
-  serviceUsersBinding: 'App.router.mainAdminSecurityController.serviceUsers',
-  hasHostPopup: true,
-  services: [],
-  serviceTimestamp: null,
-
-  isSecurityApplied: function () {
-    return this.get('stages').someProperty('stage', 'stage3') && this.get('stages').findProperty('stage', 'stage3').get('isSuccess');
-  }.property('stages.@each.isCompleted'),
-
-  clearStep: function () {
-    this.get('stages').clear();
-    this.set('isSubmitDisabled', true);
-    this.set('isBackBtnDisabled', true);
-    this.get('serviceConfigTags').clear();
-  },
-
-  retry: function () {
-    if (this.get('stages').someProperty('isError', true)) {
-      var failedStages = this.get('stages').filterProperty('isError', true);
-      failedStages.setEach('isError', false);
-      failedStages.setEach('isSuccess', false);
-      failedStages.setEach('isStarted', false);
-    }
-    this.moveToNextStage();
-  },
-
-  loadStep: function () {
-    this.set('secureMapping', require('data/secure_mapping').slice(0));
-    this.clearStep();
-    var stages = App.db.getSecurityDeployStages();
-    this.prepareSecureConfigs();
-    if (stages && stages.length > 0) {
-      stages.forEach(function (_stage, index) {
-        stages[index] = App.Poll.create(_stage);
-      }, this);
-      if (stages.someProperty('isError', true)) {
-        this.get('stages').pushObjects(stages);
-        return;
-      } else if (stages.filterProperty('isStarted', true).someProperty('isCompleted', false)) {
-        var runningStage = stages.filterProperty('isStarted', true).findProperty('isCompleted', false);
-        runningStage.set('isStarted', false);
-        this.get('stages').pushObjects(stages);
+  hostComponents: [],
+  doDownloadCsv: function(){
+    var blob = new Blob([stringUtils.arrayToCSV(this.get('hostComponents'))], {type: "text/csv;charset=utf-8"});
+    saveAs(blob, "host-principal-keytab-list.csv");
+  },
+  loadStep: function(){
+    var configs = this.get('content.serviceConfigProperties');
+    var hosts = App.Host.find();
+    var result = [];
+    var componentsToDisplay = ['NAMENODE', 'SECONDARY_NAMENODE', 'DATANODE', 'JOBTRACKER', 'ZOOKEEPER_SERVER', 'HIVE_SERVER', 'TASKTRACKER',
+      'OOZIE_SERVER', 'NAGIOS_SERVER', 'HBASE_MASTER', 'HBASE_REGIONSERVER'];
+    var securityUsers = [];
+    if (!securityUsers || securityUsers.length < 1) { // Page could be refreshed in middle
+      if (App.testMode) {
+        securityUsers.pushObject({id: 'puppet var', name: 'hdfs_user', value: 'hdfs'});
+        securityUsers.pushObject({id: 'puppet var', name: 'mapred_user', value: 'mapred'});
+        securityUsers.pushObject({id: 'puppet var', name: 'hbase_user', value: 'hbase'});
+        securityUsers.pushObject({id: 'puppet var', name: 'hive_user', value: 'hive'});
+        securityUsers.pushObject({id: 'puppet var', name: 'smokeuser', value: 'ambari-qa'});
+        securityUsers.pushObject({id: 'puppet var', name: 'zk_user', value: 'zookeeper'});
+        securityUsers.pushObject({id: 'puppet var', name: 'oozie_user', value: 'oozie'});
+        securityUsers.pushObject({id: 'puppet var', name: 'nagios_user', value: 'nagios'});
+        securityUsers.pushObject({id: 'puppet var', name: 'user_group', value: 'hadoop'});
       } else {
-        this.get('stages').pushObjects(stages);
-      }
-    } else {
-      this.loadStages();
-      this.addInfoToStages();
-      var runningOperations = App.router.get('backgroundOperationsController.services').filterProperty('isRunning');
-      var stopAllOperation = runningOperations.findProperty('name', 'Stop All Services');
-      var stopStage = this.get('stages').findProperty('name', 'STOP_SERVICES');
-      if (stopStage.get('name') === 'STOP_SERVICES' && stopAllOperation) {
-        stopStage.set('requestId', stopAllOperation.get('id'));
-      }
-    }
-    this.moveToNextStage();
-  },
-
-  enableSubmit: function () {
-    var addSecurityController = App.router.get('addSecurityController');
-    if (this.get('stages').someProperty('isError', true) || this.get('stages').everyProperty('isSuccess', true)) {
-      this.set('isSubmitDisabled', false);
-      if (this.get('stages').someProperty('isError', true)) {
-        addSecurityController.setStepsEnable();
-      }
-    } else {
-      this.set('isSubmitDisabled', true);
-      addSecurityController.setLowerStepsDisable(3);
-    }
-  }.observes('stages.@each.isCompleted'),
+        App.router.get('mainAdminSecurityController').setSecurityStatus();
+        securityUsers = App.router.get('mainAdminSecurityController').get('serviceUsers');
+      }
+    }
+    var isHbaseInstalled = App.Service.find().findProperty('serviceName', 'HBASE');
+    var generalConfigs = configs.filterProperty('serviceName', 'GENERAL');
+    var realm = generalConfigs.findProperty('name', 'kerberos_domain').value;
+    var smokeUserId = securityUsers.findProperty('name', 'smokeuser').value;
+    var hdfsUserId = securityUsers.findProperty('name', 'hdfs_user').value;
+    var hbaseUserId = securityUsers.findProperty('name', 'hbase_user').value;
+    var mapredUserId = securityUsers.findProperty('name', 'mapred_user').value;
+    var hiveUserId = securityUsers.findProperty('name', 'hive_user').value;
+    var zkUserId = securityUsers.findProperty('name', 'zk_user').value;
+    var oozieUserId = securityUsers.findProperty('name', 'oozie_user').value;
+    var nagiosUserId = securityUsers.findProperty('name', 'nagios_user').value;
+    var hadoopGroupId = securityUsers.findProperty('name', 'user_group').value;
+
+    var smokeUser = smokeUserId + '@' + realm;
+    var hdfsUser = hdfsUserId + '@' + realm;
+    var hbaseUser = hbaseUserId + '@' + realm;
+    var smokeUserKeytabPath = generalConfigs.findProperty('name', 'smokeuser_keytab').value;
+    var hdfsUserKeytabPath = generalConfigs.findProperty('name', 'keytab_path').value + "/hdfs.headless.keytab";
+    var hbaseUserKeytabPath = generalConfigs.findProperty('name', 'keytab_path').value + "/hbase.headless.keytab";
+    var httpPrincipal = generalConfigs.findProperty('name', 'hadoop_http_principal_name');
+    var httpKeytabPath = generalConfigs.findProperty('name', 'hadoop_http_keytab').value;
+    var componentToOwnerMap = {
+      'NAMENODE': hdfsUserId,
+      'SECONDARY_NAMENODE': hdfsUserId,
+      'DATANODE': hdfsUserId,
+      'TASKTRACKER': mapredUserId,
+      'JOBTRACKER': mapredUserId,
+      'ZOOKEEPER_SERVER': zkUserId,
+      'HIVE_SERVER': hiveUserId,
+      'OOZIE_SERVER': oozieUserId,
+      'NAGIOS_SERVER': nagiosUserId,
+      'HBASE_MASTER': hbaseUserId,
+      'HBASE_REGIONSERVER': hbaseUserId
+    };
 
-  updateServices: function () {
-    this.services.clear();
-    var services = this.get("services");
-    this.get("stages").forEach(function (stage) {
-      var newService = Ember.Object.create({
-        name: stage.label,
-        hosts: []
+    var addedPrincipalsHost = {}; //Keys = host_principal, Value = 'true'
+
+    hosts.forEach(function(host){
+      result.push({
+        host: host.get('hostName'),
+        component: Em.I18n.t('admin.addSecurity.user.smokeUser'),
+        principal: smokeUser,
+        keytab: smokeUserKeytabPath,
+        owner: smokeUserId,
+        group: hadoopGroupId,
+        acl: '440'
       });
-      if (stage && stage.get("polledData")) {
-        var hostNames = stage.get("polledData").mapProperty('Tasks.host_name').uniq();
-        hostNames.forEach(function (name) {
-          newService.hosts.push({
-            name: name,
-            publicName: name,
-            logTasks: stage.polledData.filterProperty("Tasks.host_name", name)
-          });
-        });
-        services.push(newService);
-      }
-    });
-    this.set('serviceTimestamp', new Date().getTime());
-  }.observes('stages.@each.polledData'),
-
-  loadStages: function () {
-    this.get('stages').pushObjects([
-      App.Poll.create({stage: 'stage2', label: Em.I18n.translations['admin.addSecurity.apply.stage2'], isPolling: true, name: 'STOP_SERVICES'}),
-      App.Poll.create({stage: 'stage3', label: Em.I18n.translations['admin.addSecurity.apply.stage3'], isPolling: false, name: 'APPLY_CONFIGURATIONS'}),
-      App.Poll.create({stage: 'stage4', label: Em.I18n.translations['admin.addSecurity.apply.stage4'], isPolling: true, name: 'START_SERVICES'})
-    ]);
-  },
-
-  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);
-          App.router.get('mainAdminSecurityController').setAddSecurityWizardStatus(null);
-        } else {
-          this.loadClusterConfigs()
-        }
-      }
-    }
-  }.observes('stages.@each.isStarted'),
-
-  onCompleteStage: function () {
-    var index = this.get('stages').filterProperty('isCompleted', true).length;
-    if (index > 0) {
-      var lastCompletedStageResult = this.get('stages').objectAt(index - 1).get('isSuccess');
-      if (lastCompletedStageResult) {
-        this.moveToNextStage();
-      }
-    }
-  }.observes('stages.@each.isCompleted'),
-
-  moveToNextStage: function () {
-    var leftStages = this.get('stages').filterProperty('isStarted', false);
-    var nextStage = leftStages.findProperty('isCompleted', false);
-    if (nextStage) {
-      nextStage.set('isStarted', true);
-    }
-  },
-
-  addInfoToStages: function () {
-    this.addInfoToStage2();
-    this.addInfoToStage4();
-  },
-
-  addInfoToStage1: function () {
-    var stage1 = this.get('stages').findProperty('stage', 'stage1');
-    if (App.testMode) {
-      stage1.set('isSuccess', 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 = '{"RequestInfo": {"context" :"' + Em.I18n.t('requestInfo.stopAllServices') + '"}, "Body": {"ServiceInfo": {"state": "INSTALLED"}}}';
-    stage2.set('url', url);
-    stage2.set('data', data);
-  },
-
-  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?params/run_smoke_test=true';
-    var data = '{"RequestInfo": {"context": "' + Em.I18n.t('requestInfo.startAllServices') + '"}, "Body": {"ServiceInfo": {"state": "STARTED"}}}';
-    stage4.set('url', url);
-    stage4.set('data', data);
-  },
-
-  loadUiSideConfigs: function () {
-    var uiConfig = [];
-    var configs = this.get('secureMapping').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
+      result.push({
+        host: host.get('hostName'),
+        component: Em.I18n.t('admin.addSecurity.user.hdfsUser'),
+        principal: hdfsUser,
+        keytab: hdfsUserKeytabPath,
+        owner: hdfsUserId,
+        group: hadoopGroupId,
+        acl: '440'
       });
-    }, this);
-    var dependentConfig = this.get('secureMapping').filterProperty('foreignKey');
-    dependentConfig.forEach(function (_config) {
-      if (App.Service.find().mapProperty('serviceName').contains(_config.serviceName)) {
-        this.setConfigValue(uiConfig, _config);
-        uiConfig.pushObject({
-          "id": "site property",
-          "name": _config._name || _config.name,
-          "value": _config.value,
-          "filename": _config.filename
+      if (isHbaseInstalled) {
+        result.push({
+          host: host.get('hostName'),
+          component: Em.I18n.t('admin.addSecurity.user.hbaseUser'),
+          principal: hbaseUser,
+          keytab: hbaseUserKeytabPath,
+          owner: hbaseUserId,
+          group: hadoopGroupId,
+          acl: '440'
         });
       }
-    }, 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);
-      var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
-      var globValue = this.get('globalProperties').findProperty('name', templateName[index]);
-      if (globValue) {
-        console.log('The template value of templateName ' + '[' + index + ']' + ': ' + templateName[index] + ' is: ' + globValue);
-        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.value);
-        }
-      } else {
-        /*
-         console.log("ERROR: The variable name is: " + templateName[index]);
-         console.log("ERROR: mapped config from secureMapping 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;
+      if(host.get('hostComponents').someProperty('componentName', 'NAMENODE') ||
+        host.get('hostComponents').someProperty('componentName', 'SECONDARY_NAMENODE') ||
+        host.get('hostComponents').someProperty('componentName', 'WEBHCAT_SERVER') ||
+        host.get('hostComponents').someProperty('componentName', 'OOZIE_SERVER')){
+        result.push({
+          host: host.get('hostName'),
+          component: Em.I18n.t('admin.addSecurity.user.httpUser'),
+          principal: httpPrincipal.value.replace('_HOST', host.get('hostName')) + httpPrincipal.unit,
+          keytab: httpKeytabPath,
+          owner: 'root',
+          group: hadoopGroupId,
+          acl: '440'
+        });
       }
-    }, this);
-    return value;
-  },
+      host.get('hostComponents').forEach(function(hostComponent){
+        if(componentsToDisplay.contains(hostComponent.get('componentName'))){
+          var serviceConfigs = configs.filterProperty('serviceName', hostComponent.get('service.serviceName'));
+          var principal, keytab;
+          serviceConfigs.forEach(function(config){
+            if (config.component && config.component === hostComponent.get('componentName')) {
+              if (config.name.endsWith('_principal_name')) {
+                principal = config.value.replace('_HOST', host.get('hostName')) + config.unit;
+              } else if (config.name.endsWith('_keytab') || config.name.endsWith('_keytab_path')) {
+                keytab = config.value;
+              }
+            } else if (config.components && config.components.contains(hostComponent.get('componentName'))) {
+              if (config.name.endsWith('_principal_name')) {
+                principal = config.value.replace('_HOST', host.get('hostName')) + config.unit;
+              } else if (config.name.endsWith('_keytab') || config.name.endsWith('_keytab_path')) {
+                keytab = config.value;
+              }
+            }
+          });
 
-  /**
-   * Set all site property that are derived from other site-properties
-   */
-  setConfigValue: function (uiConfig, config) {
-    if (config.value == null) {
-      return;
-    }
-    var fkValue = config.name.match(/<(foreignKey.*?)>/g);
-    if (fkValue) {
-      fkValue.forEach(function (_fkValue) {
-        var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]);
-        var globalValue;
-        if (uiConfig.someProperty('name', config.foreignKey[index])) {
-          globalValue = uiConfig.findProperty('name', config.foreignKey[index]).value;
-          config._name = config.name.replace(_fkValue, globalValue);
-        } else if (this.get('globalProperties').someProperty('name', config.foreignKey[index])) {
-          globalValue = this.get('globalProperties').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]);
-        var globValue = this.get('globalProperties').findProperty('name', config.templateName[index]);
-        if (globValue) {
-          config.value = config.value.replace(_value, globValue.value);
-        } else {
-          config.value = null;
+          var key = host.get('hostName') + "--" + principal;
+          if (!addedPrincipalsHost[key]) {
+            var owner = componentToOwnerMap[hostComponent.get('componentName')];
+            if(!owner){
+              owner = '';
+            }
+            result.push({
+              host: host.get('hostName'),
+              component: hostComponent.get('displayName'),
+              principal: principal,
+              keytab: keytab,
+              owner: owner,
+              group: hadoopGroupId,
+              acl: '400'
+            });
+            addedPrincipalsHost[key] = true;
+          }
         }
-      }, this);
-    }
-  },
-
-  prepareSecureConfigs: function () {
-    this.loadGlobals();
-    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);
-    this.loadStaticGlobal(); //Hack for properties which are declared in config_properties.js and not able to retrieve values declared in secure_properties.js
-    this.loadUsersToGlobal();
-    this.loadHostNamesToGlobal();
-    this.loadPrimaryNamesToGlobals();
-  },
-
-  loadUsersToGlobal: function () {
-    if (!this.get('serviceUsers').length) {
-      this.loadUsersFromServer();
-    }
-    App.router.get('mainAdminSecurityController.serviceUsers').forEach(function (_user) {
-      this.get('globalProperties').pushObject(_user);
-    }, this);
-  },
-
-  loadHostNamesToGlobal: function () {
-    var oozieHostComponent = App.Service.find('OOZIE').get('hostComponents').findProperty('componentName', 'OOZIE_SERVER');
-    if (this.get('isOozieSelected') && oozieHostComponent) {
-      var oozieHostName = oozieHostComponent.get('host.hostName');
-      this.get('globalProperties').pushObject({
-        id: 'puppet var',
-        name: 'oozieserver_host',
-        value: oozieHostName
       });
-    }
-    var hiveHostComponent = App.Service.find('HIVE').get('hostComponents').findProperty('componentName', 'HIVE_METASTORE');
-    if (this.get('isHiveSelected') && hiveHostComponent) {
-      var hiveHostName = hiveHostComponent.get('host.hostName');
-      this.get('globalProperties').pushObject({
-        id: 'puppet var',
-        name: 'hivemetastore_host',
-        value: hiveHostName
-      });
-    }
-    var webHcatComponent = App.Service.find('WEBHCAT').get('hostComponents').findProperty('componentName', 'WEBHCAT_SERVER');
-    if (this.isWebHcatSelected() && webHcatComponent) {
-      var webHcatHostName = webHcatComponent.get('host.hostName');
-      this.get('globalProperties').pushObject({
-        id: 'puppet var',
-        name: 'webhcat_server',
-        value: webHcatHostName
-      });
-    }
-  },
-
-  loadStaticGlobal: function () {
-    var globalProperties = this.get('globalProperties');
-    this.get('globalProperties').forEach(function (_property) {
-      switch (_property.name) {
-        case 'security_enabled':
-          _property.value = 'true';
-          break;
-        case 'dfs_datanode_address':
-          _property.value = '1019';
-          break;
-        case 'dfs_datanode_http_address':
-          _property.value = '1022';
-          break;
-      }
-    }, this);
-  },
-
-  loadPrimaryNamesToGlobals: function () {
-    var principalProperties = this.getPrincipalNames();
-    principalProperties.forEach(function (_principalProperty) {
-      var name = _principalProperty.name.replace('principal', 'primary');
-      var value = _principalProperty.value.split('/')[0];
-      this.get('globalProperties').pushObject({name: name, value: value});
-    }, this);
-  },
-
-  getPrincipalNames: function () {
-    var principalNames = [];
-    var allPrincipalNames = [];
-    this.get('globalProperties').forEach(function (_globalProperty) {
-      if (/principal_name?$/.test(_globalProperty.name)) {
-        principalNames.pushObject(_globalProperty);
-      }
-    }, this);
-    this.get('secureProperties').forEach(function (_secureProperty) {
-      if (/principal_name?$/.test(_secureProperty.name)) {
-        var principalName = principalNames.findProperty('name', _secureProperty.name);
-        if (!principalName) {
-          _secureProperty.value = _secureProperty.defaultValue;
-          principalNames.pushObject(_secureProperty);
-        }
-      }
-    }, this);
-    return principalNames;
-  },
-
-  loadUsersFromServer: function () {
-    if (App.testMode) {
-      var serviceUsers = this.get('serviceUsers');
-      serviceUsers.pushObject({id: 'puppet var', name: 'hdfs_user', value: 'hdfs'});
-      serviceUsers.pushObject({id: 'puppet var', name: 'mapred_user', value: 'mapred'});
-      serviceUsers.pushObject({id: 'puppet var', name: 'hbase_user', value: 'hbase'});
-      serviceUsers.pushObject({id: 'puppet var', name: 'hive_user', value: 'hive'});
-    } else {
-      App.router.get('mainAdminSecurityController').setSecurityStatus();
-    }
-  },
-
-
-  loadClusterConfigs: function () {
-    var self = this;
-    var url = App.apiPrefix + '/clusters/' + App.router.getClusterName();
-
-    App.ajax.send({
-      name: 'admin.security.add.cluster_configs',
-      sender: this,
-      success: 'loadClusterConfigsSuccessCallback',
-      error: 'loadClusterConfigsErrorCallback'
-    });
-  },
-
-  loadClusterConfigsSuccessCallback: function (data) {
-    var self = this;
-    //prepare tags to fetch all configuration for a service
-    this.get('content.services').forEach(function (_secureService) {
-      self.setServiceTagNames(_secureService, data.Clusters.desired_configs);
     });
-    this.getAllConfigurations();
-  },
-
-  loadClusterConfigsErrorCallback: function (request, ajaxOptions, error) {
-    var stage3 = this.get('stages').findProperty('stage', 'stage3');
-    if (stage3) {
-      stage3.set('isSuccess', false);
-      stage3.set('isError', true);
-    }
-    console.log("TRACE: error code status is: " + request.status);
-  },
-
-  /**
-   * set tagnames for configuration of the *-site.xml
-   */
-  setServiceTagNames: function (secureService, configs) {
-    //var serviceConfigTags = this.get('serviceConfigTags');
-    for (var index in configs) {
-      if (secureService.sites && secureService.sites.contains(index)) {
-        var serviceConfigObj = {
-          siteName: index,
-          tagName: configs[index].tag,
-          newTagName: null,
-          configs: {}
-        };
-        console.log("The value of serviceConfigTags[index]: " + configs[index]);
-        this.get('serviceConfigTags').pushObject(serviceConfigObj);
-      }
-    }
-    return serviceConfigObj;
-  },
-
-  applyConfigurationsToCluster: function () {
-    this.set('noOfWaitingAjaxCalls', this.get('serviceConfigTags').length);
-    this.get('serviceConfigTags').forEach(function (_serviceConfig) {
-      this.applyConfigurationToCluster({type: _serviceConfig.siteName, tag: _serviceConfig.newTagName, properties: _serviceConfig.configs});
-    }, this);
-  },
-
-  applyConfigurationToCluster: function (data) {
-    var clusterData = {
-      Clusters: {
-        desired_config: data
-      }
-    };
-    App.ajax.send({
-      name: 'admin.security.apply_configuration',
-      sender: this,
-      data: {
-        clusterData: clusterData
-      },
-      success: 'applyConfigurationToClusterSuccessCallback',
-      error: 'applyConfigurationToClusterErrorCallback'
-    });
-  },
-
-  applyConfigurationToClusterSuccessCallback: function (data) {
-    this.set('noOfWaitingAjaxCalls', this.get('noOfWaitingAjaxCalls') - 1);
-    if (this.get('noOfWaitingAjaxCalls') == 0) {
-      var currentStage = this.get('stages').findProperty('stage', 'stage3');
-      currentStage.set('isSuccess', true);
-      currentStage.set('isError', false);
-    }
-  },
-
-  applyConfigurationToClusterErrorCallback: function (request, ajaxOptions, error) {
-    var stage3 = this.get('stages').findProperty('stage', 'stage3');
-    if (stage3) {
-      stage3.set('isSuccess', false);
-      stage3.set('isError', true);
-    }
-  },
-
-  /**
-   * gets site config properties from server and sets it for every configuration
-   * @param serviceConfigTags
-   */
-
-  getAllConfigurations: function () {
-    var urlParams = [];
-    this.get('serviceConfigTags').forEach(function (_tag) {
-      urlParams.push('(type=' + _tag.siteName + '&tag=' + _tag.tagName + ')');
-    }, this);
-    if (urlParams.length > 0) {
-      App.ajax.send({
-        name: 'admin.security.all_configurations',
-        sender: this,
-        data: {
-          urlParams: urlParams.join('|')
-        },
-        success: 'getAllConfigurationsSuccessCallback',
-        error: 'getAllConfigurationsErrorCallback'
-      });
-    }
-  },
-
-  getAllConfigurationsSuccessCallback: function (data) {
-    console.log("TRACE: In success function for the GET getServiceConfigsFromServer call");
-    var stage3 = this.get('stages').findProperty('stage', 'stage3');
-    this.get('serviceConfigTags').forEach(function (_tag) {
-      if (!data.items.someProperty('type', _tag.siteName)) {
-        console.log("Error: Metadata for secure services (secure_configs.js) is having config tags that are not being retrieved from server");
-        if (stage3) {
-          stage3.set('isSuccess', false);
-          stage3.set('isError', true);
-        }
-      }
-      _tag.configs = data.items.findProperty('type', _tag.siteName).properties;
-    }, this);
-    this.addSecureConfigs();
-    this.applyConfigurationsToCluster();
-  },
-
-  getAllConfigurationsErrorCallback: function (request, ajaxOptions, error) {
-    var stage3 = this.get('stages').findProperty('stage', 'stage3');
-    if (stage3) {
-      stage3.set('isSuccess', false);
-      stage3.set('isError', true);
-    }
-    console.log("TRACE: In error function for the getServiceConfigsFromServer call");
-    console.log("TRACE: error code status is: " + request.status);
-  },
-
-  addSecureConfigs: function () {
-    this.get('serviceConfigTags').forEach(function (_serviceConfigTags) {
-      _serviceConfigTags.newTagName = 'version' + (new Date).getTime();
-      if (_serviceConfigTags.siteName === 'global') {
-        var realmName = this.get('globalProperties').findProperty('name', 'kerberos_domain');
-        if (this.get('isNagiosSelected')) {
-          var nagiosPrincipalName = this.get('globalProperties').findProperty('name', 'nagios_principal_name');
-          nagiosPrincipalName.value = nagiosPrincipalName.value + '@' + realmName.value;
-        }
-        if (this.get('isZkSelected')) {
-          var zkPrincipalName = this.get('globalProperties').findProperty('name', 'zookeeper_principal_name');
-          zkPrincipalName.value = zkPrincipalName.value + '@' + realmName.value;
-        }
-        this.get('globalProperties').forEach(function (_globalProperty) {
-          if (!/_hosts?$/.test(_globalProperty.name)) {
-            _serviceConfigTags.configs[_globalProperty.name] = _globalProperty.value;
-          }
-        }, this);
-      }
-      else {
-        this.get('configs').filterProperty('id', 'site property').filterProperty('filename', _serviceConfigTags.siteName + '.xml').forEach(function (_config) {
-          _serviceConfigTags.configs[_config.name] = _config.value;
-        }, this);
-      }
-    }, this);
-  },
-
-  saveStages: function () {
-    var stages = [];
-    if (this.get('stages').length === 3) {
-      this.get('stages').forEach(function (_stage) {
-        var stage = {
-          name: _stage.get('name'),
-          stage: _stage.get('stage'),
-          label: _stage.get('label'),
-          isPolling: _stage.get('isPolling'),
-          isStarted: _stage.get('isStarted'),
-          requestId: _stage.get('requestId'),
-          isSuccess: _stage.get('isSuccess'),
-          isError: _stage.get('isError'),
-          url: _stage.get('url'),
-          polledData: _stage.get('polledData'),
-          data: _stage.get('data')
-        };
-        stages.pushObject(stage);
-      }, this);
-      App.db.setSecurityDeployStages(stages);
-      if (!App.testMode) {
-        App.clusterStatus.setClusterStatus({
-          clusterName: this.get('clusterName'),
-          clusterState: 'ADD_SECURITY_STEP_3',
-          wizardControllerName: App.router.get('addSecurityController.name'),
-          localdb: App.db.data.AddSecurity
-        });
-      }
-    }
-  }.observes('stages.@each.requestId')
+    this.set('hostComponents', result);
+  }
 });

+ 597 - 0
ambari-web/app/controllers/main/admin/security/add/step4.js

@@ -0,0 +1,597 @@
+/**
+ * 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.MainAdminSecurityAddStep4Controller = Em.Controller.extend({
+
+  name: 'mainAdminSecurityAddStep4Controller',
+  secureMapping: require('data/secure_mapping'),
+  secureProperties: require('data/secure_properties').configProperties,
+  stages: [],
+  configs: [],
+  noOfWaitingAjaxCalls: 0,
+  secureServices: [],
+  serviceConfigTags: [],
+  globalProperties: [],
+
+  isSubmitDisabled: true,
+  isBackBtnDisabled: true,
+
+  isOozieSelected: function () {
+    return this.get('content.services').someProperty('serviceName', 'OOZIE');
+  }.property('content.services'),
+
+  isHiveSelected: function () {
+    return this.get('content.services').someProperty('serviceName', 'HIVE');
+  }.property('content.services'),
+
+  isNagiosSelected: function () {
+    return this.get('content.services').someProperty('serviceName', 'NAGIOS');
+  }.property('content.services'),
+
+  isZkSelected: function () {
+    return this.get('content.services').someProperty('serviceName', 'ZOOKEEPER');
+  }.property('content.services'),
+
+  isWebHcatSelected: function () {
+    var installedServices = App.Service.find().mapProperty('serviceName');
+    return installedServices.contains('WEBHCAT');
+  },
+
+  serviceUsersBinding: 'App.router.mainAdminSecurityController.serviceUsers',
+  hasHostPopup: true,
+  services: [],
+  serviceTimestamp: null,
+
+  isSecurityApplied: function () {
+    return this.get('stages').someProperty('stage', 'stage3') && this.get('stages').findProperty('stage', 'stage3').get('isSuccess');
+  }.property('stages.@each.isCompleted'),
+
+  clearStep: function () {
+    this.get('stages').clear();
+    this.set('isSubmitDisabled', true);
+    this.set('isBackBtnDisabled', true);
+    this.get('serviceConfigTags').clear();
+  },
+
+  loadStep: function () {
+    this.set('secureMapping', require('data/secure_mapping').slice(0));
+    var stages = App.db.getSecurityDeployStages();
+    this.clearStep();
+    this.prepareSecureConfigs();
+    if (stages && stages.length > 0) {
+      stages.forEach(function (_stage, index) {
+        stages[index] = App.Poll.create(_stage);
+      }, this);
+      var stopServices = stages.findProperty('name', 'STOP_SERVICES');
+      var runningOperation = App.router.get('backgroundOperationsController.services').findProperty('isRunning');
+      if(stopServices.get('isStarted')){
+        if(stopServices.get('isCompleted') || !runningOperation || !(runningOperation.get('name') === 'Stop All Services')){
+          stopServices.set('requestId', undefined);
+          stopServices.set('isError', false);
+          stopServices.set('isSuccess', false);
+          stopServices.set('isStarted', false);
+        }
+      }
+      if (stages.someProperty('isError', true)) {
+        var failedStages = stages.filterProperty('isError', true);
+        failedStages.setEach('isError', false);
+        failedStages.setEach('isStarted', false);
+      } else if (stages.filterProperty('isStarted', true).someProperty('isCompleted', false)) {
+        var runningStage = stages.filterProperty('isStarted', true).findProperty('isCompleted', false);
+        runningStage.set('isStarted', false);
+      }
+      this.get('stages').pushObjects(stages);
+    } else {
+      this.loadStages();
+      this.addInfoToStages();
+      var runningOperations = App.router.get('backgroundOperationsController.services').filterProperty('isRunning');
+      var stopAllOperation = runningOperations.findProperty('name', 'Stop All Services');
+      var stopStage = this.get('stages').findProperty('name', 'STOP_SERVICES');
+      if (stopStage.get('name') === 'STOP_SERVICES' && stopAllOperation) {
+        stopStage.set('requestId', stopAllOperation.get('id'));
+      }
+    }
+    this.moveToNextStage();
+  },
+
+  enableSubmit: function () {
+    if (this.get('stages').someProperty('isError', true) || this.get('stages').everyProperty('isSuccess', true)) {
+      this.set('isSubmitDisabled', false);
+      if (this.get('stages').someProperty('isError', true)) {
+        this.set('isBackBtnDisabled', false);
+        App.router.get('addSecurityController').setStepsEnable();
+      }
+    } else {
+      this.set('isSubmitDisabled', true);
+    }
+  }.observes('stages.@each.isCompleted'),
+
+  updateServices: function () {
+    this.services.clear();
+    var services = this.get("services");
+    this.get("stages").forEach(function (stage) {
+      var newService = Ember.Object.create({
+        name: stage.label,
+        hosts: []
+      });
+      if (stage && stage.get("polledData")) {
+        var hostNames = stage.get("polledData").mapProperty('Tasks.host_name').uniq();
+        hostNames.forEach(function (name) {
+          newService.hosts.push({
+            name: name,
+            publicName: name,
+            logTasks: stage.polledData.filterProperty("Tasks.host_name", name)
+          });
+        });
+        services.push(newService);
+      }
+    });
+    this.set('serviceTimestamp', new Date().getTime());
+  }.observes('stages.@each.polledData'),
+
+  loadStages: function () {
+    this.get('stages').pushObjects([
+      App.Poll.create({stage: 'stage2', label: Em.I18n.translations['admin.addSecurity.apply.stage2'], isPolling: true, name: 'STOP_SERVICES'}),
+      App.Poll.create({stage: 'stage3', label: Em.I18n.translations['admin.addSecurity.apply.stage3'], isPolling: false, name: 'APPLY_CONFIGURATIONS'}),
+      App.Poll.create({stage: 'stage4', label: Em.I18n.translations['admin.addSecurity.apply.stage4'], isPolling: true, name: 'START_SERVICES'})
+    ]);
+  },
+
+  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);
+          App.router.get('mainAdminSecurityController').setAddSecurityWizardStatus(null);
+        } else {
+          this.loadClusterConfigs()
+        }
+      }
+    }
+  }.observes('stages.@each.isStarted'),
+
+  onCompleteStage: function () {
+    var index = this.get('stages').filterProperty('isCompleted', true).length;
+    if (index > 0) {
+      var lastCompletedStageResult = this.get('stages').objectAt(index - 1).get('isSuccess');
+      if (lastCompletedStageResult) {
+        this.moveToNextStage();
+      }
+    }
+  }.observes('stages.@each.isCompleted'),
+
+  moveToNextStage: function () {
+    var leftStages = this.get('stages').filterProperty('isStarted', false);
+    var nextStage = leftStages.findProperty('isCompleted', false);
+    if (nextStage) {
+      nextStage.set('isStarted', true);
+    }
+  },
+
+  addInfoToStages: function () {
+    this.addInfoToStage2();
+    this.addInfoToStage4();
+  },
+
+  addInfoToStage1: function () {
+    var stage1 = this.get('stages').findProperty('stage', 'stage1');
+    if (App.testMode) {
+      stage1.set('isSuccess', 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 = '{"RequestInfo": {"context" :"' + Em.I18n.t('requestInfo.stopAllServices') + '"}, "Body": {"ServiceInfo": {"state": "INSTALLED"}}}';
+    stage2.set('url', url);
+    stage2.set('data', data);
+  },
+
+  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?params/run_smoke_test=true';
+    var data = '{"RequestInfo": {"context": "' + Em.I18n.t('requestInfo.startAllServices') + '"}, "Body": {"ServiceInfo": {"state": "STARTED"}}}';
+    stage4.set('url', url);
+    stage4.set('data', data);
+  },
+
+  loadUiSideConfigs: function () {
+    var uiConfig = [];
+    var configs = this.get('secureMapping').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('secureMapping').filterProperty('foreignKey');
+    dependentConfig.forEach(function (_config) {
+      if (App.Service.find().mapProperty('serviceName').contains( _config.serviceName)) {
+        this.setConfigValue(uiConfig, _config);
+        uiConfig.pushObject({
+          "id": "site property",
+          "name": _config._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);
+      var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
+      var globValue = this.get('globalProperties').findProperty('name', templateName[index]);
+      if (globValue) {
+        console.log('The template value of templateName ' + '[' + index + ']' + ': ' + templateName[index] + ' is: ' + globValue);
+        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.value);
+        }
+      } else {
+        /*
+         console.log("ERROR: The variable name is: " + templateName[index]);
+         console.log("ERROR: mapped config from secureMapping 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.name.match(/<(foreignKey.*?)>/g);
+    if (fkValue) {
+      fkValue.forEach(function (_fkValue) {
+        var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]);
+        var globalValue;
+        if (uiConfig.someProperty('name', config.foreignKey[index])) {
+          globalValue = uiConfig.findProperty('name', config.foreignKey[index]).value;
+          config._name = config.name.replace(_fkValue, globalValue);
+        } else if (this.get('globalProperties').someProperty('name', config.foreignKey[index])) {
+          globalValue = this.get('globalProperties').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]);
+        var globValue = this.get('globalProperties').findProperty('name', config.templateName[index]);
+        if (globValue) {
+          config.value = config.value.replace(_value, globValue.value);
+        } else {
+          config.value = null;
+        }
+      }, this);
+    }
+  },
+
+  prepareSecureConfigs: function () {
+    this.loadGlobals();
+    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);
+    this.loadStaticGlobal(); //Hack for properties which are declared in config_properties.js and not able to retrieve values declared in secure_properties.js
+    this.loadUsersToGlobal();
+    this.loadHostNamesToGlobal();
+    this.loadPrimaryNamesToGlobals();
+  },
+
+  loadUsersToGlobal: function () {
+    if (!this.get('serviceUsers').length) {
+      this.loadUsersFromServer();
+    }
+    App.router.get('mainAdminSecurityController.serviceUsers').forEach(function (_user) {
+      this.get('globalProperties').pushObject(_user);
+    }, this);
+  },
+
+  loadHostNamesToGlobal: function () {
+    var oozieHostComponent = App.Service.find('OOZIE').get('hostComponents').findProperty('componentName', 'OOZIE_SERVER');
+    if (this.get('isOozieSelected') && oozieHostComponent) {
+      var oozieHostName = oozieHostComponent.get('host.hostName');
+      this.get('globalProperties').pushObject({
+        id: 'puppet var',
+        name: 'oozieserver_host',
+        value: oozieHostName
+      });
+    }
+    var hiveHostComponent = App.Service.find('HIVE').get('hostComponents').findProperty('componentName', 'HIVE_METASTORE');
+    if (this.get('isHiveSelected') && hiveHostComponent) {
+      var hiveHostName = hiveHostComponent.get('host.hostName');
+      this.get('globalProperties').pushObject({
+        id: 'puppet var',
+        name: 'hivemetastore_host',
+        value: hiveHostName
+      });
+    }
+  },
+
+  loadStaticGlobal: function () {
+    var globalProperties = this.get('globalProperties');
+    this.get('globalProperties').forEach(function (_property) {
+      switch (_property.name) {
+        case 'security_enabled':
+          _property.value = 'true';
+          break;
+        case 'dfs_datanode_address':
+          _property.value = '1019';
+          break;
+        case 'dfs_datanode_http_address':
+          _property.value = '1022';
+          break;
+      }
+    }, this);
+  },
+
+  loadPrimaryNamesToGlobals: function () {
+    var principalProperties = this.getPrincipalNames();
+    principalProperties.forEach(function (_principalProperty) {
+      var name = _principalProperty.name.replace('principal', 'primary');
+      var value = _principalProperty.value.split('/')[0];
+      this.get('globalProperties').pushObject({name: name, value: value});
+    }, this);
+  },
+
+  getPrincipalNames: function () {
+    var principalNames = [];
+    var allPrincipalNames = [];
+    this.get('globalProperties').forEach(function (_globalProperty) {
+      if (/principal_name?$/.test(_globalProperty.name)) {
+        principalNames.pushObject(_globalProperty);
+      }
+    }, this);
+    this.get('secureProperties').forEach(function (_secureProperty) {
+      if (/principal_name?$/.test(_secureProperty.name)) {
+        var principalName = principalNames.findProperty('name', _secureProperty.name);
+        if (!principalName) {
+          _secureProperty.value = _secureProperty.defaultValue;
+          principalNames.pushObject(_secureProperty);
+        }
+      }
+    }, this);
+    return principalNames;
+  },
+
+  loadUsersFromServer: function () {
+    if (App.testMode) {
+      var serviceUsers = this.get('serviceUsers');
+      serviceUsers.pushObject({id: 'puppet var', name: 'hdfs_user', value: 'hdfs'});
+      serviceUsers.pushObject({id: 'puppet var', name: 'mapred_user', value: 'mapred'});
+      serviceUsers.pushObject({id: 'puppet var', name: 'hbase_user', value: 'hbase'});
+      serviceUsers.pushObject({id: 'puppet var', name: 'hive_user', value: 'hive'});
+    } else {
+      App.router.get('mainAdminSecurityController').setSecurityStatus();
+    }
+  },
+
+
+  loadClusterConfigs: function () {
+    var self = this;
+    var url = App.apiPrefix + '/clusters/' + App.router.getClusterName();
+
+    App.ajax.send({
+      name: 'admin.security.add.cluster_configs',
+      sender: this,
+      success: 'loadClusterConfigsSuccessCallback',
+      error: 'loadClusterConfigsErrorCallback'
+    });
+  },
+
+  loadClusterConfigsSuccessCallback: function (data) {
+    var self = this;
+    //prepare tags to fetch all configuration for a service
+    this.get('content.services').forEach(function (_secureService) {
+      self.setServiceTagNames(_secureService, data.Clusters.desired_configs);
+    });
+    this.getAllConfigurations();
+  },
+
+  loadClusterConfigsErrorCallback: function (request, ajaxOptions, error) {
+    this.get('stages').findProperty('stage', 'stage3').set('isError', true);
+    console.log("TRACE: error code status is: " + request.status);
+  },
+
+  /**
+   * set tagnames for configuration of the *-site.xml
+   */
+  setServiceTagNames: function (secureService, configs) {
+    //var serviceConfigTags = this.get('serviceConfigTags');
+    for (var index in configs) {
+      if (secureService.sites && secureService.sites.contains(index)) {
+        var serviceConfigObj = {
+          siteName: index,
+          tagName: configs[index].tag,
+          newTagName: null,
+          configs: {}
+        };
+        console.log("The value of serviceConfigTags[index]: " + configs[index]);
+        this.get('serviceConfigTags').pushObject(serviceConfigObj);
+      }
+    }
+    return serviceConfigObj;
+  },
+
+  applyConfigurationsToCluster: function () {
+    this.set('noOfWaitingAjaxCalls', this.get('serviceConfigTags').length);
+    this.get('serviceConfigTags').forEach(function (_serviceConfig) {
+      this.applyConfigurationToCluster({type: _serviceConfig.siteName, tag: _serviceConfig.newTagName, properties: _serviceConfig.configs});
+    }, this);
+  },
+
+  applyConfigurationToCluster: function (data) {
+    var clusterData = {
+      Clusters: {
+        desired_config: data
+      }
+    };
+    App.ajax.send({
+      name: 'admin.security.apply_configuration',
+      sender: this,
+      data: {
+        clusterData: clusterData
+      },
+      success: 'applyConfigurationToClusterSuccessCallback',
+      error: 'applyConfigurationToClusterErrorCallback'
+    });
+  },
+
+  applyConfigurationToClusterSuccessCallback: function (data) {
+    this.set('noOfWaitingAjaxCalls', this.get('noOfWaitingAjaxCalls') - 1);
+    if (this.get('noOfWaitingAjaxCalls') == 0) {
+      var currentStage = this.get('stages').findProperty('stage', 'stage3');
+      currentStage.set('isSuccess', true);
+    }
+  },
+
+  applyConfigurationToClusterErrorCallback: function (request, ajaxOptions, error) {
+    this.get('stages').findProperty('stage', 'stage3').set('isError', true);
+  },
+
+  /**
+   * gets site config properties from server and sets it for every configuration
+   * @param serviceConfigTags
+   */
+
+  getAllConfigurations: function () {
+    var urlParams = [];
+    this.get('serviceConfigTags').forEach(function (_tag) {
+      urlParams.push('(type=' + _tag.siteName + '&tag=' + _tag.tagName + ')');
+    }, this);
+    if (urlParams.length > 0) {
+      App.ajax.send({
+        name: 'admin.security.all_configurations',
+        sender: this,
+        data: {
+          urlParams: urlParams.join('|')
+        },
+        success: 'getAllConfigurationsSuccessCallback',
+        error: 'getAllConfigurationsErrorCallback'
+      });
+    }
+  },
+
+  getAllConfigurationsSuccessCallback: function (data) {
+    console.log("TRACE: In success function for the GET getServiceConfigsFromServer call");
+    this.get('serviceConfigTags').forEach(function (_tag) {
+      if (!data.items.someProperty('type', _tag.siteName)) {
+        console.log("Error: Metadata for secure services (secure_configs.js) is having config tags that are not being retrieved from server");
+        this.get('stages').findProperty('stage', 'stage3').set('isError', true);
+      }
+      _tag.configs = data.items.findProperty('type', _tag.siteName).properties;
+    }, this);
+    this.addSecureConfigs();
+    this.applyConfigurationsToCluster();
+  },
+
+  getAllConfigurationsErrorCallback: function (request, ajaxOptions, error) {
+    this.get('stages').findProperty('stage', 'stage3').set('isError', true);
+    console.log("TRACE: In error function for the getServiceConfigsFromServer call");
+    console.log("TRACE: error code status is: " + request.status);
+  },
+
+  addSecureConfigs: function () {
+    this.get('serviceConfigTags').forEach(function (_serviceConfigTags) {
+      _serviceConfigTags.newTagName = 'version' + (new Date).getTime();
+      if (_serviceConfigTags.siteName === 'global') {
+        var realmName = this.get('globalProperties').findProperty('name', 'kerberos_domain');
+        if (this.get('isNagiosSelected')) {
+          var nagiosPrincipalName = this.get('globalProperties').findProperty('name', 'nagios_principal_name');
+          nagiosPrincipalName.value = nagiosPrincipalName.value + '@' + realmName.value;
+        }
+        if (this.get('isZkSelected')) {
+          var zkPrincipalName = this.get('globalProperties').findProperty('name', 'zookeeper_principal_name');
+          zkPrincipalName.value = zkPrincipalName.value + '@' + realmName.value;
+        }
+        this.get('globalProperties').forEach(function (_globalProperty) {
+          _serviceConfigTags.configs[_globalProperty.name] = _globalProperty.value;
+        }, this);
+      }
+      else {
+        this.get('configs').filterProperty('id', 'site property').filterProperty('filename', _serviceConfigTags.siteName + '.xml').forEach(function (_config) {
+          _serviceConfigTags.configs[_config.name] = _config.value;
+        }, this);
+      }
+    }, this);
+  },
+
+  saveStages: function () {
+    var stages = [];
+    this.get('stages').forEach(function (_stage) {
+      var stage = {
+        name: _stage.get('name'),
+        stage: _stage.get('stage'),
+        label: _stage.get('label'),
+        isPolling: _stage.get('isPolling'),
+        isStarted: _stage.get('isStarted'),
+        requestId: _stage.get('requestId'),
+        isSuccess: _stage.get('isSuccess'),
+        isError: _stage.get('isError'),
+        url: _stage.get('url'),
+        polledData: _stage.get('polledData'),
+        data: _stage.get('data')
+      };
+      stages.pushObject(stage);
+    }, this);
+    App.db.setSecurityDeployStages(stages);
+    App.clusterStatus.setClusterStatus({
+      clusterName: this.get('clusterName'),
+      clusterState: 'ADD_SECURITY_STEP_4',
+      wizardControllerName: App.router.get('addSecurityController.name'),
+      localdb: App.db.data
+    });
+  }.observes('stages.@each.requestId', 'stages.@each.isStarted', 'stages.@each.isCompleted')
+});

+ 11 - 11
ambari-web/app/messages.js

@@ -616,7 +616,8 @@ Em.I18n.translations = {
   'admin.addSecurity.header': 'Add security wizard',
   'admin.security.step1.header': 'Get Started',
   'admin.security.step2.header': 'Configure Services',
-  'admin.security.step3.header': 'Save and Apply Configuration',
+  'admin.security.step3.header': 'Create Principals and Keytabs',
+  'admin.security.step4.header': 'Save and Apply Configuration',
   'admin.security.step1.body.header': 'Important: Before configuring Ambari to manage your Kerberos-enabled cluster, ' +
     'you must perform the following manual steps on your cluster. Be sure to record the location of the keytab files ' +
     'for each host and the principals for each Hadoop service. This information is required in order to use the wizard.',
@@ -625,16 +626,15 @@ Em.I18n.translations = {
   'admin.security.step1.body.instruction3': 'Create Kerberos principals for Hadoop services and hosts',
   'admin.security.step1.body.instruction4': 'Generate keytabs for each principal and place on the appropriate hosts',
   'admin.security.step2.body.header': 'Configure Kerberos security properties',
-  'admin.security.step2.popup.header': 'Manual Steps Required Before Proceeding',
-  'admin.security.step2.popup.notice': 'You need to create the following principals and keytabs on the hosts shown.<br />'+
-  'You can download the list as a CSV file and use it to create a script to generate the principals and keytabs.' +
-  'Once the principals and keytabs have been created, click on <i>Proceed</i> to continue. If you need to make configuration changes, click <i>Cancel</i>.',
-  'admin.security.step2.popup.table.principal': 'Principal',
-  'admin.security.step2.popup.table.keytab': 'Keytab',
-  'admin.security.step2.popup.downloadCSV': 'Download CSV',
-  'admin.security.step3.body.header': 'Applying kerberos security to the cluster',
-  'admin.security.step3.body.success.header' : 'Kerberos-based security has been enabled on your cluster. Please wait while services are started in secure mode.',
-  'admin.security.step3.body.failure.header' : 'Failed to enable Kerberos-based security on your cluster. Your cluster will keep running in non-secure mode.',
+  'admin.security.step3.notice': 'You need to create the following principals and keytabs on the hosts shown.<br />'+
+  'You can download the list as a CSV file and use it to create a script to generate the principals and keytabs. ' +
+  'Once the principals and keytabs have been created, click on <i>Proceed</i> to continue. If you need to make configuration changes, click <i>Back</i>.',
+  'admin.security.step3.table.principal': 'Principal',
+  'admin.security.step3.table.keytab': 'Keytab',
+  'admin.security.step3.downloadCSV': 'Download CSV',
+  'admin.security.step4.body.header': 'Applying kerberos security to the cluster',
+  'admin.security.step4.body.success.header' : 'Kerberos-based security has been enabled on your cluster. Please wait while services are started in secure mode.',
+  'admin.security.step4.body.failure.header' : 'Failed to enable Kerberos-based security on your cluster. Your cluster will keep running in non-secure mode.',
   'admin.security.disable.body.header' : 'Disabling kerberos security on the cluster',
   'admin.security.disable.body.success.header': 'Kerberos-based security has been disabled on your cluster. Please wait while services are started in non-secure mode.',
   'admin.security.disable.body.failure.header': 'Failed to disable Kerberos-based security on your cluster. Your cluster will keep running in secure mode.',

+ 3 - 3
ambari-web/app/models/cluster_states.js

@@ -22,8 +22,8 @@ App.clusterStatus = Ember.Object.create({
   validStates: ['CLUSTER_NOT_CREATED_1', 'CLUSTER_DEPLOY_PREP_2', 'CLUSTER_INSTALLING_3', 'SERVICE_STARTING_3', 'CLUSTER_INSTALLED_4',  'CLUSTER_STARTED_5',
     'ADD_HOSTS_DEPLOY_PREP_2', 'ADD_HOSTS_INSTALLING_3', 'ADD_HOSTS_INSTALLED_4', 'ADD_HOSTS_COMPLETED_5',
     'ADD_SERVICES_DEPLOY_PREP_2', 'ADD_SERVICES_INSTALLING_3', 'ADD_SERVICES_INSTALLED_4', 'ADD_SERVICES_COMPLETED_5',
-    'STOPPING_SERVICES', 'STACK_UPGRADING', 'STACK_UPGRADE_FAILED', 'STACK_UPGRADED', 'STACK_UPGRADE_COMPLETED','ADD_SECURITY_STEP_1',
-    'ADD_SECURITY_STEP_2','ADD_SECURITY_STEP_3','DISABLE_SECURITY','SECURITY_COMPLETED'],
+    'STOPPING_SERVICES', 'STACK_UPGRADING', 'STACK_UPGRADE_FAILED', 'STACK_UPGRADED', 'STACK_UPGRADE_COMPLETED', 'ADD_SECURITY_STEP_1',
+    'ADD_SECURITY_STEP_2', 'ADD_SECURITY_STEP_3', 'ADD_SECURITY_STEP_4', 'DISABLE_SECURITY', 'SECURITY_COMPLETED'],
   clusterState: 'CLUSTER_NOT_CREATED_1',
   wizardControllerName: null,
   localdb: null,
@@ -129,4 +129,4 @@ App.clusterStatus = Ember.Object.create({
       };
   }.property('clusterName', 'clusterState', 'localdb', 'wizardControllerName')
 
-});
+});

+ 55 - 15
ambari-web/app/routes/add_security.js

@@ -41,13 +41,14 @@ module.exports = Em.Route.extend({
 
             onClose: function () {
               var self = this;
-              if (router.get('addSecurityController.currentStep') == 3) {
-                var controller = router.get('mainAdminSecurityAddStep3Controller');
+              if (router.get('addSecurityController.currentStep') == 4) {
+                var controller = router.get('mainAdminSecurityAddStep4Controller');
                 if (!controller.get('isSubmitDisabled')) {
+                  router.get('mainAdminSecurityAddStep4Controller').clearStep();
                   self.proceedOnClose();
                   return;
                 }
-                var applyingConfigStage = router.get('mainAdminSecurityAddStep3Controller.stages').findProperty('stage', 'stage3');
+                var applyingConfigStage = router.get('mainAdminSecurityAddStep4Controller.stages').findProperty('stage', 'stage3');
                 if (applyingConfigStage) {
                   if (!applyingConfigStage.get('isCompleted')) {
                     if (applyingConfigStage.get('isStarted')) {
@@ -67,13 +68,13 @@ module.exports = Em.Route.extend({
                   return;
                 }
               }
-              router.get('mainAdminSecurityAddStep3Controller').clearStep();
+              router.get('mainAdminSecurityAddStep4Controller').clearStep();
               App.db.setSecurityDeployStages(undefined);
               self.proceedOnClose();
             },
             proceedOnClose: function () {
               this.hide();
-              router.get('mainAdminSecurityAddStep3Controller').clearStep();
+              router.get('mainAdminSecurityAddStep4Controller').clearStep();
               router.get('addSecurityController.content.services').clear();
               router.set('addSecurityController.content.serviceConfigProperties', null);
               App.router.get('updateController').set('isWorking', true);
@@ -84,7 +85,7 @@ module.exports = Em.Route.extend({
                 clusterName: router.get('content.cluster.name'),
                 clusterState: 'SECURITY_COMPLETED',
                 wizardControllerName: router.get('addSecurityController.name'),
-                localdb: App.db.data.AddSecurity
+                localdb: App.db.data
               });
               router.transitionTo('adminSecurity.index');
             },
@@ -110,7 +111,7 @@ module.exports = Em.Route.extend({
           clusterName: this.get('clusterName'),
           clusterState: 'ADD_SECURITY_STEP_1',
           wizardControllerName: router.get('addSecurityController.name'),
-          localdb:  App.db.data.AddSecurity
+          localdb: App.db.data
         });
       }
     },
@@ -141,7 +142,7 @@ module.exports = Em.Route.extend({
           clusterName: this.get('clusterName'),
           clusterState: 'ADD_SECURITY_STEP_2',
           wizardControllerName: router.get('addSecurityController.name'),
-          localdb:  App.db.data.AddSecurity
+          localdb: App.db.data
         });
       }
     },
@@ -164,29 +165,66 @@ module.exports = Em.Route.extend({
   }),
 
   step3: Em.Route.extend({
-    route: '/apply',
+    route: '/principal_keytab',
 
+    enter: function (router) {
+      router.get('addSecurityController').setCurrentStep('3');
+      if(!App.testMode){
+        App.clusterStatus.setClusterStatus({
+          clusterName: this.get('clusterName'),
+          clusterState: 'ADD_SECURITY_STEP_3',
+          wizardControllerName: router.get('addSecurityController.name'),
+          localdb: App.db.data
+        });
+      }
+    },
     connectOutlets: function (router) {
       console.log('in addSecurity.step3:connectOutlets');
       var controller = router.get('addSecurityController');
       controller.dataLoading().done(function () {
-        controller.setCurrentStep('3');
         controller.loadAllPriorSteps();
-        controller.setLowerStepsDisable(3);
         controller.connectOutlet('mainAdminSecurityAddStep3', controller.get('content'));
       })
     },
+    back: Em.Router.transitionTo('step2'),
+    next: Em.Router.transitionTo('step4')
+  }),
+
+  step4: Em.Route.extend({
+    route: '/apply',
+
+    enter: function (router) {
+      router.get('addSecurityController').setCurrentStep('4');
+      if(!App.testMode){
+        App.clusterStatus.setClusterStatus({
+          clusterName: this.get('clusterName'),
+          clusterState: 'ADD_SECURITY_STEP_4',
+          wizardControllerName: router.get('addSecurityController.name'),
+          localdb: App.db.data
+        });
+      }
+    },
+
+    connectOutlets: function (router) {
+      console.log('in addSecurity.step4:connectOutlets');
+      var controller = router.get('addSecurityController');
+      controller.dataLoading().done(function () {
+        controller.loadAllPriorSteps();
+        controller.setLowerStepsDisable(4);
+        controller.connectOutlet('mainAdminSecurityAddStep4', controller.get('content'));
+      })
+    },
     unroutePath: function () {
       return false;
     },
     back: function (router, context) {
-      var controller = router.get('mainAdminSecurityAddStep3Controller');
+      var controller = router.get('mainAdminSecurityAddStep4Controller');
       if (!controller.get('isBackBtnDisabled')) {
-        router.transitionTo('step2');
+        router.transitionTo('step3');
       }
     },
     done: function (router, context) {
-      var controller = router.get('mainAdminSecurityAddStep3Controller');
+      var controller = router.get('mainAdminSecurityAddStep4Controller');
       if (!controller.get('isSubmitDisabled')) {
         $(context.currentTarget).parents("#modal").find(".close").trigger('click');
       }
@@ -197,7 +235,9 @@ module.exports = Em.Route.extend({
 
   gotoStep2: Em.Router.transitionTo('step2'),
 
-  gotoStep3: Em.Router.transitionTo('step3')
+  gotoStep3: Em.Router.transitionTo('step3'),
+
+  gotoStep4: Em.Router.transitionTo('step4')
 
 });
 

+ 15 - 9
ambari-web/app/styles/application.less

@@ -1572,7 +1572,22 @@ width:100%;
   .progress-percentage {
     margin-left: 10px;
   }
+  a.remove-link {
+    text-decoration:none;
+    pointer-events: none;
+    color:black;
+    cursor: default;
+  }
+}
 
+#enable_security {
+  .step3 {
+    overflow: auto;
+    max-height: 500px;
+    table td {
+      word-break: break-all;
+    }
+  }
 }
 
 .faintText {
@@ -4382,15 +4397,6 @@ i.icon-asterisks {
   }
 }
 
-#security-stages {
-  a.remove-link {
-    text-decoration:none;
-    pointer-events: none;
-    color:black;
-    cursor: default;
-  }
-}
-
 #advancedRepoAccordion{
   #collapseOne{
     .pull-right{

+ 2 - 1
ambari-web/app/templates/main/admin/security/add/menu.hbs

@@ -17,7 +17,7 @@
 }}
 
 
-<div class="wizard">
+<div class="wizard" id="enable_security">
     <div class="container">
         <div class="container-fluid">
             <div class="row-fluid">
@@ -29,6 +29,7 @@
                             <li {{bindAttr class="isStep1:active view.isStep1Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep1 target="controller"}}>{{t admin.security.step1.header}}</a></li>
                             <li {{bindAttr class="isStep2:active view.isStep2Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep2 target="controller"}}>{{t admin.security.step2.header}}</a></li>
                             <li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep3 target="controller"}}>{{t admin.security.step3.header}}</a></li>
+                            <li {{bindAttr class="isStep4:active view.isStep4Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep4 target="controller"}}>{{t admin.security.step4.header}}</a></li>
                         </ul>
                     </div>
                 </div>

+ 2 - 3
ambari-web/app/templates/main/admin/security/add/step2.hbs

@@ -16,9 +16,9 @@
 * limitations under the License.
 }}
 
-<div id="serviceConfig">
-  <h2>{{t admin.security.step2.header}}</h2>
+<h2>{{t admin.security.step2.header}}</h2>
 
+<div id="serviceConfig">
   <p class="alert alert-info">
     {{t admin.security.step2.body.header}}
   </p>
@@ -29,6 +29,5 @@
 
     <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
       {{action submit target="controller"}}>{{t common.apply}} &rarr;</a>
-    <a style="margin-right:5px;" class="btn btn-info pull-right" {{action doDownloadCsv target="controller"}}>{{t admin.security.step2.popup.downloadCSV}}</a>
   </div>
 </div>

+ 28 - 11
ambari-web/app/templates/main/admin/security/add/step3.hbs

@@ -17,16 +17,33 @@
 }}
 
 <h2>{{t admin.security.step3.header}}</h2>
-
-{{#if view.message}}
-  <p {{bindAttr class="view.msgColor :alert"}}>{{view.message}}</p>
-{{/if}}
-
-{{view App.MainServiceReconfigureView}}
-
+<div class="alert alert-info">{{t admin.security.step3.notice}}</div>
+<div class="step3">
+    <table class="table table-bordered table-striped">
+        <thead>
+        <tr>
+            <th>{{t common.host}}</th>
+            <th>{{t common.component}}</th>
+            <th>{{t admin.security.step3.table.principal}}</th>
+            <th>{{t admin.security.step3.table.keytab}}</th>
+            </tr>
+        </thead>
+        <tbody>
+        {{#each hostComponent in hostComponents}}
+            <tr>
+                <td>{{hostComponent.host}}</td>
+                <td>{{hostComponent.component}}</td>
+                <td>{{hostComponent.principal}}</td>
+                <td>{{hostComponent.keytab}}</td>
+            </tr>
+        {{/each}}
+    </tbody>
+    </table>
+</div>
 <div class="btn-area">
-  <a class="btn" {{bindAttr disabled="isBackBtnDisabled"}}
-    {{action back}}>&larr; {{t common.back}}</a>
-  <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
-    {{action done}}>{{t common.done}} </a>
+    <a class="btn" {{action back}}>&larr; {{t common.back}}</a>
+    <div class="pull-right">
+        <a class="btn btn-info" {{action doDownloadCsv target="controller"}}>{{t admin.security.step3.downloadCSV}}</a>
+        <a class="btn btn-success" {{bindAttr disabled="isSubmitDisabled"}} {{action next}}>{{t common.proceed}} &rarr;</a>
+    </div>
 </div>

+ 32 - 0
ambari-web/app/templates/main/admin/security/add/step4.hbs

@@ -0,0 +1,32 @@
+{{!
+* 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.step4.header}}</h2>
+
+{{#if view.message}}
+  <p {{bindAttr class="view.msgColor :alert"}}>{{view.message}}</p>
+{{/if}}
+
+{{view App.MainServiceReconfigureView}}
+
+<div class="btn-area">
+  <a class="btn" {{bindAttr disabled="isBackBtnDisabled"}}
+    {{action back}}>&larr; {{t common.back}}</a>
+  <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
+    {{action done}}>{{t common.done}} </a>
+</div>

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

@@ -71,6 +71,7 @@ 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/admin/security/add/step4');
 require('views/main/dashboard');
 require('views/main/dashboard/service');
 require('views/main/dashboard/service/hdfs');

+ 4 - 0
ambari-web/app/views/main/admin/security/add/menu.js

@@ -32,6 +32,10 @@ App.MainAdminSecurityAddMenuView = Em.View.extend({
 
   isStep3Disabled: function () {
     return this.get('controller.isStepDisabled').findProperty('step',3).get('value');
+  }.property('controller.isStepDisabled.@each.value').cacheable(),
+
+  isStep4Disabled: function () {
+    return this.get('controller.isStepDisabled').findProperty('step',4).get('value');
   }.property('controller.isStepDisabled.@each.value').cacheable()
 
 });

+ 2 - 49
ambari-web/app/views/main/admin/security/add/step3.js

@@ -19,56 +19,9 @@
 var App = require('app');
 
 App.MainAdminSecurityAddStep3View = Em.View.extend({
-
   templateName: require('templates/main/admin/security/add/step3'),
-  didInsertElement: function () {
+  didInsertElement: function(){
     this.get('controller').loadStep();
-  },
-  msgColor: 'alert-info',
-  message: Em.I18n.t('admin.security.step3.body.header'),
-  onResult: function () {
-    var stage1 = this.get('controller.stages').findProperty('stage', 'stage2');
-    var stage2 = this.get('controller.stages').findProperty('stage', 'stage3');
-    var stage3 = this.get('controller.stages').findProperty('stage', 'stage4');
-      if (stage2 && stage2.get('isSuccess') === true ) {
-        this.set('message', Em.I18n.t('admin.security.step3.body.success.header'));
-        this.set('msgColor','alert-success');
-      } else if ((stage1 && stage1.get('isError') === true) || (stage2 && stage2.get('isError') === true)) {
-        this.set('message', Em.I18n.t('admin.security.step3.body.failure.header'));
-        this.set('msgColor','alert-error');
-      } else {
-        this.set('message', Em.I18n.t('admin.security.step3.body.header'));
-        this.set('msgColor','alert-info');
-      }
-  }.observes('controller.stages.@each.isCompleted')
-
-});
-
-App.StageStatusView = Em.View.extend({
-  tagName: 'tr',
-  hasStarted: null,
-  classNameBindings: ['faintText']
-});
-
-App.StageSuccessView = Em.View.extend({
-  template: Ember.Handlebars.compile('<i class="icon-ok icon-large"></i> Done')
-});
-
-App.StageFailureView = Em.View.extend({
-  template: 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')
-
+  }
 });
 

+ 74 - 0
ambari-web/app/views/main/admin/security/add/step4.js

@@ -0,0 +1,74 @@
+/**
+ * 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.MainAdminSecurityAddStep4View = Em.View.extend({
+
+  templateName: require('templates/main/admin/security/add/step4'),
+  didInsertElement: function () {
+    this.get('controller').loadStep();
+  },
+  msgColor: 'alert-info',
+  message: Em.I18n.t('admin.security.step4.body.header'),
+  onResult: function () {
+    var stage1 = this.get('controller.stages').findProperty('stage', 'stage2');
+    var stage2 = this.get('controller.stages').findProperty('stage', 'stage3');
+    var stage3 = this.get('controller.stages').findProperty('stage', 'stage4');
+      if (stage2 && stage2.get('isSuccess') === true ) {
+        this.set('message', Em.I18n.t('admin.security.step4.body.success.header'));
+        this.set('msgColor','alert-success');
+      } else if ((stage1 && stage1.get('isError') === true) || (stage2 && stage2.get('isError') === true)) {
+        this.set('message', Em.I18n.t('admin.security.step4.body.failure.header'));
+        this.set('msgColor','alert-error');
+      } else {
+        this.set('message', Em.I18n.t('admin.security.step4.body.header'));
+        this.set('msgColor','alert-info');
+      }
+  }.observes('controller.stages.@each.isCompleted')
+
+});
+
+App.StageStatusView = Em.View.extend({
+  tagName: 'tr',
+  hasStarted: null,
+  classNameBindings: ['faintText']
+});
+
+App.StageSuccessView = Em.View.extend({
+  template: Ember.Handlebars.compile('<i class="icon-ok icon-large"></i> Done')
+});
+
+App.StageFailureView = Em.View.extend({
+  template: 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')
+
+});
+