123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700 |
- /**
- * 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({
- kerberosDescriptor: {},
- secureProperties: require('data/HDP2/secure_properties').configProperties,
- secureMapping: require('data/HDP2/secure_mapping'),
- serviceUsersBinding: 'App.router.mainAdminSecurityController.serviceUsers',
- componentsConfig: [
- {
- serviceName: 'OOZIE',
- componentName: 'OOZIE_SERVER',
- configName: 'oozieserver_host'
- },
- {
- serviceName: 'HIVE',
- 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: function () {
- var configs = [
- {
- name: 'zookeeper_principal_name',
- serviceName: 'ZOOKEEPER'
- },
- {
- name: 'knox_principal_name',
- serviceName: 'KNOX'
- },
- {
- name: 'storm_principal_name',
- serviceName: 'STORM'
- }
- ];
- if (App.get('isHadoop22Stack')) {
- configs.push({
- name: 'nimbus_principal_name',
- serviceName: 'STORM'
- });
- }
- return configs;
- }.property('App.isHadoop22Stack'),
- 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).filter(function (_configProperty) {
- return (App.Service.find().mapProperty('serviceName').contains(_configProperty.serviceName));
- }, this);
- configs.forEach(function (_config) {
- var value = _config.value;
- if (_config.hasOwnProperty('dependedServiceName')) {
- value = this.checkServiceForConfigValue(value, _config.dependedServiceName);
- }
- value = this.getConfigValue(_config.templateName, value, _config.name);
- 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
- * @param name
- * @return {String|null}
- */
- getConfigValue: function (templateName, expression, name) {
- 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]);
- var configValue = templateName[index] == 'hive_metastore' ?
- configs.value.map(function (hostName) {
- return 'thrift://' + hostName + ':9083';
- }).join(',') : configs.value;
- if (!!value) {
- value = (configs) ? App.config.replaceConfigValues(name, _express, value, configValue) : 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 cfg = this.get('configs').findProperty('name', config.templateName[index]);
- if (cfg) {
- var cfgValue = config.templateName[index] == 'hive_metastore' ? cfg.value.join(',') : cfg.value;
- config.value = config.value.replace(_value, cfgValue);
- } else {
- config.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;
- },
- /**
- * Generate stack descriptor configs.
- *
- * @returns {$.Deferred}
- */
- getDescriptorConfigs: function () {
- return this.loadDescriptorConfigs().pipe(this.createServicesStackDescriptorConfigs.bind(this));
- },
- /**
- *
- * @param {object[]} items - stack descriptor json response
- * @returns {App.ServiceConfigProperty[]}
- */
- createServicesStackDescriptorConfigs: function (items) {
- var self = this;
- var configs = [];
- var clusterConfigs = [];
- var kerberosDescriptor = items.artifact_data;
- this.set('kerberosDescriptor', kerberosDescriptor);
- // generate configs for root level properties object, currently realm, keytab_dir
- clusterConfigs = clusterConfigs.concat(this.expandKerberosStackDescriptorProps(kerberosDescriptor.properties, 'Cluster', 'stackConfigs'));
- // generate configs for root level identities object, currently spnego property
- clusterConfigs = clusterConfigs.concat(this.createConfigsByIdentities(kerberosDescriptor.identities, 'Cluster'));
- kerberosDescriptor.services.forEach(function (service) {
- var serviceName = service.name;
- // generate configs for service level identity objects
- configs = configs.concat(self.createResourceConfigs(service, serviceName));
- // generate configs for service component level identity object
- service.components.forEach(function (component) {
- configs = configs.concat(self.createResourceConfigs(component, serviceName));
- });
- });
- // unite cluster, service and component configs
- configs = configs.concat(clusterConfigs);
- self.processConfigReferences(kerberosDescriptor, configs);
- return configs;
- },
- /**
- *
- * @param {Object} resource
- * @param {String} serviceName
- * @return {Array}
- */
- createResourceConfigs: function (resource, serviceName) {
- var identityConfigs = [];
- var resourceConfigs = [];
- if (resource.identities) {
- identityConfigs = this.createConfigsByIdentities(resource.identities, serviceName);
- }
- if (resource.configurations) {
- resource.configurations.forEach(function (_configuration) {
- for (var key in _configuration) {
- resourceConfigs = resourceConfigs.concat(this.expandKerberosStackDescriptorProps(_configuration[key], serviceName, key));
- }
- }, this);
- }
- return identityConfigs.concat(resourceConfigs);
- },
- /**
- * Create service properties based on component identity
- *
- * @param {object[]} identities
- * @param {string} serviceName
- * @returns {App.ServiceConfigProperty[]}
- */
- createConfigsByIdentities: function (identities, serviceName) {
- var self = this;
- var configs = [];
- identities.forEach(function (identity) {
- var defaultObject = {
- isOverridable: false,
- isVisible: true,
- isSecureConfig: true,
- serviceName: serviceName,
- name: identity.name,
- identityType: identity.principal && identity.principal.type
- };
- self.parseIdentityObject(identity).forEach(function (item) {
- configs.push(App.ServiceConfigProperty.create($.extend({}, defaultObject, item)));
- });
- });
- return configs;
- },
- /**
- * Bootstrap base object according to identity info. Generate objects will be converted to
- * App.ServiceConfigProperty model class instances.
- *
- * @param {object} identity
- * @returns {object[]}
- */
- parseIdentityObject: function (identity) {
- var result = [];
- var name = identity.name;
- var keys = Em.keys(identity).without('name');
- keys.forEach(function (item) {
- var configObject = {};
- var prop = identity[item];
- var itemValue = prop[{keytab: 'file', principal: 'value'}[item]];
- // skip inherited property without `configuration` and `keytab` or `file` values
- if (!prop.configuration && !itemValue) return;
- // inherited property with value should not observe value from reference
- if (name.startsWith('/') && !itemValue) {
- configObject.referenceProperty = name.substring(1) + ':' + item;
- configObject.isEditable = false;
- }
- configObject.defaultValue = configObject.value = itemValue;
- configObject.filename = prop.configuration ? prop.configuration.split('/')[0] : 'cluster-env';
- configObject.name = prop.configuration ? prop.configuration.split('/')[1] : name + '_' + item;
- configObject.displayName = configObject.filename == "cluster-env" ? App.format.normalizeName(configObject.name) : configObject.name;
- result.push(configObject);
- });
- return result;
- },
- /**
- * Wrap kerberos properties to App.ServiceConfigProperty model class instances.
- *
- * @param {object} kerberosProperties
- * @param {string} serviceName
- * @param {string} filename
- * @returns {App.ServiceConfigProperty[]}
- */
- expandKerberosStackDescriptorProps: function (kerberosProperties, serviceName, filename) {
- var configs = [];
- for (var propertyName in kerberosProperties) {
- var propertyObject = {
- name: propertyName,
- value: kerberosProperties[propertyName],
- defaultValue: kerberosProperties[propertyName],
- serviceName: serviceName,
- filename: filename,
- displayName: serviceName == "Cluster" ? App.format.normalizeName(propertyName) : propertyName,
- isOverridable: false,
- isEditable: propertyName != 'realm',
- isSecureConfig: true
- };
- configs.push(App.ServiceConfigProperty.create(propertyObject));
- }
- return configs;
- },
- /**
- * Take care about configs that should observe value from referenced configs.
- * Reference is set with `referenceProperty` key.
- *
- * @param {object[]} kerberosDescriptor
- * @param {App.ServiceConfigProperty[]} configs
- */
- processConfigReferences: function (kerberosDescriptor, configs) {
- var identities = kerberosDescriptor.identities;
- identities = identities.concat(kerberosDescriptor.services.map(function (service) {
- var _identities = service.identities || [];
- if (service.components && !!service.components.length) {
- identities = identities.concat(service.components.mapProperty('identities').reduce(function (p, c) {
- return p.concat(c);
- }, []));
- return identities;
- }
- }).reduce(function (p, c) {
- return p.concat(c);
- }, []));
- // clean up array
- identities = identities.compact().without(undefined);
- configs.forEach(function (item) {
- var reference = item.get('referenceProperty');
- if (!!reference) {
- var identity = identities.findProperty('name', reference.split(':')[0])[reference.split(':')[1]];
- if (identity && !!identity.configuration) {
- item.set('observesValueFrom', identity.configuration.split('/')[1]);
- } else {
- item.set('observesValueFrom', reference.replace(':', '_'));
- }
- }
- });
- },
- /**
- * update the kerberos descriptor to be put on cluster resource with user customizations
- * @param kerberosDescriptor {Object}
- * @param configs {Object}
- */
- updateKerberosDescriptor: function (kerberosDescriptor, configs) {
- configs.forEach(function (_config) {
- var isConfigUpdated;
- var isStackResouce = true;
- isConfigUpdated = this.updateResourceIdentityConfigs(kerberosDescriptor, _config, isStackResouce);
- if (!isConfigUpdated) {
- kerberosDescriptor.services.forEach(function (_service) {
- isConfigUpdated = this.updateResourceIdentityConfigs(_service, _config);
- if (!isConfigUpdated) {
- _service.components.forEach(function (_component) {
- isConfigUpdated = this.updateResourceIdentityConfigs(_component, _config);
- }, this);
- }
- }, this);
- }
- }, this);
- },
- /**
- * Updates the identity configs or configurations at a resource. A resource could be
- * 1) Stack
- * 2) Service
- * 3) Component
- * @param resource
- * @param config
- * @param isStackResource
- * @return boolean
- */
- updateResourceIdentityConfigs: function (resource, config, isStackResource) {
- var isConfigUpdated;
- var identities = resource.identities;
- var properties = !!isStackResource ? resource.properties : resource.configurations;
- isConfigUpdated = this.updateDescriptorConfigs(properties, config);
- if (!isConfigUpdated) {
- if (identities) {
- isConfigUpdated = this.updateDescriptorIdentityConfig(identities, config);
- }
- }
- return isConfigUpdated;
- },
- /**
- *
- * @param configurations
- * @param config
- * @return boolean
- */
- updateDescriptorConfigs: function (configurations, config) {
- var isConfigUpdated;
- if (!!configurations) {
- if (Array.isArray(configurations)) {
- configurations.forEach(function (_configuration) {
- for (var key in _configuration) {
- if (Object.keys(_configuration[key]).contains(config.name) && config.filename === key) {
- _configuration[key][config.name] = config.value;
- isConfigUpdated = true
- }
- }
- }, this);
- } else if (Object.keys(configurations).contains(config.name) && config.filename === 'stackConfigs') {
- configurations[config.name] = config.value;
- isConfigUpdated = true
- }
- }
- return isConfigUpdated;
- },
- /**
- *
- * @param identities
- * @param config
- * @return boolean
- */
- updateDescriptorIdentityConfig: function (identities, config) {
- var isConfigUpdated = false;
- identities.forEach(function (identity) {
- var keys = Em.keys(identity).without('name');
- keys.forEach(function (item) {
- var prop = identity[item];
- if (prop.configuration && prop.configuration.split('/')[0] === config.filename &&
- prop.configuration.split('/')[1] === config.name) {
- prop[{keytab: 'file', principal: 'value'}[item]] = config.value;
- isConfigUpdated = true;
- }
- });
- }, this);
- return isConfigUpdated;
- },
- /**
- * Make request for stack descriptor configs if cluster is not secure
- * or cluster descriptor configs if cluster is secure
- * @returns {$.ajax}
- * @method loadStackDescriptorConfigs
- */
- loadDescriptorConfigs: function() {
- if (App.router.get('mainAdminKerberosController.securityEnabled')) {
- return this.loadClusterDescriptorConfigs();
- } else {
- return this.loadStackDescriptorConfigs();
- }
- },
- /**
- * Make request for stack descriptor configs.
- * @returns {$.ajax}
- * @method loadStackDescriptorConfigs
- */
- loadStackDescriptorConfigs: function () {
- return App.ajax.send({
- sender: this,
- name: 'admin.kerberize.stack_descriptor',
- data: {
- stackName: App.get('currentStackName'),
- stackVersionNumber: App.get('currentStackVersionNumber')
- }
- });
- },
- /**
- * Make request for cluster descriptor configs.
- * @returns {$.ajax}
- * @method loadClusterDescriptorConfigs
- */
- loadClusterDescriptorConfigs: function () {
- return App.ajax.send({
- sender: this,
- name: 'admin.kerberize.cluster_descriptor'
- });
- }
- });
|