addSecurityConfigs.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. /**
  20. * Mixin for loading and setting secure configs
  21. *
  22. * @type {Ember.Mixin}
  23. */
  24. App.AddSecurityConfigs = Em.Mixin.create({
  25. secureProperties: function () {
  26. if (App.get('isHadoop2Stack')) {
  27. return require('data/HDP2/secure_properties').configProperties;
  28. } else {
  29. return require('data/secure_properties').configProperties;
  30. }
  31. }.property('App.isHadoop2Stack'),
  32. secureMapping: function () {
  33. return (App.get('isHadoop2Stack')) ? require('data/HDP2/secure_mapping') : require('data/secure_mapping');
  34. }.property('App.isHadoop2Stack'),
  35. serviceUsersBinding: 'App.router.mainAdminSecurityController.serviceUsers',
  36. componentsConfig: [
  37. {
  38. serviceName: 'OOZIE',
  39. componentName: 'OOZIE_SERVER',
  40. configName: 'oozieserver_host'
  41. },
  42. {
  43. serviceName: 'HIVE',
  44. componentName: 'HIVE_METASTORE',
  45. configName: 'hivemetastore_host'
  46. },
  47. {
  48. serviceName: 'HIVE',
  49. componentName: 'WEBHCAT_SERVER',
  50. configName: 'webhcat_server'
  51. }
  52. ],
  53. /**
  54. * mock users used in testMode
  55. */
  56. testModeUsers: [
  57. {
  58. name: 'hdfs_user',
  59. value: 'hdfs'
  60. },
  61. {
  62. name: 'mapred_user',
  63. value: 'mapred'
  64. },
  65. {
  66. name: 'hbase_user',
  67. value: 'hbase'
  68. },
  69. {
  70. name: 'hive_user',
  71. value: 'hive'
  72. }
  73. ],
  74. /**
  75. * security configs, which values should be modified after APPLY CONFIGURATIONS stage
  76. */
  77. secureConfigs: function () {
  78. var configs = [
  79. {
  80. name: 'nagios_principal_name',
  81. serviceName: 'NAGIOS'
  82. },
  83. {
  84. name: 'zookeeper_principal_name',
  85. serviceName: 'ZOOKEEPER'
  86. },
  87. {
  88. name: 'knox_principal_name',
  89. serviceName: 'KNOX'
  90. },
  91. {
  92. name: 'storm_principal_name',
  93. serviceName: 'STORM'
  94. }
  95. ];
  96. if (App.get('isHadoop22Stack')) {
  97. configs.push({
  98. name: 'nimbus_principal_name',
  99. serviceName: 'STORM'
  100. })
  101. }
  102. return configs;
  103. }.property('App.isHadoop22Stack'),
  104. secureServices: function() {
  105. return this.get('content.services');
  106. }.property('content.services'),
  107. /**
  108. * prepare secure configs
  109. */
  110. prepareSecureConfigs: function () {
  111. var configs = this.get('content.serviceConfigProperties');
  112. this.set('configs', configs);
  113. this.loadStaticConfigs(); //Hack for properties which are declared in site_properties.js and not able to retrieve values declared in secure_properties.js
  114. this.loadUsersToConfigs();
  115. this.loadHostNames();
  116. this.loadPrimaryNames();
  117. var uiConfigs = this.loadUiSideSecureConfigs();
  118. this.set('configs', this.get('configs').concat(uiConfigs));
  119. },
  120. /**
  121. * push users to configs
  122. */
  123. loadUsersToConfigs: function () {
  124. if (!this.get('serviceUsers').length) {
  125. this.loadUsersFromServer();
  126. }
  127. App.router.get('mainAdminSecurityController.serviceUsers').forEach(function (_user) {
  128. this.get('configs').pushObject(_user);
  129. }, this);
  130. },
  131. /**
  132. * add component config that contain host name as value
  133. * @param serviceName
  134. * @param componentName
  135. * @param configName
  136. * @return {Boolean}
  137. */
  138. addHostConfig: function (serviceName, componentName, configName) {
  139. var service = App.Service.find(serviceName);
  140. var isServiceSecure = this.get('secureServices').someProperty('serviceName', serviceName);
  141. if (service.get('isLoaded') && isServiceSecure) {
  142. var hostComponent = service.get('hostComponents').findProperty('componentName', componentName);
  143. if (hostComponent) {
  144. var hostName = hostComponent.get('hostName');
  145. this.get('configs').push({
  146. id: 'puppet var',
  147. name: configName,
  148. value: hostName
  149. });
  150. return true;
  151. }
  152. }
  153. return false;
  154. },
  155. /**
  156. * add hosts' names to configs
  157. */
  158. loadHostNames: function () {
  159. var componentsConfig = this.get('componentsConfig');
  160. componentsConfig.forEach(function (host) {
  161. this.addHostConfig(host.serviceName, host.componentName, host.configName);
  162. }, this);
  163. },
  164. /**
  165. * load static configs
  166. */
  167. loadStaticConfigs: function () {
  168. this.get('configs').forEach(function (_property) {
  169. switch (_property.name) {
  170. case 'security_enabled':
  171. _property.value = 'true';
  172. break;
  173. }
  174. }, this);
  175. },
  176. /**
  177. * add principals to properties
  178. */
  179. loadPrimaryNames: function () {
  180. var principalProperties = this.getPrincipalNames();
  181. principalProperties.forEach(function (_principalProperty) {
  182. var name = _principalProperty.name.replace('principal', 'primary');
  183. var value = _principalProperty.value.split('/')[0];
  184. this.get('configs').push({name: name, value: value});
  185. }, this);
  186. },
  187. /**
  188. * gather and return properties with "principal_name"
  189. * @return {Array}
  190. */
  191. getPrincipalNames: function () {
  192. var principalNames = [];
  193. this.get('configs').forEach(function (_property) {
  194. if (/principal_name?$/.test(_property.name)) {
  195. principalNames.push(_property);
  196. }
  197. }, this);
  198. this.get('secureProperties').forEach(function (_secureProperty) {
  199. if (/principal_name?$/.test(_secureProperty.name)) {
  200. var principalName = principalNames.findProperty('name', _secureProperty.name);
  201. if (!principalName) {
  202. _secureProperty.value = _secureProperty.defaultValue;
  203. principalNames.push(_secureProperty);
  204. }
  205. }
  206. }, this);
  207. return principalNames;
  208. },
  209. /**
  210. * load users from server
  211. */
  212. loadUsersFromServer: function () {
  213. if (App.get('testMode')) {
  214. var serviceUsers = this.get('serviceUsers');
  215. this.get('testModeUsers').forEach(function (user) {
  216. user.id = 'puppet var';
  217. serviceUsers.push(user);
  218. }, this);
  219. } else {
  220. App.router.set('mainAdminSecurityController.serviceUsers', App.db.getSecureUserInfo());
  221. }
  222. },
  223. /**
  224. * load configs from UI side
  225. * @return {Array}
  226. */
  227. loadUiSideSecureConfigs: function () {
  228. var uiConfig = [];
  229. var configs = this.get('secureMapping').filterProperty('foreignKey', null).filter(function(_configProperty){
  230. return (App.Service.find().mapProperty('serviceName').contains(_configProperty.serviceName));
  231. },this);
  232. configs.forEach(function (_config) {
  233. var value = _config.value;
  234. if (_config.hasOwnProperty('dependedServiceName')) {
  235. value = this.checkServiceForConfigValue(value, _config.dependedServiceName);
  236. }
  237. value = this.getConfigValue(_config.templateName, value);
  238. uiConfig.push({
  239. "id": "site property",
  240. "name": _config.name,
  241. "value": value,
  242. "filename": _config.filename
  243. });
  244. }, this);
  245. var dependentConfig = this.get('secureMapping').filterProperty('foreignKey');
  246. dependentConfig.forEach(function (_config) {
  247. if (App.Service.find().mapProperty('serviceName').contains(_config.serviceName)) {
  248. this.setConfigValue(_config);
  249. this.formatConfigName(uiConfig, _config);
  250. uiConfig.push({
  251. "id": "site property",
  252. "name": _config._name || _config.name,
  253. "value": _config.value,
  254. "filename": _config.filename
  255. });
  256. }
  257. }, this);
  258. return uiConfig;
  259. },
  260. /**
  261. * erase template rules from config value if service is not loaded
  262. * @param value
  263. * @param services
  264. * @return {*}
  265. */
  266. checkServiceForConfigValue: function (value, services) {
  267. services.forEach(function (_service) {
  268. if (!App.Service.find(_service.name).get('isLoaded')) {
  269. value = value.replace(_service.replace, '');
  270. }
  271. }, this);
  272. return value;
  273. },
  274. /**
  275. * Set all site property that are derived from other puppet-variable
  276. * @param templateName
  277. * @param expression
  278. * @return {String|null}
  279. */
  280. getConfigValue: function (templateName, expression) {
  281. var express = expression.match(/<(.*?)>/g);
  282. var value = expression;
  283. if (Em.isNone(express)) return expression;
  284. express.forEach(function (_express) {
  285. var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
  286. var configs = this.get('configs').findProperty('name', templateName[index]);
  287. if (!!value) {
  288. value = (configs) ? value.replace(_express, configs.value) : null;
  289. }
  290. }, this);
  291. return value;
  292. },
  293. /**
  294. * format name of config values of configs which match foreignKey
  295. * @param uiConfig
  296. * @param config
  297. * @return {Boolean}
  298. */
  299. formatConfigName: function (uiConfig, config) {
  300. if (Em.isNone(config.value)) return false;
  301. var fkValue = config.name.match(/<(foreignKey.*?)>/g);
  302. if (fkValue) {
  303. fkValue.forEach(function (_fkValue) {
  304. var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]);
  305. var value;
  306. if (uiConfig.someProperty('name', config.foreignKey[index])) {
  307. value = uiConfig.findProperty('name', config.foreignKey[index]).value;
  308. config._name = config.name.replace(_fkValue, value);
  309. } else if (this.get('configs').someProperty('name', config.foreignKey[index])) {
  310. value = this.get('configs').findProperty('name', config.foreignKey[index]).value;
  311. config._name = config.name.replace(_fkValue, value);
  312. }
  313. }, this);
  314. return true;
  315. }
  316. return false;
  317. },
  318. /**
  319. * Set config value with values of configs which match template
  320. * @param config
  321. * @return {Boolean}
  322. */
  323. setConfigValue: function (config) {
  324. if (Em.isNone(config.value)) return false;
  325. //For properties in the configMapping file having foreignKey and templateName properties.
  326. var templateValue = config.value.match(/<(templateName.*?)>/g);
  327. if (templateValue) {
  328. templateValue.forEach(function (_value) {
  329. var index = parseInt(_value.match(/\[([\d]*)(?=\])/)[1]);
  330. var cfgValue = this.get('configs').findProperty('name', config.templateName[index]);
  331. config.value = (cfgValue) ? config.value.replace(_value, cfgValue.value) : null;
  332. }, this);
  333. return true;
  334. }
  335. return false;
  336. },
  337. /**
  338. * set value of principal property
  339. * @param serviceName
  340. * @param principalName
  341. * @return {Boolean}
  342. */
  343. setPrincipalValue: function (serviceName, principalName) {
  344. var siteProperties = this.get('configs');
  345. var realmName = siteProperties.findProperty('name', 'kerberos_domain');
  346. if (this.get('secureServices').someProperty('serviceName', serviceName)) {
  347. var principalProperty = siteProperties.findProperty('name', principalName);
  348. principalProperty.value = principalProperty.value + '@' + realmName.value;
  349. return true;
  350. }
  351. return false;
  352. }
  353. });