security_progress_controller.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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. this.deleteComponents('APP_TIMELINE_SERVER', timeLineServer.get('hostName'));
  164. }
  165. }
  166. return true;
  167. }
  168. }
  169. return false;
  170. },
  171. /**
  172. * on command completion move to next command
  173. * @return {Boolean}
  174. */
  175. onCompleteCommand: function () {
  176. if (this.get('commands').length === this.get('totalSteps')) {
  177. var index = this.get('commands').filterProperty('isSuccess', true).length;
  178. if (index > 0) {
  179. var lastCompletedCommandResult = this.get('commands').objectAt(index - 1).get('isSuccess');
  180. if (lastCompletedCommandResult) {
  181. var nextCommand = this.get('commands').objectAt(index);
  182. this.moveToNextCommand(nextCommand);
  183. return true;
  184. }
  185. }
  186. }
  187. return false;
  188. },
  189. /**
  190. * move to next command
  191. * @param nextCommand
  192. */
  193. moveToNextCommand: function (nextCommand) {
  194. nextCommand = nextCommand || this.get('commands').findProperty('isStarted', false);
  195. if (nextCommand) {
  196. this.startCommand(nextCommand);
  197. return true;
  198. }
  199. return false;
  200. },
  201. /**
  202. * add query information(url, data) to commands
  203. */
  204. addInfoToCommands: function () {
  205. var operationsInfo = this.get('operationsInfo');
  206. var urlPrefix = App.apiPrefix + '/clusters/' + App.get('clusterName');
  207. operationsInfo.forEach(function (operation) {
  208. var command = this.get('commands').findProperty('name', operation.name);
  209. var url = (App.get('testMode')) ? operation.testUrl : urlPrefix + operation.realUrl;
  210. command.set('url', url);
  211. command.set('data', operation.data);
  212. }, this);
  213. },
  214. loadClusterConfigs: function () {
  215. App.ajax.send({
  216. name: 'admin.security.add.cluster_configs',
  217. sender: this,
  218. success: 'loadClusterConfigsSuccessCallback',
  219. error: 'loadClusterConfigsErrorCallback'
  220. });
  221. },
  222. loadClusterConfigsSuccessCallback: function (data) {
  223. //prepare tags to fetch all configuration for a service
  224. this.get('secureServices').forEach(function (_secureService) {
  225. this.setServiceTagNames(_secureService, data.Clusters.desired_configs);
  226. }, this);
  227. this.getAllConfigurations();
  228. },
  229. loadClusterConfigsErrorCallback: function (request, ajaxOptions, error) {
  230. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  231. command.set('isSuccess', false);
  232. command.set('isError', true);
  233. console.log("TRACE: error code status is: " + request.status);
  234. },
  235. /**
  236. * set tag names according to installed services and desired configs
  237. * @param secureService
  238. * @param configs
  239. * @return {Object}
  240. */
  241. setServiceTagNames: function (secureService, configs) {
  242. //var serviceConfigTags = this.get('serviceConfigTags');
  243. for (var index in configs) {
  244. if (secureService.sites && secureService.sites.contains(index)) {
  245. var serviceConfigObj = {
  246. siteName: index,
  247. tagName: configs[index].tag,
  248. newTagName: null,
  249. configs: {}
  250. };
  251. this.get('serviceConfigTags').pushObject(serviceConfigObj);
  252. }
  253. }
  254. return serviceConfigObj;
  255. },
  256. /**
  257. * form query data and apply security configurations to server
  258. */
  259. applyConfigurationsToCluster: function () {
  260. var configData = this.get('serviceConfigTags').map(function (_serviceConfig) {
  261. return {
  262. type: _serviceConfig.siteName,
  263. tag: _serviceConfig.newTagName,
  264. properties: _serviceConfig.configs,
  265. service_config_version_note: Em.I18n.t('admin.security.step4.save.configuration.note')
  266. };
  267. }, this);
  268. var selectedServices = this.get('secureServices');
  269. var allConfigData = [];
  270. selectedServices.forEach(function (service) {
  271. var stackService = App.StackService.find(service.serviceName);
  272. if (stackService) {
  273. var serviceConfigData = [];
  274. Object.keys(stackService.get('configTypesRendered')).forEach(function (type) {
  275. var serviceConfigTag = configData.findProperty('type', type);
  276. if (serviceConfigTag) {
  277. serviceConfigData.pushObject(serviceConfigTag);
  278. }
  279. }, this);
  280. allConfigData.pushObject(JSON.stringify({
  281. Clusters: {
  282. desired_config: serviceConfigData
  283. }
  284. }));
  285. }
  286. }, this);
  287. App.ajax.send({
  288. name: 'common.across.services.configurations',
  289. sender: this,
  290. data: {
  291. data: '[' + allConfigData.toString() + ']'
  292. },
  293. success: 'applyConfigurationToClusterSuccessCallback',
  294. error: 'applyConfigurationToClusterErrorCallback'
  295. });
  296. },
  297. applyConfigurationToClusterSuccessCallback: function (data) {
  298. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  299. command.set('isSuccess', true);
  300. command.set('isError', false);
  301. },
  302. applyConfigurationToClusterErrorCallback: function (request, ajaxOptions, error) {
  303. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  304. command.set('isSuccess', false);
  305. command.set('isError', true);
  306. },
  307. /**
  308. * gets site config properties from server and sets it for every configuration
  309. */
  310. getAllConfigurations: function () {
  311. var urlParams = [];
  312. this.get('serviceConfigTags').forEach(function (_tag) {
  313. urlParams.push('(type=' + _tag.siteName + '&tag=' + _tag.tagName + ')');
  314. }, this);
  315. if (urlParams.length > 0) {
  316. App.ajax.send({
  317. name: 'admin.get.all_configurations',
  318. sender: this,
  319. data: {
  320. urlParams: urlParams.join('|')
  321. },
  322. success: 'getAllConfigurationsSuccessCallback',
  323. error: 'getAllConfigurationsErrorCallback'
  324. });
  325. }
  326. },
  327. getAllConfigurationsSuccessCallback: function (data) {
  328. console.log("TRACE: In success function for the GET getServiceConfigsFromServer call");
  329. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  330. this.get('serviceConfigTags').forEach(function (_tag) {
  331. if (!data.items.someProperty('type', _tag.siteName)) {
  332. console.log("Error: Metadata for secure services (secure_configs.js) is having config tags that are not being retrieved from server");
  333. command.set('isSuccess', false);
  334. command.set('isError', true);
  335. }
  336. _tag.configs = data.items.findProperty('type', _tag.siteName).properties;
  337. }, this);
  338. if (this.manageSecureConfigs()) {
  339. this.escapeXMLCharacters(this.get('serviceConfigTags'));
  340. this.applyConfigurationsToCluster();
  341. }
  342. },
  343. getAllConfigurationsErrorCallback: function (request, ajaxOptions, error) {
  344. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  345. command.set('isSuccess', false);
  346. command.set('isError', true);
  347. console.log("TRACE: In error function for the getServiceConfigsFromServer call");
  348. console.log("TRACE: error code status is: " + request.status);
  349. },
  350. /*
  351. Iterate over keys of all configurations and escape xml characters in their values
  352. */
  353. escapeXMLCharacters: function (serviceConfigTags) {
  354. serviceConfigTags.forEach(function (_serviceConfigTags) {
  355. var configs = _serviceConfigTags.configs;
  356. for (var key in configs) {
  357. configs[key] = this.setServerConfigValue(key, configs[key]);
  358. }
  359. }, this);
  360. },
  361. /**
  362. * set specific server values to config
  363. * @param configName
  364. * @param value
  365. * @return {*}
  366. */
  367. setServerConfigValue: function (configName, value) {
  368. switch (configName) {
  369. case 'storm.zookeeper.servers':
  370. return value;
  371. default:
  372. return App.config.escapeXMLCharacters(value);
  373. }
  374. },
  375. /**
  376. * save commands to server and local storage
  377. */
  378. saveCommands: function () {
  379. var commands = [];
  380. if (this.get('commands').length === this.get('totalSteps')) {
  381. this.get('commands').forEach(function (_command) {
  382. var command = {
  383. name: _command.get('name'),
  384. label: _command.get('label'),
  385. isPolling: _command.get('isPolling'),
  386. isVisible: _command.get('isVisible'),
  387. isStarted: _command.get('isStarted'),
  388. requestId: _command.get('requestId'),
  389. isSuccess: _command.get('isSuccess'),
  390. isError: _command.get('isError'),
  391. url: _command.get('url'),
  392. polledData: _command.get('polledData'),
  393. data: _command.get('data')
  394. };
  395. commands.pushObject(command);
  396. }, this);
  397. App.db.setSecurityDeployCommands(commands);
  398. if (!App.get('testMode')) {
  399. App.clusterStatus.setClusterStatus({
  400. clusterName: this.get('clusterName'),
  401. clusterState: 'ADD_SECURITY_STEP_4',
  402. wizardControllerName: App.router.get('addSecurityController.name'),
  403. localdb: App.db.data
  404. });
  405. }
  406. }
  407. }.observes('commands.@each.isCompleted', 'commands.@each.requestId')
  408. });