security_progress_controller.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  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.MainAdminSecurityProgressController = Em.Controller.extend({
  20. name: 'mainAdminSecurityProgressController',
  21. commands: [],
  22. configs: [],
  23. serviceConfigTags: [],
  24. totalSteps: 3,
  25. isSubmitDisabled: true,
  26. hasHostPopup: true,
  27. services: [],
  28. serviceTimestamp: null,
  29. operationsInfo: [
  30. {
  31. name: 'STOP_SERVICES',
  32. realUrl: '/services',
  33. testUrl: '/data/wizard/deploy/2_hosts/poll_1.json',
  34. data: '{"RequestInfo": {"context" :"' + Em.I18n.t('requestInfo.stopAllServices') + '"}, "Body": {"ServiceInfo": {"state": "INSTALLED"}}}'
  35. },
  36. {
  37. name: 'START_SERVICES',
  38. realUrl: '/services?params/run_smoke_test=true',
  39. testUrl: '/data/wizard/deploy/2_hosts/poll_1.json',
  40. data: '{"RequestInfo": {"context": "' + Em.I18n.t('requestInfo.startAllServices') + '"}, "Body": {"ServiceInfo": {"state": "STARTED"}}}'
  41. }
  42. ],
  43. secureMapping: function () {
  44. return (App.get('isHadoop2Stack')) ? require('data/HDP2/secure_mapping') : require('data/secure_mapping');
  45. }.property('App.isHadoop2Stack'),
  46. secureProperties: function () {
  47. if (App.get('isHadoop2Stack')) {
  48. return require('data/HDP2/secure_properties').configProperties;
  49. } else {
  50. return require('data/secure_properties').configProperties;
  51. }
  52. }.property('App.isHadoop2Stack'),
  53. /**
  54. * prepare and restart failed command
  55. */
  56. retry: function () {
  57. var failedCommand = this.get('commands').findProperty('isError');
  58. if (failedCommand) {
  59. failedCommand.set('requestId', null);
  60. failedCommand.set('isStarted', false);
  61. failedCommand.set('isError', false);
  62. this.startCommand(failedCommand);
  63. }
  64. },
  65. /**
  66. * start updating current task in parallel
  67. * @param requestId
  68. * @param taskId
  69. * @return {Boolean}
  70. */
  71. startUpdatingTask: function (requestId, taskId) {
  72. if (!requestId || !taskId) return false;
  73. var command = this.get('commands').findProperty('requestId', requestId);
  74. command.updateTaskLog(taskId);
  75. return true;
  76. },
  77. /**
  78. * stop updating current task
  79. * @param requestId
  80. * @return {Boolean}
  81. */
  82. stopUpdatingTask: function (requestId) {
  83. if (!requestId) return false;
  84. var command = this.get('commands').findProperty('requestId', requestId);
  85. command.set('currentTaskId', null);
  86. return true;
  87. },
  88. /**
  89. * update info about progress of operation of commands
  90. */
  91. updateServices: function () {
  92. this.services.clear();
  93. var services = this.get("services");
  94. this.get("commands").forEach(function (command) {
  95. var polledData = command.get('polledData');
  96. var newService = Ember.Object.create({
  97. name: command.get('label'),
  98. hosts: []
  99. });
  100. if (polledData) {
  101. var hostNames = polledData.mapProperty('Tasks.host_name').uniq();
  102. hostNames.forEach(function (name) {
  103. newService.hosts.push({
  104. name: name,
  105. publicName: name,
  106. logTasks: polledData.filterProperty("Tasks.host_name", name)
  107. });
  108. });
  109. services.push(newService);
  110. }
  111. });
  112. this.set('serviceTimestamp', App.dateTime());
  113. }.observes('commands.@each.polledData'),
  114. /**
  115. * initialize default commands
  116. */
  117. loadCommands: function () {
  118. this.get('commands').pushObjects([
  119. App.Poll.create({name: 'STOP_SERVICES', label: Em.I18n.translations['admin.addSecurity.apply.stop.services'], isPolling: true }),
  120. App.Poll.create({name: 'APPLY_CONFIGURATIONS', label: Em.I18n.translations['admin.addSecurity.apply.save.config'], isPolling: false }),
  121. App.Poll.create({name: 'START_SERVICES', label: Em.I18n.translations['admin.addSecurity.apply.start.services'], isPolling: true })
  122. ]);
  123. },
  124. addObserverToCommands: function () {
  125. this.setIndex(this.get('commands'));
  126. this.addObserver('commands.@each.isSuccess', this, 'onCompleteCommand');
  127. },
  128. /**
  129. * set index to each command
  130. * @param commandArray
  131. */
  132. setIndex: function (commandArray) {
  133. commandArray.forEach(function (command, index) {
  134. command.set('index', index + 1);
  135. }, this);
  136. this.set('totalSteps', commandArray.length);
  137. },
  138. startCommand: function (command) {
  139. if (this.get('commands').length === this.get('totalSteps')) {
  140. if (!command) {
  141. var startedCommand = this.get('commands').filterProperty('isStarted', true);
  142. command = startedCommand.findProperty('isCompleted', false);
  143. }
  144. if (command) {
  145. if (command.get('isPolling')) {
  146. command.set('isStarted', true);
  147. command.start();
  148. } else if (command.get('name') === 'APPLY_CONFIGURATIONS') {
  149. command.set('isStarted', true);
  150. if (App.get('testMode')) {
  151. command.set('isError', false);
  152. command.set('isSuccess', true);
  153. } else {
  154. this.loadClusterConfigs();
  155. }
  156. } else if (command.get('name') === 'DELETE_ATS') {
  157. command.set('isStarted', true);
  158. if (App.get('testMode')) {
  159. command.set('isError', false);
  160. command.set('isSuccess', true);
  161. } else {
  162. var timeLineServer = App.HostComponent.find().findProperty('componentName', 'APP_TIMELINE_SERVER');
  163. if (timeLineServer) {
  164. this.deleteComponents('APP_TIMELINE_SERVER', timeLineServer.get('hostName'));
  165. } else {
  166. this.onDeleteComplete();
  167. }
  168. }
  169. }
  170. return true;
  171. }
  172. }
  173. return false;
  174. },
  175. /**
  176. * on command completion move to next command
  177. * @return {Boolean}
  178. */
  179. onCompleteCommand: function () {
  180. if (this.get('commands').length === this.get('totalSteps')) {
  181. var index = this.get('commands').filterProperty('isSuccess', true).length;
  182. if (index > 0) {
  183. var lastCompletedCommandResult = this.get('commands').objectAt(index - 1).get('isSuccess');
  184. if (lastCompletedCommandResult) {
  185. var nextCommand = this.get('commands').objectAt(index);
  186. this.moveToNextCommand(nextCommand);
  187. return true;
  188. }
  189. }
  190. }
  191. return false;
  192. },
  193. /**
  194. * move to next command
  195. * @param nextCommand
  196. */
  197. moveToNextCommand: function (nextCommand) {
  198. nextCommand = nextCommand || this.get('commands').findProperty('isStarted', false);
  199. if (nextCommand) {
  200. this.startCommand(nextCommand);
  201. return true;
  202. }
  203. return false;
  204. },
  205. /**
  206. * add query information(url, data) to commands
  207. */
  208. addInfoToCommands: function () {
  209. var operationsInfo = this.get('operationsInfo');
  210. var urlPrefix = App.apiPrefix + '/clusters/' + App.get('clusterName');
  211. operationsInfo.forEach(function (operation) {
  212. var command = this.get('commands').findProperty('name', operation.name);
  213. var url = (App.get('testMode')) ? operation.testUrl : urlPrefix + operation.realUrl;
  214. command.set('url', url);
  215. command.set('data', operation.data);
  216. }, this);
  217. },
  218. loadClusterConfigs: function () {
  219. App.ajax.send({
  220. name: 'admin.security.add.cluster_configs',
  221. sender: this,
  222. success: 'loadClusterConfigsSuccessCallback',
  223. error: 'loadClusterConfigsErrorCallback'
  224. });
  225. },
  226. loadClusterConfigsSuccessCallback: function (data) {
  227. //prepare tags to fetch all configuration for a service
  228. this.get('secureServices').forEach(function (_secureService) {
  229. this.setServiceTagNames(_secureService, data.Clusters.desired_configs);
  230. }, this);
  231. this.getAllConfigurations();
  232. },
  233. loadClusterConfigsErrorCallback: function (request, ajaxOptions, error) {
  234. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  235. command.set('isSuccess', false);
  236. command.set('isError', true);
  237. console.log("TRACE: error code status is: " + request.status);
  238. },
  239. /**
  240. * set tag names according to installed services and desired configs
  241. * @param secureService
  242. * @param configs
  243. * @return {Object}
  244. */
  245. setServiceTagNames: function (secureService, configs) {
  246. //var serviceConfigTags = this.get('serviceConfigTags');
  247. for (var index in configs) {
  248. if (secureService.sites && secureService.sites.contains(index)) {
  249. var serviceConfigObj = {
  250. siteName: index,
  251. tagName: configs[index].tag,
  252. newTagName: null,
  253. configs: {}
  254. };
  255. this.get('serviceConfigTags').pushObject(serviceConfigObj);
  256. }
  257. }
  258. return serviceConfigObj;
  259. },
  260. /**
  261. * form query data and apply security configurations to server
  262. */
  263. applyConfigurationsToCluster: function () {
  264. var configData = this.get('serviceConfigTags').map(function (_serviceConfig) {
  265. return {
  266. type: _serviceConfig.siteName,
  267. tag: _serviceConfig.newTagName,
  268. properties: _serviceConfig.configs,
  269. service_config_version_note: Em.I18n.t('admin.security.step4.save.configuration.note')
  270. };
  271. }, this);
  272. var selectedServices = this.get('secureServices');
  273. var allConfigData = [];
  274. selectedServices.forEach(function (service) {
  275. var stackService = App.StackService.find(service.serviceName);
  276. if (stackService) {
  277. var serviceConfigData = [];
  278. Object.keys(stackService.get('configTypesRendered')).forEach(function (type) {
  279. var serviceConfigTag = configData.findProperty('type', type);
  280. if (serviceConfigTag) {
  281. serviceConfigData.pushObject(serviceConfigTag);
  282. }
  283. }, this);
  284. allConfigData.pushObject(JSON.stringify({
  285. Clusters: {
  286. desired_config: serviceConfigData
  287. }
  288. }));
  289. }
  290. }, this);
  291. App.ajax.send({
  292. name: 'common.across.services.configurations',
  293. sender: this,
  294. data: {
  295. data: '[' + allConfigData.toString() + ']'
  296. },
  297. success: 'applyConfigurationToClusterSuccessCallback',
  298. error: 'applyConfigurationToClusterErrorCallback'
  299. });
  300. },
  301. applyConfigurationToClusterSuccessCallback: function (data) {
  302. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  303. command.set('isSuccess', true);
  304. command.set('isError', false);
  305. },
  306. applyConfigurationToClusterErrorCallback: function (request, ajaxOptions, error) {
  307. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  308. command.set('isSuccess', false);
  309. command.set('isError', true);
  310. },
  311. /**
  312. * gets site config properties from server and sets it for every configuration
  313. */
  314. getAllConfigurations: function () {
  315. var urlParams = [];
  316. this.get('serviceConfigTags').forEach(function (_tag) {
  317. urlParams.push('(type=' + _tag.siteName + '&tag=' + _tag.tagName + ')');
  318. }, this);
  319. if (urlParams.length > 0) {
  320. App.ajax.send({
  321. name: 'admin.get.all_configurations',
  322. sender: this,
  323. data: {
  324. urlParams: urlParams.join('|')
  325. },
  326. success: 'getAllConfigurationsSuccessCallback',
  327. error: 'getAllConfigurationsErrorCallback'
  328. });
  329. }
  330. },
  331. getAllConfigurationsSuccessCallback: function (data) {
  332. console.log("TRACE: In success function for the GET getServiceConfigsFromServer call");
  333. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  334. this.get('serviceConfigTags').forEach(function (_tag) {
  335. if (!data.items.someProperty('type', _tag.siteName)) {
  336. console.log("Error: Metadata for secure services (secure_configs.js) is having config tags that are not being retrieved from server");
  337. command.set('isSuccess', false);
  338. command.set('isError', true);
  339. }
  340. _tag.configs = data.items.findProperty('type', _tag.siteName).properties;
  341. }, this);
  342. if (this.manageSecureConfigs()) {
  343. this.escapeXMLCharacters(this.get('serviceConfigTags'));
  344. this.applyConfigurationsToCluster();
  345. }
  346. },
  347. getAllConfigurationsErrorCallback: function (request, ajaxOptions, error) {
  348. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  349. command.set('isSuccess', false);
  350. command.set('isError', true);
  351. console.log("TRACE: In error function for the getServiceConfigsFromServer call");
  352. console.log("TRACE: error code status is: " + request.status);
  353. },
  354. /*
  355. Iterate over keys of all configurations and escape xml characters in their values
  356. */
  357. escapeXMLCharacters: function (serviceConfigTags) {
  358. serviceConfigTags.forEach(function (_serviceConfigTags) {
  359. var configs = _serviceConfigTags.configs;
  360. for (var key in configs) {
  361. configs[key] = this.setServerConfigValue(key, configs[key]);
  362. }
  363. }, this);
  364. },
  365. /**
  366. * set specific server values to config
  367. * @param configName
  368. * @param value
  369. * @return {*}
  370. */
  371. setServerConfigValue: function (configName, value) {
  372. switch (configName) {
  373. case 'storm.zookeeper.servers':
  374. return value;
  375. default:
  376. return App.config.escapeXMLCharacters(value);
  377. }
  378. },
  379. /**
  380. * save commands to server and local storage
  381. */
  382. saveCommands: function () {
  383. var commands = [];
  384. if (this.get('commands').length === this.get('totalSteps')) {
  385. this.get('commands').forEach(function (_command) {
  386. var command = {
  387. name: _command.get('name'),
  388. label: _command.get('label'),
  389. isPolling: _command.get('isPolling'),
  390. isVisible: _command.get('isVisible'),
  391. isStarted: _command.get('isStarted'),
  392. requestId: _command.get('requestId'),
  393. isSuccess: _command.get('isSuccess'),
  394. isError: _command.get('isError'),
  395. url: _command.get('url'),
  396. polledData: _command.get('polledData'),
  397. data: _command.get('data')
  398. };
  399. commands.pushObject(command);
  400. }, this);
  401. App.db.setSecurityDeployCommands(commands);
  402. if (!App.get('testMode')) {
  403. App.clusterStatus.setClusterStatus({
  404. clusterName: this.get('clusterName'),
  405. clusterState: 'ADD_SECURITY_STEP_4',
  406. wizardControllerName: App.router.get('addSecurityController.name'),
  407. localdb: App.db.data
  408. });
  409. }
  410. }
  411. }.observes('commands.@each.isCompleted', 'commands.@each.requestId')
  412. });