/** * 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'); var stringUtils = require('utils/string_utils'); App.MainAdminSecurityAddStep3Controller = Em.Controller.extend({ name: 'mainAdminSecurityAddStep3Controller', hostComponents: [], hosts: [], isLoaded: false, componentToUserMap: function() { var map = { 'NAMENODE': 'hdfs_user', 'SECONDARY_NAMENODE': 'hdfs_user', 'DATANODE': 'hdfs_user', 'JOURNALNODE': 'hdfs_user', 'TASKTRACKER': 'mapred_user', 'JOBTRACKER': 'mapred_user', 'HISTORYSERVER': 'mapred_user', 'RESOURCEMANAGER': 'yarn_user', 'NODEMANAGER': 'yarn_user', 'ZOOKEEPER_SERVER': 'zk_user', 'HIVE_SERVER': 'hive_user', 'HIVE_METASTORE': 'hive_user', 'OOZIE_SERVER': 'oozie_user', 'HBASE_MASTER': 'hbase_user', 'HBASE_REGIONSERVER': 'hbase_user', 'SUPERVISOR': 'storm_user', 'NIMBUS': 'storm_user', 'STORM_UI_SERVER': 'storm_user', 'FALCON_SERVER': 'falcon_user', 'KNOX_GATEWAY': 'knox_user', 'APP_TIMELINE_SERVER': 'yarn_user' }; if (App.get('isHadoop22Stack')) { map['DRPC_SERVER'] = 'storm_user' } return map; }.property('App.isHadoop22Stack'), // The componentName, principal, and keytab have to coincide with the values in secure_properties.js componentToConfigMap: [ { componentName: 'NAMENODE', principal: 'hadoop_http_principal_name', keytab: 'hadoop_http_keytab', displayName: Em.I18n.t('admin.addSecurity.hdfs.user.httpUser') }, { componentName: 'SECONDARY_NAMENODE', principal: 'hadoop_http_principal_name', keytab: 'hadoop_http_keytab', displayName: Em.I18n.t('admin.addSecurity.hdfs.user.httpUser') }, { componentName: 'JOURNALNODE', principal: 'hadoop_http_principal_name', keytab: 'hadoop_http_keytab', displayName: Em.I18n.t('admin.addSecurity.hdfs.user.httpUser') }, { componentName: 'WEBHCAT_SERVER', principal: 'webHCat_http_principal_name', keytab: 'webhcat_http_keytab', displayName: Em.I18n.t('admin.addSecurity.webhcat.user.httpUser') }, { componentName: 'HIVE_SERVER', principal: 'hive_metastore_http_principal_name', keytab: 'hive_metastore_http_keytab', displayName: Em.I18n.t('admin.addSecurity.hive.user.httpUser') }, { componentName: 'OOZIE_SERVER', principal: 'oozie_http_principal_name', keytab: 'oozie_http_keytab', displayName: Em.I18n.t('admin.addSecurity.oozie.user.httpUser') }, { componentName: 'FALCON_SERVER', principal: 'falcon_http_principal_name', keytab: 'falcon_http_keytab', displayName: Em.I18n.t('admin.addSecurity.falcon.user.httpUser') }, { componentName: 'HISTORYSERVER', principal: 'jobhistory_http_principal_name', keytab: 'jobhistory_http_keytab', displayName: Em.I18n.t('admin.addSecurity.historyServer.user.httpUser') }, { componentName: 'RESOURCEMANAGER', principal: 'resourcemanager_http_principal_name', keytab: 'resourcemanager_http_keytab', displayName: Em.I18n.t('admin.addSecurity.rm.user.httpUser') }, { componentName: 'NODEMANAGER', principal: 'nodemanager_http_principal_name', keytab: 'nodemanager_http_keytab', displayName: Em.I18n.t('admin.addSecurity.nm.user.httpUser') }, { componentName: 'APP_TIMELINE_SERVER', principal: 'apptimelineserver_http_principal_name', keytab: 'apptimelineserver_http_keytab', displayName: Em.I18n.t('admin.addSecurity.user.yarn.atsHTTPUser') }, { componentName: 'STORM_UI_SERVER', principal: 'storm_ui_principal_name', keytab: 'storm_ui_keytab', displayName: Em.I18n.t('admin.addSecurity.storm.user.httpUser'), isHadoop22Stack: true } ], mandatoryConfigs: [ { userConfig: 'smokeuser', keytab: 'smokeuser_keytab', displayName: Em.I18n.t('admin.addSecurity.user.smokeUser') }, { userConfig: 'hdfs_user', keytab: 'hdfs_user_keytab', displayName: Em.I18n.t('admin.addSecurity.user.hdfsUser'), checkService: 'HDFS' }, { userConfig: 'hbase_user', keytab: 'hbase_user_keytab', displayName: Em.I18n.t('admin.addSecurity.user.hbaseUser'), checkService: 'HBASE' } ], /** * download CSV file */ doDownloadCsv: function () { if ($.browser.msie && $.browser.version < 10) { this.openInfoInNewTab(); } else { try { var blob = new Blob([stringUtils.arrayToCSV(this.get('hostComponents'))], {type: "text/csv;charset=utf-8;"}); saveAs(blob, "host-principal-keytab-list.csv"); } catch (e) { this.openInfoInNewTab(); } } }, /** * open content of CSV file in new window */ openInfoInNewTab: function () { var newWindow = window.open(''); var newDocument = newWindow.document; newDocument.write(stringUtils.arrayToCSV(this.get('hostComponents'))); newWindow.focus(); }, /** * load hosts from server */ loadHosts: function () { App.ajax.send({ name: 'hosts.security.wizard', sender: this, data: {}, error: 'loadHostsErrorCallback', success: 'loadHostsSuccessCallback' }) }, loadHostsSuccessCallback: function (data, opt, params) { var hosts = []; data.items.forEach(function (item) { var hostComponents = []; item.host_components.forEach(function (hostComponent) { hostComponents.push(Em.Object.create({ componentName: hostComponent.HostRoles.component_name, service: Em.Object.create({ serviceName: hostComponent.HostRoles.service_name }), displayName: App.format.role(hostComponent.HostRoles.component_name) })); }); hosts.push(Em.Object.create({ hostName: item.Hosts.host_name, hostComponents: hostComponents })); }); this.set('isLoaded', true); this.set('hosts', hosts); this.loadStep(); }, loadHostsErrorCallback: function () { this.set('isLoaded', true); this.set('hosts', []); this.loadStep(); }, /** * load step info */ loadStep: function () { var hosts = this.get('hosts'); var result = []; var securityUsers = this.getSecurityUsers(); var hadoopGroupId = securityUsers.findProperty('name', 'user_group').value; var addedPrincipalsHost = {}; //Keys = host_principal, Value = 'true' hosts.forEach(function (host) { this.setMandatoryConfigs(result, securityUsers, host.get('hostName'), hadoopGroupId); this.setComponentsConfig(result, host, hadoopGroupId); this.setHostComponentsSecureValue(result, host, addedPrincipalsHost, securityUsers, hadoopGroupId); }, this); this.set('hostComponents', result); }, /** * Returns host name for Nimbus component */ getNimbusHostName: function () { var host = this.get('hosts').find(function (host) { return !!host.get('hostComponents').findProperty('componentName', 'NIMBUS'); }); if (host) { return host.get('hostName'); } }, /** * build map of connections between component and user * @param securityUsers */ buildComponentToOwnerMap: function (securityUsers) { var componentToUserMap = this.get('componentToUserMap'); var componentToOwnerMap = {}; for (var component in componentToUserMap) { var user = componentToUserMap[component]; var securityUser = securityUsers.findProperty('name', user); componentToOwnerMap[component] = securityUser.value; } return componentToOwnerMap; }, /** * set security settings(principal and keytab) to component depending on whether host has such component * @param result * @param host * @param hadoopGroupId */ setComponentsConfig: function (result, host, hadoopGroupId) { var hostComponents = host.get('hostComponents'); var isATSInstalled = this.get('content.isATSInstalled'); var doesATSSupportKerberos = App.get("doesATSSupportKerberos"); this.get('componentToConfigMap').forEach(function (component) { //add specific components that supported only in Hadoop2 stack if (component.isHadoop22Stack && !App.get('isHadoop22Stack')) return; if (hostComponents.someProperty('componentName', component.componentName)) { if (component.componentName === "APP_TIMELINE_SERVER" && (!isATSInstalled || !doesATSSupportKerberos)) { return; } var configs = this.get('content.serviceConfigProperties'); var serviceName = App.StackServiceComponent.find(component.componentName).get('serviceName'); var serviceConfigs = configs.filterProperty('serviceName', serviceName); var servicePrincipal = serviceConfigs.findProperty('name', component.principal); var serviceKeytabPath = serviceConfigs.findProperty('name', component.keytab).value; result.push({ host: host.get('hostName'), component: component.displayName, principal: this.getPrincipal(servicePrincipal, host.get('hostName')), keytabfile: stringUtils.getFileFromPath(serviceKeytabPath), keytab: stringUtils.getPath(serviceKeytabPath), owner: 'root', group: hadoopGroupId, acl: '440' }); } }, this); }, /** * set security settings(principal and keytab) to component * if checkService is passed then verify that service to his existence in order to set configs to such service * @param result * @param securityUsers * @param hostName * @param hadoopGroupId */ setMandatoryConfigs: function (result, securityUsers, hostName, hadoopGroupId) { var generalConfigs = this.get('content.serviceConfigProperties').filterProperty('serviceName', 'GENERAL'); var realm = generalConfigs.findProperty('name', 'kerberos_domain').value; var installedServices = App.Service.find().mapProperty('serviceName'); this.get('mandatoryConfigs').forEach(function (config) { if (config.checkService && !installedServices.contains(config.checkService)) return; var userId = securityUsers.findProperty('name', config.userConfig).value; var userKeytabPath = generalConfigs.findProperty('name', config.keytab).value; result.push({ host: hostName, component: config.displayName, principal: userId + '@' + realm, keytabFile: stringUtils.getFileFromPath(userKeytabPath), keytab: stringUtils.getPath(userKeytabPath), owner: userId, group: hadoopGroupId, acl: '440' }); }, this); }, /** * set secure properties(keytab and principal) for components, which should be displayed * @param result * @param host * @param addedPrincipalsHost * @param securityUsers * @param hadoopGroupId */ setHostComponentsSecureValue: function (result, host, addedPrincipalsHost, securityUsers, hadoopGroupId) { var componentsToDisplay = ['NAMENODE', 'SECONDARY_NAMENODE', 'DATANODE', 'JOBTRACKER', 'ZOOKEEPER_SERVER', 'HIVE_SERVER', 'HIVE_METASTORE', 'TASKTRACKER', 'OOZIE_SERVER', 'HBASE_MASTER', 'HBASE_REGIONSERVER', 'HISTORYSERVER', 'RESOURCEMANAGER', 'NODEMANAGER', 'JOURNALNODE', 'SUPERVISOR', 'NIMBUS', 'STORM_UI_SERVER','FALCON_SERVER', 'KNOX_GATEWAY', 'APP_TIMELINE_SERVER']; if (App.get('isHadoop22Stack')) { componentsToDisplay.push('DRPC_SERVER'); } var configs = this.get('content.serviceConfigProperties'); var componentToOwnerMap = this.buildComponentToOwnerMap(securityUsers); var hostName = host.get('hostName'); var isATSInstalled = this.get('content.isATSInstalled'); var doesATSSupportKerberos = App.get("doesATSSupportKerberos"); host.get('hostComponents').forEach(function (hostComponent) { if (componentsToDisplay.contains(hostComponent.get('componentName'))) { var serviceConfigs = configs.filterProperty('serviceName', hostComponent.get('service.serviceName')); var targetHost = hostName; if (App.get('isHadoop22Stack') && hostComponent.get('componentName') === 'DRPC_SERVER') { targetHost = this.getNimbusHostName() } var secureProperties = this.getSecureProperties(serviceConfigs, hostComponent.get('componentName'), targetHost); var displayName = this.changeDisplayName(hostComponent.get('displayName')); var key = hostName + "--" + secureProperties.principal; if (hostComponent.get('componentName') === "APP_TIMELINE_SERVER" && (!isATSInstalled || !doesATSSupportKerberos)) { return; } if (Em.isNone(addedPrincipalsHost[key])) { var owner = componentToOwnerMap[hostComponent.get('componentName')] || ''; result.push({ host: hostName, component: displayName, principal: secureProperties.principal, keytabFile: stringUtils.getFileFromPath(secureProperties.keytab), keytab: stringUtils.getPath(secureProperties.keytab), owner: owner, group: hadoopGroupId, acl: '400' }); addedPrincipalsHost[key] = true; } } }, this); }, /** * get properties (keytab and principle) of secure config that match component * @param serviceConfigs * @param componentName * @param hostName * @return {Object} */ getSecureProperties: function (serviceConfigs, componentName, hostName) { var secureProperties = {}; serviceConfigs.forEach(function (config) { if ((config.component && config.component === componentName) || (config.components && config.components.contains(componentName))) { if (config.name.endsWith('_principal_name')) { secureProperties.principal = this.getPrincipal(config, hostName); } else if (config.name.endsWith('_keytab') || config.name.endsWith('_keytab_path')) { secureProperties.keytab = config.value; } } }, this); return secureProperties; }, /** * get formatted principal value * @param config * @param hostName * @return {String} */ getPrincipal: function (config, hostName) { return config.value.replace('_HOST', hostName.toLowerCase()) + config.unit; }, /** * get users from security configs * @return {Array} */ getSecurityUsers: function () { return App.db.getSecureUserInfo(); }, /** * format display names of specific components * @param name * @return {*} */ changeDisplayName: function (name) { if (name === 'HiveServer2' || name === 'Hive Metastore') { return 'Hive Metastore and HiveServer2'; } else { return name; } } });