You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2016/04/09 20:14:53 UTC
[1/3] ambari git commit: AMBARI-15782. trunk deploy marks
dfs.ha.fencing.methods as a required property (alexantonenko)
Repository: ambari
Updated Branches:
refs/heads/trunk 356cb9432 -> 7b64e964d
AMBARI-15782. trunk deploy marks dfs.ha.fencing.methods as a required property (alexantonenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7b64e964
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7b64e964
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7b64e964
Branch: refs/heads/trunk
Commit: 7b64e964db9e44a42cf10d0a2a717349a78cfbe6
Parents: 6de04a3
Author: Alex Antonenko <hi...@gmail.com>
Authored: Fri Apr 8 20:50:57 2016 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Sat Apr 9 21:14:47 2016 +0300
----------------------------------------------------------------------
ambari-web/app/mappers/configs/stack_config_properties_mapper.js | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b64e964/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/configs/stack_config_properties_mapper.js b/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
index 32a45a5..59f9916 100644
--- a/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
+++ b/ambari-web/app/mappers/configs/stack_config_properties_mapper.js
@@ -206,6 +206,8 @@ App.stackConfigPropertiesMapper = App.QuickDataMapper.create({
*/
addUIOnlyProperties: function(configs) {
require('data/HDP2/ui_properties').concat(require('data/HDP2/alert_notification')).forEach(function(p) {
+ if(p.name == "dfs.ha.fencing.methods" && !App.get('isHaEnabled')) return;
+
configs.push({
id: App.config.configId(p.name, p.filename),
name: p.name,
[3/3] ambari git commit: AMBARI-15779. Wrong description for property
name "ranger.usersync.sleeptimeinmillisbetweensynccycle" in Ambari UI
(alexantonenko)
Posted by al...@apache.org.
AMBARI-15779. Wrong description for property name "ranger.usersync.sleeptimeinmillisbetweensynccycle" in Ambari UI (alexantonenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e44c4f76
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e44c4f76
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e44c4f76
Branch: refs/heads/trunk
Commit: e44c4f76c9741b4cf541d8a45a584b16b81c0626
Parents: 356cb94
Author: Alex Antonenko <hi...@gmail.com>
Authored: Fri Apr 8 19:12:57 2016 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Sat Apr 9 21:14:47 2016 +0300
----------------------------------------------------------------------
.../HDP/2.3/services/RANGER/configuration/ranger-ugsync-site.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e44c4f76/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-ugsync-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-ugsync-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-ugsync-site.xml
index 6cbd12f..38a5cbe 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-ugsync-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.3/services/RANGER/configuration/ranger-ugsync-site.xml
@@ -139,7 +139,7 @@
<property>
<name>ranger.usersync.sleeptimeinmillisbetweensynccycle</name>
<value>60000</value>
- <description>Sleeptime interval in milliseconds, if < 1000 then default to 30 sec</description>
+ <description>Sleeptime interval in milliseconds, if < 6000 then default to 1 min</description>
</property>
<property>
[2/3] ambari git commit: AMBARI-15780. Kerberos wizard: Integrate
Configure Identities page with stack advisor recommendations (alexantonenko)
Posted by al...@apache.org.
AMBARI-15780. Kerberos wizard: Integrate Configure Identities page with stack advisor recommendations (alexantonenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6de04a33
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6de04a33
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6de04a33
Branch: refs/heads/trunk
Commit: 6de04a33c63ed9f6523839048e0d5a588d2037a3
Parents: e44c4f7
Author: Alex Antonenko <hi...@gmail.com>
Authored: Fri Apr 8 19:34:38 2016 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Sat Apr 9 21:14:47 2016 +0300
----------------------------------------------------------------------
ambari-web/app/config.js | 3 +-
.../app/controllers/main/admin/kerberos.js | 10 +
.../main/admin/kerberos/step4_controller.js | 350 +++++++++++++++++--
.../app/mixins/wizard/addSecurityConfigs.js | 19 +-
.../admin/kerberos/step4_controller_test.js | 202 ++++++++++-
5 files changed, 553 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6de04a33/ambari-web/app/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/config.js b/ambari-web/app/config.js
index b1f6bd5..06afa49 100644
--- a/ambari-web/app/config.js
+++ b/ambari-web/app/config.js
@@ -81,7 +81,8 @@ App.supports = {
logSearch: false,
redhatSatellite: false,
enableIpa: false,
- addingNewRepository: false
+ addingNewRepository: false,
+ kerberosStackAdvisor: true
};
if (App.enableExperimental) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/6de04a33/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 5472413..2db825a 100644
--- a/ambari-web/app/controllers/main/admin/kerberos.js
+++ b/ambari-web/app/controllers/main/admin/kerberos.js
@@ -595,6 +595,16 @@ App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
showManageKDCCredentialsPopup: function() {
return App.showManageCredentialsPopup();
+ },
+
+ loadStep: function() {
+ var self = this;
+ this.clearStep();
+ this.getDescriptor().then(function (properties) {
+ self.setStepConfigs(self.createServicesStackDescriptorConfigs(properties));
+ }).always(function() {
+ self.set('isRecommendedLoaded', true);
+ });
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/6de04a33/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 ac8c212..b3acb8b 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
@@ -23,6 +23,9 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
name: 'kerberosWizardStep4Controller',
isWithinAddService: Em.computed.equal('wizardController.name', 'addServiceController'),
+ // stores configurations loaded by ConfigurationsController.getConfigsByTags
+ servicesConfigurations: null,
+
clearStep: function() {
this.set('isRecommendedLoaded', false);
this.set('selectedService', null);
@@ -30,15 +33,28 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
},
loadStep: function() {
+ var self, stored;
if (this.get('wizardController.skipConfigureIdentitiesStep')) {
App.router.send('next');
return;
}
- var self = this;
+ self = this;
this.clearStep();
- this.getDescriptor().then(function (properties) {
- self.setStepConfigs(self.createServicesStackDescriptorConfigs(properties));
- }).always(function() {
+ stored = this.get('wizardController').loadCachedStepConfigValues(this) || [];
+ this.getDescriptor().then(function (kerberosDescriptor) {
+ var stepConfigs = self.setStepConfigs(self.createServicesStackDescriptorConfigs(kerberosDescriptor));
+ self.set('stepConfigs', stepConfigs);
+ // when configurations were stored no need to apply recommendations again
+ if (App.get('supports.kerberosStackAdvisor') && !stored.length) {
+ self.bootstrapRecommendationPayload(kerberosDescriptor).then(function(recommendations) {
+ self.loadServerSideConfigsRecommendations(recommendations).done(function() {
+ self.applyServiceConfigs(stepConfigs);
+ });
+ });
+ } else {
+ self.applyServiceConfigs(stepConfigs);
+ }
+ }, function() {
self.set('isRecommendedLoaded', true);
});
},
@@ -100,6 +116,7 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
serviceName: 'KERBEROS_GENERAL',
configCategories: categoryForGeneralConfigs,
configs: generalConfigs,
+ configGroups: [],
showConfig: true
}),
App.ServiceConfig.create({
@@ -108,6 +125,7 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
serviceName: 'KERBEROS_ADVANCED',
configCategories: categoryForAdvancedConfigs,
configs: advancedConfigs,
+ configGroups: [],
showConfig: true
})
];
@@ -119,7 +137,7 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
*/
createCategoryForServices: function() {
var services = [];
- if (this.get('wizardController.name') == 'addServiceController') {
+ if (this.get('wizardController.name') === 'addServiceController') {
services = App.StackService.find().filter(function(item) {
return item.get('isInstalled') || item.get('isSelected');
});
@@ -135,13 +153,13 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
* Prepare step configs using stack descriptor properties.
*
* @param {App.ServiceConfigProperty[]} configs
- * @param {App.ServiceConfigProperty[]} stackConfigs
+ * @param {App.ServiceConfigProperty[]} stackConfigs converted kerberos descriptor
*/
setStepConfigs: function(configs, stackConfigs) {
var configProperties = this.prepareConfigProperties(configs),
stackConfigProperties = stackConfigs ? this.prepareConfigProperties(stackConfigs) : [],
alterProperties = ['value','initialValue', 'defaultValue'];
- if (this.get('wizardController.name') == 'addServiceController') {
+ if (this.get('wizardController.name') === 'addServiceController') {
// config properties for installed services should be disabled on Add Service Wizard
configProperties.forEach(function(item) {
if (this.get('installedServiceNames').contains(item.get('serviceName')) || item.get('serviceName') == 'Cluster') {
@@ -159,7 +177,7 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
stackConfigProperties.forEach(function(_stackConfigProperty){
var isPropertyInClusterDescriptor = configProperties.filterProperty('filename', _stackConfigProperty.get('filename')).someProperty('name', _stackConfigProperty.get('name'));
if (!isPropertyInClusterDescriptor) {
- if (this.get('installedServiceNames').contains(_stackConfigProperty.get('serviceName')) || _stackConfigProperty.get('serviceName') == 'Cluster') {
+ if (this.get('installedServiceNames').contains(_stackConfigProperty.get('serviceName')) || _stackConfigProperty.get('serviceName') === 'Cluster') {
_stackConfigProperty.set('isEditable', false);
}
configProperties.pushObject(_stackConfigProperty);
@@ -167,8 +185,9 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
}, this);
}
configProperties = App.config.sortConfigs(configProperties);
- this.get('stepConfigs').pushObjects(this.createServiceConfig(configProperties));
- this.set('selectedService', this.get('stepConfigs')[0]);
+ var stepConfigs = this.createServiceConfig(configProperties);
+ this.set('selectedService', stepConfigs[0]);
+ return stepConfigs;
},
/**
@@ -189,6 +208,7 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
var installedServiceNames = ['Cluster'].concat(App.Service.find().mapProperty('serviceName'));
var configProperties = configs.slice(0);
var siteProperties = App.configsCollection.getAll();
+ var realmValue;
// override stored values
App.config.mergeStoredValue(configProperties, this.get('wizardController').loadCachedStepConfigValues(this));
@@ -199,8 +219,8 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
configProperties = configProperties.filter(function(item) {
return installedServiceNames.contains(item.get('serviceName'));
});
- if (this.get('wizardController.name') != 'addServiceController') {
- var realmValue = storedServiceConfigs.findProperty('name', 'realm').value;
+ if (this.get('wizardController.name') !== 'addServiceController') {
+ 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);
@@ -216,7 +236,7 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
property.set('value', observedValue);
property.set('recommendedValue', observedValue);
}
- if (property.get('serviceName') == 'Cluster') {
+ if (property.get('serviceName') === 'Cluster') {
property.set('category', 'Global');
}
else {
@@ -246,17 +266,21 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
* Function to override kerberos descriptor's property values
*/
tweakConfigProperty: function(config) {
+ var defaultHiveMsPort = "9083",
+ hiveMSHosts,
+ port,
+ hiveMSHostNames,
+ configValue;
if (config.name === 'templeton.hive.properties') {
- var defaultHiveMsPort = "9083";
- var hiveMSHosts = App.HostComponent.find().filterProperty('componentName', 'HIVE_METASTORE');
+ hiveMSHosts = App.HostComponent.find().filterProperty('componentName', 'HIVE_METASTORE');
if (hiveMSHosts.length > 1) {
- var hiveMSHostNames = hiveMSHosts.mapProperty('hostName');
- var port = config.value.match(/:[0-9]{2,4}/);
+ hiveMSHostNames = hiveMSHosts.mapProperty('hostName');
+ port = config.value.match(/:[0-9]{2,4}/);
port = port ? port[0].slice(1) : defaultHiveMsPort;
for (var i = 0; i < hiveMSHostNames.length; i++) {
hiveMSHostNames[i] = "thrift://" + hiveMSHostNames[i] + ":" + port;
}
- var configValue = config.value.replace(/thrift.+[0-9]{2,},/i, hiveMSHostNames.join('\\,') + ",");
+ configValue = config.value.replace(/thrift.+[0-9]{2,},/i, hiveMSHostNames.join('\\,') + ",");
config.set('value', configValue);
config.set('recommendedValue', configValue);
}
@@ -265,14 +289,14 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
/**
* Sync up values between inherited property and its reference.
- *
+ *
* @param {App.ServiceConfigProperty} configProperty
*/
spnegoPropertiesObserver: function(configProperty) {
var self = this;
- var stepConfig = this.get('stepConfigs').findProperty('name', 'ADVANCED');
+ var stepConfig = this.get('stepConfigs').findProperty('name', 'ADVANCED');
stepConfig.get('configs').forEach(function(config) {
- if (config.get('observesValueFrom') == configProperty.get('name')) {
+ if (config.get('observesValueFrom') === configProperty.get('name')) {
Em.run.once(self, function() {
config.set('value', configProperty.get('value'));
config.set('recommendedValue', configProperty.get('value'));
@@ -294,5 +318,289 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
});
this.updateKerberosDescriptor(kerberosDescriptor, configs);
App.get('router.kerberosWizardController').saveKerberosDescriptorConfigs(kerberosDescriptor);
+ },
+
+ /**
+ * Add/update property in `properties` object for each config type with
+ * associated kerberos descriptor config value.
+ *
+ * @private
+ * @param {object[]} configurations
+ * @param {App.ServiceConfigProperty[]} kerberosDescriptor
+ * @returns {object[]}
+ */
+ mergeDescriptorToConfigurations: function(configurations, kerberosDescriptor) {
+ return configurations.map(function(configType) {
+ var properties = $.extend({}, configType.properties);
+ var filteredDescriptor = kerberosDescriptor.filterProperty('filename', configType.type);
+ if (filteredDescriptor.length) {
+ filteredDescriptor.forEach(function(descriptorConfig) {
+ var configName = Em.get(descriptorConfig, 'name');
+ properties[configName] = Em.get(descriptorConfig, 'value');
+ });
+ }
+ return {
+ type: configType.type,
+ version: configType.version,
+ tag: configType.tag,
+ properties: properties
+ };
+ });
+ },
+
+ loadServerSideConfigsRecommendations: function(recommendations) {
+ return App.ajax.send({
+ 'name': 'config.recommendations',
+ 'sender': this,
+ 'data': {
+ stackVersionUrl: App.get('stackVersionURL'),
+ dataToSend: {
+ recommend: 'configurations',
+ hosts: this.get('hostNames'),
+ services: this.get('serviceNames'),
+ recommendations: recommendations
+ }
+ },
+ 'success': 'loadRecommendationsSuccess',
+ 'error': 'loadRecommendationsError'
+ });
+ },
+
+ applyServiceConfigs: function(stepConfigs) {
+ this.set('isRecommendedLoaded', true);
+ this.set('selectedService', stepConfigs[0]);
+ },
+
+ /**
+ * Callback executed when all configs specified by tags are loaded.
+ * Here we handle configurations for instlled services and Kerberos.
+ * Gather needed info for recommendation request such as configurations object.
+ *
+ * @override
+ */
+ getConfigTagsSuccess: function(data) {
+ // here we get all installed services including KERBEROS
+ var serviceNames = App.Service.find().mapProperty('serviceName').concat(['KERBEROS']).uniq();
+ // collect all config types for selected services
+ var installedServiceSites = Array.prototype.concat.apply([], App.config.get('preDefinedServiceConfigs').filter(function(serviceConfig) {
+ return serviceNames.contains(Em.get(serviceConfig, 'serviceName'));
+ }).map(function (service) {
+ // when service have no configs return <code>null</code> instead return config types
+ if (!service.get('configTypes')) return null;
+ return Object.keys(service.get('configTypes'));
+ }, this).compact()).uniq(); // cleanup <code>null</code>
+
+ // take all configs for selected services by config types recieved from API response
+ var serviceConfigTags = Em.keys(data.Clusters.desired_configs).reduce(function(tags, site) {
+ if (data.Clusters.desired_configs.hasOwnProperty(site)) {
+ // push cluster-env.xml also since it not associated with any service but need to further processing
+ if (installedServiceSites.contains(site) || site === 'cluster-env') {
+ tags.push({
+ siteName: site,
+ tagName: data.Clusters.desired_configs[site].tag,
+ newTagName: null
+ });
+ }
+ }
+ return tags;
+ }, []);
+ // store configurations
+ this.set('serviceConfigTags', serviceConfigTags);
+ this.set('isAppliedConfigLoaded', true);
+ },
+
+ /**
+ * Prepare all necessary data for recommendations payload.
+ *
+ * #mutates initialConfigValues
+ * @returns {$.Deferred.promise()}
+ */
+ bootstrapRecommendationPayload: function(kerberosDescriptor) {
+ var dfd = $.Deferred();
+ var self = this;
+ this.getServicesConfigurations().then(function(configurations) {
+ var recommendations = self.getBlueprintPayloadObject(configurations, kerberosDescriptor);
+ self.set('servicesConfigurations', configurations);
+ self.set('initialConfigValues', recommendations.blueprint.configurations);
+ dfd.resolve(recommendations);
+ });
+ return dfd.promise();
+ },
+
+ getServicesConfigurations: function() {
+ var dfd = $.Deferred();
+ var self = this;
+ var configs, servicesConfigurations;
+ if (this.get('isWithinAddService')) {
+ configs = this.get('wizardController').getDBProperty('serviceConfigProperties');
+ servicesConfigurations = configs.reduce(function(configTags, property) {
+ var fileName = App.config.getConfigTagFromFileName(property.filename),
+ configType;
+ if (!configTags.someProperty('type', fileName)) {
+ configTags.push({
+ type: fileName,
+ properties: {}
+ });
+ }
+ configType = configTags.findProperty('type', fileName);
+ configType.properties[property.name] = property.value;
+ return configTags;
+ }, []);
+ dfd.resolve(servicesConfigurations);
+ } else {
+ this.getConfigTags().then(function() {
+ App.router.get('configurationController').getConfigsByTags(self.get('serviceConfigTags')).done(function (configurations) {
+ dfd.resolve(configurations);
+ });
+ });
+ }
+
+ return dfd.promise();
+ },
+
+ /**
+ * Returns payload for recommendations request.
+ * Takes services' configurations and merge them with kerberos descriptor properties.
+ *
+ * @param {object[]} configurations services' configurations fetched from API
+ * @param {App.ServiceConfigProperty[]} kerberosDescriptor descriptor configs
+ * @returns {object} payload for recommendations request
+ */
+ getBlueprintPayloadObject: function(configurations, kerberosDescriptor) {
+ var recommendations = this.get('hostGroups');
+ var mergedConfigurations = this.mergeDescriptorToConfigurations(configurations, this.createServicesStackDescriptorConfigs(kerberosDescriptor));
+ recommendations.blueprint.configurations = mergedConfigurations.reduce(function(p, c) {
+ p[c.type] = {};
+ p[c.type].properties = c.properties;
+ return p;
+ }, {});
+
+ return recommendations;
+ },
+
+ /**
+ * @override
+ */
+ _saveRecommendedValues: function(data) {
+ var recommendedConfigurations = Em.getWithDefault(data, 'resources.0.recommendations.blueprint.configurations', {});
+ var allConfigs = Array.prototype.concat.apply([], this.get('stepConfigs').mapProperty('configs'));
+ var self = this;
+ // iterate by each config file name e.g. hdfs-site
+ var groupedProperties = this.groupRecommendationProperties(recommendedConfigurations, this.get('servicesConfigurations'), allConfigs);
+ var newProperties = [];
+ Em.keys(groupedProperties.add).forEach(function(fileName) {
+ var serviceName = self.getServiceByFilename(fileName);
+ Em.keys(groupedProperties.add[fileName]).forEach(function(propertyName) {
+ var property = self._createNewProperty(propertyName, fileName, serviceName, groupedProperties.add[fileName][propertyName]);
+ property.set('category', serviceName);
+ property.set('isOverridable', false);
+ property.set('supportsFinal', false);
+ property.set('isUserProperty', false);
+ property.set('filename', fileName);
+ newProperties.push(property);
+ });
+ });
+ Array.prototype.push.apply(self.getServicesConfigObject().get('configs'), newProperties);
+ Em.keys(groupedProperties.update).forEach(function(fileName) {
+ Em.keys(groupedProperties.update[fileName]).forEach(function(propertyName) {
+ var configProperty = allConfigs.findProperty('name', propertyName);
+ if (configProperty) {
+ self._updateConfigByRecommendation(configProperty, groupedProperties.update[fileName][propertyName], true, false);
+ }
+ });
+ });
+ Em.keys(groupedProperties.delete).forEach(function(fileName) {
+ Em.keys(groupedProperties.delete[fileName]).forEach(function(propertyName) {
+ var servicesConfigs = self.getServicesConfigObject().get('configs');
+ servicesConfigs.removeObject(servicesConfigs.filterProperty('filename', fileName).findProperty('name', propertyName));
+ });
+ });
+ },
+
+ /**
+ * Returns category where services' configuration located.
+ *
+ * @returns {App.ServiceConfig}
+ */
+ getServicesConfigObject: function() {
+ return this.get('stepConfigs').findProperty('name', 'ADVANCED');
+ },
+
+ /**
+ * Returns map with appropriate action and properties to process with.
+ * Key is an action e.g. `add`, `update`, `delete` and value is an object `fileName` -> `propertyName`: `propertyValue`.
+ *
+ * @param {object} recommendedConfigurations
+ * @param {object[]} servicesConfigurations services' configurations fetched from API
+ * @param {App.ServiceConfigProperty[]} allConfigs all current configurations stored in controller, basically kerberos descriptor
+ * @returns {object}
+ */
+ groupRecommendationProperties: function(recommendedConfigurations, servicesConfigurations, allConfigs) {
+ var resultMap = {
+ update: {},
+ add: {},
+ delete: {}
+ };
+
+ /**
+ * Adds property to associated group `add`,`delete`,`update`.
+ *
+ * @param {object} propertyMap <code>resultMap</code> object
+ * @param {string} name property name
+ * @param {string} propertyValue property value
+ * @param {string} fileName property file name
+ * @return {object} <code>resultMap</code>
+ * @param {string} group, `add`,`delete`,`update`
+ */
+ var addProperty = function(propertyMap, name, propertyValue, fileName, group) {
+ var ret = $.extend(true, {}, propertyMap);
+ if (ret.hasOwnProperty(group)) {
+ if (!ret[group].hasOwnProperty(fileName)) {
+ ret[group][fileName] = {};
+ }
+ ret[group][fileName][name] = propertyValue;
+ }
+ return ret;
+ };
+
+ return Em.keys(recommendedConfigurations || {}).reduce(function(acc, fileName) {
+ var propertyMap = acc;
+ var recommendedProperties = Em.getWithDefault(recommendedConfigurations, fileName + '.properties', {});
+ var recommendedAttributes = Em.getWithDefault(recommendedConfigurations, fileName + '.property_attributes', {});
+ // check for properties that should be delted
+ Em.keys(recommendedAttributes).forEach(function(propertyName) {
+ var attribute = recommendedAttributes[propertyName];
+ // delete properties which are present in kerberos descriptor
+ if (attribute.hasOwnProperty('delete') && allConfigs.filterProperty('filename', fileName).someProperty('name', propertyName)) {
+ propertyMap = addProperty(propertyMap, propertyName, '', fileName, 'delete');
+ }
+ });
+
+ return Em.keys(recommendedProperties).reduce(function(a, propertyName) {
+ var propertyValue = recommendedProperties[propertyName];
+ // check if property exist in saved configurations on server
+ var isExist = Em.getWithDefault(servicesConfigurations.findProperty('type', fileName) || {}, 'properties', {}).hasOwnProperty(propertyName);
+ if (!isExist) {
+ return addProperty(a, propertyName, propertyValue, fileName, 'add');
+ }
+ // when property exist check that it present in current step configs (kerberos descriptor)
+ // and add it as property to `update`
+ if (allConfigs.filterProperty('filename', fileName).someProperty('name', propertyName)) {
+ return addProperty(a, propertyName, propertyValue, fileName, 'update');
+ }
+ return a;
+ }, propertyMap);
+ }, resultMap);
+ },
+
+ getServiceByFilename: function(fileName) {
+ // core-site properties goes to HDFS
+ if (fileName === 'core-site' && App.Service.find().someProperty('serviceName', 'HDFS')) {
+ return 'HDFS';
+ }
+ var associatedService = App.StackService.find().filter(function(service) {
+ return Em.keys(service.get('configTypes')).contains(fileName);
+ })[0];
+ return associatedService ? associatedService.get('serviceName') : '';
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/6de04a33/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 c1c301f..a829cb6 100644
--- a/ambari-web/app/mixins/wizard/addSecurityConfigs.js
+++ b/ambari-web/app/mixins/wizard/addSecurityConfigs.js
@@ -17,7 +17,6 @@
*/
var App = require('app');
-var objectUtils = require('utils/object_utils');
/**
* Mixin for loading and setting secure configs
@@ -167,7 +166,12 @@ App.AddSecurityConfigs = Em.Mixin.create({
configObject.referenceProperty = name.substring(1) + ':' + item;
configObject.isEditable = false;
}
- configObject.defaultValue = configObject.savedValue = configObject.value = itemValue;
+ Em.setProperties(configObject, {
+ recommendedValue: itemValue,
+ initialValue: itemValue,
+ defaultValue: itemValue,
+ value: itemValue
+ });
configObject.filename = prop.configuration ? prop.configuration.split('/')[0] : 'cluster-env';
configObject.name = prop.configuration ? prop.configuration.split('/')[1] : name + '_' + item;
predefinedProperty = self.get('kerberosDescriptorProperties').findProperty('name', configObject.name);
@@ -207,17 +211,20 @@ App.AddSecurityConfigs = Em.Mixin.create({
for (var propertyName in kerberosProperties) {
var predefinedProperty = this.get('kerberosDescriptorProperties').findProperty('name', propertyName);
+ var value = kerberosProperties[propertyName];
+ var isRequired = propertyName == 'additional_realms' ? false : value !== "";
var propertyObject = {
name: propertyName,
- value: kerberosProperties[propertyName],
- defaultValue: kerberosProperties[propertyName],
- savedValue: kerberosProperties[propertyName],
+ value: value,
+ defaultValue: value,
+ recommendedValue: value,
+ initialValue: value,
serviceName: serviceName,
filename: filename,
displayName: serviceName == "Cluster" ? App.format.normalizeName(propertyName) : propertyName,
isOverridable: false,
isEditable: propertyName != 'realm',
- isRequired: propertyName != 'additional_realms',
+ isRequired: isRequired,
isSecureConfig: true,
placeholderText: predefinedProperty && !Em.isNone(predefinedProperty.index) ? predefinedProperty.placeholderText : '',
index: predefinedProperty && !Em.isNone(predefinedProperty.index) ? predefinedProperty.index : Infinity
http://git-wip-us.apache.org/repos/asf/ambari/blob/6de04a33/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
index 01a3b00..75507f0 100644
--- a/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
@@ -213,8 +213,8 @@ describe('App.KerberosWizardStep4Controller', function() {
})
});
sinon.stub(App.router, 'get').withArgs('mainAdminKerberosController.isManualKerberos').returns(false);
- controller.setStepConfigs(properties);
- res = controller.get('stepConfigs')[0].get('configs').concat(controller.get('stepConfigs')[1].get('configs'));
+ var stepConfigs = controller.setStepConfigs(properties);
+ res = stepConfigs[0].get('configs').concat(stepConfigs[1].get('configs'));
});
Em.A([
@@ -290,7 +290,7 @@ describe('App.KerberosWizardStep4Controller', function() {
this.wizardController = App.AddServiceController.create({});
controller.set('wizardController', this.wizardController);
sinon.stub(controller, 'clearStep').returns(true);
-
+ sinon.stub(controller, 'getDescriptor').returns({ then: function() { return { always: function() {}}}});
sinon.stub(controller, 'setStepConfigs').returns(true);
sinon.stub(App.router, 'send').withArgs('next');
});
@@ -341,4 +341,200 @@ describe('App.KerberosWizardStep4Controller', function() {
});
});
});
+
+ describe('#mergeDescriptorToConfigurations', function() {
+ var genAppConfigProperty = function(name, fileName, value) {
+ return App.ServiceConfigProperty.create({
+ name: name,
+ filename: fileName,
+ value: value
+ });
+ };
+
+ var genPropertyCollection = function(configsList) {
+ return configsList.map(function(i) {
+ return genAppConfigProperty.apply(undefined, i);
+ });
+ };
+
+ var genConfigType = function(fileName, properties) {
+ var configTypeObj = {};
+ configTypeObj.type = fileName;
+ configTypeObj.properties = properties.reduce(function(p,c) {
+ p[c[0]] = c[1];
+ return p;
+ }, {});
+ return configTypeObj;
+ };
+
+ var genConfigTypeCollection = function(coll) {
+ return coll.map(function(i) {
+ return genConfigType(i[0], i[1]);
+ });
+ };
+
+ var cases = [
+ {
+ kerberosDescriptor: genPropertyCollection([]),
+ configurations: [],
+ e: [],
+ m: 'should return empty array'
+ },
+ {
+ kerberosDescriptor: genPropertyCollection([
+ ['hadoop.proxy.group', 'hadoop-env', 'val1']
+ ]),
+ configurations: genConfigTypeCollection([
+ ['hadoop-env', [
+ ['hadoop.proxy.group', 'change_me'],
+ ['hadoop.proxy', 'val2']
+ ]],
+ ['core-site', [
+ ['hadoop.proxyuser.hcat.groups', '*']
+ ]]
+ ]),
+ e: [
+ {
+ type: 'hadoop-env',
+ properties: {
+ 'hadoop.proxy.group': 'val1',
+ 'hadoop.proxy': 'val2'
+ }
+ },
+ {
+ type: 'core-site',
+ properties: {
+ 'hadoop.proxyuser.hcat.groups': '*'
+ }
+ }
+ ],
+ m: 'should change value of `hadoop.proxy.group`, rest object should not be changed.'
+ },
+ {
+ kerberosDescriptor: genPropertyCollection([
+ ['hadoop.proxy.group', 'hadoop-env', 'val1'],
+ ['new_site_prop', 'core-site', 'new_val']
+ ]),
+ configurations: genConfigTypeCollection([
+ ['hadoop-env', [
+ ['hadoop.proxy.group', 'val1'],
+ ['hadoop.proxy', 'val2']
+ ]],
+ ['core-site', [
+ ['hadoop.proxyuser.hcat.groups', '*']
+ ]]
+ ]),
+ e: [
+ {
+ type: 'hadoop-env',
+ properties: {
+ 'hadoop.proxy.group': 'val1',
+ 'hadoop.proxy': 'val2'
+ }
+ },
+ {
+ type: 'core-site',
+ properties: {
+ 'hadoop.proxyuser.hcat.groups': '*',
+ 'new_site_prop': 'new_val'
+ }
+ }
+ ],
+ m: 'should add property `new_site_prop` value to `core-site` file type, rest object should not be changed.'
+ }
+ ];
+
+ cases.forEach(function(test) {
+ it(test.m, function() {
+ var toObj = function(res) {
+ return JSON.parse(JSON.stringify(res));
+ };
+ expect(toObj(c.mergeDescriptorToConfigurations(test.configurations, test.kerberosDescriptor))).to.be.eql(test.e);
+ });
+ });
+ });
+
+ describe('#groupRecommendationProperties', function() {
+ var cases, controller;
+ beforeEach(function() {
+ controller = App.KerberosWizardStep4Controller.create({});
+ });
+
+ afterEach(function() {
+ controller.destroy();
+ controller = null;
+ });
+
+ cases = [
+ {
+ recommendedConfigurations: {},
+ servicesConfigurations: [],
+ allConfigs: [],
+ m: 'empty objects should not fail the code',
+ e: {
+ add: {},
+ update: {},
+ delete: {}
+ }
+ },
+ {
+ recommendedConfigurations: {
+ 'some-site': {
+ properties: {
+ // property absent from servicesConfigurations and allConfigs
+ // should be added
+ 'new_prop1': 'val1',
+ // property present in servicesConfigurations but absent in allConfigs
+ // should be skipped
+ 'new_prop2': 'val2',
+ 'existing-prop': 'updated_val2'
+ },
+ property_attributes: {
+ 'delete_prop1': {
+ 'delete': true
+ }
+ }
+ }
+ },
+ servicesConfigurations: [
+ {
+ type: 'some-site',
+ properties: {
+ 'existing-prop': 'val2',
+ 'new_prop2': 'val2'
+ }
+ }
+ ],
+ allConfigs: [
+ Em.Object.create({ name: 'existing-prop', value: 'val3', filename: 'some-site'}),
+ Em.Object.create({ name: 'delete_prop1', value: 'val', filename: 'some-site'})
+ ],
+ m: 'should add "new_prop1", remove "delete_prop1", skip adding "new_prop2" and update value for "existing-prop"',
+ e: {
+ update: {
+ 'some-site': {
+ 'existing-prop': 'updated_val2'
+ }
+ },
+ add: {
+ 'some-site': {
+ 'new_prop1': 'val1'
+ }
+ },
+ delete: {
+ 'some-site': {
+ 'delete_prop1': ''
+ }
+ }
+ }
+ }
+ ];
+
+ cases.forEach(function(test) {
+ it(test.m, function() {
+ expect(controller.groupRecommendationProperties(test.recommendedConfigurations, test.servicesConfigurations, test.allConfigs))
+ .to.be.eql(test.e);
+ });
+ });
+ });
});