configs.js 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393
  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. require('controllers/wizard/slave_component_groups_controller');
  20. App.MainServiceInfoConfigsController = Em.Controller.extend({
  21. name: 'mainServiceInfoConfigsController',
  22. dataIsLoaded: false,
  23. stepConfigs: [], //contains all field properties that are viewed in this service
  24. selectedService: null,
  25. serviceConfigTags: null,
  26. globalConfigs: [],
  27. uiConfigs: [],
  28. customConfig: [],
  29. isApplyingChanges: false,
  30. serviceConfigs: require('data/service_configs'),
  31. configs: require('data/config_properties').configProperties,
  32. configMapping: require('data/config_mapping'),
  33. customConfigs: require('data/custom_configs'),
  34. /**
  35. * During page load time, we get the host overrides from the server.
  36. * The current host -> site:tag map is stored below. This will be
  37. * useful during save, so that removals can also be determined.
  38. *
  39. * Example:
  40. * {
  41. * 'hostname1':{
  42. * 'global': 'version1',
  43. * 'core-site': 'version1',
  44. * 'hdfs-site', 'tag3187261938'
  45. * }
  46. * }
  47. *
  48. * @see savedHostToOverrideSiteToTagMap
  49. */
  50. loadedHostToOverrideSiteToTagMap: {},
  51. /**
  52. * During page load time the cluster level site to tag
  53. * mapping is stored here.
  54. *
  55. * Example:
  56. * {
  57. * 'global': 'version1',
  58. * 'hdfs-site': 'version1',
  59. * 'core-site': 'version1'
  60. * }
  61. */
  62. loadedClusterSiteToTagMap: {},
  63. /**
  64. * During page save time, we set the host overrides to the server.
  65. * The new host -> site:tag map is stored below. This will be
  66. * useful during save, to update the host's host components. Also,
  67. * it will be useful in deletion of overrides.
  68. *
  69. * Example:
  70. * {
  71. * 'hostname1': {
  72. * 'global': {
  73. * 'tagName': 'tag3187261938_hostname1',
  74. * 'map': {
  75. * 'hadoop_heapsize': '2048m'
  76. * }
  77. * }
  78. * }
  79. * }
  80. *
  81. * @see loadedHostToOverrideSiteToTagMap
  82. */
  83. savedHostToOverrideSiteToTagMap: {},
  84. /**
  85. * Holds the actual base service-config server data uploaded.
  86. * This is used by the host-override mechanism to update host
  87. * specific values.
  88. */
  89. savedSiteNameToServerServiceConfigDataMap: {},
  90. isSubmitDisabled: function () {
  91. return (!(this.stepConfigs.everyProperty('errorCount', 0)) || this.get('isApplyingChanges'));
  92. }.property('stepConfigs.@each.errorCount', 'isApplyingChanges'),
  93. slaveComponentGroups: null,
  94. /**
  95. * Filter text will be located here
  96. */
  97. filter: '',
  98. /**
  99. * Dropdown menu items in filter compbobox
  100. */
  101. filterColumns: function(){
  102. var result = [];
  103. for(var i = 1; i<4; i++){
  104. result.push(Ember.Object.create({
  105. name: this.t('common.combobox.dropdown.' + i),
  106. selected: false
  107. }));
  108. }
  109. return result;
  110. }.property(),
  111. /**
  112. * clear and set properties to default value
  113. */
  114. clearStep: function () {
  115. this.set('dataIsLoaded', false);
  116. this.set('filter', '');
  117. this.get('filterColumns').setEach('selected', false);
  118. this.get('stepConfigs').clear();
  119. this.get('globalConfigs').clear();
  120. this.get('uiConfigs').clear();
  121. this.get('customConfig').clear();
  122. this.set('loadedHostToOverrideSiteToTagMap', {});
  123. this.set('savedHostToOverrideSiteToTagMap', {});
  124. this.set('savedSiteNameToServerServiceConfigDataMap', {});
  125. if (this.get('serviceConfigTags')) {
  126. this.set('serviceConfigTags', null);
  127. }
  128. },
  129. serviceConfigProperties: function () {
  130. return App.db.getServiceConfigProperties();
  131. }.property('content'),
  132. /**
  133. * On load function
  134. */
  135. loadStep: function () {
  136. console.log("TRACE: Loading configure for service");
  137. this.clearStep();
  138. this.loadServiceConfigs();
  139. },
  140. /**
  141. * Loads the actual configuration of all host components.
  142. * This helps in determining which services need a restart, and also
  143. * in showing which properties are actually applied or not.
  144. * This method also compares the actual_configs with the desired_configs
  145. * and builds a diff structure.
  146. *
  147. * Internall it calculates an array of host-components which need restart.
  148. * Example:
  149. * [
  150. * {
  151. * componentName: 'DATANODE',
  152. * serviceName: 'HDFS',
  153. * host: 'host.name',
  154. * type: 'core-site',
  155. * desiredConfigTags: {tag:'version1'},
  156. * actualConfigTags: {tag:'version4'. host_override:'version2'}
  157. * },
  158. * ...
  159. * ]
  160. *
  161. * From there it return the following restart-data for this service.
  162. * It represents the hosts, whose components need restart, and the
  163. * properties which require restart.
  164. *
  165. * {
  166. * hostAndHostComponents: {
  167. * 'hostname1': {
  168. * 'DATANODE': {
  169. * 'property1': 'value1',
  170. * 'property2': 'value2'
  171. * },
  172. * 'TASKTRACKER': {
  173. * 'prop1': 'val1'
  174. * }
  175. * },
  176. * 'hostname6': {
  177. * 'ZOOKEEPER': {
  178. * 'property1': 'value3'
  179. * }
  180. * }
  181. * },
  182. * propertyToHostAndComponent: {
  183. * 'property1': {
  184. * 'hostname1': ['DATANODE'],
  185. * 'hostname6': ['ZOOKEEPER']
  186. * },
  187. * 'property2': {
  188. * 'hostname1': ['DATANODE']
  189. * },
  190. * 'prop1': {
  191. * 'hostname1': ['TASKTRACKER']
  192. * }
  193. * }
  194. * }
  195. */
  196. loadActualConfigsAndCalculateRestarts: function () {
  197. var currentService = this.get('content.serviceName');
  198. var restartData = {
  199. hostAndHostComponents: {},
  200. propertyToHostAndComponent: {}
  201. };
  202. var self = this;
  203. var actualConfigsUrl = this.getUrl('/data/services/host_component_actual_configs.json', '/services?fields=components/host_components/HostRoles/actual_configs');
  204. $.ajax({
  205. type: 'GET',
  206. url: actualConfigsUrl,
  207. async: false,
  208. timeout: 10000,
  209. dataType: 'json',
  210. success: function (data) {
  211. var diffHostComponents = [];
  212. console.debug("loadActualConfigs(" + actualConfigsUrl + "): Data=", data);
  213. var configsToDownload = [];
  214. data.items.forEach(function (service) {
  215. // For current service, do any of the host_components differ in
  216. // configuration?
  217. if (currentService === service.ServiceInfo.service_name) {
  218. service.components.forEach(function (serviceComponent) {
  219. serviceComponent.host_components.forEach(function (hostComponent) {
  220. if (hostComponent.HostRoles.actual_configs) {
  221. for ( var site in hostComponent.HostRoles.actual_configs) {
  222. var actualConfigsTags = hostComponent.HostRoles.actual_configs[site];
  223. var desiredConfigTags = self.getDesiredConfigTag(site, hostComponent.HostRoles.host_name);
  224. if (desiredConfigTags.tag !== actualConfigsTags.tag ||
  225. (desiredConfigTags.host_override != null &&
  226. actualConfigsTags.host_override != null &&
  227. desiredConfigTags.host_override !== actualConfigsTags.host_override)) {
  228. // Restart may be necessary for this host-component
  229. diffHostComponents.push({
  230. componentName: hostComponent.HostRoles.component_name,
  231. serviceName: serviceComponent.ServiceComponentInfo.service_name,
  232. host: hostComponent.HostRoles.host_name,
  233. type: site,
  234. desiredConfigTags: desiredConfigTags,
  235. actualConfigTags: actualConfigsTags
  236. });
  237. self.addConfigDownloadParam(site, actualConfigsTags.tag, configsToDownload);
  238. self.addConfigDownloadParam(site, actualConfigsTags.host_override, configsToDownload);
  239. self.addConfigDownloadParam(site, desiredConfigTags.tag, configsToDownload);
  240. self.addConfigDownloadParam(site, desiredConfigTags.host_override, configsToDownload);
  241. }
  242. }
  243. }
  244. });
  245. });
  246. }
  247. });
  248. if (configsToDownload.length > 0) {
  249. var url = self.getUrl('/data/configurations/cluster_level_actual_configs.json?' + configsToDownload.join('|'), '/configurations?' + configsToDownload.join('|'));
  250. $.ajax({
  251. type: 'GET',
  252. url: url,
  253. async: false,
  254. timeout: 10000,
  255. dataType: 'json',
  256. success: function (data) {
  257. console.log("configsToDownload(): In success for ", url);
  258. if (data.items) {
  259. data.items.forEach(function (item) {
  260. App.config.loadedConfigurationsCache[item.type + "_" + item.tag] = item.properties;
  261. });
  262. }
  263. },
  264. error: function (request, ajaxOptions, error) {
  265. console.log("TRACE: In error function for the configsToDownload call");
  266. console.log("TRACE: value of the url is: " + url);
  267. console.log("TRACE: error code status is: " + request.status);
  268. },
  269. statusCode: require('data/statusCodes')
  270. });
  271. }
  272. // Now all the configurations are loaded.
  273. // Find the diff in properties
  274. if (diffHostComponents.length > 0) {
  275. diffHostComponents.forEach(function (diffHostComponent) {
  276. var actualConfigs = App.config.loadedConfigurationsCache[diffHostComponent.type + "_" + diffHostComponent.actualConfigTags.tag];
  277. var desiredConfigs = App.config.loadedConfigurationsCache[diffHostComponent.type + "_" + diffHostComponent.desiredConfigTags.tag];
  278. var diffs = self.getConfigDifferences(actualConfigs, desiredConfigs);
  279. if (!jQuery.isEmptyObject(diffs)) {
  280. var skip = false;
  281. if (diffHostComponent.type == 'global') {
  282. if(!App.config.isServiceEffectedByGlobalChange(
  283. diffHostComponent.serviceName,
  284. diffHostComponent.desiredConfigTags.tag,
  285. diffHostComponent.actualConfigTags.tag)){
  286. skip = true;
  287. }
  288. }
  289. if(!skip){
  290. // Populate restartData.hostAndHostComponents
  291. if (!(diffHostComponent.host in restartData.hostAndHostComponents)) {
  292. restartData.hostAndHostComponents[diffHostComponent.host] = {};
  293. }
  294. if (!(diffHostComponent.componentName in restartData.hostAndHostComponents[diffHostComponent.host])) {
  295. restartData.hostAndHostComponents[diffHostComponent.host][diffHostComponent.componentName] = {};
  296. }
  297. jQuery.extend(restartData.hostAndHostComponents[diffHostComponent.host][diffHostComponent.componentName], diffs);
  298. // Populate restartData.propertyToHostAndComponent
  299. for ( var diff in diffs) {
  300. if (!(diff in restartData.propertyToHostAndComponent)) {
  301. restartData.propertyToHostAndComponent[diff] = {};
  302. }
  303. if (!(diffHostComponent.host in restartData.propertyToHostAndComponent[diff])) {
  304. restartData.propertyToHostAndComponent[diff][diffHostComponent.host] = [];
  305. }
  306. if (!(restartData.propertyToHostAndComponent[diff][diffHostComponent.host].contains(diffHostComponent.componentName))) {
  307. restartData.propertyToHostAndComponent[diff][diffHostComponent.host].push(diffHostComponent.componentName);
  308. }
  309. }
  310. }
  311. }
  312. });
  313. }
  314. console.log("loadActualConfigs(): Finished loading. Restart host components = ", diffHostComponents);
  315. },
  316. error: function (request, ajaxOptions, error) {
  317. console.log("loadActualConfigs(): URL:" + actualConfigsUrl + ". Status:", request.status, ", Error:", error);
  318. },
  319. statusCode: require('data/statusCodes')
  320. });
  321. console.log("loadActualConfigsAndCalculateRestarts(): Restart data = ", restartData);
  322. return restartData;
  323. },
  324. /**
  325. * Determines the differences between desired and actual configs and returns
  326. * them as an object. The key is the property, and value is actual_config.
  327. */
  328. getConfigDifferences: function (actualConfigs, desiredConfigs) {
  329. var differences = {};
  330. if (actualConfigs != null && desiredConfigs != null) {
  331. for(var desiredProp in desiredConfigs){
  332. if(desiredConfigs[desiredProp] !== actualConfigs[desiredProp]){
  333. differences[desiredProp] = actualConfigs[desiredProp];
  334. }
  335. }
  336. }
  337. return differences;
  338. },
  339. addConfigDownloadParam: function(site, tag, configsToDownload){
  340. if(tag!=null && !(site+"_"+tag in App.config.loadedConfigurationsCache)){
  341. var configParam = "(type="+site+"&tag="+tag+")";
  342. if(!configsToDownload.contains(configParam)){
  343. configsToDownload.push(configParam);
  344. }
  345. }
  346. },
  347. getDesiredConfigTag: function(site, hostName){
  348. var tag = {tag: this.loadedClusterSiteToTagMap[site], host_override: null};
  349. if(hostName in this.loadedHostToOverrideSiteToTagMap){
  350. var map = this.loadedHostToOverrideSiteToTagMap[hostName];
  351. if(site in map){
  352. tag.host_overrides = map[site];
  353. }
  354. }
  355. return tag;
  356. },
  357. /**
  358. * Loads service configurations
  359. */
  360. loadServiceConfigs: function () {
  361. App.ajax.send({
  362. name: 'config.tags',
  363. sender: this,
  364. data: {
  365. serviceName: this.get('content.serviceName'),
  366. serviceConfigsDef: this.get('serviceConfigs').findProperty('serviceName', this.get('content.serviceName'))
  367. },
  368. success: 'loadServiceTagsSuccess'
  369. });
  370. },
  371. loadServiceTagsSuccess: function(data, opt, params){
  372. var serviceConfigsDef = params.serviceConfigsDef;
  373. var serviceName = this.get('content.serviceName');
  374. console.debug("loadServiceConfigs(): data=", data);
  375. this.loadedClusterSiteToTagMap = {};
  376. //STEP 1: handle tags from JSON data
  377. for ( var site in data.Clusters.desired_configs) {
  378. if (serviceConfigsDef.sites.indexOf(site) > -1) {
  379. this.loadedClusterSiteToTagMap[site] = data.Clusters.desired_configs[site]['tag'];
  380. var overrides = data.Clusters.desired_configs[site].host_overrides;
  381. if (overrides) {
  382. overrides.forEach(function (override) {
  383. var hostname = override.host_name;
  384. var tag = override.tag;
  385. if(!this.loadedHostToOverrideSiteToTagMap[hostname]){
  386. this.loadedHostToOverrideSiteToTagMap[hostname] = {};
  387. }
  388. this.loadedHostToOverrideSiteToTagMap[hostname][site] = tag;
  389. }, this);
  390. }
  391. }
  392. }
  393. //STEP 2: Create an array of objects defining tag names to be polled and new tag names to be set after submit
  394. this.setServiceConfigTags(this.loadedClusterSiteToTagMap);
  395. //STEP 3: Load advanced configs from server
  396. var advancedConfigs = App.config.loadAdvancedConfig(serviceName) || [];
  397. //STEP 4: Load on-site config by service from server
  398. var configGroups = App.config.loadConfigsByTags(this.get('serviceConfigTags'));
  399. //STEP 5: Merge global and on-site configs with pre-defined
  400. var configSet = App.config.mergePreDefinedWithLoaded(configGroups, advancedConfigs, this.get('serviceConfigTags'), serviceName);
  401. //var serviceConfigs = this.getSitesConfigProperties(advancedConfigs);
  402. var configs = configSet.configs;
  403. //put global configs into globalConfigs to save them separately
  404. this.set('globalConfigs', configSet.globalConfigs);
  405. //STEP 6: add advanced configs
  406. App.config.addAdvancedConfigs(configs, advancedConfigs, serviceName);
  407. //STEP 7: add custom configs
  408. App.config.addCustomConfigs(configs);
  409. //STEP 8: add configs as names of host components
  410. this.addHostNamesToGlobalConfig();
  411. var allConfigs = this.get('globalConfigs').concat(configs);
  412. //this.loadServiceConfigHostsOverrides(serviceConfigs, this.loadedHostToOverrideSiteToTagMap);
  413. //STEP 9: Load and add host override configs
  414. App.config.loadServiceConfigHostsOverrides(allConfigs, this.loadedHostToOverrideSiteToTagMap);
  415. var restartData = this.loadActualConfigsAndCalculateRestarts();
  416. //STEP 10: creation of serviceConfig object which contains configs for current service
  417. var serviceConfig = App.config.createServiceConfig(serviceName);
  418. this.checkForRestart(serviceConfig, restartData);
  419. if (serviceName || serviceConfig.serviceName === 'MISC') {
  420. //STEP 11: render configs and wrap each in ServiceConfigProperty object
  421. this.loadComponentConfigs(allConfigs, serviceConfig, restartData);
  422. this.get('stepConfigs').pushObject(serviceConfig);
  423. }
  424. this.set('selectedService', this.get('stepConfigs').objectAt(0));
  425. this.set('dataIsLoaded', true);
  426. },
  427. /**
  428. * Changes format from Object to Array
  429. *
  430. * {
  431. * 'core-site': 'version1',
  432. * 'hdfs-site': 'version1',
  433. * 'global': 'version2',
  434. * ...
  435. * }
  436. *
  437. * to
  438. *
  439. * [
  440. * {
  441. * siteName: 'core-site',
  442. * tagName: 'version1',
  443. * newTageName: null
  444. * },
  445. * ...
  446. * ]
  447. *
  448. * set tagnames for configuration of the *-site.xml
  449. */
  450. setServiceConfigTags: function (desiredConfigsSiteTags) {
  451. console.debug("setServiceConfigTags(): Trying to set ", desiredConfigsSiteTags);
  452. var newServiceConfigTags = [];
  453. for (var index in desiredConfigsSiteTags) {
  454. newServiceConfigTags.pushObject({
  455. siteName: index,
  456. tagName: desiredConfigsSiteTags[index],
  457. newTagName: null
  458. }, this);
  459. }
  460. console.debug("setServiceConfigTags(): Setting 'serviceConfigTags' to ", newServiceConfigTags);
  461. this.set('serviceConfigTags', newServiceConfigTags);
  462. },
  463. /**
  464. * check whether host component must be restarted
  465. * @param serviceConfig
  466. * @param restartData
  467. */
  468. checkForRestart: function(serviceConfig, restartData){
  469. var hostsCount = 0;
  470. var hostComponentCount = 0;
  471. var restartHosts = Ember.A([]);
  472. if(restartData != null && restartData.hostAndHostComponents != null && !jQuery.isEmptyObject(restartData.hostAndHostComponents)){
  473. serviceConfig.set('restartRequired', true);
  474. for(var host in restartData.hostAndHostComponents){
  475. hostsCount++;
  476. var componentsArray = Ember.A([]);
  477. for(var component in restartData.hostAndHostComponents[host]){
  478. componentsArray.push(Ember.Object.create({name: App.format.role(component)}));
  479. hostComponentCount++;
  480. }
  481. var hostObj = App.Host.find(host);
  482. restartHosts.push(Ember.Object.create({hostData: hostObj, components: componentsArray}))
  483. }
  484. serviceConfig.set('restartRequiredHostsAndComponents', restartHosts);
  485. serviceConfig.set('restartRequiredMessage', 'Service needs '+hostComponentCount+' components on ' + hostsCount +' hosts to be restarted.')
  486. }
  487. },
  488. /**
  489. * Load child components to service config object
  490. * @param configs
  491. * @param componentConfig
  492. * @param restartData
  493. */
  494. loadComponentConfigs: function (configs, componentConfig, restartData) {
  495. configs.forEach(function (_serviceConfigProperty) {
  496. console.log("config", _serviceConfigProperty);
  497. if (!_serviceConfigProperty) return;
  498. var overrides = _serviceConfigProperty.overrides;
  499. // we will populate the override properties below
  500. _serviceConfigProperty.overrides = null;
  501. if (_serviceConfigProperty.isOverridable === undefined) {
  502. _serviceConfigProperty.isOverridable = true;
  503. }
  504. var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
  505. var propertyName = serviceConfigProperty.get('name');
  506. if (restartData != null && propertyName in restartData.propertyToHostAndComponent) {
  507. serviceConfigProperty.set('isRestartRequired', true);
  508. var message = '<ul>';
  509. for(var host in restartData.propertyToHostAndComponent[propertyName]){
  510. var appHost = App.Host.find(host);
  511. message += "<li>"+appHost.get('publicHostName');
  512. message += "<ul>";
  513. restartData.propertyToHostAndComponent[propertyName][host].forEach(function(comp){
  514. message += "<li>"+App.format.role(comp)+"</li>"
  515. });
  516. message += "</ul></li>";
  517. }
  518. message += "</ul>";
  519. serviceConfigProperty.set('restartRequiredMessage', message);
  520. }
  521. if (serviceConfigProperty.get('serviceName') === this.get('content.serviceName')) {
  522. // serviceConfigProperty.serviceConfig = componentConfig;
  523. if (App.get('isAdmin')) {
  524. serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
  525. } else {
  526. serviceConfigProperty.set('isEditable', false);
  527. }
  528. console.log("config result", serviceConfigProperty);
  529. } else {
  530. serviceConfigProperty.set('isVisible', false);
  531. }
  532. if (overrides != null) {
  533. for(var overridenValue in overrides){
  534. var hostsArray = overrides[overridenValue];
  535. var newSCP = App.ServiceConfigProperty.create(_serviceConfigProperty);
  536. newSCP.set('value', overridenValue);
  537. newSCP.set('isOriginalSCP', false); // indicated this is overridden value,
  538. newSCP.set('parentSCP', serviceConfigProperty);
  539. newSCP.set('selectedHostOptions', Ember.A(hostsArray));
  540. var parentOverridesArray = serviceConfigProperty.get('overrides');
  541. if(parentOverridesArray == null){
  542. parentOverridesArray = Ember.A([]);
  543. serviceConfigProperty.set('overrides', parentOverridesArray);
  544. }
  545. parentOverridesArray.pushObject(newSCP);
  546. console.debug("createOverrideProperty(): Added:", newSCP, " to main-property:", serviceConfigProperty)
  547. }
  548. }
  549. componentConfig.configs.pushObject(serviceConfigProperty);
  550. serviceConfigProperty.validate();
  551. }, this);
  552. },
  553. /**
  554. * open popup with appropriate message
  555. */
  556. restartServicePopup: function (event) {
  557. if(this.get("isSubmitDisabled")){
  558. return;
  559. }
  560. var header;
  561. var message;
  562. var value;
  563. var flag = false;
  564. if (App.supports.hostOverrides ||
  565. (this.get('content.serviceName') !== 'HDFS' && this.get('content.isStopped') === true) ||
  566. ((this.get('content.serviceName') === 'HDFS') && this.get('content.isStopped') === true && (!App.Service.find().someProperty('id', 'MAPREDUCE') || App.Service.find('MAPREDUCE').get('isStopped')))) {
  567. var result = this.saveServiceConfigProperties();
  568. App.router.get('clusterController').updateClusterData();
  569. flag = result.flag;
  570. if (result.flag === true) {
  571. header = App.supports.hostOverrides ? Em.I18n.t('services.service.config.restartService') : Em.I18n.t('services.service.config.startService');
  572. message = Em.I18n.t('services.service.config.saveConfig');
  573. } else {
  574. header = Em.I18n.t('common.failure');
  575. message = result.message;
  576. value = result.value;
  577. }
  578. } else {
  579. if (this.get('content.serviceName') !== 'HDFS' || (this.get('content.serviceName') === 'HDFS' && !App.Service.find().someProperty('id', 'MAPREDUCE'))) {
  580. header = Em.I18n.t('services.service.config.stopService');
  581. message = Em.I18n.t('services.service.config.msgServiceStop');
  582. } else {
  583. header = Em.I18n.t('services.service.config.stopService');
  584. message = Em.I18n.t('services.service.config.msgHDFSMapRServiceStop');
  585. }
  586. }
  587. var self = this;
  588. App.ModalPopup.show({
  589. header: header,
  590. primary: Em.I18n.t('ok'),
  591. secondary: null,
  592. onPrimary: function () {
  593. this.hide();
  594. if (App.supports.hostOverrides) {
  595. self.loadStep();
  596. }
  597. },
  598. bodyClass: Ember.View.extend({
  599. flag: flag,
  600. message: message,
  601. siteProperties: value,
  602. getDisplayMessage: function () {
  603. var displayMsg = [];
  604. var siteProperties = this.get('siteProperties');
  605. if (siteProperties) {
  606. siteProperties.forEach(function (_siteProperty) {
  607. var displayProperty = _siteProperty.siteProperty;
  608. var displayNames = _siteProperty.displayNames;
  609. /////////
  610. if (displayNames && displayNames.length) {
  611. if (displayNames.length === 1) {
  612. displayMsg.push(displayProperty + Em.I18n.t('as') + displayNames[0]);
  613. } else {
  614. var name;
  615. displayNames.forEach(function (_name, index) {
  616. if (index === 0) {
  617. name = _name;
  618. } else if (index === siteProperties.length - 1) {
  619. name = name + Em.I18n.t('and') + _name;
  620. } else {
  621. name = name + ', ' + _name;
  622. }
  623. }, this);
  624. displayMsg.push(displayProperty + Em.I18n.t('as') + name);
  625. }
  626. } else {
  627. displayMsg.push(displayProperty);
  628. }
  629. }, this);
  630. }
  631. return displayMsg;
  632. }.property('siteProperties'),
  633. template: Ember.Handlebars.compile([
  634. '<h5>{{view.message}}</h5>',
  635. '{{#unless view.flag}}',
  636. '<br/>',
  637. '<div class="pre-scrollable" style="max-height: 250px;">',
  638. '<ul>',
  639. '{{#each val in view.getDisplayMessage}}',
  640. '<li>',
  641. '{{val}}',
  642. '</li>',
  643. '{{/each}}',
  644. '</ul>',
  645. '</div>',
  646. '{{/unless}}'
  647. ].join('\n'))
  648. })
  649. });
  650. },
  651. /**
  652. * Save config properties
  653. */
  654. saveServiceConfigProperties: function () {
  655. var result = {
  656. flag: false,
  657. message: null,
  658. value: null
  659. };
  660. this.savedHostToOverrideSiteToTagMap = {};
  661. var configs = this.get('stepConfigs').findProperty('serviceName', this.get('content.serviceName')).get('configs');
  662. this.saveGlobalConfigs(configs);
  663. this.saveSiteConfigs(configs);
  664. /**
  665. * First we put cluster configurations, which automatically creates /configurations
  666. * resources. Next we update host level overrides.
  667. */
  668. result.flag = this.doPUTClusterConfigurations();
  669. if (!result.flag) {
  670. result.message = Em.I18n.t('services.service.config.failSaveConfig');
  671. }else{
  672. result.flag = result.flag && this.doPUTHostOverridesConfigurationSites();
  673. if (!result.flag) {
  674. result.message = Em.I18n.t('services.service.config.failSaveConfigHostExceptions');
  675. }
  676. }
  677. console.log("The result from applyCreatdConfToService is: " + result);
  678. return result;
  679. },
  680. /**
  681. * save new or change exist configs in global configs
  682. * @param configs
  683. */
  684. saveGlobalConfigs: function (configs) {
  685. var globalConfigs = this.get('globalConfigs');
  686. configs.filterProperty('id', 'puppet var').forEach(function (uiConfigProperty) {
  687. if (globalConfigs.someProperty('name', uiConfigProperty.name)) {
  688. var modelGlobalConfig = globalConfigs.findProperty('name', uiConfigProperty.name);
  689. modelGlobalConfig.value = uiConfigProperty.value;
  690. var uiOverrides = uiConfigProperty.get('overrides');
  691. if(uiOverrides!=null && uiOverrides.get('length')>0){
  692. modelGlobalConfig.overrides = {};
  693. uiOverrides.forEach(function(uiOverride){
  694. var value = uiOverride.get('value');
  695. modelGlobalConfig.overrides[value] = [];
  696. uiOverride.get('selectedHostOptions').forEach(function(host){
  697. modelGlobalConfig.overrides[value].push(host);
  698. });
  699. });
  700. }
  701. } else {
  702. globalConfigs.pushObject({
  703. name: uiConfigProperty.name,
  704. value: uiConfigProperty.value
  705. });
  706. }
  707. }, this);
  708. this.setHiveHostName(globalConfigs);
  709. this.setOozieHostName(globalConfigs);
  710. this.set('globalConfigs', globalConfigs);
  711. },
  712. /**
  713. * set hive hostnames in global configs
  714. * @param globals
  715. */
  716. setHiveHostName: function (globals) {
  717. if (globals.someProperty('name', 'hive_database')) {
  718. var hiveDb = globals.findProperty('name', 'hive_database');
  719. if (hiveDb.value === 'New MySQL Database') {
  720. if (globals.someProperty('name', 'hive_ambari_host')) {
  721. globals.findProperty('name', 'hive_ambari_host').name = 'hive_hostname';
  722. }
  723. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_host'));
  724. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_database'));
  725. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_host'));
  726. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_database'));
  727. } else if (hiveDb.value === 'Existing MySQL Database'){
  728. globals.findProperty('name', 'hive_existing_mysql_host').name = 'hive_hostname';
  729. globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
  730. globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
  731. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_host'));
  732. globals = globals.without(globals.findProperty('name', 'hive_existing_oracle_database'));
  733. } else{ //existing oracle database
  734. globals.findProperty('name', 'hive_existing_oracle_host').name = 'hive_hostname';
  735. globals = globals.without(globals.findProperty('name', 'hive_ambari_host'));
  736. globals = globals.without(globals.findProperty('name', 'hive_ambari_database'));
  737. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_host'));
  738. globals = globals.without(globals.findProperty('name', 'hive_existing_mysql_database'));
  739. }
  740. }
  741. },
  742. /**
  743. * set hive hostnames in global configs
  744. * @param globals
  745. */
  746. setOozieHostName: function (globals) {
  747. if (globals.someProperty('name', 'oozie_database')) {
  748. var oozieDb = globals.findProperty('name', 'oozie_database');
  749. if (oozieDb.value === 'New Derby Database'){
  750. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  751. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  752. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  753. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  754. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  755. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  756. } else if (oozieDb.value === 'New MySQL Database') {
  757. if (globals.someProperty('name', 'oozie_ambari_host')) {
  758. globals.findProperty('name', 'oozie_ambari_host').name = 'oozie_hostname';
  759. }
  760. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  761. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  762. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  763. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  764. globals = globals.without(globals.findProperty('name', 'oozie_derby_database'));
  765. } else if (oozieDb.value === 'Existing MySQL Database'){
  766. globals.findProperty('name', 'oozie_existing_mysql_host').name = 'oozie_hostname';
  767. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  768. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  769. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_host'));
  770. globals = globals.without(globals.findProperty('name', 'oozie_existing_oracle_database'));
  771. globals = globals.without(globals.findProperty('name', 'oozie_derby_database'));
  772. } else{ //existing oracle database
  773. globals.findProperty('name', 'oozie_existing_oracle_host').name = 'oozie_hostname';
  774. globals = globals.without(globals.findProperty('name', 'oozie_ambari_host'));
  775. globals = globals.without(globals.findProperty('name', 'oozie_ambari_database'));
  776. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_host'));
  777. globals = globals.without(globals.findProperty('name', 'oozie_existing_mysql_database'));
  778. globals = globals.without(globals.findProperty('name', 'oozie_derby_database'));
  779. }
  780. }
  781. },
  782. /**
  783. * save site configs
  784. * @param configs
  785. */
  786. saveSiteConfigs: function (configs) {
  787. //storedConfigs contains custom configs as well
  788. var serviceConfigProperties = configs.filterProperty('id', 'site property');
  789. serviceConfigProperties.forEach(function(_config){
  790. if(typeof _config.get('value') === "boolean") _config.set('value', _config.value.toString());
  791. });
  792. var storedConfigs = serviceConfigProperties.filterProperty('value');
  793. var allUiConfigs = this.loadUiSideConfigs(this.get('configMapping').all());
  794. this.set('uiConfigs', storedConfigs.concat(allUiConfigs));
  795. },
  796. /**
  797. * return configs from the UI side
  798. * @param configMapping array with configs
  799. * @return {Array}
  800. */
  801. loadUiSideConfigs: function (configMapping) {
  802. var uiConfig = [];
  803. var configs = configMapping.filterProperty('foreignKey', null);
  804. configs.forEach(function (_config) {
  805. var valueWithOverrides = this.getGlobConfigValueWithOverrides(_config.templateName, _config.value, _config.name);
  806. if (valueWithOverrides !== null) {
  807. uiConfig.pushObject({
  808. "id": "site property",
  809. "name": _config.name,
  810. "value": valueWithOverrides.value,
  811. "filename": _config.filename,
  812. "overrides": valueWithOverrides.overrides
  813. });
  814. }
  815. }, this);
  816. return uiConfig;
  817. },
  818. /**
  819. * return global config value
  820. * @param templateName
  821. * @param expression
  822. * @param name
  823. * @return {
  824. * value: '...',
  825. * overrides: {
  826. * 'value1': [h1, h2],
  827. * 'value2': [h3]
  828. * }
  829. * }
  830. */
  831. getGlobConfigValueWithOverrides: function (templateName, expression, name) {
  832. var express = expression.match(/<(.*?)>/g);
  833. var value = expression;
  834. if (express == null) {
  835. return { value : expression, overrides: []}; // if site property do not map any global property then return the value
  836. }
  837. var overrideHostToValue = {};
  838. express.forEach(function (_express) {
  839. //console.log("The value of template is: " + _express);
  840. var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
  841. if (this.get('globalConfigs').someProperty('name', templateName[index])) {
  842. //console.log("The name of the variable is: " + this.get('content.serviceConfigProperties').findProperty('name', templateName[index]).name);
  843. var globalObj = this.get('globalConfigs').findProperty('name', templateName[index]);
  844. var globValue = globalObj.value;
  845. // Hack for templeton.zookeeper.hosts
  846. var preReplaceValue = null;
  847. if (value !== null) { // if the property depends on more than one template name like <templateName[0]>/<templateName[1]> then don't proceed to the next if the prior is null or not found in the global configs
  848. preReplaceValue = value;
  849. value = this._replaceConfigValues(name, _express, value, globValue);
  850. }
  851. if(globalObj.overrides!=null){
  852. for(ov in globalObj.overrides){
  853. var hostsArray = globalObj.overrides[ov];
  854. hostsArray.forEach(function(host){
  855. if(!(host in overrideHostToValue)){
  856. overrideHostToValue[host] = this._replaceConfigValues(name, _express, preReplaceValue, ov);
  857. }else{
  858. overrideHostToValue[host] = this._replaceConfigValues(name, _express, overrideHostToValue[host], ov);
  859. }
  860. }, this);
  861. }
  862. }
  863. } else {
  864. /*
  865. console.log("ERROR: The variable name is: " + templateName[index]);
  866. console.log("ERROR: mapped config from configMapping file has no corresponding variable in " +
  867. "content.serviceConfigProperties. Two possible reasons for the error could be: 1) The service is not selected. " +
  868. "and/OR 2) The service_config metadata file has no corresponding global var for the site property variable");
  869. */
  870. value = null;
  871. }
  872. }, this);
  873. var valueWithOverrides = {
  874. value: value,
  875. overrides: {}
  876. };
  877. if(!jQuery.isEmptyObject(overrideHostToValue)){
  878. for(var host in overrideHostToValue){
  879. var hostVal = overrideHostToValue[host];
  880. if(!(hostVal in valueWithOverrides.overrides)){
  881. valueWithOverrides.overrides[hostVal] = [];
  882. }
  883. valueWithOverrides.overrides[hostVal].push(host);
  884. }
  885. }
  886. return valueWithOverrides;
  887. },
  888. _replaceConfigValues: function (name, express, value, globValue) {
  889. if (name === "templeton.zookeeper.hosts" || name === 'hbase.zookeeper.quorum') {
  890. var zooKeeperPort = '2181';
  891. if (typeof globValue === 'string') {
  892. var temp = [];
  893. temp.push(globValue);
  894. globValue = temp;
  895. }
  896. if (name === "templeton.zookeeper.hosts") {
  897. var temp = [];
  898. globValue.forEach(function (_host, index) {
  899. temp.push(globValue[index] + ':' + zooKeeperPort);
  900. }, this);
  901. globValue = temp;
  902. }
  903. value = value.replace(express, globValue.toString());
  904. } else {
  905. value = value.replace(express, globValue);
  906. }
  907. return value;
  908. },
  909. /**
  910. * Saves cluster level configurations for all necessary sites.
  911. * PUT calls are made to /api/v1/clusters/clusterName for each site.
  912. *
  913. * @return {Boolean}
  914. */
  915. doPUTClusterConfigurations: function () {
  916. var result = true;
  917. var serviceConfigTags = this.get('serviceConfigTags');
  918. this.setNewTagNames(serviceConfigTags);
  919. var siteNameToServerDataMap = {};
  920. serviceConfigTags.forEach(function (_serviceTags) {
  921. if (_serviceTags.siteName === 'global') {
  922. console.log("TRACE: Inside global");
  923. var serverGlobalConfigs = this.createGlobalSiteObj(_serviceTags.newTagName);
  924. siteNameToServerDataMap['global'] = serverGlobalConfigs;
  925. if(this.isConfigChanged(App.config.loadedConfigurationsCache['global_'+this.loadedClusterSiteToTagMap['global']], serverGlobalConfigs.properties)){
  926. result = result && this.doPUTClusterConfigurationSite(serverGlobalConfigs);
  927. }
  928. } else if (_serviceTags.siteName === 'core-site') {
  929. console.log("TRACE: Inside core-site");
  930. if (this.get('content.serviceName') === 'HDFS') {
  931. var coreSiteConfigs = this.createCoreSiteObj(_serviceTags.newTagName);
  932. siteNameToServerDataMap['core-site'] = coreSiteConfigs;
  933. if(this.isConfigChanged(App.config.loadedConfigurationsCache['core-site_'+this.loadedClusterSiteToTagMap['core-site']], coreSiteConfigs.properties)){
  934. result = result && this.doPUTClusterConfigurationSite(coreSiteConfigs);
  935. }
  936. }
  937. } else {
  938. var serverConfigs = this.createSiteObj(_serviceTags.siteName, _serviceTags.newTagName);
  939. siteNameToServerDataMap[_serviceTags.siteName] = serverConfigs;
  940. if(this.isConfigChanged(App.config.loadedConfigurationsCache[_serviceTags.siteName+'_'+this.loadedClusterSiteToTagMap[_serviceTags.siteName]], serverConfigs.properties)){
  941. result = result && this.doPUTClusterConfigurationSite(serverConfigs);
  942. }
  943. }
  944. }, this);
  945. this.savedSiteNameToServerServiceConfigDataMap = siteNameToServerDataMap;
  946. return result;
  947. },
  948. /**
  949. * Compares the loaded config values with the saving config values.
  950. */
  951. isConfigChanged: function (loadedConfig, savingConfig) {
  952. var changed = false;
  953. if (loadedConfig != null && savingConfig != null) {
  954. var seenLoadKeys = [];
  955. for ( var loadKey in loadedConfig) {
  956. seenLoadKeys.push(loadKey);
  957. var loadValue = loadedConfig[loadKey];
  958. var saveValue = savingConfig[loadKey];
  959. if("boolean" == typeof(saveValue)){
  960. saveValue = saveValue.toString();
  961. }
  962. if(saveValue==null){
  963. saveValue = "null";
  964. }
  965. if (loadValue !== saveValue) {
  966. changed = true;
  967. break;
  968. }
  969. }
  970. for ( var saveKey in savingConfig) {
  971. if (seenLoadKeys.indexOf(saveKey) < 0) {
  972. changed = true;
  973. break;
  974. }
  975. }
  976. }
  977. return changed;
  978. },
  979. /**
  980. * Saves configuration of a particular site. The provided data
  981. * contains the site name and tag to be used.
  982. */
  983. doPUTClusterConfigurationSite: function (data) {
  984. var result;
  985. var url = this.getUrl('', '');
  986. var clusterData = {
  987. Clusters: {
  988. desired_config: data
  989. }
  990. };
  991. console.log("applyClusterConfigurationToSite(): PUTting data:", clusterData);
  992. $.ajax({
  993. type: 'PUT',
  994. url: url,
  995. async: false,
  996. dataType: 'text',
  997. data: JSON.stringify(clusterData),
  998. timeout: 5000,
  999. success: function (data) {
  1000. console.log("applyClusterConfigurationToSite(): In success for data:", data);
  1001. result = true;
  1002. },
  1003. error: function (request, ajaxOptions, error) {
  1004. console.log('applyClusterConfigurationToSite(): ERROR:', request.responseText, ", error=", error);
  1005. result = false;
  1006. },
  1007. statusCode: require('data/statusCodes')
  1008. });
  1009. console.log("applyClusterConfigurationToSite(): Exiting with result=" + result);
  1010. return result;
  1011. },
  1012. /**
  1013. * Creates host level overrides for service configuration.
  1014. *
  1015. */
  1016. doPUTHostOverridesConfigurationSites: function(){
  1017. var singlePUTHostData = [];
  1018. var savedHostSiteArray = [];
  1019. for ( var host in this.savedHostToOverrideSiteToTagMap) {
  1020. for ( var siteName in this.savedHostToOverrideSiteToTagMap[host]) {
  1021. var tagName = this.savedHostToOverrideSiteToTagMap[host][siteName].tagName;
  1022. var map = this.savedHostToOverrideSiteToTagMap[host][siteName].map;
  1023. savedHostSiteArray.push(host+"///"+siteName);
  1024. singlePUTHostData.push({
  1025. RequestInfo: {
  1026. query: 'Hosts/host_name='+host
  1027. },
  1028. Body: {
  1029. Hosts: {
  1030. desired_config: {
  1031. type: siteName,
  1032. tag: tagName,
  1033. properties: map
  1034. }
  1035. }
  1036. }
  1037. });
  1038. }
  1039. }
  1040. // Now cleanup removed overrides
  1041. for ( var loadedHost in this.loadedHostToOverrideSiteToTagMap) {
  1042. for ( var loadedSiteName in this.loadedHostToOverrideSiteToTagMap[loadedHost]) {
  1043. if (!(savedHostSiteArray.contains(loadedHost + "///" + loadedSiteName))) {
  1044. // This host-site combination was loaded, but not saved.
  1045. // Meaning it is not needed anymore. Hence send a DELETE command.
  1046. singlePUTHostData.push({
  1047. RequestInfo: {
  1048. query: 'Hosts/host_name='+loadedHost
  1049. },
  1050. Body: {
  1051. Hosts: {
  1052. desired_config: {
  1053. type: loadedSiteName,
  1054. tag: this.loadedHostToOverrideSiteToTagMap[loadedHost][loadedSiteName],
  1055. selected: false
  1056. }
  1057. }
  1058. }
  1059. });
  1060. }
  1061. }
  1062. }
  1063. console.debug("createHostOverrideConfigSites(): PUTting host-overrides. Data=",singlePUTHostData);
  1064. if(singlePUTHostData.length>0){
  1065. var url = this.getUrl('', '/hosts');
  1066. var hostOverrideResult = true;
  1067. $.ajax({
  1068. type: 'PUT',
  1069. url: url,
  1070. data: JSON.stringify(singlePUTHostData),
  1071. async: false,
  1072. dataType: 'text',
  1073. timeout: 5000,
  1074. success: function (data) {
  1075. var jsonData = jQuery.parseJSON(data);
  1076. hostOverrideResult = true;
  1077. console.log("createHostOverrideConfigSites(): SUCCESS:", url, ". RESPONSE:",jsonData);
  1078. },
  1079. error: function (request, ajaxOptions, error) {
  1080. hostOverrideResult = false;
  1081. console.log("createHostOverrideConfigSites(): ERROR:", url, ". RESPONSE:",request.responseText);
  1082. },
  1083. statusCode: require('data/statusCodes')
  1084. });
  1085. return hostOverrideResult;
  1086. }
  1087. return true;
  1088. },
  1089. /**
  1090. * add newTagName property to each config in serviceConfigs
  1091. * @param serviceConfigs
  1092. */
  1093. setNewTagNames: function (serviceConfigs) {
  1094. var time = (new Date).getTime();
  1095. serviceConfigs.forEach(function (_serviceConfigs) {
  1096. _serviceConfigs.newTagName = 'version' + time;
  1097. }, this);
  1098. },
  1099. /**
  1100. * create global site object
  1101. * @param tagName
  1102. * @return {Object}
  1103. */
  1104. createGlobalSiteObj: function (tagName) {
  1105. var globalSiteProperties = {};
  1106. this.get('globalConfigs').forEach(function (_globalSiteObj) {
  1107. // do not pass any globalConfigs whose name ends with _host or _hosts
  1108. if (!/_hosts?$/.test(_globalSiteObj.name)) {
  1109. // append "m" to JVM memory options except for hadoop_heapsize
  1110. if (/_heapsize|_newsize|_maxnewsize$/.test(_globalSiteObj.name) && _globalSiteObj.name !== 'hadoop_heapsize') {
  1111. _globalSiteObj.value += "m";
  1112. }
  1113. globalSiteProperties[_globalSiteObj.name] = _globalSiteObj.value;
  1114. this.recordHostOverride(_globalSiteObj, 'global', tagName, this);
  1115. //console.log("TRACE: name of the global property is: " + _globalSiteObj.name);
  1116. //console.log("TRACE: value of the global property is: " + _globalSiteObj.value);
  1117. }
  1118. }, this);
  1119. return {"type": "global", "tag": tagName, "properties": globalSiteProperties};
  1120. },
  1121. recordHostOverride: function(serviceConfigObj, siteName, tagName, self){
  1122. if('get' in serviceConfigObj){
  1123. return this._recordHostOverrideFromEmberObj(serviceConfigObj, siteName, tagName, self);
  1124. }else{
  1125. return this._recordHostOverrideFromObj(serviceConfigObj, siteName, tagName, self);
  1126. }
  1127. },
  1128. /**
  1129. * Records all the host overrides per site/tag
  1130. */
  1131. _recordHostOverrideFromObj: function(serviceConfigObj, siteName, tagName, self){
  1132. var overrides = serviceConfigObj.overrides;
  1133. if(overrides){
  1134. for(var value in overrides){
  1135. overrides[value].forEach(function(host){
  1136. if(!(host in self.savedHostToOverrideSiteToTagMap)){
  1137. self.savedHostToOverrideSiteToTagMap[host] = {};
  1138. }
  1139. if(!(siteName in self.savedHostToOverrideSiteToTagMap[host])){
  1140. self.savedHostToOverrideSiteToTagMap[host][siteName] = {};
  1141. self.savedHostToOverrideSiteToTagMap[host][siteName].map = {};
  1142. }
  1143. var finalTag = tagName + '_' + host;
  1144. console.log("recordHostOverride(): Saving host override for host="+host+", site="+siteName+", tag="+finalTag+", (key,value)=("+serviceConfigObj.name+","+value+")");
  1145. self.savedHostToOverrideSiteToTagMap[host][siteName].tagName = finalTag;
  1146. self.savedHostToOverrideSiteToTagMap[host][siteName].map[serviceConfigObj.name] = value;
  1147. });
  1148. }
  1149. }
  1150. },
  1151. /**
  1152. * Records all the host overrides per site/tag
  1153. */
  1154. _recordHostOverrideFromEmberObj: function(serviceConfigObj, siteName, tagName, self){
  1155. var overrides = serviceConfigObj.get('overrides');
  1156. if(overrides){
  1157. overrides.forEach(function(override){
  1158. override.get('selectedHostOptions').forEach(function(host){
  1159. if(!(host in self.savedHostToOverrideSiteToTagMap)){
  1160. self.savedHostToOverrideSiteToTagMap[host] = {};
  1161. }
  1162. if(!(siteName in self.savedHostToOverrideSiteToTagMap[host])){
  1163. self.savedHostToOverrideSiteToTagMap[host][siteName] = {};
  1164. self.savedHostToOverrideSiteToTagMap[host][siteName].map = {};
  1165. }
  1166. var finalTag = tagName + '_' + host;
  1167. console.log("recordHostOverride(): Saving host override for host="+host+", site="+siteName+", tag="+finalTag+", (key,value)=("+serviceConfigObj.name+","+override.get('value')+")");
  1168. self.savedHostToOverrideSiteToTagMap[host][siteName].tagName = finalTag;
  1169. self.savedHostToOverrideSiteToTagMap[host][siteName].map[serviceConfigObj.name] = override.get('value');
  1170. });
  1171. });
  1172. }
  1173. },
  1174. /**
  1175. * create core site object
  1176. * @param tagName
  1177. * @return {Object}
  1178. */
  1179. createCoreSiteObj: function (tagName) {
  1180. var coreSiteObj = this.get('uiConfigs').filterProperty('filename', 'core-site.xml');
  1181. var coreSiteProperties = {};
  1182. // hadoop.proxyuser.oozie.hosts needs to be skipped if oozie is not selected
  1183. var isOozieSelected = App.Service.find().someProperty('serviceName', 'OOZIE');
  1184. var oozieUser = this.get('globalConfigs').someProperty('name', 'oozie_user') ? this.get('globalConfigs').findProperty('name', 'oozie_user').value : null;
  1185. var isHiveSelected = App.Service.find().someProperty('serviceName', 'HIVE');
  1186. var hiveUser = this.get('globalConfigs').someProperty('name', 'hive_user') ? this.get('globalConfigs').findProperty('name', 'hive_user').value : null;
  1187. var isHcatSelected = App.Service.find().someProperty('serviceName', 'WEBHCAT');
  1188. var hcatUser = this.get('globalConfigs').someProperty('name', 'hcat_user') ? this.get('globalConfigs').findProperty('name', 'hcat_user').value : null;
  1189. coreSiteObj.forEach(function (_coreSiteObj) {
  1190. if ((isOozieSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + oozieUser + '.groups')) && (isHiveSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hiveUser + '.groups')) && (isHcatSelected || (_coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.hosts' && _coreSiteObj.name != 'hadoop.proxyuser.' + hcatUser + '.groups'))) {
  1191. coreSiteProperties[_coreSiteObj.name] = _coreSiteObj.value;
  1192. this.recordHostOverride(_coreSiteObj, 'core-site', tagName, this);
  1193. }
  1194. }, this);
  1195. return {"type": "core-site", "tag": tagName, "properties": coreSiteProperties};
  1196. },
  1197. /**
  1198. * create site object
  1199. * @param siteName
  1200. * @param tagName
  1201. * @return {Object}
  1202. */
  1203. createSiteObj: function (siteName, tagName) {
  1204. var siteObj = this.get('uiConfigs').filterProperty('filename', siteName + '.xml');
  1205. var siteProperties = {};
  1206. siteObj.forEach(function (_siteObj) {
  1207. siteProperties[_siteObj.name] = _siteObj.value;
  1208. this.recordHostOverride(_siteObj, siteName, tagName, this);
  1209. }, this);
  1210. return {"type": siteName, "tag": tagName, "properties": siteProperties};
  1211. },
  1212. /**
  1213. * Set display names of the property tfrom he puppet/global names
  1214. * @param: displayNames: a field to be set with displayNames
  1215. * @param names: array of property puppet/global names
  1216. */
  1217. setPropertyDisplayNames: function (displayNames, names) {
  1218. var stepConfigs = this.get('stepConfigs').findProperty('serviceName', this.get('content.serviceName')).configs;
  1219. names.forEach(function (_name, index) {
  1220. if (stepConfigs.someProperty('name', _name)) {
  1221. displayNames.push(stepConfigs.findProperty('name', _name).displayName);
  1222. }
  1223. }, this);
  1224. },
  1225. /**
  1226. * Set property of the site variable
  1227. */
  1228. setSiteProperty: function (key, value, filename) {
  1229. if (filename === 'core-site.xml' && this.get('uiConfigs').filterProperty('filename', 'core-site.xml').someProperty('name', key)) {
  1230. this.get('uiConfigs').filterProperty('filename', 'core-site.xml').findProperty('name', key).value = value;
  1231. return;
  1232. }
  1233. this.get('uiConfigs').pushObject({
  1234. "id": "site property",
  1235. "name": key,
  1236. "value": value,
  1237. "filename": filename
  1238. });
  1239. },
  1240. /**
  1241. * return either specific url for request if testMode is false or testUrl
  1242. * @param testUrl
  1243. * @param url
  1244. * @return {*}
  1245. */
  1246. getUrl: function (testUrl, url) {
  1247. return (App.testMode) ? testUrl : App.apiPrefix + '/clusters/' + App.router.getClusterName() + url;
  1248. },
  1249. /**
  1250. * Adds host name of master component to global config;
  1251. */
  1252. addHostNamesToGlobalConfig: function () {
  1253. var serviceName = this.get('content.serviceName');
  1254. var globalConfigs = this.get('globalConfigs');
  1255. var serviceConfigs = this.get('serviceConfigs').findProperty('serviceName', serviceName).configs;
  1256. //namenode_host is required to derive "fs.default.name" a property of core-site
  1257. var nameNodeHost = this.get('serviceConfigs').findProperty('serviceName', 'HDFS').configs.findProperty('name', 'namenode_host');
  1258. nameNodeHost.defaultValue = App.Service.find('HDFS').get('hostComponents').findProperty('componentName', 'NAMENODE').get('host.hostName');
  1259. globalConfigs.push(nameNodeHost);
  1260. //zooKeeperserver_host
  1261. var zooKeperHost = this.get('serviceConfigs').findProperty('serviceName', 'ZOOKEEPER').configs.findProperty('name', 'zookeeperserver_hosts');
  1262. if (serviceName === 'ZOOKEEPER' || serviceName === 'HBASE' || serviceName === 'WEBHCAT') {
  1263. zooKeperHost.defaultValue = App.Service.find('ZOOKEEPER').get('hostComponents').filterProperty('componentName', 'ZOOKEEPER_SERVER').mapProperty('host.hostName');
  1264. globalConfigs.push(zooKeperHost);
  1265. }
  1266. switch (serviceName) {
  1267. case 'HDFS':
  1268. var sNameNodeHost = serviceConfigs.findProperty('name', 'snamenode_host');
  1269. sNameNodeHost.defaultValue = this.get('content.hostComponents').findProperty('componentName', 'SECONDARY_NAMENODE').get('host.hostName');
  1270. globalConfigs.push(sNameNodeHost);
  1271. break;
  1272. case 'MAPREDUCE':
  1273. var jobTrackerHost = serviceConfigs.findProperty('name', 'jobtracker_host');
  1274. jobTrackerHost.defaultValue = this.get('content.hostComponents').findProperty('componentName', 'JOBTRACKER').get('host.hostName');
  1275. globalConfigs.push(jobTrackerHost);
  1276. break;
  1277. case 'HIVE':
  1278. var hiveMetastoreHost = serviceConfigs.findProperty('name', 'hivemetastore_host');
  1279. hiveMetastoreHost.defaultValue = this.get('content.hostComponents').findProperty('componentName', 'HIVE_SERVER').get('host.hostName');
  1280. globalConfigs.push(hiveMetastoreHost);
  1281. break;
  1282. case 'OOZIE':
  1283. var oozieServerHost = serviceConfigs.findProperty('name', 'oozieserver_host');
  1284. oozieServerHost.defaultValue = this.get('content.hostComponents').findProperty('componentName', 'OOZIE_SERVER').get('host.hostName');
  1285. globalConfigs.push(oozieServerHost);
  1286. break;
  1287. case 'HBASE':
  1288. var hbaseMasterHost = serviceConfigs.findProperty('name', 'hbasemaster_host');
  1289. hbaseMasterHost.defaultValue = this.get('content.hostComponents').filterProperty('componentName', 'HBASE_MASTER').mapProperty('host.hostName');
  1290. globalConfigs.push(hbaseMasterHost);
  1291. break;
  1292. }
  1293. },
  1294. /**
  1295. * Provides service component name and display-name information for
  1296. * the current selected service.
  1297. */
  1298. getCurrentServiceComponents: function () {
  1299. var service = this.get('content');
  1300. var components = service.get('hostComponents');
  1301. var validComponents = Ember.A([]);
  1302. var seenComponents = {};
  1303. components.forEach(function(component){
  1304. var cn = component.get('componentName');
  1305. var cdn = component.get('displayName');
  1306. if(!seenComponents[cn]){
  1307. validComponents.push(Ember.Object.create({
  1308. componentName: cn,
  1309. displayName: cdn,
  1310. selected: false
  1311. }));
  1312. seenComponents[cn] = cn;
  1313. }
  1314. });
  1315. return validComponents;
  1316. }.property('content'),
  1317. getAllHosts: function () {
  1318. return App.router.get('mainHostController.content');
  1319. }.property('App.router.mainHostController.content'),
  1320. doCancel: function () {
  1321. location.reload();
  1322. }
  1323. });