You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ja...@apache.org on 2015/08/06 18:34:01 UTC

ambari git commit: AMBARI-12641. Allow user to update Kerberos Descriptor from admin Kerberos page. (jaimin)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.1 c9f85096c -> 6257c3f17


AMBARI-12641. Allow user to update Kerberos Descriptor from admin Kerberos page. (jaimin)


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

Branch: refs/heads/branch-2.1
Commit: 6257c3f1752648df4a86fb10080d25d543eb68bc
Parents: c9f8509
Author: Jaimin Jetly <ja...@hortonworks.com>
Authored: Thu Aug 6 09:33:20 2015 -0700
Committer: Jaimin Jetly <ja...@hortonworks.com>
Committed: Thu Aug 6 09:33:20 2015 -0700

----------------------------------------------------------------------
 .../app/controllers/main/admin/kerberos.js      | 183 +++++++++++++++----
 .../main/admin/kerberos/step4_controller.js     |   1 +
 .../app/mixins/wizard/addSecurityConfigs.js     |   3 +-
 .../app/templates/main/admin/kerberos.hbs       |  34 +++-
 4 files changed, 178 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/6257c3f1/ambari-web/app/controllers/main/admin/kerberos.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos.js b/ambari-web/app/controllers/main/admin/kerberos.js
index 2ff79f0..969c09a 100644
--- a/ambari-web/app/controllers/main/admin/kerberos.js
+++ b/ambari-web/app/controllers/main/admin/kerberos.js
@@ -26,12 +26,13 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
   defaultKerberosLoaded: false,
   dataIsLoaded: false,
   isRecommendedLoaded: true,
