step6_controller.js 26 KB

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