add_controller.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  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. App.AddHostController = App.WizardController.extend({
  20. name: 'addHostController',
  21. totalSteps: 7,
  22. /**
  23. * Used for hiding back button in wizard
  24. */
  25. hideBackButton: true,
  26. /**
  27. * All wizards data will be stored in this variable
  28. *
  29. * cluster - cluster name
  30. * hosts - hosts, ssh key, repo info, etc.
  31. * services - services list
  32. * hostsInfo - list of selected hosts
  33. * slaveComponentHosts, hostSlaveComponents - info about slave hosts
  34. * masterComponentHosts - info about master hosts
  35. * serviceConfigGroups - info about selected config group for service
  36. * configGroups - all config groups
  37. * config??? - to be described later
  38. */
  39. content: Em.Object.create({
  40. cluster: null,
  41. hosts: null,
  42. installOptions: null,
  43. services: null,
  44. slaveComponentHosts: null,
  45. masterComponentHosts: null,
  46. serviceConfigProperties: null,
  47. advancedServiceConfig: null,
  48. controllerName: 'addHostController',
  49. serviceConfigGroups: null,
  50. configGroups: null
  51. }),
  52. /**
  53. * save info about wizard progress, particularly current step of wizard
  54. * @param currentStep
  55. * @param completed
  56. */
  57. setCurrentStep: function (currentStep, completed) {
  58. this._super(currentStep, completed);
  59. App.clusterStatus.setClusterStatus({
  60. wizardControllerName: this.get('name'),
  61. localdb: App.db.data
  62. });
  63. },
  64. /**
  65. * return new object extended from clusterStatusTemplate
  66. * @return Object
  67. */
  68. getCluster: function () {
  69. return jQuery.extend({}, this.get('clusterStatusTemplate'), {name: App.router.getClusterName()});
  70. },
  71. /**
  72. * return new object extended from installOptionsTemplate
  73. * @return Object
  74. */
  75. getInstallOptions: function () {
  76. return jQuery.extend({}, this.get('installOptionsTemplate'));
  77. },
  78. /**
  79. * Remove host from model. Used at <code>Confirm hosts</code> step
  80. * @param hosts Array of hosts, which we want to delete
  81. */
  82. removeHosts: function (hosts) {
  83. var dbHosts = this.getDBProperty('hosts');
  84. hosts.forEach(function (_hostInfo) {
  85. var host = _hostInfo.hostName;
  86. delete dbHosts[host];
  87. });
  88. this.setDBProperty('hosts', dbHosts);
  89. },
  90. /**
  91. * Load services data from server.
  92. * TODO move to mixin
  93. */
  94. loadServicesFromServer: function () {
  95. var apiService = this.loadServiceComponents();
  96. apiService.forEach(function (item, index) {
  97. apiService[index].isSelected = App.Service.find().someProperty('id', item.serviceName);
  98. apiService[index].isDisabled = apiService[index].isSelected;
  99. apiService[index].isInstalled = apiService[index].isSelected;
  100. });
  101. this.set('content.services', apiService);
  102. this.setDBProperty('service', apiService);
  103. },
  104. /**
  105. * Load services data. Will be used at <code>Select services(step4)</code> step
  106. */
  107. loadServices: function () {
  108. var servicesInfo = this.getDBProperty('service');
  109. console.log('AddHostController.loadServices: loaded data ', servicesInfo);
  110. servicesInfo.forEach(function (item, index) {
  111. servicesInfo[index] = Em.Object.create(item);
  112. });
  113. this.set('content.services', servicesInfo);
  114. var serviceNames = servicesInfo.filterProperty('isSelected', true).mapProperty('serviceName');
  115. console.log('selected services ', serviceNames);
  116. },
  117. /**
  118. * return slaveComponents bound to hosts
  119. * @return {Array}
  120. */
  121. getSlaveComponentHosts: function () {
  122. return this._super().filter(function (component) {
  123. return component.isInstalled;
  124. });
  125. },
  126. /**
  127. * Load master component hosts data for using in required step controllers
  128. * TODO move to mixin
  129. */
  130. loadSlaveComponentHosts: function () {
  131. var slaveComponentHosts = this.getDBProperty('slaveComponentHosts');
  132. if (!slaveComponentHosts) {
  133. slaveComponentHosts = this.getSlaveComponentHosts();
  134. }
  135. this.set("content.slaveComponentHosts", slaveComponentHosts);
  136. console.log("AddHostController.loadSlaveComponentHosts: loaded hosts ", slaveComponentHosts);
  137. },
  138. /**
  139. * Generate clients list for selected services and save it to model
  140. */
  141. saveClients: function () {
  142. var clients = [];
  143. var serviceComponents = App.StackServiceComponent.find();
  144. var hostComponents = App.HostComponent.find();
  145. this.get('content.services').filterProperty('isSelected').forEach(function (_service) {
  146. var client = serviceComponents.filterProperty('serviceName', _service.serviceName).findProperty('isClient');
  147. if (client) {
  148. clients.push({
  149. component_name: client.get('componentName'),
  150. display_name: client.get('displayName'),
  151. isInstalled: hostComponents.filterProperty('componentName', client.get('componentName')).length > 0
  152. });
  153. }
  154. }, this);
  155. this.setDBProperty('clientInfo', clients);
  156. this.set('content.clients', clients);
  157. console.log("AddHostController.saveClients: saved list ", clients);
  158. },
  159. /**
  160. * Apply config groups from step4 Configurations
  161. */
  162. applyConfigGroup: function () {
  163. var serviceConfigGroups = this.get('content.serviceConfigGroups');
  164. serviceConfigGroups.forEach(function (group) {
  165. if (group.configGroups.someProperty('ConfigGroup.group_name', group.selectedConfigGroup)) {
  166. var configGroup = group.configGroups.findProperty('ConfigGroup.group_name', group.selectedConfigGroup);
  167. group.hosts.forEach(function (host) {
  168. configGroup.ConfigGroup.hosts.push({
  169. host_name: host
  170. });
  171. }, this);
  172. delete configGroup.href;
  173. App.ajax.send({
  174. name: 'config_groups.update_config_group',
  175. sender: this,
  176. data: {
  177. id: configGroup.ConfigGroup.id,
  178. configGroup: configGroup
  179. }
  180. });
  181. }
  182. }, this);
  183. },
  184. /**
  185. * Load information about selected config groups
  186. */
  187. getServiceConfigGroups: function () {
  188. var serviceConfigGroups = this.getDBProperty('serviceConfigGroups');
  189. this.set('content.serviceConfigGroups', serviceConfigGroups);
  190. },
  191. /**
  192. * Save information about selected config groups
  193. */
  194. saveServiceConfigGroups: function () {
  195. this.setDBProperty('serviceConfigGroups', this.get('content.serviceConfigGroups'));
  196. this.set('content.serviceConfigGroups', this.get('content.serviceConfigGroups'));
  197. },
  198. /**
  199. * Set content.serviceConfigGroups for step4
  200. */
  201. loadServiceConfigGroups: function () {
  202. var selectedServices = [];
  203. this.loadServiceConfigGroupsBySlaves(selectedServices);
  204. this.loadServiceConfigGroupsByClients(selectedServices);
  205. this.sortServiceConfigGroups(selectedServices);
  206. this.set('content.serviceConfigGroups', selectedServices);
  207. },
  208. /**
  209. * sort config groups by name
  210. * @param selectedServices
  211. */
  212. sortServiceConfigGroups: function (selectedServices) {
  213. selectedServices.forEach(function (selectedService) {
  214. selectedService.configGroups.sort(function (cfgA, cfgB) {
  215. if (cfgA.ConfigGroup.group_name < cfgB.ConfigGroup.group_name) return -1;
  216. if (cfgA.ConfigGroup.group_name > cfgB.ConfigGroup.group_name) return 1;
  217. return 0;
  218. });
  219. });
  220. },
  221. /**
  222. * load service config groups by slave components,
  223. * push them into selectedServices
  224. * @param selectedServices
  225. */
  226. loadServiceConfigGroupsBySlaves: function (selectedServices) {
  227. var componentServiceMap = App.QuickDataMapper.componentServiceMap();
  228. var slaveComponentHosts = this.get('content.slaveComponentHosts');
  229. if (slaveComponentHosts && slaveComponentHosts.length > 0) {
  230. slaveComponentHosts.forEach(function (slave) {
  231. if (slave.hosts.length > 0) {
  232. if (slave.componentName !== "CLIENT") {
  233. var service = componentServiceMap[slave.componentName];
  234. var configGroups = this.get('content.configGroups').filterProperty('ConfigGroup.tag', service);
  235. var configGroupsNames = configGroups.mapProperty('ConfigGroup.group_name');
  236. var defaultGroupName = App.Service.DisplayNames[service] + ' Default';
  237. configGroupsNames.unshift(defaultGroupName);
  238. selectedServices.push({
  239. serviceId: service,
  240. displayName: App.Service.DisplayNames[service],
  241. hosts: slave.hosts.mapProperty('hostName'),
  242. configGroupsNames: configGroupsNames,
  243. configGroups: configGroups,
  244. selectedConfigGroup: defaultGroupName
  245. });
  246. }
  247. }
  248. }, this);
  249. return true;
  250. }
  251. return false;
  252. },
  253. /**
  254. * load service config groups by clients,
  255. * push them into selectedServices
  256. * @param selectedServices
  257. */
  258. loadServiceConfigGroupsByClients: function (selectedServices) {
  259. var componentServiceMap = App.QuickDataMapper.componentServiceMap();
  260. var slaveComponentHosts = this.get('content.slaveComponentHosts');
  261. var clients = this.get('content.clients');
  262. var client = slaveComponentHosts && slaveComponentHosts.findProperty('componentName', 'CLIENT');
  263. var selectedClientHosts = client && client.hosts.mapProperty('hostName');
  264. if (clients && selectedClientHosts && clients.length > 0 && selectedClientHosts.length > 0) {
  265. this.loadClients();
  266. clients.forEach(function (client) {
  267. var service = componentServiceMap[client.component_name];
  268. var serviceMatch = selectedServices.findProperty('serviceId', service);
  269. if (serviceMatch) {
  270. serviceMatch.hosts = serviceMatch.hosts.concat(selectedClientHosts).uniq();
  271. } else {
  272. var configGroups = this.get('content.configGroups').filterProperty('ConfigGroup.tag', service);
  273. var configGroupsNames = configGroups.mapProperty('ConfigGroup.group_name').sort();
  274. var defaultGroupName = App.Service.DisplayNames[service] + ' Default';
  275. configGroupsNames.unshift(defaultGroupName);
  276. selectedServices.push({
  277. serviceId: service,
  278. displayName: App.Service.DisplayNames[service],
  279. hosts: selectedClientHosts,
  280. configGroupsNames: configGroupsNames,
  281. configGroups: configGroups,
  282. selectedConfigGroup: defaultGroupName
  283. });
  284. }
  285. }, this);
  286. return true;
  287. }
  288. return false;
  289. },
  290. loadServiceConfigProperties: function () {
  291. var serviceConfigProperties = App.db.get('AddService', 'serviceConfigProperties');
  292. if (!serviceConfigProperties || !serviceConfigProperties.length) {
  293. serviceConfigProperties = App.db.get('Installer', 'serviceConfigProperties');
  294. }
  295. this.set('content.serviceConfigProperties', serviceConfigProperties);
  296. console.log("AddHostController.loadServiceConfigProperties: loaded config ", serviceConfigProperties);
  297. },
  298. /**
  299. * Load data for all steps until <code>current step</code>
  300. */
  301. loadAllPriorSteps: function () {
  302. var step = this.get('currentStep');
  303. switch (step) {
  304. case '7':
  305. case '6':
  306. case '5':
  307. this.loadServiceConfigProperties();
  308. this.getServiceConfigGroups();
  309. case '4':
  310. case '3':
  311. this.loadClients();
  312. this.loadServices();
  313. this.loadMasterComponentHosts();
  314. this.loadSlaveComponentHosts();
  315. this.load('hosts');
  316. case '2':
  317. this.loadServices();
  318. case '1':
  319. this.load('hosts');
  320. this.load('installOptions');
  321. this.load('cluster');
  322. }
  323. },
  324. /**
  325. * Remove all loaded data.
  326. * Created as copy for App.router.clearAllSteps
  327. */
  328. clearAllSteps: function () {
  329. this.clearInstallOptions();
  330. // clear temporary information stored during the install
  331. this.set('content.cluster', this.getCluster());
  332. },
  333. /**
  334. * Clear all temporary data
  335. */
  336. finish: function () {
  337. this.setCurrentStep('1');
  338. this.clearAllSteps();
  339. this.clearStorageData();
  340. App.router.get('updateController').updateAll();
  341. App.updater.immediateRun('updateHost');
  342. },
  343. /**
  344. * send request to server in order to install services
  345. * @param isRetry
  346. */
  347. installServices: function (isRetry) {
  348. this.set('content.cluster.oldRequestsId', []);
  349. var clusterName = this.get('content.cluster.name');
  350. var hostNames = [];
  351. for (var hostname in this.getDBProperty('hosts')) {
  352. hostNames.push(hostname);
  353. }
  354. if(!clusterName || hostNames.length === 0) return false;
  355. var name = 'wizard.install_services.add_host_controller.';
  356. name += (isRetry) ? 'is_retry' : 'not_is_retry';
  357. var data = JSON.stringify({
  358. "RequestInfo": {
  359. "context": Em.I18n.t('requestInfo.installComponents'),
  360. "query": "HostRoles/host_name.in(" + hostNames.join(',') + ")"
  361. },
  362. "Body": {
  363. "HostRoles": {"state": "INSTALLED"}
  364. }
  365. });
  366. App.ajax.send({
  367. name: name,
  368. sender: this,
  369. data: {
  370. data: data,
  371. cluster: clusterName
  372. },
  373. success: 'installServicesSuccessCallback',
  374. error: 'installServicesErrorCallback'
  375. });
  376. return true;
  377. }
  378. });