Repository: ambari Updated Branches: refs/heads/trunk 2e432f3b4 -> 0f24bc24b
AMBARI-6769 Add security configs on Add service wizard. (ababiichuk) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0f24bc24 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0f24bc24 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0f24bc24 Branch: refs/heads/trunk Commit: 0f24bc24bab737a5998e5063a7b2fddf41884ede Parents: 2e432f3 Author: aBabiichuk <[email protected]> Authored: Thu Aug 7 16:07:33 2014 +0300 Committer: aBabiichuk <[email protected]> Committed: Thu Aug 7 16:07:33 2014 +0300 ---------------------------------------------------------------------- .../controllers/global/cluster_controller.js | 1 + .../main/admin/highAvailability_controller.js | 57 +-- .../main/admin/security/add/step4.js | 339 +---------------- ambari-web/app/controllers/main/host/details.js | 11 +- ambari-web/app/controllers/main/service/item.js | 2 - .../app/controllers/wizard/step7_controller.js | 44 ++- .../app/controllers/wizard/step8_controller.js | 15 +- ambari-web/app/mixins.js | 1 + .../app/mixins/wizard/addSecurityConfigs.js | 370 +++++++++++++++++++ .../views/main/admin/highAvailability_view.js | 4 - .../main/admin/security/add/step4_test.js | 309 +--------------- .../test/controllers/wizard/step8_test.js | 15 - .../mixins/wizard/addSeccurityConfigs_test.js | 338 +++++++++++++++++ 13 files changed, 777 insertions(+), 729 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/ambari-web/app/controllers/global/cluster_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js index 738ee1f..77bcccd 100644 --- a/ambari-web/app/controllers/global/cluster_controller.js +++ b/ambari-web/app/controllers/global/cluster_controller.js @@ -345,6 +345,7 @@ App.ClusterController = Em.Controller.extend({ }); }); }); + App.router.get('mainAdminSecurityController').getUpdatedSecurityStatus(); }, requestHosts: function (realUrl, callback) { http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/ambari-web/app/controllers/main/admin/highAvailability_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability_controller.js b/ambari-web/app/controllers/main/admin/highAvailability_controller.js index e090662..c40e99a 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability_controller.js @@ -21,7 +21,9 @@ var App = require('app'); App.MainAdminHighAvailabilityController = Em.Controller.extend({ name: 'mainAdminHighAvailabilityController', - securityEnabled: false, + securityEnabled: function () { + return App.router.get('mainAdminSecurityController.securityEnabled'); + }.property('App.router.mainAdminSecurityController.securityEnabled'), tag: null, @@ -84,59 +86,6 @@ App.MainAdminHighAvailabilityController = Em.Controller.extend({ return true; }, - setSecurityStatus: function () { - if (App.get('testMode')) { - this.set('securityEnabled', !App.get('testEnableSecurity')); - this.set('dataIsLoaded', true); - } else { - //get Security Status From Server - return App.ajax.send({ - name: 'admin.security_status', - sender: this, - success: 'getSecurityStatusFromServerSuccessCallback', - error: 'errorCallback' - }); - } - }, - - errorCallback: function () { - this.showErrorPopup(Em.I18n.t('admin.security.status.error')); - }, - - getSecurityStatusFromServerSuccessCallback: function (data) { - var configs = data.Clusters.desired_configs; - if ('hadoop-env' in configs) { - this.set('tag', configs['hadoop-env'].tag); - this.getServiceConfigsFromServer(); - } else { - this.showErrorPopup(Em.I18n.t('admin.security.status.error')); - } - }, - - /** - * get service configs from server and - * indicate whether security is enabled - */ - getServiceConfigsFromServer: function () { - var self = this; - var tags = [ - { - siteName: "hadoop-env", - tagName: this.get('tag') - } - ]; - App.router.get('configurationController').getConfigsByTags(tags).done(function (data) { - self.set('securityEnabled', self.isSecurityEnabled(data.findProperty('tag', self.get('tag')).properties)); - self.set('dataIsLoaded', true); - }); - }, - - /** - * identify whether security is enabled by security config - */ - isSecurityEnabled: function(properties){ - return !!(properties && (properties['security_enabled'] === 'true' || properties['security_enabled'] === true)); - }, /** * join or wrap message depending on whether it is array or string * @param message http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/ambari-web/app/controllers/main/admin/security/add/step4.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/security/add/step4.js b/ambari-web/app/controllers/main/admin/security/add/step4.js index 08c23d0..939647d 100644 --- a/ambari-web/app/controllers/main/admin/security/add/step4.js +++ b/ambari-web/app/controllers/main/admin/security/add/step4.js @@ -18,77 +18,10 @@ var App = require('app'); -App.MainAdminSecurityAddStep4Controller = App.MainAdminSecurityProgressController.extend({ +App.MainAdminSecurityAddStep4Controller = App.MainAdminSecurityProgressController.extend(App.AddSecurityConfigs, { name: 'mainAdminSecurityAddStep4Controller', - serviceUsersBinding: 'App.router.mainAdminSecurityController.serviceUsers', - - /** - * component configs which should be added to configs - */ - componentsConfig: [ - { - serviceName: 'OOZIE', - componentName: 'OOZIE_SERVER', - configName: 'oozieserver_host' - }, - { - serviceName: 'HIVE', - componentName: 'HIVE_METASTORE', - configName: 'hivemetastore_host' - }, - { - serviceName: 'WEBHCAT', - componentName: 'WEBHCAT_SERVER', - configName: 'webhcat_server' - } - ], - - /** - * mock users used in testMode - */ - testModeUsers: [ - { - name: 'hdfs_user', - value: 'hdfs' - }, - { - name: 'mapred_user', - value: 'mapred' - }, - { - name: 'hbase_user', - value: 'hbase' - }, - { - name: 'hive_user', - value: 'hive' - } - ], - - /** - * security configs, which values should be modified after APPLY CONFIGURATIONS stage - */ - secureConfigs: [ - { - name: 'nagios_principal_name', - serviceName: 'NAGIOS' - }, - { - name: 'zookeeper_principal_name', - serviceName: 'ZOOKEEPER' - }, - { - name: 'storm_principal_name', - serviceName: 'STORM' - } - ], - - secureServices: function() { - return this.get('content.services'); - }.property('content.services'), - isBackBtnDisabled: function () { return !this.get('commands').someProperty('isError'); }.property('[email protected]'), @@ -188,258 +121,6 @@ App.MainAdminSecurityAddStep4Controller = App.MainAdminSecurityProgressControlle return true; }, - /** - * load configs from UI side - * @return {Array} - */ - loadUiSideConfigs: function () { - var uiConfig = []; - var configs = this.get('secureMapping').filterProperty('foreignKey', null); - configs.forEach(function (_config) { - var value = _config.value; - if (_config.hasOwnProperty('dependedServiceName')) { - value = this.checkServiceForConfigValue(value, _config.dependedServiceName); - } - value = this.getConfigValue(_config.templateName, value); - uiConfig.push({ - "id": "site property", - "name": _config.name, - "value": value, - "filename": _config.filename - }); - }, this); - var dependentConfig = this.get('secureMapping').filterProperty('foreignKey'); - dependentConfig.forEach(function (_config) { - if (App.Service.find().mapProperty('serviceName').contains(_config.serviceName)) { - this.setConfigValue(_config); - this.formatConfigName(uiConfig, _config); - uiConfig.push({ - "id": "site property", - "name": _config._name || _config.name, - "value": _config.value, - "filename": _config.filename - }); - } - }, this); - return uiConfig; - }, - - /** - * erase template rules from config value if service is not loaded - * @param value - * @param services - * @return {*} - */ - checkServiceForConfigValue: function (value, services) { - services.forEach(function (_service) { - if (!App.Service.find(_service.name).get('isLoaded')) { - value = value.replace(_service.replace, ''); - } - }, this); - return value; - }, - - /** - * Set all site property that are derived from other puppet-variable - * @param templateName - * @param expression - * @return {String|null} - */ - getConfigValue: function (templateName, expression) { - var express = expression.match(/<(.*?)>/g); - var value = expression; - if (Em.isNone(express)) return expression; - - express.forEach(function (_express) { - var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]); - var configs = this.get('configs').findProperty('name', templateName[index]); - - if (!!value) { - value = (configs) ? value.replace(_express, configs.value) : null; - } - }, this); - return value; - }, - - /** - * format name of config values of configs which match foreignKey - * @param uiConfig - * @param config - * @return {Boolean} - */ - formatConfigName: function (uiConfig, config) { - if (Em.isNone(config.value)) return false; - - var fkValue = config.name.match(/<(foreignKey.*?)>/g); - if (fkValue) { - fkValue.forEach(function (_fkValue) { - var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]); - var value; - if (uiConfig.someProperty('name', config.foreignKey[index])) { - value = uiConfig.findProperty('name', config.foreignKey[index]).value; - config._name = config.name.replace(_fkValue, value); - } else if (this.get('configs').someProperty('name', config.foreignKey[index])) { - value = this.get('configs').findProperty('name', config.foreignKey[index]).value; - config._name = config.name.replace(_fkValue, value); - } - }, this); - return true; - } - return false; - }, - - /** - * Set config value with values of configs which match template - * @param config - * @return {Boolean} - */ - setConfigValue: function (config) { - if (Em.isNone(config.value)) return false; - - //For properties in the configMapping file having foreignKey and templateName properties. - var templateValue = config.value.match(/<(templateName.*?)>/g); - if (templateValue) { - templateValue.forEach(function (_value) { - var index = parseInt(_value.match(/\[([\d]*)(?=\])/)[1]); - var cfgValue = this.get('configs').findProperty('name', config.templateName[index]); - - config.value = (cfgValue) ? config.value.replace(_value, cfgValue.value) : null; - }, this); - return true; - } - return false; - }, - - /** - * prepare secure configs - */ - prepareSecureConfigs: function () { - var configs = this.get('content.serviceConfigProperties'); - this.set('configs', configs); - this.loadStaticConfigs(); //Hack for properties which are declared in site_properties.js and not able to retrieve values declared in secure_properties.js - this.loadUsersToConfigs(); - this.loadHostNames(); - this.loadPrimaryNames(); - var uiConfigs = this.loadUiSideConfigs(); - this.set('configs', this.get('configs').concat(uiConfigs)); - }, - - - /** - * push users to configs - */ - loadUsersToConfigs: function () { - if (!this.get('serviceUsers').length) { - this.loadUsersFromServer(); - } - App.router.get('mainAdminSecurityController.serviceUsers').forEach(function (_user) { - this.get('configs').pushObject(_user); - }, this); - }, - - /** - * add component config that contain host name as value - * @param serviceName - * @param componentName - * @param configName - * @return {Boolean} - */ - addHostConfig: function(serviceName, componentName, configName) { - var service = App.Service.find(serviceName); - var isServiceSecure = this.get('secureServices').someProperty('serviceName', serviceName); - - if (service.get('isLoaded') && isServiceSecure) { - var hostComponent = service.get('hostComponents').findProperty('componentName', componentName); - if (hostComponent) { - var hostName = hostComponent.get('hostName'); - this.get('configs').push({ - id: 'puppet var', - name: configName, - value: hostName - }); - return true; - } - } - return false; - }, - - /** - * add hosts' names to configs - */ - loadHostNames: function () { - var componentsConfig = this.get('componentsConfig'); - componentsConfig.forEach(function (host) { - this.addHostConfig(host.serviceName, host.componentName, host.configName); - }, this); - }, - - /** - * load static configs - */ - loadStaticConfigs: function () { - this.get('configs').forEach(function (_property) { - switch (_property.name) { - case 'security_enabled': - _property.value = 'true'; - break; - } - }, this); - }, - - /** - * add principals to properties - */ - loadPrimaryNames: function () { - var principalProperties = this.getPrincipalNames(); - principalProperties.forEach(function (_principalProperty) { - var name = _principalProperty.name.replace('principal', 'primary'); - var value = _principalProperty.value.split('/')[0]; - this.get('configs').push({name: name, value: value}); - }, this); - }, - - /** - * gather and return properties with "principal_name" - * @return {Array} - */ - getPrincipalNames: function () { - var principalNames = []; - this.get('configs').forEach(function (_property) { - if (/principal_name?$/.test(_property.name)) { - principalNames.push(_property); - } - }, this); - this.get('secureProperties').forEach(function (_secureProperty) { - if (/principal_name?$/.test(_secureProperty.name)) { - var principalName = principalNames.findProperty('name', _secureProperty.name); - if (!principalName) { - _secureProperty.value = _secureProperty.defaultValue; - principalNames.push(_secureProperty); - } - } - }, this); - return principalNames; - }, - - /** - * load users from server - */ - loadUsersFromServer: function () { - if (App.get('testMode')) { - var serviceUsers = this.get('serviceUsers'); - this.get('testModeUsers').forEach(function (user) { - user.id = 'puppet var'; - serviceUsers.push(user); - }, this); - } else { - App.router.set('mainAdminSecurityController.serviceUsers', App.db.getSecureUserInfo()); - } - }, - - /** - * manage secure configs - * @return {Boolean} - */ manageSecureConfigs: function () { var serviceConfigTags = this.get('serviceConfigTags'); var secureConfigs = this.get('secureConfigs'); @@ -467,24 +148,6 @@ App.MainAdminSecurityAddStep4Controller = App.MainAdminSecurityProgressControlle }, /** - * set value of principal property - * @param serviceName - * @param principalName - * @return {Boolean} - */ - setPrincipalValue: function (serviceName, principalName) { - var siteProperties = this.get('configs'); - var realmName = siteProperties.findProperty('name', 'kerberos_domain'); - - if (this.get('secureServices').someProperty('serviceName', serviceName)) { - var principalProperty = siteProperties.findProperty('name', principalName); - principalProperty.value = principalProperty.value + '@' + realmName.value; - return true; - } - return false; - }, - - /** * send DELETE command to server to delete component * @param componentName * @param hostName http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/ambari-web/app/controllers/main/host/details.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js index 751a385..591d90b 100644 --- a/ambari-web/app/controllers/main/host/details.js +++ b/ambari-web/app/controllers/main/host/details.js @@ -378,9 +378,10 @@ App.MainHostDetailsController = Em.Controller.extend({ * if true security is enabled otherwise disabled * @return {Boolean} */ - getSecurityStatus: function () { - return App.router.get('mainAdminSecurityController').getUpdatedSecurityStatus(); - }, + securityEnabled: function () { + return App.router.get('mainAdminSecurityController.securityEnabled'); + }.property('App.router.mainAdminSecurityController.securityEnabled'), + /** * Send command to server to install selected host component @@ -392,15 +393,13 @@ App.MainHostDetailsController = Em.Controller.extend({ var component = event.context; var componentName = component.get('componentName'); - var securityEnabled = this.getSecurityStatus(); - if (componentName === 'ZOOKEEPER_SERVER') { return App.showConfirmationPopup(function () { self.primary(component); }, Em.I18n.t('hosts.host.addComponent.addZooKeeper')); } else { - if (securityEnabled && componentName !== 'CLIENTS') { + if (this.get('securityEnabled') && componentName !== 'CLIENTS') { return App.showConfirmationPopup(function () { self.primary(component); }, Em.I18n.t('hosts.host.addComponent.securityNote').format(componentName, self.get('content.hostName'))); http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/ambari-web/app/controllers/main/service/item.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js index 899a402..255bde0 100644 --- a/ambari-web/app/controllers/main/service/item.js +++ b/ambari-web/app/controllers/main/service/item.js @@ -580,13 +580,11 @@ App.MainServiceItemController = Em.Controller.extend({ enableHighAvailability: function() { var ability_controller = App.router.get('mainAdminHighAvailabilityController'); - ability_controller.setSecurityStatus(); ability_controller.enableHighAvailability(); }, disableHighAvailability: function() { var ability_controller = App.router.get('mainAdminHighAvailabilityController'); - ability_controller.setSecurityStatus(); ability_controller.disableHighAvailability(); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/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 a4f2718..0df2bf5 100644 --- a/ambari-web/app/controllers/wizard/step7_controller.js +++ b/ambari-web/app/controllers/wizard/step7_controller.js @@ -49,6 +49,22 @@ App.WizardStep7Controller = Em.Controller.extend({ secureConfigs: require('data/secure_mapping'), /** + * config categories with secure properties + * use only for add service wizard when security is enabled; + */ + secureServices: function () { + return (App.get('isHadoop2Stack')) ? + $.extend(true, [], require('data/HDP2/secure_configs')) : + $.extend(true, [], require('data/secure_configs')); + }.property('App.isHadoop2Stack'), + + /** + * uses for add service - find out is security is enabled + */ + securityEnabled: function () { + return App.router.get('mainAdminSecurityController.securityEnabled'); + }.property('App.router.mainAdminSecurityController.securityEnabled'), + /** * If miscConfigChange Modal is shown * @type {bool} */ @@ -741,8 +757,12 @@ App.WizardStep7Controller = Em.Controller.extend({ serviceConfigs.setEach('selected', false); this.get('selectedServiceNames').forEach(function (serviceName) { if (!serviceConfigs.findProperty('serviceName', serviceName)) return; - serviceConfigs.findProperty('serviceName', serviceName).set('selected', true); - }); + var selectedService = serviceConfigs.findProperty('serviceName', serviceName).set('selected', true); + // add secure configs when security is enabled + if(this.get('securityEnabled')) { + this.addSecureConfigs(selectedService, serviceName) ; + } + }, this); // Remove SNameNode if HA is enabled if (App.get('isHaEnabled')) { @@ -759,6 +779,26 @@ App.WizardStep7Controller = Em.Controller.extend({ }, /** + * + * @param selectedService + * @param serviceName + */ + addSecureConfigs: function(selectedService, serviceName) { + var secureService = this.get('secureServices').findProperty('serviceName', serviceName); + if (!secureService) { + return; + } + secureService.configCategories.forEach(function (category) { + selectedService.get('configCategories').push(category); + }); + secureService.configs.forEach(function (conf) { + conf.isVisible = !conf.displayType.contains('masterHost') && !conf.displayType.contains('slaveHost'); + var config = App.ServiceConfigProperty.create(conf); + selectedService.get('configs').push(config); + }, this); + }, + + /** * Select first addable service for <code>addServiceWizard</code> * Select first service at all in other cases * @method selectProperService http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/ambari-web/app/controllers/wizard/step8_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step8_controller.js b/ambari-web/app/controllers/wizard/step8_controller.js index 6986d29..e2a2a29 100644 --- a/ambari-web/app/controllers/wizard/step8_controller.js +++ b/ambari-web/app/controllers/wizard/step8_controller.js @@ -19,7 +19,7 @@ var App = require('app'); var stringUtils = require('utils/string_utils'); -App.WizardStep8Controller = Em.Controller.extend({ +App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, { name: 'wizardStep8Controller', @@ -194,13 +194,20 @@ App.WizardStep8Controller = Em.Controller.extend({ */ loadStep: function () { console.log("TRACE: Loading step8: Review Page"); - if (this.get('content.controllerName') != 'installerController') { - App.router.get('mainAdminSecurityController').setSecurityStatus(); - } this.clearStep(); if (this.get('content.serviceConfigProperties')) { this.formatProperties(); this.loadConfigs(); + if (this.get('content.controllerName') != 'installerController' && this.get('securityEnabled')) { + this.prepareSecureConfigs(); + this.get('content.services').filterProperty('isSelected', true) + .mapProperty('serviceName').forEach(function(serviceName){ + var config = this.get('secureConfigs').findProperty('serviceName', serviceName); + if (config) { + this.setPrincipalValue(serviceName, config.name); + } + }, this); + } } this.loadClusterInfo(); this.loadServices(); http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/ambari-web/app/mixins.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins.js b/ambari-web/app/mixins.js index 98cc3d8..3384391 100644 --- a/ambari-web/app/mixins.js +++ b/ambari-web/app/mixins.js @@ -26,3 +26,4 @@ require('mixins/common/tableServerProvider'); require('mixins/common/table_server_mixin'); require('mixins/main/host/details/host_components/decommissionable'); require('mixins/wizard/selectHost'); +require('mixins/wizard/addSecurityConfigs'); http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/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 new file mode 100644 index 0000000..8c3d5f0 --- /dev/null +++ b/ambari-web/app/mixins/wizard/addSecurityConfigs.js @@ -0,0 +1,370 @@ +/** + * 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'); + +/** + * Mixin for loading and setting secure configs + * + * @type {Ember.Mixin} + */ +App.AddSecurityConfigs = Em.Mixin.create({ + + secureProperties: function () { + if (App.get('isHadoop2Stack')) { + return require('data/HDP2/secure_properties').configProperties; + } else { + return require('data/secure_properties').configProperties; + } + }.property('App.isHadoop2Stack'), + + secureMapping: function () { + return (App.get('isHadoop2Stack')) ? require('data/HDP2/secure_mapping') : require('data/secure_mapping'); + }.property('App.isHadoop2Stack'), + + serviceUsersBinding: 'App.router.mainAdminSecurityController.serviceUsers', + + componentsConfig: [ + { + serviceName: 'OOZIE', + componentName: 'OOZIE_SERVER', + configName: 'oozieserver_host' + }, + { + serviceName: 'HIVE', + componentName: 'HIVE_METASTORE', + configName: 'hivemetastore_host' + }, + { + serviceName: 'WEBHCAT', + componentName: 'WEBHCAT_SERVER', + configName: 'webhcat_server' + } + ], + + /** + * mock users used in testMode + */ + testModeUsers: [ + { + name: 'hdfs_user', + value: 'hdfs' + }, + { + name: 'mapred_user', + value: 'mapred' + }, + { + name: 'hbase_user', + value: 'hbase' + }, + { + name: 'hive_user', + value: 'hive' + } + ], + + /** + * security configs, which values should be modified after APPLY CONFIGURATIONS stage + */ + secureConfigs: [ + { + name: 'nagios_principal_name', + serviceName: 'NAGIOS' + }, + { + name: 'zookeeper_principal_name', + serviceName: 'ZOOKEEPER' + }, + { + name: 'storm_principal_name', + serviceName: 'STORM' + } + ], + + secureServices: function() { + return this.get('content.services'); + }.property('content.services'), + + /** + * prepare secure configs + */ + prepareSecureConfigs: function () { + var configs = this.get('content.serviceConfigProperties'); + this.set('configs', configs); + this.loadStaticConfigs(); //Hack for properties which are declared in site_properties.js and not able to retrieve values declared in secure_properties.js + this.loadUsersToConfigs(); + this.loadHostNames(); + this.loadPrimaryNames(); + var uiConfigs = this.loadUiSideSecureConfigs(); + this.set('configs', this.get('configs').concat(uiConfigs)); + }, + + + /** + * push users to configs + */ + loadUsersToConfigs: function () { + if (!this.get('serviceUsers').length) { + this.loadUsersFromServer(); + } + App.router.get('mainAdminSecurityController.serviceUsers').forEach(function (_user) { + this.get('configs').pushObject(_user); + }, this); + }, + + /** + * add component config that contain host name as value + * @param serviceName + * @param componentName + * @param configName + * @return {Boolean} + */ + addHostConfig: function (serviceName, componentName, configName) { + var service = App.Service.find(serviceName); + var isServiceSecure = this.get('secureServices').someProperty('serviceName', serviceName); + + if (service.get('isLoaded') && isServiceSecure) { + var hostComponent = service.get('hostComponents').findProperty('componentName', componentName); + if (hostComponent) { + var hostName = hostComponent.get('hostName'); + this.get('configs').push({ + id: 'puppet var', + name: configName, + value: hostName + }); + return true; + } + } + return false; + }, + + /** + * add hosts' names to configs + */ + loadHostNames: function () { + var componentsConfig = this.get('componentsConfig'); + componentsConfig.forEach(function (host) { + this.addHostConfig(host.serviceName, host.componentName, host.configName); + }, this); + }, + + /** + * load static configs + */ + loadStaticConfigs: function () { + this.get('configs').forEach(function (_property) { + switch (_property.name) { + case 'security_enabled': + _property.value = 'true'; + break; + } + }, this); + }, + + /** + * add principals to properties + */ + loadPrimaryNames: function () { + var principalProperties = this.getPrincipalNames(); + principalProperties.forEach(function (_principalProperty) { + var name = _principalProperty.name.replace('principal', 'primary'); + var value = _principalProperty.value.split('/')[0]; + this.get('configs').push({name: name, value: value}); + }, this); + }, + + /** + * gather and return properties with "principal_name" + * @return {Array} + */ + getPrincipalNames: function () { + var principalNames = []; + this.get('configs').forEach(function (_property) { + if (/principal_name?$/.test(_property.name)) { + principalNames.push(_property); + } + }, this); + this.get('secureProperties').forEach(function (_secureProperty) { + if (/principal_name?$/.test(_secureProperty.name)) { + var principalName = principalNames.findProperty('name', _secureProperty.name); + if (!principalName) { + _secureProperty.value = _secureProperty.defaultValue; + principalNames.push(_secureProperty); + } + } + }, this); + return principalNames; + }, + + /** + * load users from server + */ + loadUsersFromServer: function () { + if (App.get('testMode')) { + var serviceUsers = this.get('serviceUsers'); + this.get('testModeUsers').forEach(function (user) { + user.id = 'puppet var'; + serviceUsers.push(user); + }, this); + } else { + App.router.set('mainAdminSecurityController.serviceUsers', App.db.getSecureUserInfo()); + } + }, + + /** + * load configs from UI side + * @return {Array} + */ + loadUiSideSecureConfigs: function () { + var uiConfig = []; + var configs = this.get('secureMapping').filterProperty('foreignKey', null); + configs.forEach(function (_config) { + var value = _config.value; + if (_config.hasOwnProperty('dependedServiceName')) { + value = this.checkServiceForConfigValue(value, _config.dependedServiceName); + } + value = this.getConfigValue(_config.templateName, value); + uiConfig.push({ + "id": "site property", + "name": _config.name, + "value": value, + "filename": _config.filename + }); + }, this); + var dependentConfig = this.get('secureMapping').filterProperty('foreignKey'); + dependentConfig.forEach(function (_config) { + if (App.Service.find().mapProperty('serviceName').contains(_config.serviceName)) { + this.setConfigValue(_config); + this.formatConfigName(uiConfig, _config); + uiConfig.push({ + "id": "site property", + "name": _config._name || _config.name, + "value": _config.value, + "filename": _config.filename + }); + } + }, this); + return uiConfig; + }, + + /** + * erase template rules from config value if service is not loaded + * @param value + * @param services + * @return {*} + */ + checkServiceForConfigValue: function (value, services) { + services.forEach(function (_service) { + if (!App.Service.find(_service.name).get('isLoaded')) { + value = value.replace(_service.replace, ''); + } + }, this); + return value; + }, + + /** + * Set all site property that are derived from other puppet-variable + * @param templateName + * @param expression + * @return {String|null} + */ + getConfigValue: function (templateName, expression) { + var express = expression.match(/<(.*?)>/g); + var value = expression; + if (Em.isNone(express)) return expression; + + express.forEach(function (_express) { + var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]); + var configs = this.get('configs').findProperty('name', templateName[index]); + + if (!!value) { + value = (configs) ? value.replace(_express, configs.value) : null; + } + }, this); + return value; + }, + + /** + * format name of config values of configs which match foreignKey + * @param uiConfig + * @param config + * @return {Boolean} + */ + formatConfigName: function (uiConfig, config) { + if (Em.isNone(config.value)) return false; + + var fkValue = config.name.match(/<(foreignKey.*?)>/g); + if (fkValue) { + fkValue.forEach(function (_fkValue) { + var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]); + var value; + if (uiConfig.someProperty('name', config.foreignKey[index])) { + value = uiConfig.findProperty('name', config.foreignKey[index]).value; + config._name = config.name.replace(_fkValue, value); + } else if (this.get('configs').someProperty('name', config.foreignKey[index])) { + value = this.get('configs').findProperty('name', config.foreignKey[index]).value; + config._name = config.name.replace(_fkValue, value); + } + }, this); + return true; + } + return false; + }, + + /** + * Set config value with values of configs which match template + * @param config + * @return {Boolean} + */ + setConfigValue: function (config) { + if (Em.isNone(config.value)) return false; + + //For properties in the configMapping file having foreignKey and templateName properties. + var templateValue = config.value.match(/<(templateName.*?)>/g); + if (templateValue) { + templateValue.forEach(function (_value) { + var index = parseInt(_value.match(/\[([\d]*)(?=\])/)[1]); + var cfgValue = this.get('configs').findProperty('name', config.templateName[index]); + + config.value = (cfgValue) ? config.value.replace(_value, cfgValue.value) : null; + }, this); + return true; + } + return false; + }, + + /** + * set value of principal property + * @param serviceName + * @param principalName + * @return {Boolean} + */ + setPrincipalValue: function (serviceName, principalName) { + var siteProperties = this.get('configs'); + + var realmName = siteProperties.findProperty('name', 'kerberos_domain'); + + if (this.get('secureServices').someProperty('serviceName', serviceName)) { + var principalProperty = siteProperties.findProperty('name', principalName); + principalProperty.value = principalProperty.value + '@' + realmName.value; + return true; + } + return false; + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/ambari-web/app/views/main/admin/highAvailability_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/admin/highAvailability_view.js b/ambari-web/app/views/main/admin/highAvailability_view.js index cf9fb1c..2338f5a 100644 --- a/ambari-web/app/views/main/admin/highAvailability_view.js +++ b/ambari-web/app/views/main/admin/highAvailability_view.js @@ -21,10 +21,6 @@ var App = require('app'); App.MainAdminHighAvailabilityView = Em.View.extend({ templateName: require('templates/main/admin/highAvailability'), - didInsertElement: function () { - this.get('controller').setSecurityStatus(); - }, - supportRMHA: function () { return App.get('isHadoop21Stack') && App.get('supports.resourceManagerHighAvailability'); } http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/ambari-web/test/controllers/main/admin/security/add/step4_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/security/add/step4_test.js b/ambari-web/test/controllers/main/admin/security/add/step4_test.js index ddc9b3a..302b2cd 100644 --- a/ambari-web/test/controllers/main/admin/security/add/step4_test.js +++ b/ambari-web/test/controllers/main/admin/security/add/step4_test.js @@ -20,6 +20,7 @@ var App = require('app'); require('controllers/main/admin/security/security_progress_controller'); require('controllers/main/admin/security/add/step4'); +require('mixins/wizard/addSecurityConfigs'); require('utils/polling'); require('models/cluster_states'); require('models/service'); @@ -32,20 +33,11 @@ describe('App.MainAdminSecurityAddStep4Controller', function () { this._super() }, secureMapping: [], - secureProperties: [] + secureProperties: [], + secureServices: [] }); - describe('#secureServices', function() { - it('content.services is correct', function() { - controller.set('content.services', [{}]); - expect(controller.get('secureServices')).to.eql([{}]); - controller.reopen({ - secureServices: [] - }) - }); - }); - - describe('#isBackBtnDisabled', function() { + describe('#isBackBtnDisabled', function() { it('commands have error', function() { controller.set('commands', [Em.Object.create({ isError: true @@ -353,298 +345,7 @@ describe('App.MainAdminSecurityAddStep4Controller', function () { }); }); - describe('#loadUiSideConfigs()', function() { - - beforeEach(function(){ - sinon.stub(controller, 'checkServiceForConfigValue', function() { - return 'value2'; - }); - sinon.stub(controller, 'setConfigValue', Em.K); - sinon.stub(controller, 'formatConfigName', Em.K); - }); - afterEach(function(){ - controller.checkServiceForConfigValue.restore(); - controller.setConfigValue.restore(); - controller.formatConfigName.restore(); - }); - - it('secureMapping is empty', function() { - controller.set('secureMapping', []); - - expect(controller.loadUiSideConfigs()).to.be.empty; - }); - it('Config does not have dependedServiceName', function() { - controller.set('secureMapping', [{ - name: 'config1', - value: 'value1', - filename: 'file1', - foreignKey: null - }]); - - expect(controller.loadUiSideConfigs()).to.eql([{ - "id": "site property", - "name": 'config1', - "value": 'value1', - "filename": 'file1' - }]); - }); - it('Config has dependedServiceName', function() { - controller.set('secureMapping', [{ - name: 'config1', - value: 'value1', - filename: 'file1', - foreignKey: null, - dependedServiceName: 'service' - }]); - - expect(controller.loadUiSideConfigs()).to.eql([{ - "id": "site property", - "name": 'config1', - "value": 'value2', - "filename": 'file1' - }]); - }); - it('Config has non-existent serviceName', function() { - controller.set('secureMapping', [{ - name: 'config1', - value: 'value1', - filename: 'file1', - foreignKey: true, - serviceName: 'service' - }]); - sinon.stub(App.Service, 'find', function(){ - return []; - }); - - expect(controller.loadUiSideConfigs()).to.be.empty; - App.Service.find.restore(); - }); - it('Config has correct serviceName', function() { - controller.set('secureMapping', [{ - name: 'config1', - value: 'value1', - filename: 'file1', - foreignKey: true, - serviceName: 'HDFS' - }]); - sinon.stub(App.Service, 'find', function(){ - return [{serviceName: 'HDFS'}]; - }); - - expect(controller.loadUiSideConfigs()).to.eql([{ - "id": "site property", - "name": 'config1', - "value": 'value1', - "filename": 'file1' - }]); - expect(controller.setConfigValue.calledOnce).to.be.true; - expect(controller.formatConfigName.calledOnce).to.be.true; - App.Service.find.restore(); - }); - }); - - describe('#checkServiceForConfigValue()', function() { - it('services is empty', function() { - var services = []; - - expect(controller.checkServiceForConfigValue('value1', services)).to.equal('value1'); - }); - it('Service is loaded', function() { - var services = [{}]; - sinon.stub(App.Service, 'find', function () { - return Em.Object.create({isLoaded: false}); - }); - - expect(controller.checkServiceForConfigValue('value1', services)).to.equal('value1'); - - App.Service.find.restore(); - }); - it('Service is not loaded', function() { - var services = [{ - replace: 'val' - }]; - sinon.stub(App.Service, 'find', function () { - return Em.Object.create({isLoaded: false}); - }); - - expect(controller.checkServiceForConfigValue('value1', services)).to.equal('ue1'); - - App.Service.find.restore(); - }); - }); - - describe('#formatConfigName()', function() { - it('config.value is null', function() { - var config = { - value: null - }; - - expect(controller.formatConfigName([], config)).to.be.false; - }); - it('config.name does not contain foreignKey', function() { - var config = { - value: 'value1', - name: 'config1' - }; - - expect(controller.formatConfigName([], config)).to.be.false; - }); - it('globalProperties is empty, use uiConfig', function() { - var config = { - value: 'value1', - name: '<foreignKey[0]>', - foreignKey: ['key1'] - }; - controller.set('globalProperties', []); - var uiConfig = [{ - name: 'key1', - value: 'globalValue1' - }]; - - expect(controller.formatConfigName(uiConfig, config)).to.be.true; - expect(config._name).to.equal('globalValue1'); - }); - - }); - - describe('#setConfigValue()', function() { - it('config.value is null', function() { - var config = { - value: null - }; - - expect(controller.setConfigValue(config)).to.be.false; - }); - it('config.value does not match "templateName"', function() { - var config = { - value: '' - }; - - expect(controller.setConfigValue(config)).to.be.false; - }); - it('No such property in global configs', function() { - var config = { - value: '<templateName[0]>', - templateName: ['config1'] - }; - controller.set('globalProperties', []); - - expect(controller.setConfigValue(config)).to.be.true; - expect(config.value).to.be.null; - }); - - }); - - describe('#addHostConfig()', function() { - - afterEach(function () { - App.Service.find.restore(); - }); - - it('No such service loaded', function() { - sinon.stub(App.Service, 'find', function(){ - return Em.Object.create({isLoaded: false}); - }); - - expect(controller.addHostConfig('service1', 'comp1', 'config1')).to.be.false; - }); - it('No such service in secureServices', function() { - sinon.stub(App.Service, 'find', function(){ - return Em.Object.create({isLoaded: true}); - }); - controller.set('secureServices', []); - - expect(controller.addHostConfig('service1', 'comp1', 'config1')).to.be.false; - }); - it('Service does not have such host-component', function() { - sinon.stub(App.Service, 'find', function(){ - return Em.Object.create({ - isLoaded: true, - hostComponents: [] - }); - }); - controller.set('secureServices', [{ - serviceName: 'service1' - }]); - - expect(controller.addHostConfig('service1', 'comp1', 'config1')).to.be.false; - }); - }); - - describe('#getPrincipalNames()', function() { - - beforeEach(function () { - controller.set('globalProperties', []); - controller.set('secureProperties', []); - }); - - it('globalProperties and secureProperties are empty', function() { - expect(controller.getPrincipalNames()).to.be.empty; - }); - it('global property name does not match "principal_name"', function() { - controller.set('globalProperties', [{ - name: 'config1' - }]); - expect(controller.getPrincipalNames()).to.be.empty; - }); - it('secure property name does not match "principal_name"', function() { - controller.set('secureProperties', [{ - name: 'config1' - }]); - expect(controller.getPrincipalNames()).to.be.empty; - }); - it('property with such name already exists', function() { - controller.set('globalProperties', [{ - name: 'principal_name' - }]); - controller.set('secureProperties', [{ - name: 'principal_name' - }]); - expect(controller.getPrincipalNames().mapProperty('name')).to.eql(['principal_name']); - }); - }); - - describe('#loadUsersFromServer()', function() { - it('testMode = true', function() { - controller.set('testModeUsers', [{ - name: 'user1', - value: 'value1' - }]); - controller.set('serviceUsers', []); - sinon.stub(App, 'get', function(k) { - if ('testMode' === k) return true; - return Em.get(App, k); - }); - - controller.loadUsersFromServer(); - expect(controller.get('serviceUsers')).to.eql([{ - name: 'user1', - value: 'value1', - id: 'puppet var' - }]); - App.get.restore(); - }); - it('testMode = false', function() { - sinon.stub(App.router, 'set', Em.K); - sinon.stub(App.db, 'getSecureUserInfo', function(){ - return []; - }); - sinon.stub(App, 'get', function(k) { - if ('testMode' === k) return false; - return Em.get(App, k); - }); - - controller.loadUsersFromServer(); - expect(App.db.getSecureUserInfo.calledOnce).to.be.true; - expect(App.router.set.calledWith('mainAdminSecurityController.serviceUsers', [])).to.be.true; - - App.router.set.restore(); - App.get.restore(); - App.db.getSecureUserInfo.restore(); - }); - }); - - describe('#manageSecureConfigs()', function() { + describe('#manageSecureConfigs()', function() { beforeEach(function () { sinon.stub(controller, 'setPrincipalValue', Em.K); http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/ambari-web/test/controllers/wizard/step8_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step8_test.js b/ambari-web/test/controllers/wizard/step8_test.js index 9f2e5d6..14a9801 100644 --- a/ambari-web/test/controllers/wizard/step8_test.js +++ b/ambari-web/test/controllers/wizard/step8_test.js @@ -282,21 +282,6 @@ describe('App.WizardStep8Controller', function () { installerStep8Controller.loadStep(); expect(installerStep8Controller.get('isBackBtnDisabled')).to.equal(false); }); - it('should call setSecurityStatus for non-installerController', function () { - var obj = Em.Object.create({ - setSecurityStatus: Em.K - }); - sinon.stub(App.router, 'get', function () { - return obj; - }); - sinon.spy(obj, 'setSecurityStatus'); - installerStep8Controller.set('content.controllerName', 'addServiceController'); - installerStep8Controller.loadStep(); - expect(obj.setSecurityStatus.calledOnce).to.equal(true); - obj.setSecurityStatus.restore(); - App.router.get.restore(); - - }); }); describe('#removeHiveConfigs', function () { http://git-wip-us.apache.org/repos/asf/ambari/blob/0f24bc24/ambari-web/test/mixins/wizard/addSeccurityConfigs_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/mixins/wizard/addSeccurityConfigs_test.js b/ambari-web/test/mixins/wizard/addSeccurityConfigs_test.js new file mode 100644 index 0000000..d78ce48 --- /dev/null +++ b/ambari-web/test/mixins/wizard/addSeccurityConfigs_test.js @@ -0,0 +1,338 @@ +/** + * 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('mixins/wizard/addSecurityConfigs'); + +describe('App.AddSecurityConfigs', function () { + + var controller = App.AddSecurityConfigs.create({ + content: {}, + enableSubmit: function () { + this._super() + }, + secureMapping: [], + secureProperties: [] + }); + + describe('#secureServices', function() { + it('content.services is correct', function() { + controller.set('content.services', [{}]); + expect(controller.get('secureServices')).to.eql([{}]); + controller.reopen({ + secureServices: [] + }) + }); + }); + + describe('#loadUiSideSecureConfigs()', function() { + + beforeEach(function(){ + sinon.stub(controller, 'checkServiceForConfigValue', function() { + return 'value2'; + }); + sinon.stub(controller, 'setConfigValue', Em.K); + sinon.stub(controller, 'formatConfigName', Em.K); + }); + afterEach(function(){ + controller.checkServiceForConfigValue.restore(); + controller.setConfigValue.restore(); + controller.formatConfigName.restore(); + }); + + it('secureMapping is empty', function() { + controller.set('secureMapping', []); + + expect(controller.loadUiSideSecureConfigs()).to.be.empty; + }); + it('Config does not have dependedServiceName', function() { + controller.set('secureMapping', [{ + name: 'config1', + value: 'value1', + filename: 'file1', + foreignKey: null + }]); + + expect(controller.loadUiSideSecureConfigs()).to.eql([{ + "id": "site property", + "name": 'config1', + "value": 'value1', + "filename": 'file1' + }]); + }); + it('Config has dependedServiceName', function() { + controller.set('secureMapping', [{ + name: 'config1', + value: 'value1', + filename: 'file1', + foreignKey: null, + dependedServiceName: 'service' + }]); + + expect(controller.loadUiSideSecureConfigs()).to.eql([{ + "id": "site property", + "name": 'config1', + "value": 'value2', + "filename": 'file1' + }]); + }); + it('Config has non-existent serviceName', function() { + controller.set('secureMapping', [{ + name: 'config1', + value: 'value1', + filename: 'file1', + foreignKey: true, + serviceName: 'service' + }]); + sinon.stub(App.Service, 'find', function(){ + return []; + }); + + expect(controller.loadUiSideSecureConfigs()).to.be.empty; + App.Service.find.restore(); + }); + it('Config has correct serviceName', function() { + controller.set('secureMapping', [{ + name: 'config1', + value: 'value1', + filename: 'file1', + foreignKey: true, + serviceName: 'HDFS' + }]); + sinon.stub(App.Service, 'find', function(){ + return [{serviceName: 'HDFS'}]; + }); + + expect(controller.loadUiSideSecureConfigs()).to.eql([{ + "id": "site property", + "name": 'config1', + "value": 'value1', + "filename": 'file1' + }]); + expect(controller.setConfigValue.calledOnce).to.be.true; + expect(controller.formatConfigName.calledOnce).to.be.true; + App.Service.find.restore(); + }); + }); + + describe('#checkServiceForConfigValue()', function() { + it('services is empty', function() { + var services = []; + + expect(controller.checkServiceForConfigValue('value1', services)).to.equal('value1'); + }); + it('Service is loaded', function() { + var services = [{}]; + sinon.stub(App.Service, 'find', function () { + return Em.Object.create({isLoaded: false}); + }); + + expect(controller.checkServiceForConfigValue('value1', services)).to.equal('value1'); + + App.Service.find.restore(); + }); + it('Service is not loaded', function() { + var services = [{ + replace: 'val' + }]; + sinon.stub(App.Service, 'find', function () { + return Em.Object.create({isLoaded: false}); + }); + + expect(controller.checkServiceForConfigValue('value1', services)).to.equal('ue1'); + + App.Service.find.restore(); + }); + }); + + describe('#formatConfigName()', function() { + it('config.value is null', function() { + var config = { + value: null + }; + + expect(controller.formatConfigName([], config)).to.be.false; + }); + it('config.name does not contain foreignKey', function() { + var config = { + value: 'value1', + name: 'config1' + }; + + expect(controller.formatConfigName([], config)).to.be.false; + }); + it('globalProperties is empty, use uiConfig', function() { + var config = { + value: 'value1', + name: '<foreignKey[0]>', + foreignKey: ['key1'] + }; + controller.set('globalProperties', []); + var uiConfig = [{ + name: 'key1', + value: 'globalValue1' + }]; + + expect(controller.formatConfigName(uiConfig, config)).to.be.true; + expect(config._name).to.equal('globalValue1'); + }); + + }); + + describe('#setConfigValue()', function() { + it('config.value is null', function() { + var config = { + value: null + }; + + expect(controller.setConfigValue(config)).to.be.false; + }); + it('config.value does not match "templateName"', function() { + var config = { + value: '' + }; + + expect(controller.setConfigValue(config)).to.be.false; + }); + it('No such property in global configs', function() { + var config = { + value: '<templateName[0]>', + templateName: ['config1'] + }; + controller.set('globalProperties', []); + + expect(controller.setConfigValue(config)).to.be.true; + expect(config.value).to.be.null; + }); + + }); + + describe('#addHostConfig()', function() { + + afterEach(function () { + App.Service.find.restore(); + }); + + it('No such service loaded', function() { + sinon.stub(App.Service, 'find', function(){ + return Em.Object.create({isLoaded: false}); + }); + + expect(controller.addHostConfig('service1', 'comp1', 'config1')).to.be.false; + }); + it('No such service in secureServices', function() { + sinon.stub(App.Service, 'find', function(){ + return Em.Object.create({isLoaded: true}); + }); + controller.set('secureServices', []); + + expect(controller.addHostConfig('service1', 'comp1', 'config1')).to.be.false; + }); + it('Service does not have such host-component', function() { + sinon.stub(App.Service, 'find', function(){ + return Em.Object.create({ + isLoaded: true, + hostComponents: [] + }); + }); + controller.set('secureServices', [{ + serviceName: 'service1' + }]); + + expect(controller.addHostConfig('service1', 'comp1', 'config1')).to.be.false; + }); + }); + + describe('#getPrincipalNames()', function() { + + beforeEach(function () { + controller.set('globalProperties', []); + controller.set('secureProperties', []); + }); + + it('globalProperties and secureProperties are empty', function() { + expect(controller.getPrincipalNames()).to.be.empty; + }); + it('global property name does not match "principal_name"', function() { + controller.set('globalProperties', [{ + name: 'config1' + }]); + expect(controller.getPrincipalNames()).to.be.empty; + }); + it('secure property name does not match "principal_name"', function() { + controller.set('secureProperties', [{ + name: 'config1' + }]); + expect(controller.getPrincipalNames()).to.be.empty; + }); + it('property with such name already exists', function() { + controller.set('globalProperties', [{ + name: 'principal_name' + }]); + controller.set('secureProperties', [{ + name: 'principal_name' + }]); + expect(controller.getPrincipalNames().mapProperty('name')).to.eql(['principal_name']); + }); + }); + + describe('#loadUsersFromServer()', function() { + it('testMode = true', function() { + controller.set('testModeUsers', [{ + name: 'user1', + value: 'value1' + }]); + controller.set('serviceUsers', []); + sinon.stub(App, 'get', function(k) { + if ('testMode' === k) return true; + return Em.get(App, k); + }); + + controller.loadUsersFromServer(); + expect(controller.get('serviceUsers')).to.eql([{ + name: 'user1', + value: 'value1', + id: 'puppet var' + }]); + App.get.restore(); + }); + it('testMode = false', function() { + sinon.stub(App.router, 'set', Em.K); + sinon.stub(App.db, 'getSecureUserInfo', function(){ + return []; + }); + sinon.stub(App, 'get', function(k) { + if ('testMode' === k) return false; + return Em.get(App, k); + }); + + controller.loadUsersFromServer(); + expect(App.db.getSecureUserInfo.calledOnce).to.be.true; + expect(App.router.set.calledWith('mainAdminSecurityController.serviceUsers', [])).to.be.true; + + App.router.set.restore(); + App.get.restore(); + App.db.getSecureUserInfo.restore(); + }); + }); + +}); + + +
