config.js 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668
  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. var stringUtils = require('utils/string_utils');
  20. var configPropertyHelper = require('utils/configs/config_property_helper');
  21. App.config = Em.Object.create({
  22. CONFIG_GROUP_NAME_MAX_LENGTH: 18,
  23. /**
  24. * filename exceptions used to support substandard sitenames which don't have "xml" extension
  25. * @type {string[]}
  26. */
  27. filenameExceptions: [],
  28. preDefinedServiceConfigs: [],
  29. /**
  30. *
  31. * Returns file name version that stored on server.
  32. *
  33. * Example:
  34. * App.config.getOriginalFileName('core-site') // returns core-site.xml
  35. * App.config.getOriginalFileName('zoo.cfg') // returns zoo.cfg
  36. *
  37. * @param {String} fileName
  38. * @method getOriginalFileName
  39. **/
  40. getOriginalFileName: function (fileName) {
  41. if (/\.xml$/.test(fileName)) return fileName;
  42. return this.get('filenameExceptions').contains(fileName) ? fileName : fileName + '.xml';
  43. },
  44. /**
  45. * Check if Hive installation with new MySQL database created via Ambari is allowed
  46. * @param osFamily
  47. * @returns {boolean}
  48. */
  49. isManagedMySQLForHiveAllowed: function (osFamily) {
  50. var osList = ['redhat5', 'suse11'];
  51. return !osList.contains(osFamily);
  52. },
  53. /**
  54. *
  55. * Returns the configuration tagName from supplied filename
  56. *
  57. * Example:
  58. * App.config.getConfigTagFromFileName('core-site.xml') // returns core-site
  59. * App.config.getConfigTagFromFileName('zoo.cfg') // returns zoo.cfg
  60. *
  61. * @param {String} fileName
  62. * @method getConfigTagFromFileName
  63. **/
  64. getConfigTagFromFileName: function (fileName) {
  65. return fileName.endsWith('.xml') ? fileName.slice(0, -4) : fileName;
  66. },
  67. setPreDefinedServiceConfigs: function (isMiscTabToBeAdded) {
  68. var configs = this.get('preDefinedSiteProperties');
  69. var services = [];
  70. var self = this;
  71. var stackServices = App.StackService.find().filterProperty('id');
  72. // Only include services that has configTypes related to them for service configuration page
  73. var servicesWithConfigTypes = stackServices.filter(function (service) {
  74. var configtypes = service.get('configTypes');
  75. return configtypes && !!Object.keys(configtypes).length;
  76. }, this);
  77. var allTabs;
  78. if (isMiscTabToBeAdded) {
  79. var nonServiceTab = require('data/service_configs');
  80. var miscService = nonServiceTab.findProperty('serviceName', 'MISC');
  81. var tagTypes = {};
  82. servicesWithConfigTypes.mapProperty('configTypes').forEach(function (configTypes) {
  83. for (var fileName in configTypes) {
  84. if (fileName.endsWith('-env') && !miscService.get('configTypes')[fileName]) {
  85. tagTypes[fileName] = configTypes[fileName];
  86. }
  87. }
  88. });
  89. miscService.set('configTypes', $.extend(miscService.get('configTypes'), tagTypes));
  90. allTabs = servicesWithConfigTypes.concat(nonServiceTab);
  91. } else {
  92. allTabs = servicesWithConfigTypes;
  93. }
  94. allTabs.forEach(function (service) {
  95. var configTypes = Em.keys(service.get('configTypes'));
  96. // filter properties by service name and service config types
  97. var serviceConfigs = configs.filterProperty('serviceName', service.get('serviceName')).filter(function(property) {
  98. var propFilename = self.getConfigTagFromFileName(Em.getWithDefault(property, 'filename', ''));
  99. if (propFilename && service.get('serviceName') != 'MISC') {
  100. return configTypes.contains(propFilename);
  101. }
  102. return true;
  103. });
  104. service.set('configs', serviceConfigs);
  105. services.push(service);
  106. });
  107. this.set('preDefinedServiceConfigs', services);
  108. },
  109. configMapping: require('data/HDP2/config_mapping'),
  110. preDefinedSiteProperties: function () {
  111. var sitePropertiesForCurrentStack = this.preDefinedConfigFile('site_properties');
  112. if (sitePropertiesForCurrentStack) {
  113. return sitePropertiesForCurrentStack.configProperties;
  114. }
  115. if (App.get('isHadoop23Stack')) {
  116. return require('data/HDP2.3/site_properties').configProperties;
  117. }
  118. if (App.get('isHadoop22Stack')) {
  119. return require('data/HDP2.2/site_properties').configProperties;
  120. }
  121. return require('data/HDP2/site_properties').configProperties;
  122. }.property('App.isHadoop22Stack', 'App.isHadoop23Stack'),
  123. preDefinedConfigFile: function(file) {
  124. try {
  125. return require('data/{0}/{1}'.format(App.get('currentStackName'), file));
  126. } catch (err) {
  127. // the file doesn't exist, which might be expected.
  128. }
  129. },
  130. /**
  131. * Create array of service properties for Log4j files
  132. * @returns {Array}
  133. */
  134. createContentProperties: function (configs) {
  135. var services = App.StackService.find();
  136. var contentProperties = [];
  137. if (configs) {
  138. services.forEach(function (service) {
  139. if (service.get('configTypes')) {
  140. Object.keys(service.get('configTypes')).forEach(function (type) {
  141. var contentProperty = configs.filterProperty('filename', type + '.xml').someProperty('name', 'content');
  142. if (contentProperty && (type.endsWith('-log4j') || type.endsWith('-env'))) {
  143. var property = {
  144. "id": "site property",
  145. "name": "content",
  146. "displayName": type.endsWith('-env') ? type + ' template' : "content",
  147. "value": "",
  148. "description": type + " properties",
  149. "displayType": "content",
  150. "isOverridable": true,
  151. "isRequired": false,
  152. "isVisible": true,
  153. "showLabel": type.endsWith('-env'),
  154. "serviceName": service.get('serviceName'),
  155. "filename": type + '.xml',
  156. "category": "Advanced " + type
  157. };
  158. contentProperties.pushObject(property);
  159. }
  160. }, this);
  161. }
  162. }, this);
  163. }
  164. return contentProperties;
  165. },
  166. //configs with these filenames go to appropriate category not in Advanced
  167. customFileNames: ['flume-conf.xml'],
  168. /**
  169. * Function should be used post-install as precondition check should not be done only after installer wizard
  170. * @param siteNames {String|Array}
  171. * @returns {Array}
  172. */
  173. getBySiteName: function (siteNames) {
  174. var computedConfigs = this.get('configMapping').computed();
  175. var siteProperties = [];
  176. if (typeof siteNames === "string") {
  177. siteProperties = computedConfigs.filterProperty('filename', siteNames);
  178. } else if (siteNames instanceof Array) {
  179. siteNames.forEach(function (_siteName) {
  180. siteProperties = siteProperties.concat(computedConfigs.filterProperty('filename', _siteName));
  181. }, this);
  182. }
  183. return siteProperties;
  184. },
  185. /**
  186. * identify category by filename of config
  187. * @param config
  188. * @return {object|null}
  189. */
  190. identifyCategory: function (config) {
  191. var category = null,
  192. serviceConfigMetaData = this.get('preDefinedServiceConfigs').findProperty('serviceName', Em.get(config, 'serviceName')),
  193. configCategories = (serviceConfigMetaData && serviceConfigMetaData.get('configCategories')) || [];
  194. if (Em.get(config, 'filename') && Em.get(config, 'filename').contains("env")) {
  195. if (Em.get(config, 'category')) {
  196. category = configCategories.findProperty("name", Em.get(config, 'category'));
  197. } else {
  198. configCategories.forEach(function (_category) {
  199. if (_category.name.contains(this.getConfigTagFromFileName(Em.get(config, 'filename')))) {
  200. category = _category;
  201. }
  202. }, this);
  203. }
  204. } else {
  205. configCategories.forEach(function (_category) {
  206. if (_category.siteFileNames && Array.isArray(_category.siteFileNames) && _category.siteFileNames.contains(Em.get(config, 'filename'))) {
  207. category = _category;
  208. }
  209. });
  210. category = Em.isNone(category) ? configCategories.findProperty('siteFileName', this.getOriginalFileName(Em.get(config, 'filename'))) : category;
  211. }
  212. return category;
  213. },
  214. /**
  215. * additional handling for special properties such as
  216. * checkbox and digital which values with 'm' at the end
  217. * @param config
  218. */
  219. handleSpecialProperties: function (config) {
  220. if (Em.get(config, 'displayType') === 'int' && /\d+m$/.test(Em.get(config, 'value') )) {
  221. Em.set(config, 'value', Em.get(config, 'value').slice(0, Em.get(config, 'value.length') - 1));
  222. Em.set(config, 'savedValue', Em.get(config, 'value'));
  223. }
  224. },
  225. /**
  226. * calculate config properties:
  227. * category, filename, description
  228. * @param config
  229. * @param isAdvanced
  230. * @param advancedProperty
  231. */
  232. calculateConfigProperties: function (config, isAdvanced, advancedProperty) {
  233. if (!isAdvanced || this.get('customFileNames').contains(Em.get(config, 'filename'))) {
  234. var categoryMetaData = this.identifyCategory(config);
  235. if (categoryMetaData != null) {
  236. Em.set(config, 'category', categoryMetaData.get('name'));
  237. }
  238. } else {
  239. var configType = this.getConfigTagFromFileName(Em.get(config, 'filename'));
  240. Em.set(config, 'category', Em.get(config, 'category') ? Em.get(config, 'category') : 'Advanced ' + configType);
  241. }
  242. if (advancedProperty) {
  243. Em.set(config, 'description', Em.get(advancedProperty, 'description'));
  244. }
  245. },
  246. /**
  247. * get service for current config type
  248. * @param {String} configType - config fileName without xml
  249. * @return App.StackService
  250. */
  251. getServiceByConfigType: function(configType) {
  252. return App.StackService.find().find(function(s) {
  253. return Object.keys(s.get('configTypes')).contains(configType);
  254. });
  255. },
  256. /**
  257. * return:
  258. * configs,
  259. * mappingConfigs
  260. *
  261. * @param configCategories
  262. * @param advancedConfigs
  263. * @param tags
  264. * @param serviceName
  265. * @return {object}
  266. */
  267. mergePreDefinedWithLoaded: function (configCategories, advancedConfigs, tags, serviceName) {
  268. var configs = [];
  269. var contentProperties = this.createContentProperties(advancedConfigs);
  270. var preDefinedConfigs = this.get('preDefinedSiteProperties').concat(contentProperties);
  271. var mappingConfigs = [];
  272. var filenameExceptions = this.get('filenameExceptions');
  273. tags.forEach(function (_tag) {
  274. var service = this.getServiceByConfigType(_tag.siteName);
  275. if (service) {
  276. serviceName = service.get('serviceName');
  277. }
  278. var filename = App.config.getOriginalFileName(_tag.siteName);
  279. var siteConfig = configCategories.filter(function (serviceConfigProperties) {
  280. return _tag.tagName === serviceConfigProperties.tag && _tag.siteName === serviceConfigProperties.type;
  281. });
  282. siteConfig = siteConfig[0] || {};
  283. var attributes = siteConfig['properties_attributes'] || {};
  284. var finalAttributes = attributes.final || {};
  285. var properties = siteConfig.properties || {};
  286. for (var index in properties) {
  287. var configsPropertyDef = preDefinedConfigs.filterProperty('name', index).findProperty('filename', filename);
  288. var advancedConfig = advancedConfigs.filterProperty('name', index).findProperty('filename', filename);
  289. var isAdvanced = Boolean(advancedConfig);
  290. if (!configsPropertyDef) {
  291. configsPropertyDef = advancedConfig;
  292. }
  293. var value = this.parseValue(properties[index], configsPropertyDef, advancedConfig);
  294. var serviceConfigObj = App.ServiceConfig.create({
  295. name: index,
  296. value: value,
  297. savedValue: value,
  298. recommendedValue: advancedConfig ? Em.get(advancedConfig, 'recommendedValue') : null,
  299. filename: filename,
  300. isUserProperty: !advancedConfig,
  301. isVisible: !!service,
  302. isOverridable: true,
  303. isReconfigurable: true,
  304. isRequired: isAdvanced,
  305. isFinal: finalAttributes[index] === "true",
  306. savedIsFinal: finalAttributes[index] === "true",
  307. recommendedIsFinal: advancedConfig ? Em.get(advancedConfig, 'recommendedIsFinal') : null,
  308. showLabel: true,
  309. serviceName: serviceName,
  310. belongsToService: [],
  311. supportsFinal: advancedConfig ? Em.get(advancedConfig, 'supportsFinal') : this.shouldSupportFinal(serviceName, _tag.siteName)
  312. });
  313. if (configsPropertyDef) {
  314. this.setServiceConfigUiAttributes(serviceConfigObj, configsPropertyDef);
  315. // check if defined UI config present in config list obtained from server.
  316. // in case when config is absent on server and defined UI config is required
  317. // by server, this config should be ignored
  318. var serverProperty = properties[serviceConfigObj.get('name')];
  319. if (Em.isNone(serverProperty) && serviceConfigObj.get('isRequiredByAgent')) {
  320. continue;
  321. }
  322. }
  323. this.tweakConfigVisibility(serviceConfigObj, properties);
  324. if (!this.getBySiteName(serviceConfigObj.get('filename')).someProperty('name', index)) {
  325. if (configsPropertyDef) {
  326. if (Em.get(configsPropertyDef, 'isRequiredByAgent') === false) {
  327. configs.push(serviceConfigObj);
  328. continue;
  329. }
  330. this.handleSpecialProperties(serviceConfigObj);
  331. } else {
  332. serviceConfigObj.set('displayType', stringUtils.isSingleLine(serviceConfigObj.get('value')) ? 'advanced' : 'multiLine');
  333. }
  334. serviceConfigObj.setProperties({
  335. 'id': 'site property',
  336. 'displayName': configsPropertyDef && Em.get(configsPropertyDef, 'displayName') ? Em.get(configsPropertyDef, 'displayName') : index,
  337. 'options': configsPropertyDef ? Em.get(configsPropertyDef, 'options') : null,
  338. 'radioName': configsPropertyDef ? Em.get(configsPropertyDef, 'radioName') : null,
  339. 'serviceName': configsPropertyDef && Em.get(configsPropertyDef, 'serviceName') ? Em.get(configsPropertyDef, 'serviceName') : serviceName,
  340. 'belongsToService': configsPropertyDef && Em.get(configsPropertyDef, 'belongsToService') ? Em.get(configsPropertyDef, 'belongsToService') : []
  341. });
  342. this.calculateConfigProperties(serviceConfigObj, isAdvanced, advancedConfig);
  343. this.setValueByDisplayType(serviceConfigObj);
  344. configs.push(serviceConfigObj);
  345. } else {
  346. mappingConfigs.push(serviceConfigObj);
  347. }
  348. }
  349. }, this);
  350. return {
  351. configs: configs,
  352. mappingConfigs: mappingConfigs
  353. }
  354. },
  355. /**
  356. * additional parsing when value is int of float
  357. * ex: if value is "0.40" result will be "0.4"
  358. * @param value
  359. * @param predefinedConfig
  360. * @param advancedConfig
  361. * @returns {String}
  362. */
  363. parseValue: function(value, predefinedConfig, advancedConfig) {
  364. var type = predefinedConfig ? Em.get(predefinedConfig, 'displayType') :
  365. advancedConfig && Em.get(advancedConfig, 'valueAttributes.type');
  366. switch (type) {
  367. case 'int':
  368. var res = parseInt(value);
  369. return isNaN(res) ? "" : res.toString();
  370. case 'float':
  371. var res = parseFloat(value);
  372. return isNaN(res) ? "" : res.toString();
  373. default:
  374. return value;
  375. }
  376. },
  377. tweakConfigVisibility: function (config, allSiteConfigs) {
  378. var kdcType = allSiteConfigs['kdc_type'];
  379. if (kdcType === 'active-directory' && ['container_dn', 'ldap_url'].contains(Em.get(config, 'name'))) {
  380. Em.set(config, 'isVisible', true);
  381. }
  382. },
  383. setValueByDisplayType: function (serviceConfigObj) {
  384. if (serviceConfigObj.get('displayType') == 'directories' && (serviceConfigObj.get('category') == 'DataNode' || serviceConfigObj.get('category') == 'NameNode')) {
  385. var dirs = serviceConfigObj.get('value').split(',').sort();
  386. serviceConfigObj.set('value', dirs.join(','));
  387. serviceConfigObj.set('savedValue', dirs.join(','));
  388. }
  389. if (serviceConfigObj.get('displayType') == 'directory' && serviceConfigObj.get('category') == 'SNameNode') {
  390. var dirs = serviceConfigObj.get('value').split(',').sort();
  391. serviceConfigObj.set('value', dirs[0]);
  392. serviceConfigObj.set('savedValue', dirs[0]);
  393. }
  394. if (serviceConfigObj.get('displayType') == 'masterHosts') {
  395. if (typeof(serviceConfigObj.get('value')) == 'string') {
  396. var value = serviceConfigObj.get('value').replace(/\[|]|'|'/g, "").split(',');
  397. serviceConfigObj.set('value', value);
  398. }
  399. }
  400. },
  401. /**
  402. * @param serviceConfigObj : Object
  403. * @param configsPropertyDef : Object
  404. */
  405. setServiceConfigUiAttributes: function (serviceConfigObj, configsPropertyDef) {
  406. serviceConfigObj.setProperties({
  407. 'displayType': Em.get(configsPropertyDef, 'displayType'),
  408. 'isRequired': (Em.get(configsPropertyDef, 'isRequired') !== undefined) ? Em.get(configsPropertyDef, 'isRequired') : true,
  409. 'isRequiredByAgent': (Em.get(configsPropertyDef, 'isRequiredByAgent') !== undefined) ? Em.get(configsPropertyDef, 'isRequiredByAgent') : true,
  410. 'isReconfigurable': (Em.get(configsPropertyDef, 'isReconfigurable') !== undefined) ? Em.get(configsPropertyDef, 'isReconfigurable') : true,
  411. 'isVisible': (Em.get(configsPropertyDef, 'isVisible') !== undefined) ? Em.get(configsPropertyDef, 'isVisible') : true,
  412. 'unit': Em.get(configsPropertyDef, 'unit'),
  413. 'description': Em.get(configsPropertyDef, 'description'),
  414. 'isOverridable': Em.get(configsPropertyDef, 'isOverridable') === undefined ? true : Em.get(configsPropertyDef, 'isOverridable'),
  415. 'serviceName': configsPropertyDef ? Em.get(configsPropertyDef, 'serviceName') : serviceConfigObj.get('serviceName'),
  416. 'index': Em.get(configsPropertyDef, 'index'),
  417. 'isSecureConfig': Em.get(configsPropertyDef, 'isSecureConfig') === undefined ? false : Em.get(configsPropertyDef, 'isSecureConfig'),
  418. 'belongsToService': Em.get(configsPropertyDef, 'belongsToService'),
  419. 'category': Em.get(configsPropertyDef, 'category'),
  420. 'showLabel': Em.get(configsPropertyDef, 'showLabel') !== false,
  421. 'dependentConfigPattern': Em.get(configsPropertyDef, 'dependentConfigPattern')
  422. });
  423. },
  424. /**
  425. * synchronize order of config properties with order, that on UI side
  426. *
  427. * @method syncOrderWithPredefined
  428. * @param configSet {object}
  429. * @return {Object}
  430. */
  431. syncOrderWithPredefined: function (configSet) {
  432. var siteConfigs = configSet.configs,
  433. siteStart = [];
  434. var preDefinedSiteProperties = this.get('preDefinedSiteProperties').mapProperty('name');
  435. var contentProperties = this.createContentProperties(siteConfigs).mapProperty('name');
  436. var siteProperties = preDefinedSiteProperties.concat(contentProperties);
  437. siteProperties.forEach(function (name) {
  438. var _site = siteConfigs.filterProperty('name', name);
  439. if (_site.length == 1) {
  440. siteStart.push(_site[0]);
  441. siteConfigs = siteConfigs.without(_site[0]);
  442. } else if (_site.length > 1) {
  443. _site.forEach(function (site) {
  444. siteStart.push(site);
  445. siteConfigs = siteConfigs.without(site);
  446. }, this);
  447. }
  448. }, this);
  449. return {
  450. configs: siteStart.concat(siteConfigs.sortProperty('name')),
  451. mappingConfigs: configSet.mappingConfigs
  452. };
  453. },
  454. /**
  455. * merge stored configs with pre-defined
  456. * @param storedConfigs
  457. * @param advancedConfigs
  458. * @param selectedServiceNames
  459. * @return {Array}
  460. */
  461. mergePreDefinedWithStored: function (storedConfigs, advancedConfigs, selectedServiceNames) {
  462. var mergedConfigs = [];
  463. var contentProperties = advancedConfigs ? this.createContentProperties(advancedConfigs) : [];
  464. var preDefinedConfigs = this.get('preDefinedSiteProperties').concat(contentProperties);
  465. var self = this;
  466. storedConfigs = (storedConfigs) ? storedConfigs : [];
  467. var preDefinedNames = preDefinedConfigs.mapProperty('name');
  468. var storedNames = storedConfigs.mapProperty('name');
  469. var names = preDefinedNames.concat(storedNames).uniq();
  470. var configTypes = App.StackService.find().filter(function(service) {
  471. return selectedServiceNames.contains(service.get('serviceName'));
  472. }).map(function(item) {
  473. return Em.keys(item.get('configTypes'));
  474. }).reduce(function(p,c) { return p.concat(c); })
  475. .uniq().compact().filter(function(configType) { return !!configType; });
  476. names.forEach(function (name) {
  477. var storedCfgs = storedConfigs.filterProperty('name', name);
  478. var preDefinedCfgs = [];
  479. var preDefinedConfig = preDefinedConfigs.filterProperty('name', name);
  480. preDefinedConfig.forEach(function (_preDefinedConfig) {
  481. if (selectedServiceNames.contains(_preDefinedConfig.serviceName) || _preDefinedConfig.serviceName === 'MISC') {
  482. if (_preDefinedConfig.serviceName != 'MISC' && _preDefinedConfig.filename && !configTypes.contains(self.getConfigTagFromFileName(_preDefinedConfig.filename))) {
  483. return;
  484. }
  485. preDefinedCfgs.push(_preDefinedConfig);
  486. }
  487. }, this);
  488. var configData = {};
  489. var isAdvanced = advancedConfigs && advancedConfigs.someProperty('name', name);
  490. if (storedCfgs.length <= 1 && preDefinedCfgs.length <= 1) {
  491. var stored = storedCfgs[0];
  492. var preDefined = preDefinedCfgs[0];
  493. if (preDefined && stored) {
  494. configData = preDefined;
  495. configData.value = stored.value;
  496. configData.savedValue = stored.savedValue;
  497. configData.recommendedValue = stored.recommendedValue;
  498. configData.overrides = stored.overrides;
  499. configData.displayName = stored.displayName;
  500. configData.name = stored.name;
  501. configData.filename = stored.filename;
  502. configData.description = stored.description;
  503. configData.isVisible = stored.isVisible;
  504. configData.isFinal = stored.isFinal;
  505. configData.supportsFinal = stored.supportsFinal;
  506. configData.isRequired = (configData.isRequired !== undefined) ? configData.isRequired : true;
  507. configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
  508. configData.showLabel = !!stored.showLabel;
  509. }
  510. else if (!preDefined && stored) {
  511. configData = this.addUserProperty(stored, isAdvanced, advancedConfigs);
  512. }
  513. else if (preDefined && !stored) {
  514. configData = preDefined;
  515. // skip property if predefined config doesn't exist or ignored in stack property definition for current stack.
  516. // if `isRequiredByAgent` is set to `false` then this property used by UI only to display properties like
  517. // host names or some misc properties that won't be persisted.
  518. if (Em.get(preDefined, 'isRequiredByAgent') !== false && !isAdvanced &&
  519. Em.get(preDefined, 'filename') != 'alert_notification' &&
  520. ![
  521. 'hive_hostname',
  522. 'oozie_hostname',
  523. 'hive_existing_oracle_host',
  524. 'hive_existing_postgresql_host',
  525. 'hive_existing_mysql_host',
  526. 'hive_existing_mssql_server_host',
  527. 'hive_existing_mssql_server_2_host',
  528. 'oozie_existing_oracle_host',
  529. 'oozie_existing_postgresql_host',
  530. 'oozie_existing_mysql_host',
  531. 'oozie_existing_mssql_server_host',
  532. 'oozie_existing_mssql_server_2_host'
  533. ].contains(Em.get(preDefined, 'name'))) {
  534. return;
  535. }
  536. configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
  537. if (isAdvanced) {
  538. var advanced = advancedConfigs.filterProperty('filename', configData.filename).findProperty('name', configData.name);
  539. this.setPropertyFromStack(configData, advanced);
  540. }
  541. }
  542. mergedConfigs.push(configData);
  543. } else {
  544. preDefinedCfgs.forEach(function (cfg) {
  545. configData = cfg;
  546. configData.isRequiredByAgent = (configData.isRequiredByAgent !== undefined) ? configData.isRequiredByAgent : true;
  547. var storedCfg = storedCfgs.findProperty('filename', cfg.filename);
  548. if (storedCfg) {
  549. configData.value = storedCfg.value;
  550. configData.recommendedValue = storedCfg.recommendedValue;
  551. configData.savedValue = storedCfg.savedValue;
  552. configData.overrides = storedCfg.overrides;
  553. configData.filename = storedCfg.filename;
  554. configData.description = storedCfg.description;
  555. configData.isFinal = storedCfg.isFinal;
  556. configData.supportsFinal = storedCfg.supportsFinal;
  557. configData.showLabel = !!storedCfg.showLabel;
  558. configData.displayName = storedCfg.displayName;
  559. } else if (isAdvanced) {
  560. advanced = advancedConfigs.filterProperty('filename', configData.filename).findProperty('name', configData.name);
  561. this.setPropertyFromStack(configData, advanced);
  562. }
  563. mergedConfigs.push(configData);
  564. }, this);
  565. }
  566. }, this);
  567. return mergedConfigs;
  568. },
  569. /**
  570. *
  571. * @param configData {Object} Configs that will be bound to the view on step-7 of installer wizard
  572. * @param advanced {Object} Config property loaded from Server side stack definition
  573. */
  574. setPropertyFromStack: function (configData, advanced) {
  575. // Password fields should be made blank by default in installer wizard
  576. // irrespective of whatever value is sent from stack definition.
  577. // This forces the user to fill the password field.
  578. if (configData.displayType == 'password') {
  579. configData.value = '';
  580. } else {
  581. configData.value = advanced ? advanced.value : configData.value;
  582. }
  583. configData.recommendedValue = configData.value;
  584. configData.filename = advanced ? advanced.filename : configData.filename;
  585. configData.displayName = advanced && advanced.displayName ? advanced.displayName : configData.displayName;
  586. configData.name = advanced && advanced.name ? advanced.name : configData.name;
  587. configData.description = advanced ? advanced.description : configData.description;
  588. configData.isFinal = !!(advanced && (advanced.isFinal === "true"));
  589. configData.supportsFinal = !!(advanced && advanced.supportsFinal);
  590. },
  591. /**
  592. * look over advanced configs and add missing configs to serviceConfigs
  593. * filter fetched configs by service if passed
  594. * @param serviceConfigs
  595. * @param advancedConfigs
  596. * @param serviceName
  597. */
  598. addAdvancedConfigs: function (serviceConfigs, advancedConfigs, serviceName) {
  599. var miscConfigs = serviceConfigs.filterProperty('serviceName', 'MISC');
  600. var configsToVerifying = (serviceName) ? serviceConfigs.filterProperty('serviceName', serviceName).concat(miscConfigs) : serviceConfigs.slice();
  601. var definedService = this.get('preDefinedServiceConfigs').findProperty('serviceName', serviceName);
  602. if (definedService) {
  603. var definedConfigs = (serviceName) ? definedService.get('configs') : [];
  604. if (definedConfigs.length) {
  605. advancedConfigs = advancedConfigs.filter(function (property) {
  606. return !(definedConfigs.someProperty('name', property.name) && !serviceConfigs.someProperty('name', property.name));
  607. }, this);
  608. }
  609. }
  610. if (advancedConfigs) {
  611. advancedConfigs.forEach(function (_config) {
  612. var configType = this.getConfigTagFromFileName(_config.filename);
  613. var configCategory = _config.category || 'Advanced ' + configType;
  614. var categoryMetaData = null;
  615. if (_config) {
  616. if (!(this.get('configMapping').computed().someProperty('name', _config.name) ||
  617. configsToVerifying.filterProperty('name', _config.name).someProperty('filename', _config.filename))) {
  618. if (this.get('customFileNames').contains(_config.filename)) {
  619. categoryMetaData = this.identifyCategory(_config);
  620. if (categoryMetaData != null) {
  621. configCategory = categoryMetaData.get('name');
  622. }
  623. }
  624. _config.id = "site property";
  625. _config.category = configCategory;
  626. _config.displayName = _config.displayName || _config.name;
  627. _config.recommendedValue = _config.value;
  628. // make all advanced configs optional and populated by default
  629. /*
  630. * if (/\${.*}/.test(_config.value) || (service.serviceName !==
  631. * 'OOZIE' && service.serviceName !== 'HBASE')) { _config.isRequired =
  632. * false; _config.value = ''; } else if
  633. * (/^\s+$/.test(_config.value)) { _config.isRequired = false; }
  634. */
  635. _config.isRequired = true;
  636. _config.displayType = _config.displayType ? _config.displayType : stringUtils.isSingleLine(_config.value) ? 'advanced' : 'multiLine';
  637. serviceConfigs.push(_config);
  638. }
  639. }
  640. }, this);
  641. }
  642. },
  643. miscConfigVisibleProperty: function (configs, serviceToShow) {
  644. configs.forEach(function (item) {
  645. if (item.get('isVisible') && item.belongsToService && item.belongsToService.length) {
  646. if (item.get('belongsToService').contains('Cluster') && item.get('displayType') == 'user') {
  647. item.set('isVisible', true);
  648. return;
  649. }
  650. item.set("isVisible", item.belongsToService.some(function (cur) {
  651. return serviceToShow.contains(cur)
  652. }));
  653. }
  654. });
  655. return configs;
  656. },
  657. /**
  658. * render configs, distribute them by service
  659. * and wrap each in ServiceConfigProperty object
  660. * @param configs
  661. * @param storedConfigs
  662. * @param allSelectedServiceNames
  663. * @param installedServiceNames
  664. * @param localDB
  665. * @return {App.ServiceConfig[]}
  666. */
  667. renderConfigs: function (configs, storedConfigs, allSelectedServiceNames, installedServiceNames, localDB) {
  668. var renderedServiceConfigs = [];
  669. var services = [];
  670. this.get('preDefinedServiceConfigs').forEach(function (serviceConfig) {
  671. var serviceName = serviceConfig.get('serviceName');
  672. if (allSelectedServiceNames.contains(serviceName) || serviceName === 'MISC') {
  673. console.log('pushing ' + serviceName, serviceConfig);
  674. if (!installedServiceNames.contains(serviceName) || serviceName === 'MISC') {
  675. serviceConfig.set('showConfig', true);
  676. }
  677. services.push(serviceConfig);
  678. }
  679. });
  680. services.forEach(function (service) {
  681. var configsByService = [];
  682. var serviceConfigs = configs.filterProperty('serviceName', service.get('serviceName'));
  683. serviceConfigs.forEach(function (_config) {
  684. _config.isOverridable = (_config.isOverridable === undefined) ? true : _config.isOverridable;
  685. var serviceConfigProperty = App.ServiceConfigProperty.create(_config);
  686. this.updateHostOverrides(serviceConfigProperty, _config);
  687. if (!storedConfigs && !serviceConfigProperty.get('hasInitialValue')) {
  688. var hiveMetastoreUrisConfig = configs.filterProperty('filename', 'hive-site.xml').findProperty('name', 'hive.metastore.uris');
  689. var clientPortConfig = configs.filterProperty('filename', 'zoo.cfg.xml').findProperty('name', 'clientPort');
  690. var dependencies = {
  691. 'hive.metastore.uris': hiveMetastoreUrisConfig && hiveMetastoreUrisConfig.recommendedValue,
  692. 'clientPort': clientPortConfig && clientPortConfig.recommendedValue
  693. };
  694. configPropertyHelper.initialValue(serviceConfigProperty, localDB, dependencies);
  695. }
  696. if (storedConfigs && storedConfigs.filterProperty('name', _config.name).length && !!_config.filename) {
  697. var storedConfig = storedConfigs.filterProperty('name', _config.name).findProperty('filename', _config.filename);
  698. if (storedConfig) {
  699. serviceConfigProperty.set('recommendedValue', storedConfig.recommendedValue);
  700. serviceConfigProperty.set('value', storedConfig.value);
  701. }
  702. }
  703. this.tweakDynamicDefaults(localDB, serviceConfigProperty, _config);
  704. serviceConfigProperty.validate();
  705. configsByService.pushObject(serviceConfigProperty);
  706. }, this);
  707. var serviceConfig = this.createServiceConfig(service.get('serviceName'));
  708. serviceConfig.set('showConfig', service.get('showConfig'));
  709. serviceConfig.set('configs', configsByService);
  710. renderedServiceConfigs.push(serviceConfig);
  711. }, this);
  712. return renderedServiceConfigs;
  713. },
  714. /**
  715. Takes care of the "dynamic defaults" for the GLUSTERFS configs. Sets
  716. some of the config defaults to previously user-entered data.
  717. **/
  718. tweakDynamicDefaults: function (localDB, serviceConfigProperty, config) {
  719. var firstHost;
  720. for (var host in localDB.hosts) {
  721. firstHost = host;
  722. break;
  723. }
  724. try {
  725. if (typeof(config.recommendedValue) == "string" && config.recommendedValue.indexOf("{firstHost}") >= 0) {
  726. serviceConfigProperty.set('value', serviceConfigProperty.value.replace(new RegExp("{firstHost}"), firstHost));
  727. serviceConfigProperty.set('recommendedValue', serviceConfigProperty.recommendedValue.replace(new RegExp("{firstHost}"), firstHost));
  728. }
  729. } catch (err) {
  730. // Nothing to worry about here, most likely trying indexOf on a non-string
  731. }
  732. },
  733. /**
  734. * create new child configs from overrides, attach them to parent config
  735. * override - value of config, related to particular host(s)
  736. * @param configProperty
  737. * @param storedConfigProperty
  738. */
  739. updateHostOverrides: function (configProperty, storedConfigProperty) {
  740. if (storedConfigProperty.overrides != null && storedConfigProperty.overrides.length > 0) {
  741. var overrides = [];
  742. storedConfigProperty.overrides.forEach(function (overrideEntry) {
  743. // create new override with new value
  744. var newSCP = App.ServiceConfigProperty.create(configProperty);
  745. newSCP.set('value', overrideEntry.value);
  746. newSCP.set('isOriginalSCP', false); // indicated this is overridden value,
  747. newSCP.set('parentSCP', configProperty);
  748. var hostsArray = Ember.A([]);
  749. overrideEntry.hosts.forEach(function (host) {
  750. hostsArray.push(host);
  751. });
  752. newSCP.set('selectedHostOptions', hostsArray);
  753. overrides.pushObject(newSCP);
  754. });
  755. configProperty.set('overrides', overrides);
  756. }
  757. },
  758. /**
  759. * create new ServiceConfig object by service name
  760. * @param {string} serviceName
  761. * @return {App.ServiceConfig}
  762. * @method createServiceConfig
  763. */
  764. createServiceConfig: function (serviceName) {
  765. var preDefinedServiceConfig = App.config.get('preDefinedServiceConfigs').findProperty('serviceName', serviceName);
  766. return App.ServiceConfig.create({
  767. serviceName: preDefinedServiceConfig.get('serviceName'),
  768. displayName: preDefinedServiceConfig.get('displayName'),
  769. configCategories: preDefinedServiceConfig.get('configCategories'),
  770. configs: [],
  771. configGroups: []
  772. });
  773. },
  774. /**
  775. * GETs all cluster level sites in one call.
  776. *
  777. * @return {$.ajax}
  778. */
  779. loadConfigsByTags: function (tags) {
  780. var urlParams = [];
  781. tags.forEach(function (_tag) {
  782. urlParams.push('(type=' + _tag.siteName + '&tag=' + _tag.tagName + ')');
  783. });
  784. var params = urlParams.join('|');
  785. return App.ajax.send({
  786. name: 'config.on_site',
  787. sender: this,
  788. data: {
  789. params: params
  790. }
  791. });
  792. },
  793. /**
  794. * Fetch cluster configs from server
  795. *
  796. * @param callback
  797. * @return {$.ajax}
  798. */
  799. loadClusterConfig: function (callback) {
  800. return App.ajax.send({
  801. name: 'config.cluster',
  802. sender: this,
  803. data: {
  804. stackVersionUrl: App.get('stackVersionURL'),
  805. callback: callback
  806. },
  807. success: 'loadClusterConfigSuccess',
  808. error: 'loadClusterConfigError'
  809. });
  810. },
  811. loadClusterConfigSuccess: function (data, opt, params) {
  812. console.log("TRACE: In success function for the loadClusterConfigSuccess; url is ", opt.url);
  813. var properties = [];
  814. if (data.items.length) {
  815. data.items.forEach(function (item) {
  816. item.StackLevelConfigurations.property_type = item.StackLevelConfigurations.property_type || [];
  817. item.StackLevelConfigurations.service_name = 'MISC';
  818. var property = this.createAdvancedPropertyObject(item.StackLevelConfigurations);
  819. if (property) properties.push(property);
  820. }, this);
  821. }
  822. params.callback(properties);
  823. },
  824. loadClusterConfigError: function (request, ajaxOptions, error, opt, params) {
  825. console.log('ERROR: Failed to load cluster-env configs');
  826. params.callback([]);
  827. },
  828. /**
  829. * Generate serviceProperties save it to localDB
  830. * called from stepController step6WizardController
  831. *
  832. * @method loadAdvancedConfig
  833. * @param serviceName
  834. * @param callback
  835. * @return {object|null}
  836. */
  837. loadAdvancedConfig: function (serviceName, callback) {
  838. return App.ajax.send({
  839. name: 'config.advanced',
  840. sender: this,
  841. data: {
  842. serviceName: serviceName,
  843. stackVersionUrl: App.get('stackVersionURL'),
  844. stackVersion: App.get('currentStackVersionNumber'),
  845. callback: callback
  846. },
  847. success: 'loadAdvancedConfigSuccess',
  848. error: 'loadAdvancedConfigError'
  849. });
  850. },
  851. /**
  852. * Generate serviceProperties save it to localDB
  853. * called from stepController step6WizardController
  854. *
  855. * @method loadAdvancedConfig
  856. * @param {Array} serviceNames
  857. * @param callback
  858. * @return {object|null}
  859. */
  860. loadAdvancedConfigAll: function (serviceNames, callback) {
  861. return App.ajax.send({
  862. name: 'config.advanced.multiple.services',
  863. sender: this,
  864. data: {
  865. serviceNames: serviceNames.join(','),
  866. stackVersionUrl: App.get('stackVersionURL'),
  867. stackVersion: App.get('currentStackVersionNumber'),
  868. callback: callback
  869. },
  870. success: 'loadAdvancedConfigAllSuccess',
  871. error: 'loadAdvancedConfigAllError'
  872. });
  873. },
  874. loadAdvancedConfigAllSuccess: function (data, opt, params, request) {
  875. console.log("TRACE: In success function for the loadAdvancedConfig; url is ", opt.url);
  876. var serviceConfigMap = {};
  877. if (data.items.length) {
  878. data.items.forEach(function (service) {
  879. var properties = [];
  880. service.configurations.forEach(function(item){
  881. properties.push(this.createAdvancedPropertyObject(item.StackConfigurations));
  882. }, this);
  883. serviceConfigMap[service.StackServices.service_name] = properties;
  884. }, this);
  885. }
  886. params.callback(serviceConfigMap, request);
  887. },
  888. loadAdvancedConfigAllError: function (request, ajaxOptions, error, opt, params) {
  889. console.log('ERROR: failed to load stack configs for', params.serviceNames);
  890. params.callback([], request);
  891. },
  892. /**
  893. * Load advanced configs by service names etc.
  894. * Use this method when you need to get configs for
  895. * particular services by single request
  896. *
  897. * @method loadAdvancedConfigPartial
  898. * @param {String[]} serviceNames
  899. * @param {Object} opt
  900. * @param {Function} callback
  901. * @returns {$.ajax}
  902. */
  903. loadAdvancedConfigPartial: function (serviceNames, opt, callback) {
  904. var data = {
  905. serviceList: serviceNames.join(','),
  906. stackVersionUrl: App.get('stackVersionURL'),
  907. stackVersion: App.get('currentStackVersionNumber'),
  908. queryFilter: ('&' + opt.queryFilter) || '',
  909. callback: callback
  910. };
  911. return App.ajax.send({
  912. name: 'config.advanced.partial',
  913. sender: this,
  914. data: data,
  915. success: 'loadAdvancedConfigPartialSuccess',
  916. error: 'loadAdvancedConfigError'
  917. });
  918. },
  919. loadAdvancedConfigSuccess: function (data, opt, params, request) {
  920. console.log("TRACE: In success function for the loadAdvancedConfig; url is ", opt.url);
  921. var properties = [];
  922. if (data.items.length) {
  923. data.items.forEach(function (item) {
  924. var property = this.createAdvancedPropertyObject(item.StackConfigurations);
  925. if (property) properties.push(property);
  926. }, this);
  927. }
  928. params.callback(properties, request);
  929. },
  930. loadAdvancedConfigError: function (request, ajaxOptions, error, opt, params) {
  931. console.log('ERROR: failed to load stack configs for', params.serviceName);
  932. params.callback([], request);
  933. },
  934. loadAdvancedConfigPartialSuccess: function (data, opt, params, request) {
  935. var properties = [];
  936. if (data.items.length && data.items.mapProperty('configurations').length) {
  937. var configurations = data.items.mapProperty('configurations').reduce(function (p, c) {
  938. return p.concat(c);
  939. });
  940. configurations.forEach(function (item) {
  941. var property = this.createAdvancedPropertyObject(item.StackConfigurations);
  942. if (property) properties.push(property);
  943. }, this);
  944. }
  945. params.callback(properties, request);
  946. },
  947. /**
  948. * Bootstrap configuration property object according to
  949. * format that we using in our application.
  950. *
  951. * @method createAdvancedPropertyObject
  952. * @param {Object} item
  953. * @returns {Object|Boolean}
  954. */
  955. createAdvancedPropertyObject: function (item) {
  956. var serviceName = item.service_name;
  957. var fileName = item.type;
  958. /**
  959. * Properties from mapred-queue-acls.xml are ignored
  960. * Properties from capacity-scheduler.xml are ignored unless HDP stack version is 2.x or
  961. * HDP stack version is 1.x
  962. */
  963. if (fileName == 'mapred-queue-acls.xml') return false;
  964. item.isVisible = fileName != 'cluster-env.xml';
  965. var property = {
  966. serviceName: serviceName,
  967. name: item.property_name,
  968. value: item.property_value,
  969. description: item.property_description,
  970. isVisible: item.isVisible,
  971. isFinal: item.final === "true",
  972. recommendedIsFinal: item.final === "true",
  973. filename: item.filename || fileName
  974. };
  975. return $.extend(property, this.advancedConfigIdentityData(item));
  976. },
  977. /**
  978. * Add additional properties to advanced property config object.
  979. * Additional logic based on `property_type`.
  980. *
  981. * @method advancedConfigIdentityData
  982. * @param {Object} config
  983. * @return {Object}
  984. */
  985. advancedConfigIdentityData: function (config) {
  986. var propertyData = {};
  987. var proxyUserGroupServices = ['HIVE', 'OOZIE', 'FALCON'];
  988. var nameToDisplayNameMap = {
  989. 'smokeuser': 'Smoke Test User',
  990. 'user_group': 'Hadoop Group',
  991. 'mapred_user': 'MapReduce User',
  992. 'zk_user': 'ZooKeeper User',
  993. 'ignore_groupsusers_create': 'Skip group modifications during install',
  994. 'override_hbase_uid': 'Have Ambari manage UIDs'
  995. };
  996. var checkboxProperties = ['ignore_groupsusers_create', 'override_hbase_uid'];
  997. if (Em.isArray(config.property_type)) {
  998. if (config.property_type.contains('USER') || config.property_type.contains('ADDITIONAL_USER_PROPERTY') || config.property_type.contains('GROUP')) {
  999. propertyData.id = "puppet var";
  1000. propertyData.category = 'Users and Groups';
  1001. propertyData.isVisible = !App.get('isHadoopWindowsStack');
  1002. propertyData.serviceName = 'MISC';
  1003. propertyData.isOverridable = false;
  1004. propertyData.isReconfigurable = false;
  1005. propertyData.displayName = nameToDisplayNameMap[config.property_name] || App.format.normalizeName(config.property_name);
  1006. propertyData.displayType = checkboxProperties.contains(config.property_name) ? 'checkbox' : 'user';
  1007. if (config.service_name && !config.property_type.contains('ADDITIONAL_USER_PROPERTY')) {
  1008. var propertyIndex = config.service_name == 'MISC' ? 30 : App.StackService.find().mapProperty('serviceName').indexOf(config.service_name);
  1009. propertyData.belongsToService = [config.service_name];
  1010. propertyData.index = propertyIndex;
  1011. } else {
  1012. propertyData.index = 30;
  1013. }
  1014. if (config.property_name == 'proxyuser_group') propertyData.belongsToService = proxyUserGroupServices;
  1015. }
  1016. if (config.property_type.contains('PASSWORD')) {
  1017. propertyData.displayType = "password";
  1018. }
  1019. }
  1020. return propertyData;
  1021. },
  1022. /**
  1023. * Get config types and config type attributes from stack service
  1024. *
  1025. * @param service
  1026. * @return {object}
  1027. */
  1028. getConfigTypesInfoFromService: function (service) {
  1029. var configTypes = service.get('configTypes');
  1030. var configTypesInfo = {
  1031. items: [],
  1032. supportsFinal: []
  1033. };
  1034. if (configTypes) {
  1035. for (var key in configTypes) {
  1036. if (configTypes.hasOwnProperty(key)) {
  1037. configTypesInfo.items.push(key);
  1038. if (configTypes[key].supports && configTypes[key].supports.final === "true") {
  1039. configTypesInfo.supportsFinal.push(key);
  1040. }
  1041. }
  1042. }
  1043. }
  1044. return configTypesInfo;
  1045. },
  1046. /**
  1047. * Get properties from server by type and tag with properties, that belong to group
  1048. * push them to common {serviceConfigs} and call callback function
  1049. */
  1050. loadServiceConfigGroupOverrides: function (serviceConfigs, loadedGroupToOverrideSiteToTagMap, configGroups, callback, sender) {
  1051. var configKeyToConfigMap = {};
  1052. serviceConfigs.forEach(function (item) {
  1053. if (!configKeyToConfigMap[item.filename]) {
  1054. configKeyToConfigMap[item.filename] = {};
  1055. }
  1056. configKeyToConfigMap[item.filename][item.name] = item;
  1057. });
  1058. var typeTagToGroupMap = {};
  1059. var urlParams = [];
  1060. for (var group in loadedGroupToOverrideSiteToTagMap) {
  1061. var overrideTypeTags = loadedGroupToOverrideSiteToTagMap[group];
  1062. for (var type in overrideTypeTags) {
  1063. var tag = overrideTypeTags[type];
  1064. typeTagToGroupMap[type + "///" + tag] = configGroups.findProperty('name', group);
  1065. urlParams.push('(type=' + type + '&tag=' + tag + ')');
  1066. }
  1067. }
  1068. var params = urlParams.join('|');
  1069. if (urlParams.length) {
  1070. App.ajax.send({
  1071. name: 'config.host_overrides',
  1072. sender: this,
  1073. data: {
  1074. params: params,
  1075. configKeyToConfigMap: configKeyToConfigMap,
  1076. typeTagToGroupMap: typeTagToGroupMap,
  1077. callback: callback,
  1078. sender: sender,
  1079. serviceConfigs: serviceConfigs
  1080. },
  1081. success: 'loadServiceConfigGroupOverridesSuccess'
  1082. });
  1083. } else {
  1084. callback.call(sender, serviceConfigs);
  1085. }
  1086. },
  1087. loadServiceConfigGroupOverridesSuccess: function (data, opt, params) {
  1088. data.items.forEach(function (config) {
  1089. var group = params.typeTagToGroupMap[config.type + "///" + config.tag];
  1090. var properties = config.properties;
  1091. for (var prop in properties) {
  1092. var fileName = this.getOriginalFileName(config.type);
  1093. var serviceConfig = !!params.configKeyToConfigMap[fileName] ? params.configKeyToConfigMap[fileName][prop] : false;
  1094. var hostOverrideValue = this.formatOverrideValue(serviceConfig, properties[prop]);
  1095. var hostOverrideIsFinal = !!(config.properties_attributes && config.properties_attributes.final && config.properties_attributes.final[prop]);
  1096. if (serviceConfig) {
  1097. // Value of this property is different for this host.
  1098. if (!Em.get(serviceConfig, 'overrides')) Em.set(serviceConfig, 'overrides', []);
  1099. console.log("loadServiceConfigGroupOverridesSuccess(): [" + group + "] OVERRODE(" + serviceConfig.name + "): " + serviceConfig.value + " -> " + hostOverrideValue);
  1100. serviceConfig.overrides.pushObject({value: hostOverrideValue, group: group, isFinal: hostOverrideIsFinal});
  1101. } else {
  1102. params.serviceConfigs.push(this.createCustomGroupConfig(prop, config, group));
  1103. }
  1104. }
  1105. }, this);
  1106. params.callback.call(params.sender, params.serviceConfigs);
  1107. },
  1108. /**
  1109. * Create config with non default config group. Some custom config properties
  1110. * can be created and assigned to non-default config group.
  1111. *
  1112. * @param {String} propertyName - name of the property
  1113. * @param {Object} config - config info
  1114. * @param {Em.Object} group - config group to set
  1115. * @return {Object}
  1116. **/
  1117. createCustomGroupConfig: function (propertyName, config, group) {
  1118. var propertyValue = config.properties[propertyName];
  1119. var propertyObject = {
  1120. name: propertyName,
  1121. displayName: propertyName,
  1122. savedValue: propertyValue,
  1123. value: propertyValue,
  1124. displayType: stringUtils.isSingleLine(propertyValue) ? 'advanced' : 'multiLine',
  1125. isSecureConfig: false,
  1126. group: group,
  1127. id: 'site property',
  1128. serviceName: group.get('service.serviceName'),
  1129. filename: this.getOriginalFileName(config.type),
  1130. isUserProperty: true,
  1131. isVisible: true,
  1132. isOverridable: false
  1133. };
  1134. propertyObject.category = this.identifyCategory(propertyObject).name;
  1135. group.set('switchGroupTextShort', Em.I18n.t('services.service.config_groups.switchGroupTextShort').format(group.get('name')));
  1136. group.set('switchGroupTextFull', Em.I18n.t('services.service.config_groups.switchGroupTextFull').format(group.get('name')));
  1137. return App.ServiceConfigProperty.create(propertyObject);
  1138. },
  1139. /**
  1140. * format value of override of config
  1141. * @param serviceConfig
  1142. * @param hostOverrideValue
  1143. */
  1144. formatOverrideValue: function (serviceConfig, hostOverrideValue) {
  1145. if (serviceConfig && serviceConfig.displayType === 'int') {
  1146. if (/\d+m$/.test(hostOverrideValue)) {
  1147. return hostOverrideValue.slice(0, hostOverrideValue.length - 1);
  1148. }
  1149. }
  1150. return hostOverrideValue;
  1151. },
  1152. /**
  1153. * Set all site property that are derived from other site-properties
  1154. * Replace <foreignKey[0]>, <foreignKey[1]>, ... (in the name and value) to values from configs with names in foreignKey-array
  1155. * Replace <templateName[0]>, <templateName[1]>, ... (in the value) to values from configs with names in templateName-array
  1156. * Example:
  1157. * <code>
  1158. * config: {
  1159. * name: "name.<foreignKey[0]>.name",
  1160. * foreignKey: ["name1"],
  1161. * templateName: ["name2"],
  1162. * value: "<foreignKey[0]><templateName[0]>"
  1163. * }
  1164. * </code>
  1165. * "<foreignKey[0]>" in the name will be replaced with value from config with name "name1" (this config will be found
  1166. * in the mappedConfigs or allConfigs). New name will be set to the '_name'-property. If config with name "name1" won't
  1167. * be found, updated config will be marked as skipped (<code>noMatchSoSkipThisConfig</code>-property is set to true)
  1168. * "<templateName[0]>" in the value will be replace with value from config with name "name2" (it also will be found
  1169. * in the mappedConfigs or allConfigs).
  1170. *
  1171. * @param {object[]} mappedConfigs
  1172. * @param {object[]} allConfigs
  1173. * @param {object} config
  1174. * @method setConfigValue
  1175. */
  1176. setConfigValue: function (mappedConfigs, allConfigs, config) {
  1177. var globalValue;
  1178. if (config.value == null) {
  1179. return;
  1180. }
  1181. var fkValue = config.value.match(/<(foreignKey.*?)>/g);
  1182. var fkName = config.name.match(/<(foreignKey.*?)>/g);
  1183. var templateValue = config.value.match(/<(templateName.*?)>/g);
  1184. if (fkValue) {
  1185. fkValue.forEach(function (_fkValue) {
  1186. var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]);
  1187. var cfk = config.foreignKey[index];
  1188. var cFromMapped = mappedConfigs.findProperty('name', cfk);
  1189. if (Em.isNone(cFromMapped)) {
  1190. var cFromAll = allConfigs.findProperty('name', cfk);
  1191. if (!Em.isNone(cFromAll)) {
  1192. globalValue = Em.get(cFromAll, 'value') === '' ? Em.get(cFromAll, 'recommendedValue') : Em.get(cFromAll, 'value');
  1193. config.value = config.value.replace(_fkValue, globalValue);
  1194. }
  1195. }
  1196. else {
  1197. globalValue = Em.get(cFromMapped, 'value');
  1198. config.value = config.value.replace(_fkValue, globalValue);
  1199. }
  1200. });
  1201. }
  1202. // config._name - formatted name from original config name
  1203. if (fkName) {
  1204. fkName.forEach(function (_fkName) {
  1205. var index = parseInt(_fkName.match(/\[([\d]*)(?=\])/)[1]);
  1206. var cfk = config.foreignKey[index];
  1207. var cFromMapped = mappedConfigs.findProperty('name', cfk);
  1208. if (Em.isNone(cFromMapped)) {
  1209. var cFromAll = allConfigs.findProperty('name', cfk);
  1210. if (Em.isNone(cFromAll)) {
  1211. config.noMatchSoSkipThisConfig = true;
  1212. }
  1213. else {
  1214. globalValue = Em.get(cFromAll, 'value') === '' ? Em.get(cFromAll, 'recommendedValue') : Em.get(cFromAll, 'value');
  1215. config._name = config.name.replace(_fkName, globalValue);
  1216. }
  1217. }
  1218. else {
  1219. globalValue = Em.get(cFromMapped, 'value');
  1220. config._name = config.name.replace(_fkName, globalValue);
  1221. }
  1222. });
  1223. }
  1224. //For properties in the configMapping file having foreignKey and templateName properties.
  1225. if (templateValue) {
  1226. templateValue.forEach(function (_value) {
  1227. var index = parseInt(_value.match(/\[([\d]*)(?=\])/)[1]);
  1228. var cfk = config.templateName[index];
  1229. var cFromAll = allConfigs.findProperty('name', cfk);
  1230. if (Em.isNone(cFromAll)) {
  1231. config.value = null;
  1232. }
  1233. else {
  1234. var globalValue = Em.get(cFromAll, 'value');
  1235. config.value = config.value.replace(_value, globalValue);
  1236. }
  1237. });
  1238. }
  1239. },
  1240. /**
  1241. * identify service name of config by its config's type
  1242. * @param type
  1243. * @return {string|null}
  1244. */
  1245. getServiceNameByConfigType: function (type) {
  1246. var preDefinedServiceConfigs = this.get('preDefinedServiceConfigs');
  1247. var service = preDefinedServiceConfigs.find(function (serviceConfig) {
  1248. return !!serviceConfig.get('configTypes')[type];
  1249. }, this);
  1250. return service && service.get('serviceName');
  1251. },
  1252. /**
  1253. * add user property
  1254. * @param stored
  1255. * @param isAdvanced
  1256. * @param advancedConfigs
  1257. * @return {Object}
  1258. */
  1259. addUserProperty: function (stored, isAdvanced, advancedConfigs) {
  1260. var
  1261. skipAttributeChanges = {
  1262. displayType: ['ignore_groupsusers_create'],
  1263. displayName: ['ignore_groupsusers_create', 'smokeuser', 'user_group', 'mapred_user', 'zk_user']
  1264. },
  1265. configData = {
  1266. id: stored.id,
  1267. name: stored.name,
  1268. displayName: skipAttributeChanges.displayName.contains(stored.name) ?
  1269. this.getOriginalConfigAttribute(stored, 'displayName', advancedConfigs) : App.format.normalizeName(stored.name),
  1270. serviceName: stored.serviceName,
  1271. value: stored.value,
  1272. savedValue: stored.savedValue,
  1273. recommendedValue: stored.recommendedValue,
  1274. displayType: skipAttributeChanges.displayType.contains(stored.name) ?
  1275. this.getOriginalConfigAttribute(stored, 'displayType', advancedConfigs) :
  1276. (stringUtils.isSingleLine(stored.value) ? 'advanced' : 'multiLine'),
  1277. filename: stored.filename,
  1278. isUserProperty: stored.isUserProperty === true,
  1279. hasInitialValue: !!stored.hasInitialValue,
  1280. isOverridable: true,
  1281. overrides: stored.overrides,
  1282. isRequired: false,
  1283. isVisible: stored.isVisible,
  1284. isFinal: stored.isFinal,
  1285. savedIsFinal: stored.savedIsFinal,
  1286. supportsFinal: stored.supportsFinal,
  1287. showLabel: stored.showLabel !== false,
  1288. category: stored.category
  1289. };
  1290. if (stored.category == 'Users and Groups') {
  1291. configData.index = this.getOriginalConfigAttribute(stored, 'index', advancedConfigs);
  1292. }
  1293. var advancedConfig = advancedConfigs.filterProperty('name', stored.name).findProperty('filename', stored.filename);
  1294. App.get('config').calculateConfigProperties(configData, isAdvanced, advancedConfig);
  1295. return configData;
  1296. },
  1297. getOriginalConfigAttribute: function (stored, key, advancedConfigs) {
  1298. return advancedConfigs.findProperty('name', stored.name) ?
  1299. advancedConfigs.findProperty('name', stored.name)[key] : stored[key];
  1300. },
  1301. complexConfigsTemplate: [
  1302. {
  1303. "id": "site property",
  1304. "name": "capacity-scheduler",
  1305. "displayName": "Capacity Scheduler",
  1306. "value": "",
  1307. "description": "Capacity Scheduler properties",
  1308. "displayType": "custom",
  1309. "isOverridable": true,
  1310. "isRequired": true,
  1311. "isVisible": true,
  1312. "isReconfigurable": true,
  1313. "supportsFinal": false,
  1314. "serviceName": "YARN",
  1315. "filename": "capacity-scheduler.xml",
  1316. "category": "CapacityScheduler"
  1317. }
  1318. ],
  1319. /**
  1320. * transform set of configs from file
  1321. * into one config with textarea content:
  1322. * name=value
  1323. * @param {App.ServiceConfigProperty[]} configs
  1324. * @param {String} filename
  1325. * @param {App.ServiceConfigProperty[]} [configsToSkip=[]]
  1326. * @return {*}
  1327. */
  1328. fileConfigsIntoTextarea: function (configs, filename, configsToSkip) {
  1329. var fileConfigs = configs.filterProperty('filename', filename);
  1330. var value = '', savedValue = '', recommendedValue = '';
  1331. var template = this.get('complexConfigsTemplate').findProperty('filename', filename);
  1332. var complexConfig = $.extend({}, template);
  1333. if (complexConfig) {
  1334. fileConfigs.forEach(function (_config) {
  1335. if (!(configsToSkip && configsToSkip.someProperty('name', _config.name))) {
  1336. value += _config.name + '=' + _config.value + '\n';
  1337. if (!Em.isNone(_config.savedValue)) {
  1338. savedValue += _config.name + '=' + _config.savedValue + '\n';
  1339. }
  1340. if (!Em.isNone(_config.recommendedValue)) {
  1341. recommendedValue += _config.name + '=' + _config.recommendedValue + '\n';
  1342. }
  1343. }
  1344. }, this);
  1345. var isFinal = fileConfigs.someProperty('isFinal', true);
  1346. var savedIsFinal = fileConfigs.someProperty('savedIsFinal', true);
  1347. var recommendedIsFinal = fileConfigs.someProperty('recommendedIsFinal', true);
  1348. complexConfig.value = value;
  1349. if (savedValue) {
  1350. complexConfig.savedValue = savedValue;
  1351. }
  1352. if (recommendedValue) {
  1353. complexConfig.recommendedValue = recommendedValue;
  1354. }
  1355. complexConfig.isFinal = isFinal;
  1356. complexConfig.savedIsFinal = savedIsFinal;
  1357. complexConfig.recommendedIsFinal = recommendedIsFinal;
  1358. configs = configs.filter(function (_config) {
  1359. return _config.filename !== filename || (configsToSkip && configsToSkip.someProperty('name', _config.name));
  1360. });
  1361. configs.push(complexConfig);
  1362. }
  1363. return configs;
  1364. },
  1365. /**
  1366. * transform one config with textarea content
  1367. * into set of configs of file
  1368. * @param configs
  1369. * @param filename
  1370. * @return {*}
  1371. */
  1372. textareaIntoFileConfigs: function (configs, filename) {
  1373. var complexConfigName = this.get('complexConfigsTemplate').findProperty('filename', filename).name;
  1374. var configsTextarea = configs.findProperty('name', complexConfigName);
  1375. if (configsTextarea && !App.get('testMode')) {
  1376. var properties = configsTextarea.get('value').split('\n');
  1377. properties.forEach(function (_property) {
  1378. var name, value;
  1379. if (_property) {
  1380. _property = _property.split('=');
  1381. name = _property[0];
  1382. value = (_property[1]) ? _property[1] : "";
  1383. configs.push(Em.Object.create({
  1384. id: configsTextarea.get('id'),
  1385. name: name,
  1386. value: value,
  1387. savedValue: value,
  1388. serviceName: configsTextarea.get('serviceName'),
  1389. filename: filename,
  1390. isFinal: configsTextarea.get('isFinal'),
  1391. isNotDefaultValue: configsTextarea.get('isNotDefaultValue'),
  1392. isRequiredByAgent: configsTextarea.get('isRequiredByAgent'),
  1393. group: null
  1394. }));
  1395. }
  1396. });
  1397. return configs.without(configsTextarea);
  1398. }
  1399. console.log('ERROR: textarea config - ' + complexConfigName + ' is missing');
  1400. return configs;
  1401. },
  1402. /**
  1403. * trim trailing spaces for all properties.
  1404. * trim both trailing and leading spaces for host displayType and hive/oozie datebases url.
  1405. * for directory or directories displayType format string for further using.
  1406. * for password and values with spaces only do nothing.
  1407. * @param {Object} property
  1408. * @param {Boolean} isEmberObject
  1409. * @returns {*}
  1410. */
  1411. trimProperty: function (property, isEmberObject) {
  1412. var displayType = (isEmberObject) ? property.get('displayType') : property.displayType;
  1413. var value = (isEmberObject) ? property.get('value') : property.value;
  1414. var name = (isEmberObject) ? property.get('name') : property.name;
  1415. var rez;
  1416. switch (displayType) {
  1417. case 'directories':
  1418. case 'directory':
  1419. case 'datanodedirs':
  1420. rez = value.replace(/,/g, ' ').trim().split(/\s+/g).join(',');
  1421. break;
  1422. case 'host':
  1423. rez = value.trim();
  1424. break;
  1425. case 'password':
  1426. break;
  1427. case 'advanced':
  1428. if (name == 'javax.jdo.option.ConnectionURL' || name == 'oozie.service.JPAService.jdbc.url') {
  1429. rez = value.trim();
  1430. }
  1431. default:
  1432. rez = (typeof value == 'string') ? value.replace(/(\s+$)/g, '') : value;
  1433. }
  1434. return ((rez == '') || (rez == undefined)) ? value : rez;
  1435. },
  1436. /**
  1437. * exclude configs that depends on services which are uninstalled
  1438. * if config doesn't have serviceName or dependent service is installed then
  1439. * config not excluded
  1440. * @param {object[]} configs
  1441. * @param {string[]} installedServices
  1442. * @return {object[]}
  1443. * @method excludeUnsupportedConfigs
  1444. */
  1445. excludeUnsupportedConfigs: function (configs, installedServices) {
  1446. return configs.filter(function (config) {
  1447. return !(config.serviceName && !installedServices.contains(config.serviceName));
  1448. });
  1449. },
  1450. /**
  1451. * Generate minimal config property object used in *_properties.js files.
  1452. * Example:
  1453. * <code>
  1454. * var someProperties = App.config.generateConfigPropertiesByName([
  1455. * 'property_1', 'property_2', 'property_3'], { category: 'General', filename: 'myFileName'});
  1456. * // someProperties contains Object[]
  1457. * [
  1458. * {
  1459. * name: 'property_1',
  1460. * displayName: 'property_1',
  1461. * isVisible: true,
  1462. * isReconfigurable: true,
  1463. * category: 'General',
  1464. * filename: 'myFileName'
  1465. * },
  1466. * .......
  1467. * ]
  1468. * </code>
  1469. * @param {string[]} names
  1470. * @param {Object} properties - additional properties which will merge with base object definition
  1471. * @returns {object[]}
  1472. * @method generateConfigPropertiesByName
  1473. */
  1474. generateConfigPropertiesByName: function (names, properties) {
  1475. return names.map(function (item) {
  1476. var baseObj = {
  1477. name: item,
  1478. displayName: item,
  1479. isVisible: true,
  1480. isReconfigurable: true
  1481. };
  1482. if (properties) return $.extend(baseObj, properties);
  1483. else return baseObj;
  1484. });
  1485. },
  1486. /**
  1487. * replace some values in config property
  1488. * @param {string} name
  1489. * @param {string} express
  1490. * @param {string} value
  1491. * @param {string} globValue
  1492. * @return {string}
  1493. * @private
  1494. * @method replaceConfigValues
  1495. */
  1496. replaceConfigValues: function (name, express, value, globValue) {
  1497. if (name == 'templeton.hive.properties') {
  1498. globValue = globValue.replace(/,/g, '\\,');
  1499. }
  1500. return value.replace(express, globValue);
  1501. },
  1502. /**
  1503. * load stack configs from server and run mapper
  1504. * @param {String[]} [serviceNames=null]
  1505. * @returns {$.ajax}
  1506. * @method loadConfigsFromStack
  1507. */
  1508. loadConfigsFromStack: function (serviceNames) {
  1509. serviceNames = serviceNames || [];
  1510. var name = serviceNames.length > 0 ? 'configs.stack_configs.load.services' : 'configs.stack_configs.load.all';
  1511. return App.ajax.send({
  1512. name: name,
  1513. sender: this,
  1514. data: {
  1515. stackVersionUrl: App.get('stackVersionURL'),
  1516. serviceList: serviceNames.join(',')
  1517. },
  1518. success: 'saveConfigsToModel'
  1519. });
  1520. },
  1521. /**
  1522. * Runs <code>stackConfigPropertiesMapper<code>
  1523. * @param {object} data
  1524. * @method saveConfigsToModel
  1525. */
  1526. saveConfigsToModel: function (data) {
  1527. App.stackConfigPropertiesMapper.map(data);
  1528. },
  1529. /**
  1530. * Check if config filename supports final attribute
  1531. * @param serviceName
  1532. * @param filename
  1533. * @returns {boolean}
  1534. */
  1535. shouldSupportFinal: function (serviceName, filename) {
  1536. if (!serviceName || serviceName == 'MISC' || !filename) {
  1537. return false;
  1538. } else {
  1539. var stackService = App.StackService.find().findProperty('serviceName', serviceName);
  1540. var supportsFinal = this.getConfigTypesInfoFromService(stackService).supportsFinal;
  1541. var matchingConfigType = supportsFinal.find(function (configType) {
  1542. return filename.startsWith(configType);
  1543. });
  1544. return !!matchingConfigType;
  1545. }
  1546. },
  1547. /**
  1548. * Remove all ranger-related configs, that should be available only if Ranger is installed
  1549. * @param configs - stepConfigs object
  1550. */
  1551. removeRangerConfigs: function (configs) {
  1552. configs.forEach(function (service) {
  1553. var filteredConfigs = [];
  1554. service.get('configs').forEach(function (config) {
  1555. if (!/^ranger-/.test(config.get('filename'))) {
  1556. filteredConfigs.push(config);
  1557. }
  1558. });
  1559. service.set('configs', filteredConfigs);
  1560. var filteredCategories = [];
  1561. service.get('configCategories').forEach(function (category) {
  1562. if (!/ranger-/.test(category.get('name'))) {
  1563. filteredCategories.push(category);
  1564. }
  1565. });
  1566. service.set('configCategories', filteredCategories);
  1567. });
  1568. }
  1569. });