+  isEditMode: false,
   kdc_type: '',
 
   kdcTypesValues: {
-    'mit-kdc'         : Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'),
+    'mit-kdc': Em.I18n.t('admin.kerberos.wizard.step1.option.kdc'),
     'active-directory': Em.I18n.t('admin.kerberos.wizard.step1.option.ad'),
-    'none'            : Em.I18n.t('admin.kerberos.wizard.step1.option.manual')
+    'none': Em.I18n.t('admin.kerberos.wizard.step1.option.manual')
   },
 
   getAddSecurityWizardStatus: function () {
@@ -71,9 +72,10 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
   /**
    * Show confirmation popup for regenerate keytabs
    * @method regenerateKeytabs
+   * @param callback function (optional)
    * @return {App.ModalPopup}
    */
-  regenerateKeytabs: function () {
+  regenerateKeytabs: function (callback) {
     var self = this;
 
     return App.ModalPopup.show({
@@ -92,7 +94,7 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
 
       onPrimary: function () {
         this._super();
-        return self.restartServicesAfterRegenerate(this.get('regenerateKeytabsOnlyForMissing'));
+        return self.restartServicesAfterRegenerate(this.get('regenerateKeytabsOnlyForMissing'), callback);
       }
     });
   },
@@ -101,9 +103,10 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
    * Show confirmation popup for restarting all services and after confirmation regenerate keytabs
    *
    * @param regenerateKeytabsOnlyForMissing {Boolean}
+   * @param callback (optional)
    * @returns {*}
    */
-  restartServicesAfterRegenerate: function (regenerateKeytabsOnlyForMissing) {
+  restartServicesAfterRegenerate: function (regenerateKeytabsOnlyForMissing, callback) {
     var self = this;
 
     return App.ModalPopup.show({
@@ -122,7 +125,15 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
 
       onPrimary: function () {
         this._super();
-        self.regenerateKeytabsRequest(regenerateKeytabsOnlyForMissing, this.get('restartComponents'));
+        var popupContext = this;
+        // Keytabs can either be regenerated directly or after updating kerberos descriptor in the callback function
+        if (Em.typeOf(callback) === 'function') {
+          callback().done(function () {
+            self.regenerateKeytabsRequest(regenerateKeytabsOnlyForMissing, popupContext.get('restartComponents'));
+          });
+        } else {
+          self.regenerateKeytabsRequest(regenerateKeytabsOnlyForMissing, popupContext.get('restartComponents'));
+        }
       }
     });
   },
@@ -192,7 +203,7 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
    * otherwise runs <code>startKerberosWizard<code>
    * @method checkAndStartKerberosWizard
    */
-  checkAndStartKerberosWizard: function() {
+  checkAndStartKerberosWizard: function () {
     if (App.get('supports.preKerberizeCheck')) {
       App.ajax.send({
         name: "admin.kerberos_security.checks",
@@ -262,31 +273,31 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
         success: 'getSecurityStatusSuccessCallback',
         error: 'errorCallback'
       })
-      .always(this.getSecurityType.bind(this))
-      .always(function() {
-        // check for kerberos descriptor artifact
-        if (self.get('securityEnabled')) {
-          self.loadClusterDescriptorConfigs().then(function() {
-            dfd.resolve();
-          }, function() {
-            // if kerberos descriptor doesn't exist in cluster artifacts get the default descriptor
-            self.loadStackDescriptorConfigs().then(function() {
-              self.set('defaultKerberosLoaded', true);
-              dfd.resolve();
-            }, function() {
-              self.set('securityEnabled', false);
+        .always(this.getSecurityType.bind(this))
+        .always(function () {
+          // check for kerberos descriptor artifact
+          if (self.get('securityEnabled')) {
+            self.loadClusterDescriptorConfigs().then(function () {
               dfd.resolve();
+            }, function () {
+              // if kerberos descriptor doesn't exist in cluster artifacts get the default descriptor
+              self.loadStackDescriptorConfigs().then(function () {
+                self.set('defaultKerberosLoaded', true);
+                dfd.resolve();
+              }, function () {
+                self.set('securityEnabled', false);
+                dfd.resolve();
+              });
             });
-          });
-        } else {
-          dfd.resolve();
-        }
-      });
+          } else {
+            dfd.resolve();
+          }
+        });
     }
     return dfd.promise();
   },
 
-  getSecurityStatusSuccessCallback: function(data) {
+  getSecurityStatusSuccessCallback: function (data) {
     this.set('dataIsLoaded', true);
     var securityType = data.Clusters.security_type;
     this.set('securityEnabled', securityType === 'KERBEROS');
@@ -319,6 +330,9 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
   setStepConfigs: function (properties) {
     this.get('stepConfigs').clear();
     this._super(properties);
+    this.get('stepConfigs').forEach(function (serviceConfig) {
+      serviceConfig.set('initConfigsLength', serviceConfig.get('configs.length'));
+    });
   },
 
   /**
@@ -327,15 +341,19 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
    * @param {App.ServiceConfigProperty[]} configs
    * @returns {App.ServiceConfigProperty[]}
    */
-  prepareConfigProperties: function(configs) {
+  prepareConfigProperties: function (configs) {
+    var self = this;
     var configProperties = configs.slice(0);
     var siteProperties = App.config.get('preDefinedSiteProperties');
     var installedServiceNames = ['Cluster'].concat(App.Service.find().mapProperty('serviceName'));
-    configProperties = configProperties.filter(function(item) {
+    configProperties = configProperties.filter(function (item) {
       return installedServiceNames.contains(item.get('serviceName'));
     });
     configProperties.setEach('isSecureConfig', false);
-    configProperties.forEach(function(property, item, allConfigs) {
+    configProperties.forEach(function (property, item, allConfigs) {
+      if (['spnego_keytab', 'spnego_principal'].contains(property.get('name'))) {
+        property.addObserver('value', self, 'spnegoPropertiesObserver');
+      }
       if (property.get('observesValueFrom')) {
         var observedValue = allConfigs.findProperty('name', property.get('observesValueFrom')).get('value');
         property.set('value', observedValue);
@@ -351,7 +369,7 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
       var siteProperty = siteProperties.findProperty('name', property.get('name'));
       if (siteProperty) {
         if (siteProperty.category === property.get('category')) {
-          property.set('displayName',siteProperty.displayName);
+          property.set('displayName', siteProperty.displayName);
           if (siteProperty.index) {
             property.set('index', siteProperty.index);
           }
@@ -365,7 +383,7 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
     return configProperties;
   },
 
-  getKDCSessionState: function(callback, kdcCancelHandler) {
+  getKDCSessionState: function (callback, kdcCancelHandler) {
     if (this.get('securityEnabled') || App.get('isKerberosEnabled')) {
       App.ajax.send({
         name: 'kerberos.session.state',
@@ -392,7 +410,7 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
         },
         success: 'getSecurityTypeSuccess'
       });
-    } else if (Em.typeOf(callback)=== 'function') {
+    } else if (Em.typeOf(callback) === 'function') {
       callback();
     } else {
       return $.Deferred().resolve().promise;
@@ -412,7 +430,7 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
     return this.get('kdc_type') === 'none';
   }.property('kdc_type'),
 
-  checkState: function(data, opt, params) {
+  checkState: function (data, opt, params) {
     var res = Em.get(data, 'Services.attributes.kdc_validation_result');
     var message = Em.get(data, 'Services.attributes.kdc_validation_failure_details');
     if (res.toUpperCase() === "OK") {
@@ -420,5 +438,102 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
     } else {
       App.showInvalidKDCPopup(opt, App.format.kdcErrorMsg(message, false));
     }
-  }
+  },
+
+  /**
+   * @Override   <code>App.AddSecurityConfigs</code>
+   * Wrap kerberos properties to App.ServiceConfigProperty model class instances.
+   *
+   * @param {object} kerberosProperties
+   * @param {string} serviceName
+   * @param {string} filename
+   * @returns {App.ServiceConfigProperty[]}
+   */
+  expandKerberosStackDescriptorProps: function (kerberosProperties, serviceName, filename) {
+    var configs = [];
+
+    for (var propertyName in kerberosProperties) {
+      var propertyObject = {
+        name: propertyName,
+        value: kerberosProperties[propertyName],
+        defaultValue: kerberosProperties[propertyName],
+        savedValue: kerberosProperties[propertyName],
+        serviceName: serviceName,
+        filename: filename,
+        displayName: serviceName == "Cluster" ? App.format.normalizeName(propertyName) : propertyName,
+        isOverridable: false,
+        isEditable: true,
+        isSecureConfig: true
+      };
+      configs.push(App.ServiceConfigProperty.create(propertyObject));
+    }
+
+    return configs;
+  },
+
+  /**
+   * Determines if some config value is changed
+   * @type {boolean}
+   */
+  isPropertiesChanged: function () {
+    return this.get('stepConfigs').someProperty('isPropertiesChanged', true);
+  }.property('stepConfigs.@each.isPropertiesChanged'),
+
+  /**
+   * Determines if the save button is disabled
+   */
+  isSaveButtonDisabled: function () {
+    return this.get('isSubmitDisabled') || !this.get('isPropertiesChanged');
+  }.property('isSubmitDisabled', 'isPropertiesChanged'),
+
+
+  makeConfigsEditable: function () {
+    this.set('isEditMode', true);
+    this.get('stepConfigs').forEach(function(_stepConfig){
+      _stepConfig.get('configs').setEach('isEditable', true);
+    }, this);
+  },
+
+  makeConfigsNonEditable: function () {
+    this.set('isEditMode', false);
+    this.loadStep();
+  },
+
+  /**
+   * Update kerberos descriptor and regenerate keytabs
+   */
+  submit: function (context) {
+    var callback;
+    var self = this;
+    if (this.get('isPropertiesChanged')) {
+      var kerberosDescriptor = this.get('kerberosDescriptor');
+      var configs = [];
+      this.get('stepConfigs').forEach(function (_stepConfig) {
+        configs = configs.concat(_stepConfig.get('configs'));
+      });
+      this.updateKerberosDescriptor(kerberosDescriptor, configs);
+      callback = function () {
+        return App.ajax.send({
+          name: 'admin.kerberos.cluster.artifact.update',
+          sender: self,
+          data: {
+            artifactName: 'kerberos_descriptor',
+            data: {
+              artifact_data: kerberosDescriptor
+            }
+          },
+          success: 'makeConfigsNonEditable'
+        });
+      };
+    } else {
+      callback = function() {
+        var dfd = $.Deferred();
+        self.makeConfigsNonEditable();
+        dfd.resolve();
+        return dfd.promise();
+      }
+    }
+    this.regenerateKeytabs(callback);
+  },
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/6257c3f1/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
index aaf3640..3aaf453 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
@@ -204,6 +204,7 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
     if (this.get('wizardController.name') != 'addServiceController') {
       var realmValue = storedServiceConfigs.findProperty('name', 'realm').value;
       configProperties.findProperty('name', 'realm').set('value', realmValue);
+      configProperties.findProperty('name', 'realm').set('savedValue', realmValue);
       configProperties.findProperty('name', 'realm').set('recommendedValue', realmValue);
     }
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/6257c3f1/ambari-web/app/mixins/wizard/addSecurityConfigs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/wizard/addSecurityConfigs.js b/ambari-web/app/mixins/wizard/addSecurityConfigs.js
index 7ffdd3b..30b263d 100644
--- a/ambari-web/app/mixins/wizard/addSecurityConfigs.js
+++ b/ambari-web/app/mixins/wizard/addSecurityConfigs.js
@@ -488,7 +488,7 @@ App.AddSecurityConfigs = Em.Mixin.create({
         configObject.referenceProperty = name.substring(1) + ':' + item;
         configObject.isEditable = false;
       }
-      configObject.defaultValue = configObject.value = itemValue;
+      configObject.defaultValue = configObject.savedValue = configObject.value = itemValue;
       configObject.filename = prop.configuration ? prop.configuration.split('/')[0] : 'cluster-env';
       configObject.name = prop.configuration ? prop.configuration.split('/')[1] : name + '_' + item;
       configObject.displayName = configObject.filename == "cluster-env" ? App.format.normalizeName(configObject.name) : configObject.name;
@@ -513,6 +513,7 @@ App.AddSecurityConfigs = Em.Mixin.create({
         name: propertyName,
         value: kerberosProperties[propertyName],
         defaultValue: kerberosProperties[propertyName],
+        savedValue: kerberosProperties[propertyName],
         serviceName: serviceName,
         filename: filename,
         displayName: serviceName == "Cluster" ? App.format.normalizeName(propertyName) : propertyName,

http://git-wip-us.apache.org/repos/asf/ambari/blob/6257c3f1/ambari-web/app/templates/main/admin/kerberos.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/kerberos.hbs b/ambari-web/app/templates/main/admin/kerberos.hbs
index b191dc2..fcbad72 100644
--- a/ambari-web/app/templates/main/admin/kerberos.hbs
+++ b/ambari-web/app/templates/main/admin/kerberos.hbs
@@ -18,19 +18,37 @@
 {{#if dataIsLoaded}}
   {{#if securityEnabled}}
     <div>
-      <p class="text-success">{{t admin.security.enabled}}
-        {{#isAccessible ADMIN}}
-          <a class="btn btn-padding btn-warning admin-disable-security-btn" {{bindAttr disabled="isSubmitDisabled"}} {{action notifySecurityOffPopup target="controller"}}>{{t admin.kerberos.button.disable}} </a>
-          {{#unless isManualKerberos}}
-            <button class="btn btn-success"{{action regenerateKeytabs target="controller"}}><i class="icon-repeat"></i> {{t admin.kerberos.button.regenerateKeytabs}}</button>
-          {{/unless}}
-          <br/>
-        {{/isAccessible}}
+    <p class="text-success">{{t admin.security.enabled}}
+      {{#isAccessible ADMIN}}
+        <a class="btn btn-padding btn-warning admin-disable-security-btn" {{bindAttr disabled="isSubmitDisabled"}} {{action notifySecurityOffPopup target="controller"}}>{{t admin.kerberos.button.disable}} </a>
+        <br/>
+        {{#unless isManualKerberos}}
+          {{#if isEditMode}}
+            <a class="pull-right" href="#" {{action makeConfigsNonEditable target="controller"}}>
+                <span class="icon-stack">
+                <i class="icon-pencil"></i>
+                <i class="icon-ban-circle icon-rotate-90 text-error"></i>
+                </span>
+            </a>
+          {{else}}
+            <a class="pull-right" href="#" {{action makeConfigsEditable target="controller"}}>
+              <i class="icon-edit"></i>
+            </a>
+          {{/if}}
+        {{/unless}}
+      {{/isAccessible}}
       </p>
     </div>
     <div id="serviceConfig">
       {{view App.ServicesConfigView}}
     </div>
+    {{#if isEditMode}}
+      <div class="btn-area">
+        <button id="submit-kerberos-reconfigure-identities"
+                class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
+          {{action submit target="controller"}}>{{t common.save}}</button>
+      </div>
+    {{/if}}
   {{else}}
     <div>
       <p class="muted">{{t admin.security.disabled}}