security_progress_controller.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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: require('data/HDP2/secure_mapping'),
  44. secureProperties: require('data/HDP2/secure_properties').configProperties,
  45. /**
  46. * prepare and restart failed command
  47. */
  48. retry: function () {
  49. var failedCommand = this.get('commands').findProperty('isError');
  50. if (failedCommand) {
  51. failedCommand.set('requestId', null);
  52. failedCommand.set('isStarted', false);
  53. failedCommand.set('isError', false);
  54. this.startCommand(failedCommand);
  55. }
  56. },
  57. /**
  58. * start updating current task in parallel
  59. * @param requestId
  60. * @param taskId
  61. * @return {Boolean}
  62. */
  63. startUpdatingTask: function (requestId, taskId) {
  64. if (!requestId || !taskId) return false;
  65. var command = this.get('commands').findProperty('requestId', requestId);
  66. command.updateTaskLog(taskId);
  67. return true;
  68. },
  69. /**
  70. * stop updating current task
  71. * @param requestId
  72. * @return {Boolean}
  73. */
  74. stopUpdatingTask: function (requestId) {
  75. if (!requestId) return false;
  76. var command = this.get('commands').findProperty('requestId', requestId);
  77. command.set('currentTaskId', null);
  78. return true;
  79. },
  80. /**
  81. * update info about progress of operation of commands
  82. */
  83. updateServices: function () {
  84. this.services.clear();
  85. var services = this.get("services");
  86. this.get("commands").forEach(function (command) {
  87. var polledData = command.get('polledData');
  88. var newService = Ember.Object.create({
  89. name: command.get('label'),
  90. hosts: []
  91. });
  92. if (polledData) {
  93. var hostNames = polledData.mapProperty('Tasks.host_name').uniq();
  94. hostNames.forEach(function (name) {
  95. newService.hosts.push({
  96. name: name,
  97. publicName: name,
  98. logTasks: polledData.filterProperty("Tasks.host_name", name)
  99. });
  100. });
  101. services.push(newService);
  102. }
  103. });
  104. this.set('serviceTimestamp', App.dateTime());
  105. }.observes('commands.@each.polledData'),
  106. /**
  107. * initialize default commands
  108. */
  109. loadCommands: function () {
  110. this.get('commands').pushObjects([
  111. App.Poll.create({name: 'STOP_SERVICES', label: Em.I18n.translations['admin.addSecurity.apply.stop.services'], isPolling: true }),
  112. App.Poll.create({name: 'APPLY_CONFIGURATIONS', label: Em.I18n.translations['admin.addSecurity.apply.save.config'], isPolling: false }),
  113. App.Poll.create({name: 'START_SERVICES', label: Em.I18n.translations['admin.addSecurity.apply.start.services'], isPolling: true })
  114. ]);
  115. },
  116. addObserverToCommands: function () {
  117. this.setIndex(this.get('commands'));
  118. this.addObserver('commands.@each.isSuccess', this, 'onCompleteCommand');
  119. },
  120. /**
  121. * set index to each command
  122. * @param commandArray
  123. */
  124. setIndex: function (commandArray) {
  125. commandArray.forEach(function (command, index) {
  126. command.set('index', index + 1);
  127. }, this);
  128. this.set('totalSteps', commandArray.length);
  129. },
  130. startCommand: function (command) {
  131. if (this.get('commands').length === this.get('totalSteps')) {
  132. if (!command) {
  133. var startedCommand = this.get('commands').filterProperty('isStarted', true);
  134. command = startedCommand.findProperty('isCompleted', false);
  135. }
  136. if (command) {
  137. if (command.get('isPolling')) {
  138. command.set('isStarted', true);
  139. command.start();
  140. } else if (command.get('name') === 'APPLY_CONFIGURATIONS') {
  141. command.set('isStarted', true);
  142. if (App.get('testMode')) {
  143. command.set('isError', false);
  144. command.set('isSuccess', true);
  145. } else {
  146. this.loadClusterConfigs();
  147. }
  148. } else if (command.get('name') === 'DELETE_ATS') {
  149. command.set('isStarted', true);
  150. if (App.get('testMode')) {
  151. command.set('isError', false);
  152. command.set('isSuccess', true);
  153. } else {
  154. var timeLineServer = App.HostComponent.find().findProperty('componentName', 'APP_TIMELINE_SERVER');
  155. if (timeLineServer) {
  156. this.deleteComponents('APP_TIMELINE_SERVER', timeLineServer.get('hostName'));
  157. } else {
  158. this.onDeleteComplete();
  159. }
  160. }
  161. }
  162. return true;
  163. }
  164. }
  165. return false;
  166. },
  167. /**
  168. * on command completion move to next command
  169. * @return {Boolean}
  170. */
  171. onCompleteCommand: function () {
  172. if (this.get('commands').length === this.get('totalSteps')) {
  173. var index = this.get('commands').filterProperty('isSuccess', true).length;
  174. if (index > 0) {
  175. var lastCompletedCommandResult = this.get('commands').objectAt(index - 1).get('isSuccess');
  176. if (lastCompletedCommandResult) {
  177. var nextCommand = this.get('commands').objectAt(index);
  178. this.moveToNextCommand(nextCommand);
  179. return true;
  180. }
  181. }
  182. }
  183. return false;
  184. },
  185. /**
  186. * move to next command
  187. * @param nextCommand
  188. */
  189. moveToNextCommand: function (nextCommand) {
  190. nextCommand = nextCommand || this.get('commands').findProperty('isStarted', false);
  191. if (nextCommand) {
  192. this.startCommand(nextCommand);
  193. return true;
  194. }
  195. return false;
  196. },
  197. /**
  198. * add query information(url, data) to commands
  199. */
  200. addInfoToCommands: function () {
  201. var operationsInfo = this.get('operationsInfo');
  202. var urlPrefix = App.apiPrefix + '/clusters/' + App.get('clusterName');
  203. operationsInfo.forEach(function (operation) {
  204. var command = this.get('commands').findProperty('name', operation.name);
  205. var url = (App.get('testMode')) ? operation.testUrl : urlPrefix + operation.realUrl;
  206. command.set('url', url);
  207. command.set('data', operation.data);
  208. }, this);
  209. },
  210. loadClusterConfigs: function () {
  211. App.ajax.send({
  212. name: 'admin.security.add.cluster_configs',
  213. sender: this,
  214. success: 'loadClusterConfigsSuccessCallback',
  215. error: 'loadClusterConfigsErrorCallback'
  216. });
  217. },
  218. loadClusterConfigsSuccessCallback: function (data) {
  219. //prepare tags to fetch all configuration for a service
  220. this.get('secureServices').forEach(function (_secureService) {
  221. this.setServiceTagNames(_secureService, data.Clusters.desired_configs);
  222. }, this);
  223. this.getAllConfigurations();
  224. },
  225. loadClusterConfigsErrorCallback: function (request, ajaxOptions, error) {
  226. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  227. command.set('isSuccess', false);
  228. command.set('isError', true);
  229. console.log("TRACE: error code status is: " + request.status);
  230. },
  231. /**
  232. * set tag names according to installed services and desired configs
  233. * @param secureService
  234. * @param configs
  235. * @return {Object}
  236. */
  237. setServiceTagNames: function (secureService, configs) {
  238. //var serviceConfigTags = this.get('serviceConfigTags');
  239. for (var index in configs) {
  240. if (secureService.sites && secureService.sites.contains(index)) {
  241. var serviceConfigObj = {
  242. siteName: index,
  243. tagName: configs[index].tag,
  244. newTagName: null,
  245. configs: {}
  246. };
  247. this.get('serviceConfigTags').pushObject(serviceConfigObj);
  248. }
  249. }
  250. return serviceConfigObj;
  251. },
  252. /**
  253. * form query data and apply security configurations to server
  254. */
  255. applyConfigurationsToCluster: function () {
  256. var configData = this.get('serviceConfigTags').map(function (_serviceConfig) {
  257. var res = {
  258. type: _serviceConfig.siteName,
  259. tag: _serviceConfig.newTagName,
  260. properties: _serviceConfig.configs,
  261. service_config_version_note: Em.I18n.t('admin.security.step4.save.configuration.note')
  262. };
  263. if (_serviceConfig.properties_attributes) {
  264. res['properties_attributes'] = _serviceConfig.properties_attributes
  265. }
  266. return res;
  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. var clusterConfig = configData.findProperty('type', 'cluster-env');
  288. if (clusterConfig) {
  289. allConfigData.pushObject(JSON.stringify({
  290. Clusters: {
  291. desired_config: [clusterConfig]
  292. }
  293. }));
  294. }
  295. App.ajax.send({
  296. name: 'common.across.services.configurations',
  297. sender: this,
  298. data: {
  299. data: '[' + allConfigData.toString() + ']'
  300. },
  301. success: 'applyConfigurationToClusterSuccessCallback',
  302. error: 'applyConfigurationToClusterErrorCallback'
  303. });
  304. },
  305. applyConfigurationToClusterSuccessCallback: function (data) {
  306. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  307. command.set('isSuccess', true);
  308. command.set('isError', false);
  309. },
  310. applyConfigurationToClusterErrorCallback: function (request, ajaxOptions, error) {
  311. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  312. command.set('isSuccess', false);
  313. command.set('isError', true);
  314. },
  315. /**
  316. * gets site config properties from server and sets it for every configuration
  317. */
  318. getAllConfigurations: function () {
  319. var urlParams = [];
  320. this.get('serviceConfigTags').forEach(function (_tag) {
  321. urlParams.push('(type=' + _tag.siteName + '&tag=' + _tag.tagName + ')');
  322. }, this);
  323. if (urlParams.length > 0) {
  324. App.ajax.send({
  325. name: 'admin.get.all_configurations',
  326. sender: this,
  327. data: {
  328. urlParams: urlParams.join('|')
  329. },
  330. success: 'getAllConfigurationsSuccessCallback',
  331. error: 'getAllConfigurationsErrorCallback'
  332. });
  333. }
  334. },
  335. getAllConfigurationsSuccessCallback: function (data) {
  336. console.log("TRACE: In success function for the GET getServiceConfigsFromServer call");
  337. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  338. this.get('serviceConfigTags').forEach(function (_tag) {
  339. if (!data.items.someProperty('type', _tag.siteName)) {
  340. console.log("Error: Metadata for secure services (secure_configs.js) is having config tags that are not being retrieved from server");
  341. command.set('isSuccess', false);
  342. command.set('isError', true);
  343. }
  344. var cfg = data.items.findProperty('type', _tag.siteName);
  345. _tag.configs = this.modifyConfigsForSecure(_tag.siteName, cfg);
  346. if (cfg.properties_attributes) {
  347. _tag.properties_attributes = cfg.properties_attributes;
  348. }
  349. }, this);
  350. if (this.manageSecureConfigs()) {
  351. this.applyConfigurationsToCluster();
  352. }
  353. },
  354. propertiesToUpdate: [
  355. {
  356. siteName: 'storm-site',
  357. name: 'ui.childopts',
  358. append: ' -Djava.security.auth.login.config=/etc/storm/conf/storm_jaas.conf'
  359. },
  360. {
  361. siteName: 'storm-site',
  362. name: 'supervisor.childopts',
  363. append: ' -Djava.security.auth.login.config=/etc/storm/conf/storm_jaas.conf'
  364. },
  365. {
  366. siteName: 'storm-site',
  367. name: 'nimbus.childopts',
  368. append: ' -Djava.security.auth.login.config=/etc/storm/conf/storm_jaas.conf'
  369. }
  370. ],
  371. /**
  372. * updates some configs for correct work in secure mode
  373. * @method modifyConfigsForSecure
  374. * @param {String} siteName
  375. * @param {Object} cfg
  376. * {
  377. * properties: {
  378. * 'ui.childopts': 'value1'
  379. * 'property2': 'value2'
  380. * }
  381. * };
  382. * has other properties but required filed is "properties";
  383. * @returns {Object}
  384. * properties: {
  385. * 'ui.childopts': 'value1 -Djava.security.auth.login.config=/etc/storm/conf/storm_jaas.conf'
  386. * 'property2': 'value2'
  387. * }
  388. */
  389. modifyConfigsForSecure: function(siteName, cfg) {
  390. var propertiesToUpdate = this.get('propertiesToUpdate').filterProperty('siteName', siteName);
  391. if (propertiesToUpdate.length) {
  392. propertiesToUpdate.forEach(function(p) {
  393. cfg.properties[p.name] += p.append;
  394. }, this);
  395. }
  396. return cfg.properties
  397. },
  398. getAllConfigurationsErrorCallback: function (request, ajaxOptions, error) {
  399. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  400. command.set('isSuccess', false);
  401. command.set('isError', true);
  402. console.log("TRACE: In error function for the getServiceConfigsFromServer call");
  403. console.log("TRACE: error code status is: " + request.status);
  404. },
  405. /**
  406. * save commands to server and local storage
  407. */
  408. saveCommands: function () {
  409. var commands = [];
  410. if (this.get('commands').length === this.get('totalSteps')) {
  411. this.get('commands').forEach(function (_command) {
  412. var command = {
  413. name: _command.get('name'),
  414. label: _command.get('label'),
  415. isPolling: _command.get('isPolling'),
  416. isVisible: _command.get('isVisible'),
  417. isStarted: _command.get('isStarted'),
  418. requestId: _command.get('requestId'),
  419. isSuccess: _command.get('isSuccess'),
  420. isError: _command.get('isError'),
  421. url: _command.get('url'),
  422. polledData: _command.get('polledData'),
  423. data: _command.get('data')
  424. };
  425. commands.pushObject(command);
  426. }, this);
  427. App.db.setSecurityDeployCommands(commands);
  428. if (!App.get('testMode')) {
  429. App.clusterStatus.setClusterStatus({
  430. clusterName: this.get('clusterName'),
  431. clusterState: 'ADD_SECURITY_STEP_4',
  432. wizardControllerName: App.router.get('addSecurityController.name'),
  433. localdb: App.db.data
  434. });
  435. }
  436. }
  437. }.observes('commands.@each.isCompleted', 'commands.@each.requestId')
  438. });