AMBARI-9626. Enabling ranger plugin config should modify dependent configs (srimanth)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ec4bed3a Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ec4bed3a Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ec4bed3a Branch: refs/heads/trunk Commit: ec4bed3a9e4de72fd04f1dfc81f5788f005ce293 Parents: 7f752be Author: Srimanth Gunturi <sgunt...@hortonworks.com> Authored: Fri Feb 13 07:09:05 2015 -0800 Committer: Srimanth Gunturi <sgunt...@hortonworks.com> Committed: Fri Feb 13 13:36:56 2015 -0800 ---------------------------------------------------------------------- .../app/controllers/wizard/step7_controller.js | 2 +- ambari-web/app/data/HDP2.2/site_properties.js | 15 +- ambari-web/app/messages.js | 2 + .../configs/propertyDependence_footer.hbs | 4 +- .../configs/modification_handlers/hbase.js | 126 ++++++++++++++ .../utils/configs/modification_handlers/hdfs.js | 58 +++++++ .../utils/configs/modification_handlers/hive.js | 127 ++++++++++++++ .../utils/configs/modification_handlers/knox.js | 73 ++++++++ .../utils/configs/modification_handlers/misc.js | 93 +++++++++++ .../modification_handler.js | 63 +++++++ .../configs/modification_handlers/storm.js | 75 +++++++++ .../configs/service_configs_by_category_view.js | 167 +++++++------------ ambari-web/app/views/common/controls_view.js | 13 +- 13 files changed, 700 insertions(+), 118 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/controllers/wizard/step7_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step7_controller.js b/ambari-web/app/controllers/wizard/step7_controller.js index 5f44e80..b0d8463 100644 --- a/ambari-web/app/controllers/wizard/step7_controller.js +++ b/ambari-web/app/controllers/wizard/step7_controller.js @@ -70,7 +70,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, { return App.router.get('mainAdminKerberosController.securityEnabled'); }.property('App.router.mainAdminKerberosController.securityEnabled'), /** - * If miscConfigChange Modal is shown + * If configChangeObserver Modal is shown * @type {bool} */ miscModalVisible: false, http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/data/HDP2.2/site_properties.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/data/HDP2.2/site_properties.js b/ambari-web/app/data/HDP2.2/site_properties.js index d84d531..8ce4c0d 100644 --- a/ambari-web/app/data/HDP2.2/site_properties.js +++ b/ambari-web/app/data/HDP2.2/site_properties.js @@ -133,7 +133,8 @@ hdp22properties.push( "isOverridable": false, "filename": "ranger-hdfs-plugin-properties.xml", "category": "Advanced ranger-hdfs-plugin-properties", - "serviceName": "HDFS" + "serviceName": "HDFS", + "index": 1 }, { "id": "site property", @@ -189,7 +190,8 @@ hdp22properties.push( "isOverridable": false, "filename": "ranger-hive-plugin-properties.xml", "category": "Advanced ranger-hive-plugin-properties", - "serviceName": "HIVE" + "serviceName": "HIVE", + "index": 1 }, { "id": "site property", @@ -255,7 +257,8 @@ hdp22properties.push( "isOverridable": false, "filename": "ranger-hbase-plugin-properties.xml", "category": "Advanced ranger-hbase-plugin-properties", - "serviceName": "HBASE" + "serviceName": "HBASE", + "index": 1 }, { "id": "site property", @@ -321,7 +324,8 @@ hdp22properties.push( "isOverridable": false, "filename": "ranger-storm-plugin-properties.xml", "category": "Advanced ranger-storm-plugin-properties", - "serviceName": "STORM" + "serviceName": "STORM", + "index": 1 }, { "id": "site property", @@ -377,7 +381,8 @@ hdp22properties.push( "isOverridable": false, "filename": "ranger-knox-plugin-properties.xml", "category": "Advanced ranger-knox-plugin-properties", - "serviceName": "KNOX" + "serviceName": "KNOX", + "index": 1 }, { "id": "site property", http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index b5c0ee1..74ab371 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -379,6 +379,8 @@ Em.I18n.translations = { 'services.storm.topology.metrics.total': 'Total topologies', 'services.storm.tasks.metrics.title': 'Number of tasks', 'services.storm.tasks.metrics.total': 'Total tasks', + 'services.storm.configs.range-plugin-enable.dialog.title': 'Enable Ranger for STORM', + 'services.storm.configs.range-plugin-enable.dialog.message': 'Enabling Ranger plugin for STORM is effective only on a secured cluster.', 'services.alerts.head':'You have {0} critical alert notification(s).', http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/templates/common/configs/propertyDependence_footer.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/common/configs/propertyDependence_footer.hbs b/ambari-web/app/templates/common/configs/propertyDependence_footer.hbs index 7b7bab9..b09e2bb 100644 --- a/ambari-web/app/templates/common/configs/propertyDependence_footer.hbs +++ b/ambari-web/app/templates/common/configs/propertyDependence_footer.hbs @@ -18,6 +18,8 @@ <div class="pull-right"> <button class="btn" {{action onUndo target="view.parentView"}}>{{t common.cancel}}</button> - <button class="btn btn-warning" {{action onIgnore target="view.parentView"}}>{{t common.ignore}}</button> + {{#if view.canIgnore}} + <button class="btn btn-warning" {{action onIgnore target="view.parentView"}}>{{t common.ignore}}</button> + {{/if}} <button class="btn btn-success" {{action onApply target="view.parentView"}}>{{t common.apply}}</button> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/utils/configs/modification_handlers/hbase.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/configs/modification_handlers/hbase.js b/ambari-web/app/utils/configs/modification_handlers/hbase.js new file mode 100644 index 0000000..1fb6b29 --- /dev/null +++ b/ambari-web/app/utils/configs/modification_handlers/hbase.js @@ -0,0 +1,126 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +var App = require('app'); +require('utils/configs/modification_handlers/modification_handler'); + +module.exports = App.ServiceConfigModificationHandler.create({ + serviceId : 'HBASE', + + getConfig : function(allConfigs, configName, configFilename, configServiceName) { + return allConfigs.findProperty("serviceName", configServiceName).get("configs").find(function(config) { + return configName == config.get('name') && (configFilename == null || configFilename == config.get('filename')); + }); + }, + + updateConfigClasses : function(configClasses, authEnabled, affectedProperties, addOldValue) { + if (configClasses != null) { + var xaAuthCoProcessorClass = "com.xasecure.authorization.hbase.XaSecureAuthorizationCoprocessor"; + var nonXAClass = 'org.apache.hadoop.hbase.security.access.AccessController'; + var currentClassesList = configClasses.get('value').trim().length > 0 ? configClasses.get('value').trim().split(',') : []; + var newClassesList = null, xaClassIndex, nonXaClassIndex; + + if (authEnabled) { + var nonXaClassIndex = currentClassesList.indexOf(nonXAClass); + if (nonXaClassIndex > -1) { + currentClassesList = currentClassesList.splice(nonXaClassIndex, nonXaClassIndex); + newClassesList = currentClassesList; + } + var xaClassIndex = currentClassesList.indexOf(xaAuthCoProcessorClass); + if (xaClassIndex < 0) { + currentClassesList.push(xaAuthCoProcessorClass); + newClassesList = currentClassesList; + } + } else { + var xaClassIndex = currentClassesList.indexOf(xaAuthCoProcessorClass); + if (xaClassIndex > -1) { + currentClassesList = currentClassesList.splice(xaClassIndex, xaClassIndex); + newClassesList = currentClassesList; + } + if (addOldValue) { + var nonXaClassIndex = currentClassesList.indexOf(nonXAClass); + if (nonXaClassIndex < 0) { + currentClassesList.push(nonXAClass); + newClassesList = currentClassesList; + } + } + } + + if (newClassesList != null) { + affectedProperties.push({ + serviceName : "HBASE", + sourceServiceName : "HBASE", + propertyName : configClasses.get('name'), + propertyDisplayName : configClasses.get('name'), + newValue : newClassesList.join(','), + curValue : configClasses.get('value'), + changedPropertyName : 'ranger-hbase-plugin-enabled', + removed : false, + filename : 'hbase-site.xml' + }); + } + } + }, + + getDependentConfigChanges : function(changedConfig, selectedServices, allConfigs, securityEnabled) { + var affectedProperties = []; + var newValue = changedConfig.get("value"); + var hbaseAuthEnabledPropertyName = "ranger-hbase-plugin-enabled"; + var affectedPropertyName = changedConfig.get("name"); + if (affectedPropertyName == hbaseAuthEnabledPropertyName) { + var configAuthEnabled = this.getConfig(allConfigs, 'hbase.security.authorization', 'hbase-site.xml', 'HBASE'); + var configMasterClasses = this.getConfig(allConfigs, 'hbase.coprocessor.master.classes', 'hbase-site.xml', 'HBASE'); + var configRegionClasses = this.getConfig(allConfigs, 'hbase.coprocessor.region.classes', 'hbase-site.xml', 'HBASE'); + var configRpcProtection = this.getConfig(allConfigs, 'hbase.rpc.protection', 'hbase-site.xml', 'HBASE'); + + var authEnabled = newValue == "Yes"; + var newAuthEnabledValue = authEnabled ? "true" : "false"; + var newRpcProtectionValue = authEnabled ? "privacy" : "authentication"; + + // Add Hive-Ranger configs + this.updateConfigClasses(configMasterClasses, authEnabled, affectedProperties, configAuthEnabled.get('value') != 'true'); + this.updateConfigClasses(configRegionClasses, authEnabled, affectedProperties, configAuthEnabled.get('value') != 'true'); + if (newRpcProtectionValue !== configRpcProtection.get('value')) { + affectedProperties.push({ + serviceName : "HBASE", + sourceServiceName : "HBASE", + propertyName : 'hbase.rpc.protection', + propertyDisplayName : 'hbase.rpc.protection', + newValue : newRpcProtectionValue, + curValue : configRpcProtection.get('value'), + changedPropertyName : hbaseAuthEnabledPropertyName, + removed : false, + filename : 'hbase-site.xml' + }); + } + if (authEnabled && newAuthEnabledValue !== configAuthEnabled.get('value')) { + affectedProperties.push({ + serviceName : "HBASE", + sourceServiceName : "HBASE", + propertyName : 'hbase.security.authorization', + propertyDisplayName : 'hbase.security.authorization', + newValue : newAuthEnabledValue, + curValue : configAuthEnabled.get('value'), + changedPropertyName : hbaseAuthEnabledPropertyName, + removed : false, + filename : 'hbase-site.xml' + }); + } + } + return affectedProperties; + } +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/utils/configs/modification_handlers/hdfs.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/configs/modification_handlers/hdfs.js b/ambari-web/app/utils/configs/modification_handlers/hdfs.js new file mode 100644 index 0000000..128b62b --- /dev/null +++ b/ambari-web/app/utils/configs/modification_handlers/hdfs.js @@ -0,0 +1,58 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +var App = require('app'); +require('utils/configs/modification_handlers/modification_handler'); + +module.exports = App.ServiceConfigModificationHandler.create({ + serviceId : 'HDFS', + + getConfig : function(allConfigs, configName, configFilename, configServiceName) { + return allConfigs.findProperty("serviceName", configServiceName).get("configs").find(function(config) { + return configName == config.get('name') && (configFilename == null || configFilename == config.get('filename')); + }); + }, + + getDependentConfigChanges : function(changedConfig, selectedServices, allConfigs, securityEnabled) { + var affectedProperties = []; + var newValue = changedConfig.get("value"); + var rangerPluginEnabledName = "ranger-hdfs-plugin-enabled"; + var affectedPropertyName = changedConfig.get("name"); + if (affectedPropertyName == rangerPluginEnabledName) { + var configDfsPermissionsEnabled = this.getConfig(allConfigs, 'dfs.permissions.enabled', 'hdfs-site.xml', 'HDFS'); + + var rangerPluginEnabled = newValue == "Yes"; + var newDfsPermissionsEnabled = rangerPluginEnabled ? "true" : "true"; + + // Add Hive-Ranger configs + if (configDfsPermissionsEnabled != null && newDfsPermissionsEnabled !== configDfsPermissionsEnabled.get('value')) { + affectedProperties.push({ + serviceName : "HDFS", + sourceServiceName : "HDFS", + propertyName : 'dfs.permissions.enabled', + propertyDisplayName : 'dfs.permissions.enabled', + newValue : newDfsPermissionsEnabled, + curValue : configDfsPermissionsEnabled.get('value'), + changedPropertyName : rangerPluginEnabledName, + removed : false, + filename : 'hdfs-site.xml' + }); + } + } + return affectedProperties; + } +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/utils/configs/modification_handlers/hive.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/configs/modification_handlers/hive.js b/ambari-web/app/utils/configs/modification_handlers/hive.js new file mode 100644 index 0000000..092ef40 --- /dev/null +++ b/ambari-web/app/utils/configs/modification_handlers/hive.js @@ -0,0 +1,127 @@ +/** + * 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'); +require('utils/configs/modification_handlers/modification_handler'); + +module.exports = App.ServiceConfigModificationHandler.create({ + serviceId : 'HIVE', + + getConfig : function(allConfigs, configName, configFilename, configServiceName) { + return allConfigs.findProperty("serviceName", configServiceName).get("configs").find(function(config) { + return configName == config.get('name') && (configFilename == null || configFilename == config.get('filename')); + }); + }, + + getDependentConfigChanges : function(changedConfig, selectedServices, allConfigs, securityEnabled) { + var affectedProperties = []; + var newValue = changedConfig.get("value"); + var rangerPluginEnabledName = "ranger-hive-plugin-enabled"; + var affectedPropertyName = changedConfig.get("name"); + if (affectedPropertyName == rangerPluginEnabledName) { + var configAuthorizationEnabled = this.getConfig(allConfigs, 'hive.security.authorization.enabled', 'hive-site.xml', 'HIVE'); + var configAuthorizationManager = this.getConfig(allConfigs, 'hive.security.authorization.manager', 'hiveserver2-site.xml', 'HIVE'); + var configAuthenticatorManager = this.getConfig(allConfigs, 'hive.security.authenticator.manager', 'hiveserver2-site.xml', 'HIVE'); + var configRestrictedList = this.getConfig(allConfigs, 'hive.conf.restricted.list', 'hive-site.xml', 'HIVE'); + + var rangerPluginEnabled = newValue == "Yes"; + var newConfigAuthorizationEnabledValue = rangerPluginEnabled ? "true" : "false"; + var newAuthorizationManagerValue = rangerPluginEnabled ? "com.xasecure.authorization.hive.authorizer.XaSecureHiveAuthorizerFactory" + : "org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory"; + var newAuthenticatorManagerValue = rangerPluginEnabled ? "org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator" + : "org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator"; + var enabledRestrictedMap = { + "hive.security.authorization.enabled" : "hive.security.authorization.enabled", + "hive.security.authorization.manager" : "hive.security.authorization.manager", + "hive.security.authenticator.manager" : "hive.security.authenticator.manager" + } + var enabledRestrictedList = Object.keys(enabledRestrictedMap); + var newRestrictedListValue = rangerPluginEnabled ? enabledRestrictedList : []; + + // Add Hive-Ranger configs + if (configAuthorizationEnabled != null && newConfigAuthorizationEnabledValue !== configAuthorizationEnabled.get('value')) { + affectedProperties.push({ + serviceName : "HIVE", + sourceServiceName : "HIVE", + propertyName : 'hive.security.authorization.enabled', + propertyDisplayName : 'hive.security.authorization.enabled', + newValue : newConfigAuthorizationEnabledValue, + curValue : configAuthorizationEnabled.get('value'), + changedPropertyName : rangerPluginEnabledName, + removed : false, + filename : 'hive-site.xml' + }); + } + if (configAuthorizationManager != null && newAuthorizationManagerValue !== configAuthorizationManager.get('value')) { + affectedProperties.push({ + serviceName : "HIVE", + sourceServiceName : "HIVE", + propertyName : 'hive.security.authorization.manager', + propertyDisplayName : 'hive.security.authorization.manager', + newValue : newAuthorizationManagerValue, + curValue : configAuthorizationManager.get('value'), + changedPropertyName : rangerPluginEnabledName, + removed : false, + filename : 'hiveserver2-site.xml' + }); + } + if (configAuthenticatorManager != null && newAuthenticatorManagerValue !== configAuthenticatorManager.get('value')) { + affectedProperties.push({ + serviceName : "HIVE", + sourceServiceName : "HIVE", + propertyName : 'hive.security.authenticator.manager', + propertyDisplayName : 'hive.security.authenticator.manager', + newValue : newAuthenticatorManagerValue, + curValue : configAuthenticatorManager.get('value'), + changedPropertyName : rangerPluginEnabledName, + removed : false, + filename : 'hiveserver2-site.xml' + }); + } + if (configRestrictedList != null) { + var currentValueList = configRestrictedList.get('value').split(','); + // 'newRestrictedListValue' elements should be found in existing list + var newValueList = []; + currentValueList.forEach(function(s) { + if (enabledRestrictedMap[s] == s) { + return; + } + newValueList.push(s); + }); + if (newRestrictedListValue.length > 0) + newValueList = newValueList.concat(newRestrictedListValue); + + if (newValueList.length != currentValueList.length) { + // One of the value was not found - set all of them in. + var newValueListString = newValueList.join(','); + affectedProperties.push({ + serviceName : "HIVE", + sourceServiceName : "HIVE", + propertyName : 'hive.conf.restricted.list', + propertyDisplayName : 'hive.conf.restricted.list', + newValue : newValueListString, + curValue : configRestrictedList.get('value'), + changedPropertyName : rangerPluginEnabledName, + removed : false, + filename : 'hive-site.xml' + }); + } + } + } + return affectedProperties; + } +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/utils/configs/modification_handlers/knox.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/configs/modification_handlers/knox.js b/ambari-web/app/utils/configs/modification_handlers/knox.js new file mode 100644 index 0000000..3b0740c --- /dev/null +++ b/ambari-web/app/utils/configs/modification_handlers/knox.js @@ -0,0 +1,73 @@ +/** + * 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'); +require('utils/configs/modification_handlers/modification_handler'); + +module.exports = App.ServiceConfigModificationHandler.create({ + serviceId : 'KNOX', + + getConfig : function(allConfigs, configName, configFilename, configServiceName) { + return allConfigs.findProperty("serviceName", configServiceName).get("configs").find(function(config) { + return configName == config.get('name') && (configFilename == null || configFilename == config.get('filename')); + }); + }, + + getDependentConfigChanges : function(changedConfig, selectedServices, allConfigs, securityEnabled) { + var affectedProperties = []; + var newValue = changedConfig.get("value"); + var rangerPluginEnablePropertyName = "ranger-knox-plugin-enabled"; + var affectedPropertyName = changedConfig.get("name"); + if (affectedPropertyName == rangerPluginEnablePropertyName) { + var topologyXmlContent = this.getConfig(allConfigs, 'content', 'topology.xml', 'KNOX'); + if (topologyXmlContent != null) { + var topologyXmlContentString = topologyXmlContent.get('value'); + var newTopologyXmlContentString = null; + var authEnabled = newValue == "Yes"; + var authXml = /<provider>[\s]*<role>[\s]*authorization[\s]*<\/role>[\s\S]*?<\/provider>/.exec(topologyXmlContentString); + if (authXml != null && authXml.length > 0) { + var nameArray = /<name>\s*(.*?)\s*<\/name>/.exec(authXml[0]); + if (nameArray != null && nameArray.length > 1) { + if (authEnabled && 'AclsAuthz' == nameArray[1]) { + var newName = nameArray[0].replace('AclsAuthz', 'XASecurePDPKnox'); + var newAuthXml = authXml[0].replace(nameArray[0], newName); + newTopologyXmlContentString = topologyXmlContentString.replace(authXml[0], newAuthXml); + } else if (!authEnabled && 'XASecurePDPKnox' == nameArray[1]) { + var newName = nameArray[0].replace('XASecurePDPKnox', 'AclsAuthz'); + var newAuthXml = authXml[0].replace(nameArray[0], newName); + newTopologyXmlContentString = topologyXmlContentString.replace(authXml[0], newAuthXml); + } + } + } + if (newTopologyXmlContentString != null) { + affectedProperties.push({ + serviceName : "KNOX", + sourceServiceName : "KNOX", + propertyName : 'content', + propertyDisplayName : 'content', + newValue : newTopologyXmlContentString, + curValue : topologyXmlContent.get('value'), + changedPropertyName : rangerPluginEnablePropertyName, + removed : false, + filename : 'topology.xml' + }); + } + } + } + return affectedProperties; + } +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/utils/configs/modification_handlers/misc.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/configs/modification_handlers/misc.js b/ambari-web/app/utils/configs/modification_handlers/misc.js new file mode 100644 index 0000000..42decb5 --- /dev/null +++ b/ambari-web/app/utils/configs/modification_handlers/misc.js @@ -0,0 +1,93 @@ +/** + * 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'); +require('utils/configs/modification_handlers/modification_handler'); + +module.exports = App.ServiceConfigModificationHandler.create({ + serviceId : 'MISC', + getDependentConfigChanges : function(changedConfig, selectedServices, allConfigs, securityEnabled) { + var affectedProperties = []; + var newValue = changedConfig.get("value"); + var curConfigs = ""; + var affectedPropertyName = "dfs.permissions.superusergroup"; + if (changedConfig.get("name") == "hdfs_user") { + curConfigs = allConfigs.findProperty("serviceName", "HDFS").get("configs"); + if (newValue != curConfigs.findProperty("name", affectedPropertyName).get("value")) { + affectedProperties.push({ + serviceName : "HDFS", + sourceServiceName : "MISC", + propertyName : affectedPropertyName, + propertyDisplayName : affectedPropertyName, + newValue : newValue, + curValue : curConfigs.findProperty("name", affectedPropertyName).get("value"), + changedPropertyName : "hdfs_user", + remove : false, + filename : 'hdfs-site.xml' + }); + } + if ($.trim(newValue) != $.trim(curConfigs.findProperty("name", "dfs.cluster.administrators").get("value"))) { + affectedProperties.push({ + serviceName : "HDFS", + sourceServiceName : "MISC", + propertyName : "dfs.cluster.administrators", + propertyDisplayName : "dfs.cluster.administrators", + newValue : " " + $.trim(newValue), + curValue : curConfigs.findProperty("name", "dfs.cluster.administrators").get("value"), + changedPropertyName : "hdfs_user", + remove : false, + filename : 'hdfs-site.xml' + }); + } + } else if (changedConfig.get("name") == "user_group") { + if (!(selectedServices.indexOf("YARN") >= 0)) { + return; + } + if (selectedServices.indexOf("MAPREDUCE2") >= 0) { + curConfigs = allConfigs.findProperty("serviceName", "MAPREDUCE2").get("configs"); + if ($.trim(newValue) != $.trim(curConfigs.findProperty("name", "mapreduce.cluster.administrators").get("value"))) { + affectedProperties.push({ + serviceName : "MAPREDUCE2", + sourceServiceName : "MISC", + propertyName : "mapreduce.cluster.administrators", + propertyDisplayName : "mapreduce.cluster.administrators", + newValue : " " + $.trim(newValue), + curValue : curConfigs.findProperty("name", "mapreduce.cluster.administrators").get("value"), + changedPropertyName : "user_group", + filename : 'mapred-site.xml' + }); + } + } + if (selectedServices.indexOf("YARN") >= 0) { + curConfigs = allConfigs.findProperty("serviceName", "YARN").get("configs"); + if (newValue != curConfigs.findProperty("name", "yarn.nodemanager.linux-container-executor.group").get("value")) { + affectedProperties.push({ + serviceName : "YARN", + sourceServiceName : "MISC", + propertyName : "yarn.nodemanager.linux-container-executor.group", + propertyDisplayName : "yarn.nodemanager.linux-container-executor.group", + newValue : newValue, + curValue : curConfigs.findProperty("name", "yarn.nodemanager.linux-container-executor.group").get("value"), + changedPropertyName : "user_group", + filename : 'yarn-site.xml' + }) + } + } + } + return affectedProperties; + } +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/utils/configs/modification_handlers/modification_handler.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/configs/modification_handlers/modification_handler.js b/ambari-web/app/utils/configs/modification_handlers/modification_handler.js new file mode 100644 index 0000000..5b32cde --- /dev/null +++ b/ambari-web/app/utils/configs/modification_handlers/modification_handler.js @@ -0,0 +1,63 @@ +/** + * 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'); + +/** + * Config modification handler for a given service. + * + * This handler should take care of scenarios that arise from modification of a + * config. Scenarios like updating dependency configs, or doing any special + * processing. + */ +App.ServiceConfigModificationHandler = Em.Object.extend({ + + /** + * Service whose configs this handler will react to. + */ + serviceId : DS.attr('string'), + + /** + * Given a changed config, provide an array of changes to dependent configs + * across all services. Dependent configs can be created, updated and deleted. + * + * Example: Here, setting 'hdfs_user' updates 'dfs.permissions.superusergroup'. + * [ + * { + * serviceName: "HDFS", + * sourceServiceName: "MISC", // Cross service configs + * propertyName: "dfs.permissions.superusergroup", + * propertyDisplayName: "dfs.permissions.superusergroup", + * filename: 'hdfs-site', + * remove: false, + * curValue: "hdfs", + * newValue: "my_hdfs", + * changedPropertyName: "hdfs_user" + * } + * ] + * + * @param changedConfig + * @param selectedServices + * @param allConfigs + * @param securityEnabled + * @return Array of dependent config updates + */ + getDependentConfigChanges : function(changedConfig, selectedServices, allConfigs, securityEnabled) { + return []; + } + +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/utils/configs/modification_handlers/storm.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/configs/modification_handlers/storm.js b/ambari-web/app/utils/configs/modification_handlers/storm.js new file mode 100644 index 0000000..3e27e3e --- /dev/null +++ b/ambari-web/app/utils/configs/modification_handlers/storm.js @@ -0,0 +1,75 @@ +/** + * 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'); +require('utils/configs/modification_handlers/modification_handler'); + +module.exports = App.ServiceConfigModificationHandler.create({ + serviceId : 'STORM', + + getConfig : function(allConfigs, configName, configFilename, configServiceName) { + return allConfigs.findProperty("serviceName", configServiceName).get("configs").find(function(config) { + return configName == config.get('name') && (configFilename == null || configFilename == config.get('filename')); + }); + }, + + getDependentConfigChanges : function(changedConfig, selectedServices, allConfigs, securityEnabled) { + var affectedProperties = []; + var newValue = changedConfig.get("value"); + var rangerPluginEnablePropertyName = "ranger-storm-plugin-enabled"; + var affectedPropertyName = changedConfig.get("name"); + if (affectedPropertyName == rangerPluginEnablePropertyName) { + var authEnabled = newValue == "Yes"; + var configNimbusAuthorizer = this.getConfig(allConfigs, 'nimbus.authorizer', 'storm-site.xml', 'STORM'); + if (configNimbusAuthorizer != null) { + // Only when configuration is already present, do we act on it. + // Unsecured clusters do not have this config, and hence we skip any + // updates + var newNimbusAuthorizer = authEnabled ? "com.xasecure.authorization.storm.authorizer.XaSecureStormAuthorizer" + : "backtype.storm.security.auth.authorizer.SimpleACLAuthorizer"; + + // Add Hive-Ranger configs + if (newNimbusAuthorizer !== configNimbusAuthorizer.get('value')) { + affectedProperties.push({ + serviceName : "STORM", + sourceServiceName : "STORM", + propertyName : 'nimbus.authorizer', + propertyDisplayName : 'nimbus.authorizer', + newValue : newNimbusAuthorizer, + curValue : configNimbusAuthorizer.get('value'), + changedPropertyName : rangerPluginEnablePropertyName, + removed : false, + filename : 'storm-site.xml' + }); + } + } + if (authEnabled && affectedProperties.length < 1 && !securityEnabled) { + App.ModalPopup.show({ + header : Em.I18n.t('services.storm.configs.range-plugin-enable.dialog.title'), + primary : Em.I18n.t('ok'), + secondary : false, + showCloseButton : false, + onPrimary : function() { + this.hide(); + }, + body : Em.I18n.t('services.storm.configs.range-plugin-enable.dialog.message') + }); + } + } + return affectedProperties; + } +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/views/common/configs/service_configs_by_category_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/configs/service_configs_by_category_view.js b/ambari-web/app/views/common/configs/service_configs_by_category_view.js index f4f61b2..5334c7c 100644 --- a/ambari-web/app/views/common/configs/service_configs_by_category_view.js +++ b/ambari-web/app/views/common/configs/service_configs_by_category_view.js @@ -20,6 +20,7 @@ var App = require('app'); var validator = require('utils/validator'); var stringUtils = require('utils/string_utils'); +require('utils/configs/modification_handlers/modification_handler'); App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, { @@ -113,7 +114,7 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, { * Warn/prompt user to adjust Service props when changing user/groups in Misc * Is triggered when user ended editing text field */ - miscConfigChange: function (manuallyChangedProperty) { + configChangeObserver: function (manuallyChangedProperty) { var changedProperty; if (manuallyChangedProperty.get("id")) { changedProperty = [manuallyChangedProperty]; @@ -128,114 +129,62 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, { else { return; } - if (this.get('controller.selectedService.serviceName') == 'MISC') { - var newValue = changedProperty.get("value"); - var stepConfigs = this.get("controller.stepConfigs"); - this.affectedProperties = []; - var curConfigs = ""; - var affectedPropertyName = "dfs.permissions.superusergroup"; - if (changedProperty.get("name") == "hdfs_user") { - curConfigs = stepConfigs.findProperty("serviceName", "HDFS").get("configs"); - if (newValue != curConfigs.findProperty("name", affectedPropertyName).get("value")) { - this.affectedProperties.push( - { - serviceName: "HDFS", - propertyName: affectedPropertyName, - propertyDisplayName: affectedPropertyName, - newValue: newValue, - curValue: curConfigs.findProperty("name", affectedPropertyName).get("value"), - changedPropertyName: "hdfs_user" - } - ); - } - if ($.trim(newValue) != $.trim(curConfigs.findProperty("name", "dfs.cluster.administrators").get("value"))) { - this.affectedProperties.push( - { - serviceName: "HDFS", - propertyName: "dfs.cluster.administrators", - propertyDisplayName: "dfs.cluster.administrators", - newValue: " " + $.trim(newValue), - curValue: curConfigs.findProperty("name", "dfs.cluster.administrators").get("value"), - changedPropertyName: "hdfs_user" - } - ); - } - } - else if (changedProperty.get("name") == "user_group") { - if (!(this.get("controller.selectedServiceNames").indexOf("YARN") >= 0)) { - return; - } - if (this.get("controller.selectedServiceNames").indexOf("MAPREDUCE2") >= 0) { - curConfigs = stepConfigs.findProperty("serviceName", "MAPREDUCE2").get("configs"); - if ($.trim(newValue) != $.trim(curConfigs.findProperty("name", "mapreduce.cluster.administrators").get("value"))) { - this.affectedProperties.push( - { - serviceName: "MAPREDUCE2", - propertyName: "mapreduce.cluster.administrators", - propertyDisplayName: "mapreduce.cluster.administrators", - newValue: " " + $.trim(newValue), - curValue: curConfigs.findProperty("name", "mapreduce.cluster.administrators").get("value"), - changedPropertyName: "user_group" - } - ); - } - } - if (this.get("controller.selectedServiceNames").indexOf("YARN") >= 0) { - curConfigs = stepConfigs.findProperty("serviceName", "YARN").get("configs"); - if (newValue != curConfigs.findProperty("name", "yarn.nodemanager.linux-container-executor.group").get("value")) { - this.affectedProperties.push( - { - serviceName: "YARN", - propertyName: "yarn.nodemanager.linux-container-executor.group", - propertyDisplayName: "yarn.nodemanager.linux-container-executor.group", - newValue: newValue, - curValue: curConfigs.findProperty("name", "yarn.nodemanager.linux-container-executor.group").get("value"), - changedPropertyName: "user_group" - } - ) + this.affectedProperties = []; + var stepConfigs = this.get("controller.stepConfigs"); + var serviceId = this.get('controller.selectedService.serviceName'); + var serviceConfigModificationHandler = null; + try{ + serviceConfigModificationHandler = require('utils/configs/modification_handlers/'+serviceId.toLowerCase()); + }catch (e) { + console.log("Unable to load modification handler for ", serviceId); + } + if (serviceConfigModificationHandler != null) { + var securityEnabled = App.router.get('mainAdminSecurityController.securityEnabled'); + this.affectedProperties = serviceConfigModificationHandler.getDependentConfigChanges(changedProperty, this.get("controller.selectedServiceNames"), stepConfigs, securityEnabled); + } + changedProperty.set("editDone", false); // Turn off flag + + if (this.affectedProperties.length > 0 && !this.get("controller.miscModalVisible")) { + this.newAffectedProperties = this.affectedProperties; + var self = this; + return App.ModalPopup.show({ + classNames: ['modal-690px-width'], + showCloseButton: false, + header: "Warning: you must also change these Service properties", + onApply: function () { + self.get("newAffectedProperties").forEach(function(item) { + self.get("controller.stepConfigs").findProperty("serviceName", item.serviceName).get("configs").find(function(config) { + return item.propertyName == config.get('name') && (item.filename == null || item.filename == config.get('filename')); + }).set("value", item.newValue); + }); + self.get("controller").set("miscModalVisible", false); + this.hide(); + }, + onIgnore: function () { + self.get("controller").set("miscModalVisible", false); + this.hide(); + }, + onUndo: function () { + var affected = self.get("newAffectedProperties").objectAt(0); + self.get("controller.stepConfigs").findProperty("serviceName", affected.sourceServiceName).get("configs") + .findProperty("name", affected.changedPropertyName).set("value", $.trim(affected.curValue)); + self.get("controller").set("miscModalVisible", false); + this.hide(); + }, + footerClass: Ember.View.extend({ + classNames: ['modal-footer'], + templateName: require('templates/common/configs/propertyDependence_footer'), + canIgnore: serviceId == 'MISC' + }), + bodyClass: Ember.View.extend({ + templateName: require('templates/common/configs/propertyDependence'), + controller: this, + propertyChange: self.get("newAffectedProperties"), + didInsertElement: function () { + self.get("controller").set("miscModalVisible", true); } - } - } - if (this.affectedProperties.length > 0 && !this.get("controller.miscModalVisible")) { - this.newAffectedProperties = this.affectedProperties; - var self = this; - return App.ModalPopup.show({ - classNames: ['modal-690px-width'], - showCloseButton: false, - header: "Warning: you must also change these Service properties", - onApply: function () { - self.get("newAffectedProperties").forEach(function (item) { - self.get("controller.stepConfigs").findProperty("serviceName", item.serviceName).get("configs") - .findProperty("name", item.propertyName).set("value", item.newValue); - }); - self.get("controller").set("miscModalVisible", false); - this.hide(); - }, - onIgnore: function () { - self.get("controller").set("miscModalVisible", false); - this.hide(); - }, - onUndo: function () { - var affected = self.get("newAffectedProperties").objectAt(0); - self.get("controller.stepConfigs").findProperty("serviceName", "MISC").get("configs") - .findProperty("name", affected.changedPropertyName).set("value", $.trim(affected.curValue)); - self.get("controller").set("miscModalVisible", false); - this.hide(); - }, - footerClass: Ember.View.extend({ - classNames: ['modal-footer'], - templateName: require('templates/common/configs/propertyDependence_footer') - }), - bodyClass: Ember.View.extend({ - templateName: require('templates/common/configs/propertyDependence'), - controller: this, - propertyChange: self.get("newAffectedProperties"), - didInsertElement: function () { - self.get("controller").set("miscModalVisible", true); - } - }) - }); - } + }) + }); } }.observes('categoryConfigs.@each.editDone'), @@ -658,7 +607,7 @@ App.ServiceConfigsByCategoryView = Em.View.extend(App.UserPref, { if (supportsFinal) { serviceConfigProperty.set('isFinal', defaultIsFinal); } - this.miscConfigChange(serviceConfigProperty); + this.configChangeObserver(serviceConfigProperty); Em.$('body>.tooltip').remove(); //some tooltips get frozen when their owner's DOM element is removed }, http://git-wip-us.apache.org/repos/asf/ambari/blob/ec4bed3a/ambari-web/app/views/common/controls_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/controls_view.js b/ambari-web/app/views/common/controls_view.js index bd5e7e6..91441e3 100644 --- a/ambari-web/app/views/common/controls_view.js +++ b/ambari-web/app/views/common/controls_view.js @@ -248,8 +248,10 @@ App.ServiceConfigCheckbox = Ember.Checkbox.extend(App.ServiceConfigPopoverSuppor * change service config value if click on checkbox */ toggleValue: function() { - if (this.isNotAppropriateValue()) + if (this.isNotAppropriateValue()){ this.set('serviceConfig.value', this.get(this.get('checked') + 'Value')); + this.get('serviceConfig').set("editDone", true); + } }.observes('checked'), /** @@ -262,7 +264,14 @@ App.ServiceConfigCheckbox = Ember.Checkbox.extend(App.ServiceConfigPopoverSuppor disabled: function () { return !this.get('serviceConfig.isEditable'); - }.property('serviceConfig.isEditable') + }.property('serviceConfig.isEditable'), + + //Set editDone false for all current category config text field parameter + focusIn: function (event) { + if (!this.get('serviceConfig.isOverridden') && !this.get('serviceConfig.isComparison')) { + this.get("parentView.categoryConfigsAll").setEach("editDone", false); + } + } }); /**