step6_controller.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  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 blueprintUtils = require('utils/blueprint');
  20. var validationUtils = require('utils/validator');
  21. /**
  22. * By Step 6, we have the following information stored in App.db and set on this
  23. * controller by the router:
  24. *
  25. * hosts: App.db.hosts (list of all hosts the user selected in Step 3)
  26. * selectedServiceNames: App.db.selectedServiceNames (the services that the user selected in Step 4)
  27. * masterComponentHosts: App.db.masterComponentHosts (master-components-to-hosts mapping the user selected in Step 5)
  28. *
  29. * Step 6 will set the following information in App.db:
  30. * slaveComponentHosts: App.db.slaveComponentHosts (slave-components-to-hosts mapping the user selected in Step 6)
  31. *
  32. */
  33. App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
  34. name: 'wizardStep6Controller',
  35. /**
  36. * List of hosts
  37. * @type {object[]}
  38. */
  39. hosts: [],
  40. /**
  41. * List of components info about selecting/deselecting status for components.
  42. *
  43. * @type {Array}
  44. * @item {Em.Object}
  45. * @property name {String} - component name
  46. * @property label {String} - component display name
  47. * @property allChecked {bool} - all checkboxes are checked
  48. * @property noChecked {bool} - no checkboxes checked
  49. */
  50. headers: [],
  51. /**
  52. * @type {bool}
  53. */
  54. isLoaded: false,
  55. /**
  56. * Indication if user has chosen hosts to install clients
  57. * @type {bool}
  58. */
  59. isClientsSet: false,
  60. /**
  61. * Define state for submit button
  62. * @type {bool}
  63. */
  64. submitDisabled: Em.computed.or('validationInProgress', 'App.router.btnClickInProgress'),
  65. /**
  66. * timer for validation request
  67. */
  68. timer: null,
  69. /**
  70. * true if request for validation is in progress
  71. *
  72. * @type {bool}
  73. */
  74. validationInProgress: false,
  75. /**
  76. * Check if <code>addHostWizard</code> used
  77. * @type {bool}
  78. */
  79. isAddHostWizard: Em.computed.equal('content.controllerName', 'addHostController'),
  80. /**
  81. * Check if <code>installerWizard</code> used
  82. * @type {bool}
  83. */
  84. isInstallerWizard: Em.computed.equal('content.controllerName', 'installerController'),
  85. isAllCheckboxesEmpty: function() {
  86. var hosts = this.get('hosts');
  87. for (var i = 0; i < hosts.length; i++) {
  88. var checkboxes = hosts[i].checkboxes;
  89. for (var j = 0; j < checkboxes.length; j++) {
  90. if (checkboxes[j].checked) {
  91. return false;
  92. }
  93. }
  94. }
  95. return true;
  96. },
  97. /**
  98. * Check if <code>addServiceWizard</code> used
  99. * @type {bool}
  100. */
  101. isAddServiceWizard: Em.computed.equal('content.controllerName', 'addServiceController'),
  102. installedServiceNames: function () {
  103. return this.get('content.services').filterProperty('isInstalled').mapProperty('serviceName');
  104. }.property('content.services').cacheable(),
  105. /**
  106. * Validation error messages which don't related with any master
  107. */
  108. generalErrorMessages: [],
  109. /**
  110. * Validation warning messages which don't related with any master
  111. */
  112. generalWarningMessages: [],
  113. /**
  114. * true if validation has any general (which is not related with concrete host) error message
  115. */
  116. anyGeneralErrors: Em.computed.or('errorMessage','generalErrorMessages.length'),
  117. /**
  118. * true if validation has any general (which is not related with concrete host) warning message
  119. */
  120. anyGeneralWarnings: Em.computed.gt('generalWarningMessages.length', 0),
  121. /**
  122. * true if validation has any general (which is not related with concrete host) error or warning message
  123. */
  124. anyGeneralIssues: Em.computed.or('anyGeneralErrors', 'anyGeneralWarnings'),
  125. anyHostErrors: function () {
  126. return this.get('hosts').some(function(h) { return h.errorMessages ? h.errorMessages.length > 0 : false;});
  127. }.property('hosts.@each.errorMessages'),
  128. /**
  129. * true if validation has any error message (general or host specific)
  130. */
  131. anyErrors: Em.computed.or('anyGeneralErrors', 'anyHostErrors'),
  132. anyHostWarnings: function () {
  133. return this.get('hosts').some(function(h) { return h.warnMessages ? h.warnMessages.length > 0 : false;});
  134. }.property('hosts.@each.warnMessages'),
  135. /**
  136. * true if validation has any warning message (general or host specific)
  137. */
  138. anyWarnings: Em.computed.or('anyGeneralWarnings', 'anyHostWarnings'),
  139. openSlavesAndClientsIssues: function () {
  140. App.ModalPopup.show({
  141. header: Em.I18n.t('installer.step6.validationSlavesAndClients.popup.header'),
  142. bodyClass: Em.View.extend({
  143. controller: this,
  144. templateName: require('templates/wizard/step6/step6_issues_popup')
  145. }),
  146. secondary: null
  147. });
  148. },
  149. /**
  150. * Verify condition that at least one checkbox of each component was checked
  151. * @method clearError
  152. */
  153. clearError: function () {
  154. var self = this;
  155. var isError = false;
  156. var err = false;
  157. var hosts = this.get('hosts');
  158. var headers = this.get('headers');
  159. var headersMap = headers.toWickMapByProperty('name');
  160. hosts.forEach(function (host) {
  161. host.checkboxes.forEach(function (checkbox) {
  162. if (headersMap[checkbox.component]) {
  163. headersMap[checkbox.component] = !checkbox.checked;
  164. }
  165. });
  166. });
  167. for (var i in headersMap) {
  168. err |= headersMap[i];
  169. }
  170. if (!err) {
  171. this.set('errorMessage', '');
  172. }
  173. if (this.get('isAddHostWizard')) {
  174. hosts.forEach(function (host) {
  175. isError = false;
  176. headers.forEach(function (header) {
  177. isError |= host.checkboxes.findProperty('title', header.get('label')).checked;
  178. });
  179. isError = !isError;
  180. if (!isError) {
  181. self.set('errorMessage', '');
  182. }
  183. });
  184. }
  185. },
  186. /**
  187. * Clear Step6 data like <code>hosts</code>, <code>headers</code> etc
  188. * @method clearStep
  189. */
  190. clearStep: function () {
  191. this.set('hosts', []);
  192. this.set('headers', []);
  193. this.clearError();
  194. this.set('isLoaded', false);
  195. this.set('validationInProgress', false);
  196. },
  197. /**
  198. * Enable some service for all hosts
  199. * @param {object} event
  200. * @method selectAllNodes
  201. */
  202. selectAllNodes: function (event) {
  203. var name = Em.get(event, 'context.name');
  204. if (name) {
  205. this.setAllNodes(name, true);
  206. this.callValidation();
  207. }
  208. },
  209. /**
  210. * Disable some services for all hosts
  211. * @param {object} event
  212. * @method deselectAllNodes
  213. */
  214. deselectAllNodes: function (event) {
  215. var name = Em.get(event, 'context.name');
  216. if (name) {
  217. this.setAllNodes(name, false);
  218. this.callValidation();
  219. }
  220. },
  221. /**
  222. * Enable/disable some service for all hosts
  223. * @param {String} component - component name
  224. * @param {bool} checked - true - enable, false - disable
  225. * @method setAllNodes
  226. */
  227. setAllNodes: function (component, checked) {
  228. this.get('hosts').forEach(function (host) {
  229. host.checkboxes.filterProperty('isInstalled', false).forEach(function (checkbox) {
  230. if (checkbox.component === component) {
  231. Em.set(checkbox, 'checked', checked);
  232. }
  233. });
  234. });
  235. this.checkCallback(component);
  236. },
  237. /**
  238. * Checkbox check callback
  239. * Verify if all/none checkboxes for current component are checked
  240. * @param {String} component
  241. * @method checkCallback
  242. */
  243. checkCallback: function (component) {
  244. var header = this.get('headers').findProperty('name', component);
  245. if (header) {
  246. var hosts = this.get('hosts');
  247. var allTrue = true;
  248. var allFalse = true;
  249. hosts.forEach(function (host) {
  250. host.checkboxes.forEach(function (checkbox) {
  251. if (checkbox.component === component && !checkbox.isInstalled) {
  252. allTrue = allTrue && checkbox.checked;
  253. allFalse = allFalse && !checkbox.checked;
  254. }
  255. });
  256. });
  257. header.set('allChecked', allTrue);
  258. header.set('noChecked', allFalse);
  259. }
  260. this.clearError();
  261. },
  262. /**
  263. * Init step6 data
  264. * @method loadStep
  265. */
  266. loadStep: function () {
  267. this.clearStep();
  268. var selectedServices = App.StackService.find().filterProperty('isSelected');
  269. var installedServices = App.StackService.find().filterProperty('isInstalled');
  270. var services;
  271. if (this.get('isInstallerWizard')) services = selectedServices;
  272. else if (this.get('isAddHostWizard')) services = installedServices;
  273. else if (this.get('isAddServiceWizard')) services = installedServices.concat(selectedServices);
  274. var headers = Em.A([]);
  275. services.forEach(function (stackService) {
  276. stackService.get('serviceComponents').forEach(function (serviceComponent) {
  277. if (serviceComponent.get('isShownOnInstallerSlaveClientPage')) {
  278. headers.pushObject(Em.Object.create({
  279. name: serviceComponent.get('componentName'),
  280. label: App.format.role(serviceComponent.get('componentName'), false),
  281. allChecked: false,
  282. isRequired: serviceComponent.get('isRequired'),
  283. noChecked: true,
  284. isDisabled: installedServices.someProperty('serviceName', stackService.get('serviceName')) && this.get('isAddServiceWizard'),
  285. allId: 'all-' + serviceComponent.get('componentName'),
  286. noneId: 'none-' + serviceComponent.get('componentName')
  287. }));
  288. }
  289. }, this);
  290. }, this);
  291. if (this.get('content.clients') && !!this.get('content.clients').length) {
  292. headers.pushObject(Em.Object.create({
  293. name: 'CLIENT',
  294. label: App.format.role('CLIENT', false),
  295. allChecked: false,
  296. noChecked: true,
  297. isDisabled: false,
  298. allId: 'all-CLIENT',
  299. noneId: 'none-CLIENT'
  300. }));
  301. }
  302. this.get('headers').pushObjects(headers);
  303. this.render();
  304. if (this.get('content.skipSlavesStep')) {
  305. App.router.send('next');
  306. } else {
  307. this.callValidation();
  308. }
  309. },
  310. /**
  311. * Get active host names
  312. * @return {string[]}
  313. * @method getHostNames
  314. */
  315. getHostNames: function () {
  316. var hostInfo = this.get('content.hosts');
  317. var hostNames = [];
  318. //flag identify whether get all hosts or only uninstalled(newly added) hosts
  319. var getUninstalledHosts = this.get('content.controllerName') !== 'addServiceController';
  320. for (var index in hostInfo) {
  321. if (hostInfo.hasOwnProperty(index)) {
  322. if (hostInfo[index].bootStatus === 'REGISTERED') {
  323. if (!getUninstalledHosts || !hostInfo[index].isInstalled) {
  324. hostNames.push(hostInfo[index].name);
  325. }
  326. }
  327. }
  328. }
  329. return hostNames;
  330. },
  331. /**
  332. * Load all data needed for this module. Then it automatically renders in template
  333. * @method render
  334. */
  335. render: function () {
  336. var hostsObj = [],
  337. masterHosts = [],
  338. headers = this.get('headers'),
  339. masterHostNames = this.get('content.masterComponentHosts').mapProperty('hostName').uniq(),
  340. masterHostNamesMap = masterHostNames.toWickMap();
  341. this.getHostNames().forEach(function (_hostName) {
  342. var hasMaster = masterHostNamesMap[_hostName];
  343. var obj = {
  344. hostName: _hostName,
  345. hasMaster: hasMaster,
  346. checkboxes: headers.map(function (header) {
  347. return{
  348. component: header.name,
  349. title: header.label,
  350. checked: false,
  351. isInstalled: false,
  352. isDisabled: header.get('isDisabled')
  353. };
  354. })
  355. };
  356. if (hasMaster) {
  357. masterHosts.pushObject(obj)
  358. } else {
  359. hostsObj.pushObject(obj);
  360. }
  361. });
  362. //hosts with master components should be in the beginning of list
  363. hostsObj.unshift.apply(hostsObj, masterHosts);
  364. hostsObj = this.renderSlaves(hostsObj);
  365. this.set('hosts', hostsObj);
  366. headers.forEach(function (header) {
  367. this.checkCallback(header.get('name'));
  368. }, this);
  369. this.set('isLoaded', true);
  370. },
  371. /**
  372. * Set checked values for slaves checkboxes
  373. * @param {Array} hostsObj
  374. * @return {Array}
  375. * @method renderSlaves
  376. */
  377. renderSlaves: function (hostsObj) {
  378. var slaveComponents = this.get('content.slaveComponentHosts');
  379. if (Em.isNone(slaveComponents)) { // we are at this page for the first time
  380. this.selectRecommendedComponents(hostsObj);
  381. this.setInstalledComponents(hostsObj);
  382. } else {
  383. this.restoreComponentsSelection(hostsObj, slaveComponents);
  384. }
  385. this.selectClientHost(hostsObj);
  386. return hostsObj;
  387. },
  388. /**
  389. * set installed flag of host-components
  390. * @param {Array} hostsObj
  391. * @returns {boolean}
  392. */
  393. setInstalledComponents: function(hostsObj) {
  394. if (Em.isNone(this.get('content.installedHosts'))) return false;
  395. var hosts = this.get('content.installedHosts');
  396. hostsObj.forEach(function(host) {
  397. var installedHost = hosts[host.hostName];
  398. var installedComponents = installedHost ? installedHost.hostComponents.mapProperty('HostRoles.component_name') : [];
  399. host.checkboxes.forEach(function(checkbox) {
  400. checkbox.isInstalled = installedComponents.contains(checkbox.component);
  401. if (checkbox.isInstalled) {
  402. checkbox.checked = true;
  403. }
  404. });
  405. });
  406. },
  407. /**
  408. * restore previous component selection
  409. * @param {Array} hostsObj
  410. * @param {Array} slaveComponents
  411. */
  412. restoreComponentsSelection: function(hostsObj, slaveComponents) {
  413. var slaveComponentsMap = slaveComponents.toMapByProperty('componentName');
  414. var hostsObjMap = hostsObj.toMapByProperty('hostName');
  415. this.get('headers').forEach(function (header) {
  416. var slaveComponent = slaveComponentsMap[header.get('name')];
  417. if (slaveComponent) {
  418. slaveComponent.hosts.forEach(function (_node) {
  419. var node = hostsObjMap[_node.hostName];
  420. if (node) {
  421. Em.set(node.checkboxes.findProperty('title', header.get('label')), 'checked', true);
  422. Em.set(node.checkboxes.findProperty('title', header.get('label')), 'isInstalled', _node.isInstalled);
  423. }
  424. });
  425. }
  426. });
  427. },
  428. /**
  429. * select component which should be checked according to recommendations
  430. * @param hostsObj
  431. */
  432. selectRecommendedComponents: function(hostsObj) {
  433. var recommendations = this.get('content.recommendations'),
  434. recommendedMap = {},
  435. clientComponentsMap = App.get('components.clients').toWickMap();
  436. recommendations.blueprint.host_groups.forEach(function(hostGroup) {
  437. var group = recommendations.blueprint_cluster_binding.host_groups.findProperty('name', hostGroup.name);
  438. var hosts = group.hosts || [];
  439. hosts.forEach(function (host) {
  440. recommendedMap[host.fqdn] = hostGroup.components.mapProperty('name');
  441. });
  442. });
  443. hostsObj.forEach(function (host) {
  444. var checkboxes = host.checkboxes;
  445. var hostComponents = recommendedMap[host.hostName] || [];
  446. checkboxes.forEach(function (checkbox) {
  447. var checked;
  448. if (!checkbox.isDisabled) {
  449. checked = hostComponents.contains(checkbox.component);
  450. if (checkbox.component === 'CLIENT' && !checked) {
  451. checked = hostComponents.some(function (componentName) {
  452. return clientComponentsMap[componentName];
  453. });
  454. }
  455. checkbox.checked = checked;
  456. }
  457. });
  458. });
  459. },
  460. /**
  461. * For clients - select first non-master host, if all has masters then last host
  462. * @param hostsObj
  463. */
  464. selectClientHost: function (hostsObj) {
  465. if (!this.get('isClientsSet')) {
  466. var nonMasterHost = hostsObj.findProperty('hasMaster', false);
  467. var clientHost = !!nonMasterHost ? nonMasterHost : hostsObj[hostsObj.length - 1]; // last host
  468. var clientCheckBox = clientHost.checkboxes.findProperty('component', 'CLIENT');
  469. if (clientCheckBox) {
  470. Em.set(clientCheckBox, 'checked', true);
  471. }
  472. this.set('isClientsSet', true);
  473. }
  474. },
  475. /**
  476. * Select checkboxes which correspond to master components
  477. *
  478. * @param {Array} hostsObj
  479. * @return {Array}
  480. * @method selectMasterComponents
  481. */
  482. selectMasterComponents: function (hostsObj) {
  483. var masterComponentHosts = this.get('content.masterComponentHosts');
  484. if (masterComponentHosts) {
  485. masterComponentHosts.forEach(function (item) {
  486. var host = hostsObj.findProperty('hostName', item.hostName);
  487. if (host) {
  488. var checkbox = host.get('checkboxes').findProperty('component', item.component);
  489. if (checkbox) {
  490. checkbox.set('checked', true);
  491. }
  492. }
  493. });
  494. }
  495. return hostsObj;
  496. },
  497. /**
  498. * Return list of master components for specified <code>hostname</code>
  499. * @param {string} hostName
  500. * @return {string[]}
  501. * @method getMasterComponentsForHost
  502. */
  503. getMasterComponentsForHost: function (hostName) {
  504. return this.get('content.masterComponentHosts').filterProperty('hostName', hostName).mapProperty('component');
  505. },
  506. callValidation: function (successCallback) {
  507. var self = this;
  508. clearTimeout(this.get('timer'));
  509. if (this.get('validationInProgress')) {
  510. this.set('timer', setTimeout(function () {
  511. self.callValidation(successCallback);
  512. }, 700));
  513. } else {
  514. this.callServerSideValidation(successCallback);
  515. }
  516. },
  517. /**
  518. * Update submit button status
  519. * @method callServerSideValidation
  520. */
  521. callServerSideValidation: function (successCallback) {
  522. var self = this;
  523. this.set('validationInProgress', true);
  524. var selectedServices = App.StackService.find().filterProperty('isSelected').mapProperty('serviceName');
  525. var installedServices = App.StackService.find().filterProperty('isInstalled').mapProperty('serviceName');
  526. var services = installedServices.concat(selectedServices).uniq();
  527. var hostNames = self.get('hosts').mapProperty('hostName');
  528. var slaveBlueprint = self.getCurrentBlueprint();
  529. var masterBlueprint = null;
  530. //Existing Installed but invisible masters on `Assign Masters page` should be included in host component layout for recommnedation/validation call
  531. var invisibleInstalledMasters = [];
  532. if (this.get('isAddServiceWizard')) {
  533. var invisibleMasters = App.StackServiceComponent.find().filterProperty("isMaster").filterProperty("isShownOnAddServiceAssignMasterPage", false);
  534. invisibleInstalledMasters = invisibleMasters.filter(function(item){
  535. var masterComponent = App.MasterComponent.find().findProperty('componentName', item.get('componentName'));
  536. return masterComponent && !!masterComponent.get('totalCount');
  537. }).mapProperty("componentName");
  538. }
  539. var invisibleSlavesAndClients = App.StackServiceComponent.find().filter(function (component) {
  540. return component.get("isSlave") && component.get("isShownOnInstallerSlaveClientPage") === false ||
  541. component.get("isClient") && component.get("isRequiredOnAllHosts");
  542. }).mapProperty("componentName");
  543. if (this.get('isInstallerWizard') || this.get('isAddServiceWizard')) {
  544. masterBlueprint = self.getCurrentMastersBlueprint();
  545. var selectedClientComponents = self.get('content.clients').mapProperty('component_name');
  546. var alreadyInstalledClients = App.get('components.clients').reject(function (c) {
  547. return selectedClientComponents.contains(c);
  548. });
  549. var invisibleComponents = invisibleInstalledMasters.concat(invisibleSlavesAndClients).concat(alreadyInstalledClients);
  550. var invisibleBlueprint = blueprintUtils.filterByComponents(this.get('content.recommendations'), invisibleComponents);
  551. masterBlueprint = blueprintUtils.mergeBlueprints(masterBlueprint, invisibleBlueprint);
  552. } else if (this.get('isAddHostWizard')) {
  553. masterBlueprint = self.getCurrentMasterSlaveBlueprint();
  554. hostNames = hostNames.concat(App.Host.find().mapProperty("hostName")).uniq();
  555. slaveBlueprint = blueprintUtils.addComponentsToBlueprint(slaveBlueprint, invisibleSlavesAndClients);
  556. }
  557. var bluePrintsForValidation = blueprintUtils.mergeBlueprints(masterBlueprint, slaveBlueprint);
  558. this.set('content.recommendationsHostGroups', bluePrintsForValidation);
  559. return App.ajax.send({
  560. name: 'config.validations',
  561. sender: self,
  562. data: {
  563. stackVersionUrl: App.get('stackVersionURL'),
  564. hosts: hostNames,
  565. services: services,
  566. validate: 'host_groups',
  567. recommendations: bluePrintsForValidation
  568. },
  569. success: 'updateValidationsSuccessCallback',
  570. error: 'updateValidationsErrorCallback'
  571. }).
  572. then(function () {
  573. self.set('validationInProgress', false);
  574. if (App.get('router.btnClickInProgress') && successCallback) {
  575. successCallback();
  576. }
  577. }
  578. );
  579. },
  580. /**
  581. * Success-callback for validations request
  582. * @param {object} data
  583. * @method updateValidationsSuccessCallback
  584. */
  585. updateValidationsSuccessCallback: function (data) {
  586. var self = this;
  587. var clientComponents = App.get('components.clients');
  588. this.set('generalErrorMessages', []);
  589. this.set('generalWarningMessages', []);
  590. this.get('hosts').setEach('warnMessages', []);
  591. this.get('hosts').setEach('errorMessages', []);
  592. this.get('hosts').setEach('anyMessage', false);
  593. this.get('hosts').forEach(function (host) {
  594. host.checkboxes.setEach('hasWarnMessage', false);
  595. host.checkboxes.setEach('hasErrorMessage', false);
  596. });
  597. var anyGeneralClientErrors = false; // any error/warning for any client component (under "CLIENT" alias)
  598. var validationData = validationUtils.filterNotInstalledComponents(data);
  599. validationData.filterProperty('type', 'host-component').filter(function (i) {
  600. return !(i['component-name'] && App.StackServiceComponent.find().findProperty('componentName', i['component-name']).get('isMaster'));
  601. }).forEach(function (item) {
  602. var checkboxWithIssue = null;
  603. var isGeneralClientValidationItem = clientComponents.contains(item['component-name']); // it is an error/warning for any client component (under "CLIENT" alias)
  604. var host = self.get('hosts').find(function (h) {
  605. return h.hostName === item.host && h.checkboxes.some(function (checkbox) {
  606. var isClientComponent = checkbox.component === "CLIENT" && isGeneralClientValidationItem;
  607. if (checkbox.component === item['component-name'] || isClientComponent) {
  608. checkboxWithIssue = checkbox;
  609. return true;
  610. }
  611. return false;
  612. });
  613. });
  614. if (host) {
  615. Em.set(host, 'anyMessage', true);
  616. if (item.level === 'ERROR') {
  617. host.errorMessages.pushObject(item.message);
  618. Em.set(checkboxWithIssue, 'hasErrorMessage', true);
  619. }
  620. else
  621. if (item.level === 'WARN') {
  622. host.warnMessages.pushObject(item.message);
  623. Em.set(checkboxWithIssue, 'hasWarnMessage', true);
  624. }
  625. }
  626. else {
  627. var component;
  628. if (isGeneralClientValidationItem) {
  629. if (!anyGeneralClientErrors) {
  630. anyGeneralClientErrors = true;
  631. component = "Client";
  632. }
  633. }
  634. else {
  635. component = item['component-name'];
  636. }
  637. if (component || !item['component-name']) {
  638. var details = "";
  639. if (item.host) {
  640. details += " (" + item.host + ")";
  641. }
  642. if (item.level === 'ERROR') {
  643. self.get('generalErrorMessages').push(item.message + details);
  644. }
  645. else
  646. if (item.level === 'WARN') {
  647. self.get('generalWarningMessages').push(item.message + details);
  648. }
  649. }
  650. }
  651. });
  652. },
  653. /**
  654. * Error-callback for validations request
  655. * @param {object} jqXHR
  656. * @param {object} ajaxOptions
  657. * @param {string} error
  658. * @param {object} opt
  659. * @method updateValidationsErrorCallback
  660. */
  661. updateValidationsErrorCallback: function (jqXHR, ajaxOptions, error, opt) {
  662. },
  663. /**
  664. * Composes selected values of comboboxes into blueprint format
  665. */
  666. getCurrentBlueprint: function () {
  667. var self = this;
  668. var res = {
  669. blueprint: { host_groups: [] },
  670. blueprint_cluster_binding: { host_groups: [] }
  671. };
  672. var clientComponents = self.get('content.clients').mapProperty('component_name');
  673. var mapping = self.get('hosts');
  674. mapping.forEach(function (item, i) {
  675. var groupName = 'host-group-' + (i+1);
  676. var hostGroup = {
  677. name: groupName,
  678. components: item.checkboxes.filterProperty('checked', true).map(function (checkbox) {
  679. if (checkbox.component === "CLIENT") {
  680. return clientComponents.map(function (client) {
  681. return { name: client };
  682. });
  683. } else {
  684. return { name: checkbox.component };
  685. }
  686. })
  687. };
  688. hostGroup.components = [].concat.apply([], hostGroup.components);
  689. var binding = {
  690. name: groupName,
  691. hosts: [
  692. { fqdn: item.hostName }
  693. ]
  694. };
  695. res.blueprint.host_groups.push(hostGroup);
  696. res.blueprint_cluster_binding.host_groups.push(binding);
  697. });
  698. return res;
  699. },
  700. /**
  701. * Create blueprint from assigned master components to appropriate hosts
  702. * @returns {Object}
  703. * @method getCurrentMastersBlueprint
  704. */
  705. getCurrentMastersBlueprint: function () {
  706. var res = {
  707. blueprint: { host_groups: [] },
  708. blueprint_cluster_binding: { host_groups: [] }
  709. };
  710. var masters = this.get('content.masterComponentHosts');
  711. var hosts = this.get('content.hosts');
  712. Em.keys(hosts).forEach(function (host, i) {
  713. var groupName = 'host-group-' + (i + 1);
  714. var components = [];
  715. masters.forEach(function (master) {
  716. if (master.hostName === host) {
  717. components.push({
  718. name: master.component
  719. });
  720. }
  721. });
  722. res.blueprint.host_groups.push({
  723. name: groupName,
  724. components: components
  725. });
  726. res.blueprint_cluster_binding.host_groups.push({
  727. name: groupName,
  728. hosts: [
  729. {
  730. fqdn: host
  731. }
  732. ]
  733. });
  734. }, this);
  735. return blueprintUtils.mergeBlueprints(res, this.getCurrentSlaveBlueprint());
  736. },
  737. /**
  738. * In case of any validation issues shows accept dialog box for user which allow cancel and fix issues or continue anyway
  739. * @metohd submit
  740. */
  741. showValidationIssuesAcceptBox: function(callback) {
  742. var self = this;
  743. if (self.get('anyWarnings') || self.get('anyErrors')) {
  744. App.ModalPopup.show({
  745. primary: Em.I18n.t('common.continueAnyway'),
  746. header: Em.I18n.t('installer.step6.validationIssuesAttention.header'),
  747. body: Em.I18n.t('installer.step6.validationIssuesAttention'),
  748. primaryClass: 'btn-danger',
  749. onPrimary: function () {
  750. this.hide();
  751. callback();
  752. },
  753. onSecondary: function () {
  754. App.set('router.nextBtnClickInProgress', false);
  755. this._super();
  756. }
  757. });
  758. } else {
  759. callback();
  760. }
  761. }
  762. });