security_progress_controller.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  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. var res = {
  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. if (_serviceConfig.properties_attributes) {
  272. res['properties_attributes'] = _serviceConfig.properties_attributes
  273. }
  274. return res;
  275. }, this);
  276. var selectedServices = this.get('secureServices');
  277. var allConfigData = [];
  278. selectedServices.forEach(function (service) {
  279. var stackService = App.StackService.find(service.serviceName);
  280. if (stackService) {
  281. var serviceConfigData = [];
  282. Object.keys(stackService.get('configTypesRendered')).forEach(function (type) {
  283. var serviceConfigTag = configData.findProperty('type', type);
  284. if (serviceConfigTag) {
  285. serviceConfigData.pushObject(serviceConfigTag);
  286. }
  287. }, this);
  288. allConfigData.pushObject(JSON.stringify({
  289. Clusters: {
  290. desired_config: serviceConfigData
  291. }
  292. }));
  293. }
  294. }, this);
  295. var clusterConfig = configData.findProperty('type', 'cluster-env');
  296. if (clusterConfig) {
  297. allConfigData.pushObject(JSON.stringify({
  298. Clusters: {
  299. desired_config: [clusterConfig]
  300. }
  301. }));
  302. }
  303. App.ajax.send({
  304. name: 'common.across.services.configurations',
  305. sender: this,
  306. data: {
  307. data: '[' + allConfigData.toString() + ']'
  308. },
  309. success: 'applyConfigurationToClusterSuccessCallback',
  310. error: 'applyConfigurationToClusterErrorCallback'
  311. });
  312. },
  313. applyConfigurationToClusterSuccessCallback: function (data) {
  314. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  315. command.set('isSuccess', true);
  316. command.set('isError', false);
  317. },
  318. applyConfigurationToClusterErrorCallback: function (request, ajaxOptions, error) {
  319. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  320. command.set('isSuccess', false);
  321. command.set('isError', true);
  322. },
  323. /**
  324. * gets site config properties from server and sets it for every configuration
  325. */
  326. getAllConfigurations: function () {
  327. var urlParams = [];
  328. this.get('serviceConfigTags').forEach(function (_tag) {
  329. urlParams.push('(type=' + _tag.siteName + '&tag=' + _tag.tagName + ')');
  330. }, this);
  331. if (urlParams.length > 0) {
  332. App.ajax.send({
  333. name: 'admin.get.all_configurations',
  334. sender: this,
  335. data: {
  336. urlParams: urlParams.join('|')
  337. },
  338. success: 'getAllConfigurationsSuccessCallback',
  339. error: 'getAllConfigurationsErrorCallback'
  340. });
  341. }
  342. },
  343. getAllConfigurationsSuccessCallback: function (data) {
  344. console.log("TRACE: In success function for the GET getServiceConfigsFromServer call");
  345. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  346. this.get('serviceConfigTags').forEach(function (_tag) {
  347. if (!data.items.someProperty('type', _tag.siteName)) {
  348. console.log("Error: Metadata for secure services (secure_configs.js) is having config tags that are not being retrieved from server");
  349. command.set('isSuccess', false);
  350. command.set('isError', true);
  351. }
  352. var cfg = data.items.findProperty('type', _tag.siteName);
  353. _tag.configs = this.modifyConfigsForSecure(_tag.siteName, cfg);
  354. if (cfg.properties_attributes) {
  355. _tag.properties_attributes = cfg.properties_attributes;
  356. }
  357. }, this);
  358. if (this.manageSecureConfigs()) {
  359. this.applyConfigurationsToCluster();
  360. }
  361. },
  362. propertiesToUpdate: [
  363. {
  364. siteName: 'storm-site',
  365. name: 'ui.childopts',
  366. append: ' -Djava.security.auth.login.config=/etc/storm/conf/storm_jaas.conf'
  367. },
  368. {
  369. siteName: 'storm-site',
  370. name: 'supervisor.childopts',
  371. append: ' -Djava.security.auth.login.config=/etc/storm/conf/storm_jaas.conf'
  372. },
  373. {
  374. siteName: 'storm-site',
  375. name: 'nimbus.childopts',
  376. append: ' -Djava.security.auth.login.config=/etc/storm/conf/storm_jaas.conf'
  377. }
  378. ],
  379. /**
  380. * updates some configs for correct work in secure mode
  381. * @method modifyConfigsForSecure
  382. * @param {String} siteName
  383. * @param {Object} cfg
  384. * {
  385. * properties: {
  386. * 'ui.childopts': 'value1'
  387. * 'property2': 'value2'
  388. * }
  389. * };
  390. * has other properties but required filed is "properties";
  391. * @returns {Object}
  392. * properties: {
  393. * 'ui.childopts': 'value1 -Djava.security.auth.login.config=/etc/storm/conf/storm_jaas.conf'
  394. * 'property2': 'value2'
  395. * }
  396. */
  397. modifyConfigsForSecure: function(siteName, cfg) {
  398. var propertiesToUpdate = this.get('propertiesToUpdate').filterProperty('siteName', siteName);
  399. if (propertiesToUpdate.length) {
  400. propertiesToUpdate.forEach(function(p) {
  401. cfg.properties[p.name] += p.append;
  402. }, this);
  403. }
  404. return cfg.properties
  405. },
  406. getAllConfigurationsErrorCallback: function (request, ajaxOptions, error) {
  407. var command = this.get('commands').findProperty('name', 'APPLY_CONFIGURATIONS');
  408. command.set('isSuccess', false);
  409. command.set('isError', true);
  410. console.log("TRACE: In error function for the getServiceConfigsFromServer call");
  411. console.log("TRACE: error code status is: " + request.status);
  412. },
  413. /**
  414. * save commands to server and local storage
  415. */
  416. saveCommands: function () {
  417. var commands = [];
  418. if (this.get('commands').length === this.get('totalSteps')) {
  419. this.get('commands').forEach(function (_command) {
  420. var command = {
  421. name: _command.get('name'),
  422. label: _command.get('label'),
  423. isPolling: _command.get('isPolling'),
  424. isVisible: _command.get('isVisible'),
  425. isStarted: _command.get('isStarted'),
  426. requestId: _command.get('requestId'),
  427. isSuccess: _command.get('isSuccess'),
  428. isError: _command.get('isError'),
  429. url: _command.get('url'),
  430. polledData: _command.get('polledData'),
  431. data: _command.get('data')
  432. };
  433. commands.pushObject(command);
  434. }, this);
  435. App.db.setSecurityDeployCommands(commands);
  436. if (!App.get('testMode')) {
  437. App.clusterStatus.setClusterStatus({
  438. clusterName: this.get('clusterName'),
  439. clusterState: 'ADD_SECURITY_STEP_4',
  440. wizardControllerName: App.router.get('addSecurityController.name'),
  441. localdb: App.db.data
  442. });
  443. }
  444. }
  445. }.observes('commands.@each.isCompleted', 'commands.@each.requestId')
  446. });