Explorar el Código

AMBARI-16901 Add Service wizard: All kerberos related configurations shown on Configure Identities page should be made non-editable on configure services page. (ababiichuk)

ababiichuk hace 9 años
padre
commit
97ff55232f

+ 39 - 10
ambari-web/app/controllers/main/service/info/configs.js

@@ -19,7 +19,9 @@
 var App = require('app');
 var batchUtils = require('utils/batch_scheduled_requests');
 
-App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, App.ServerValidatorMixin, App.EnhancedConfigsMixin, App.ThemesMappingMixin, App.ConfigsSaverMixin, App.ConfigsComparator, App.ComponentActionsByConfigs, {
+App.MainServiceInfoConfigsController = Em.Controller.extend(App.AddSecurityConfigs, App.ConfigsLoader,
+  App.ServerValidatorMixin, App.EnhancedConfigsMixin, App.ThemesMappingMixin, App.ConfigsSaverMixin,
+  App.ConfigsComparator, App.ComponentActionsByConfigs, {
 
   name: 'mainServiceInfoConfigsController',
 
@@ -328,15 +330,17 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
   },
 
   parseConfigData: function(data) {
-    this.prepareConfigObjects(data, this.get('content.serviceName'));
     var self = this;
-    this.loadCompareVersionConfigs(this.get('allConfigs')).done(function() {
-      self.addOverrides(data, self.get('allConfigs'));
-      self.onLoadOverrides(self.get('allConfigs'));
+    this.loadKerberosIdentitiesConfigs().done(function(identityConfigs) {
+      self.prepareConfigObjects(data, identityConfigs);
+      self.loadCompareVersionConfigs(self.get('allConfigs')).done(function() {
+        self.addOverrides(data, self.get('allConfigs'));
+        self.onLoadOverrides(self.get('allConfigs'));
+      });
     });
   },
 
-  prepareConfigObjects: function(data, serviceName) {
+  prepareConfigObjects: function(data, identitiesMap) {
     this.get('stepConfigs').clear();
 
     var configs = [];
@@ -362,7 +366,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
     }
 
     this.setPropertyIsVisible(configs);
-    this.setPropertyIsEditable(configs);
+    this.setPropertyIsEditable(configs, identitiesMap);
     this.set('allConfigs', configs);
   },
 
@@ -387,16 +391,41 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ConfigsLoader, A
   },
 
   /**
-   * Set <code>isEditable<code> proeperty based on selected group, security
+   * Set <code>isEditable<code> property based on selected group, security
    * and controller restriction
    * @param configs
+   * @param identitiesMap
    */
-  setPropertyIsEditable: function(configs) {
+  setPropertyIsEditable: function (configs, identitiesMap) {
     if (!this.get('selectedConfigGroup.isDefault') || !this.get('canEdit')) {
       configs.setEach('isEditable', false);
     } else if (App.get('isKerberosEnabled')) {
-      configs.filterProperty('isSecureConfig').setEach('isEditable', false);
+      configs.forEach(function (c) {
+        if (identitiesMap[c.get('id')]) {
+          c.set('isConfigIdentity', true);
+          c.set('isEditable', false);
+          c.set('isSecureConfig', true);
+          c.set('description', App.config.kerberosIdentitiesDescription(c.get('description')));
+        }
+      });
+    }
+  },
+
+  /**
+   * Load config Identities
+   *
+   * @returns {*}
+   */
+  loadKerberosIdentitiesConfigs: function () {
+    var dfd = $.Deferred();
+    if (App.get('isKerberosEnabled')) {
+      this.loadClusterDescriptorConfigs().then(function (kerberosDescriptor) {
+        dfd.resolve(App.config.parseDescriptor(kerberosDescriptor));
+      });
+    } else {
+      dfd.resolve(true);
     }
+    return dfd.promise();
   },
 
   /**

+ 22 - 12
ambari-web/app/controllers/wizard/step7_controller.js

@@ -389,6 +389,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
   },
 
   onLoadOverrides: function () {
+    debugger;
     this.get('stepConfigs').forEach(function(stepConfig) {
       stepConfig.set('configGroups', App.ServiceConfigGroup.find().filterProperty('serviceName', stepConfig.get('serviceName')));
 
@@ -412,7 +413,9 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
    */
   _updateIsEditableFlagForConfig: function (serviceConfigProperty, defaultGroupSelected) {
     if (App.isAuthorized('AMBARI.ADD_DELETE_CLUSTERS')) {
-      if (defaultGroupSelected && !Em.get(serviceConfigProperty, 'group')) {
+      if (App.get('isKerberosEnabled') && serviceConfigProperty.get('isConfigIdentity')) {
+        serviceConfigProperty.set('isEditable', false);
+      } else if (defaultGroupSelected && !Em.get(serviceConfigProperty, 'group')) {
         if (serviceConfigProperty.get('serviceName') === 'MISC') {
           var service = App.config.get('serviceByConfigTypeMap')[App.config.getConfigTagFromFileName(serviceConfigProperty.get('filename'))];
           serviceConfigProperty.set('isEditable', service && !this.get('installedServiceNames').contains(service.get('serviceName')));
@@ -422,8 +425,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
       } else if (!(Em.get(serviceConfigProperty, 'group') && Em.get(serviceConfigProperty, 'group.name') === this.get('selectedConfigGroup.name'))) {
         serviceConfigProperty.set('isEditable', false);
       }
-    }
-    else {
+    } else {
       serviceConfigProperty.set('isEditable', false);
     }
     return serviceConfigProperty;
@@ -588,6 +590,10 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
           displayName: Em.get(item, 'name'),
           isUserProperty: false,
           isOverridable: false,
+          isConfigIdentity: Em.get(item, 'isConfigIdentity'),
+          description: Em.get(item, 'isConfigIdentity')
+            ? App.config.kerberosIdentitiesDescription(Em.get(property, 'description'))
+            : Em.get(property, 'description'),
           category: 'Advanced ' + Em.get(item, 'filename')
         });
       }
@@ -1123,17 +1129,21 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, App.E
   _setEditableValue: function (config) {
     var selectedGroup = this.get('selectedConfigGroup');
     if (!selectedGroup) return config;
-    var isEditable = config.get('isEditable'),
-      isServiceInstalled = this.get('installedServiceNames').contains(this.get('selectedService.serviceName'));
-    if (isServiceInstalled) {
-      isEditable = config.get('isReconfigurable') && selectedGroup.get('isDefault');
+    if (App.get('isKerberosEnabled') && config.get('isConfigIdentity')) {
+      config.set('isEditable', false);
     } else {
-      isEditable = selectedGroup.get('isDefault');
-    }
-    if (config.get('group')) {
-      isEditable = config.get('group.name') === this.get('selectedConfigGroup.name');
+      var isEditable = config.get('isEditable'),
+        isServiceInstalled = this.get('installedServiceNames').contains(this.get('selectedService.serviceName'));
+      if (isServiceInstalled) {
+        isEditable = config.get('isReconfigurable') && selectedGroup.get('isDefault');
+      } else {
+        isEditable = selectedGroup.get('isDefault');
+      }
+      if (config.get('group')) {
+        isEditable = config.get('group.name') === this.get('selectedConfigGroup.name');
+      }
+      config.set('isEditable', isEditable);
     }
-    config.set('isEditable', isEditable);
     return config;
   },
 

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

@@ -2000,6 +2000,7 @@ Em.I18n.translations = {
   'services.service.config.nothing.to.display': 'No properties to display.',
   'services.service.config.final':'Final',
   'services.service.config.password.additionalDescription': 'For security purposes, password changes will not be shown in configuration version comparisons',
+  'services.service.config.secure.additionalDescription': ' This config can be changed from Kerberos page under Admin tab by privileged users.',
   'services.service.config.saved':'Save Configuration Changes',
   'services.service.config.notSaved':'Unable to Save Configuration Changes',
   'services.service.config.restartService.TooltipMessage':'<b>Restart Service</b><br>Stale configuration used by {0} components on {1} hosts:{2}',

+ 1 - 14
ambari-web/app/mixins/wizard/addSecurityConfigs.js

@@ -128,6 +128,7 @@ App.AddSecurityConfigs = Em.Mixin.create({
     var configs = [];
     identities.forEach(function (identity) {
       var defaultObject = {
+        isConfigIdentity: true,
         isOverridable: false,
         isVisible: true,
         isSecureConfig: true,
@@ -415,20 +416,6 @@ App.AddSecurityConfigs = Em.Mixin.create({
     return isConfigUpdated;
   },
 
-  /**
-   * Make request for stack descriptor configs if cluster  is not secure
-   * or cluster descriptor configs if cluster is secure
-   * @returns {$.ajax}
-   * @method loadStackDescriptorConfigs
-   */
-  loadDescriptorConfigs: function() {
-    if (this.get('shouldLoadClusterDescriptor')) {
-      return this.loadClusterDescriptorConfigs();
-    } else {
-      return this.loadStackDescriptorConfigs();
-    }
-  },
-
   /**
    * Check if cluster descriptor should be loaded
    * @returns {Boolean}

+ 2 - 0
ambari-web/app/models/configs/objects/service_config_property.js

@@ -142,6 +142,8 @@ App.ServiceConfigProperty = Em.Object.extend({
   isComparison: false,
   hasCompareDiffs: false,
   showLabel: true,
+  isConfigIdentity: false,
+
 
   error: Em.computed.bool('errorMessage.length'),
   warn: Em.computed.bool('warnMessage.length'),

+ 49 - 0
ambari-web/app/utils/config.js

@@ -462,6 +462,55 @@ App.config = Em.Object.create({
     return description
   },
 
+  /**
+   * parse Kerberos descriptor
+   *
+   * @param kerberosDescriptor
+   * @returns {{}}
+   */
+  parseDescriptor: function(kerberosDescriptor) {
+    var identitiesMap = {};
+    Em.get(kerberosDescriptor, 'KerberosDescriptor.kerberos_descriptor.services').forEach(function (service) {
+      this.parseIdentities(service, identitiesMap);
+      service.components.forEach(function (component) {
+        this.parseIdentities(component, identitiesMap);
+      }, this);
+    }, this);
+    return identitiesMap;
+  },
+
+  /**
+   * Looking for configs identities and add them to <code>identitiesMap<code>
+   *
+   * @param item
+   * @param identitiesMap
+   */
+  parseIdentities: function (item, identitiesMap) {
+    if (item.identities) {
+      item.identities.forEach(function (identity) {
+
+        Em.keys(identity).without('name').forEach(function (item) {
+          if (identity[item].configuration) {
+            var cfg = identity[item].configuration.split('/'), name = cfg[1], fileName = cfg[0];
+            identitiesMap[App.config.configId(name, fileName)] = true;
+          }
+        });
+      });
+    }
+    return identitiesMap;
+  },
+
+  /**
+   * Update description for disabled kerberos configs which are identities
+   *
+   * @param description
+   * @returns {*}
+   */
+  kerberosIdentitiesDescription: function(description) {
+    return (description.endsWith('.') ? description : description + '.') +
+      Em.I18n.t('services.service.config.secure.additionalDescription');
+  },
+
   /**
    * Get view class based on display type of config
    *

+ 12 - 3
ambari-web/test/controllers/wizard/step7_test.js

@@ -1442,10 +1442,19 @@ describe('App.InstallerStep7Controller', function () {
   });
 
   describe('#addKerberosDescriptorConfigs', function() {
+
+    beforeEach(function() {
+      sinon.stub(App.config, 'kerberosIdentitiesDescription');
+    });
+
+    afterEach(function() {
+      App.config.kerberosIdentitiesDescription.restore();
+    });
+
     var configs = [
-      { name: 'prop1', displayName: 'Prop1' },
-      { name: 'prop2', displayName: 'Prop2' },
-      { name: 'prop3', displayName: 'Prop3' }
+      { name: 'prop1', displayName: 'Prop1', description: 'd1' },
+      { name: 'prop2', displayName: 'Prop2', description: 'd1' },
+      { name: 'prop3', displayName: 'Prop3', description: 'd1' }
     ];
     var descriptor = [
       Em.Object.create({ name: 'prop4', filename: 'file-1'}),

+ 54 - 0
ambari-web/test/utils/config_test.js

@@ -915,4 +915,58 @@ describe('App.config', function () {
     });
 
   });
+
+  describe('#parseIdentities', function() {
+    var testObject = {
+      identities: [
+        {
+          name: "/spnego"
+        },
+        {
+          principal: {
+            configuration: "hbase-env/hbase_principal_name",
+            type: "user",
+            local_username: "${hbase-env/hbase_user}",
+            value: "${hbase-env/hbase_user}-${cluster_name|toLower()}@${realm}"
+          },
+          name: "hbase",
+          keytab: {
+            owner: {
+              access: "r",
+              name: "${hbase-env/hbase_user}"
+            },
+            file: "${keytab_dir}/hbase.headless.keytab",
+            configuration: "hbase-env/hbase_user_keytab",
+            group: {
+              access: "r",
+              name: "${cluster-env/user_group}"
+            }
+          }
+        },
+        {
+          name: "/smokeuser"
+        }
+      ]
+    };
+    var result = {
+      "hbase_principal_name__hbase-env": true,
+      "hbase_user_keytab__hbase-env": true
+    };
+
+    it('generates map with identities', function() {
+      expect(App.config.parseIdentities(testObject, {})).to.eql(result);
+    });
+  });
+
+  describe('#kerberosIdentitiesDescription', function () {
+    it('update description for identities (without dot)', function() {
+      expect(App.config.kerberosIdentitiesDescription('some text')).to.eql('some text.'
+        + Em.I18n.t('services.service.config.secure.additionalDescription'));
+    });
+
+    it('update description for identities (with dot)', function() {
+      expect(App.config.kerberosIdentitiesDescription('some text.')).to.eql('some text.'
+        + Em.I18n.t('services.service.config.secure.additionalDescription'));
+    });
+  });
 });