quick_view_link_view.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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. var stringUtils = require('utils/string_utils');
  20. App.QuickViewLinks = Em.View.extend({
  21. isLoaded: false,
  22. loadTags: function () {
  23. App.ajax.send({
  24. name: 'config.tags',
  25. sender: this,
  26. success: 'loadTagsSuccess',
  27. error: 'loadTagsError'
  28. });
  29. },
  30. loadTagsSuccess: function (data) {
  31. this.get('actualTags').clear();
  32. var tags = [];
  33. var self = this;
  34. for (var prop in data.Clusters.desired_configs) {
  35. tags.push(Em.Object.create({
  36. siteName: prop,
  37. tagName: data.Clusters.desired_configs[prop]['tag']
  38. }));
  39. }
  40. this.get('actualTags').pushObjects(tags);
  41. this.setConfigProperties().done(function (data) {
  42. self.get('configProperties').pushObjects(data);
  43. self.getQuickLinksHosts();
  44. });
  45. },
  46. loadTagsError: function() {
  47. this.getQuickLinksHosts();
  48. },
  49. getQuickLinksHosts: function () {
  50. var masterHosts = App.HostComponent.find().filterProperty('isMaster').mapProperty('hostName').uniq();
  51. App.ajax.send({
  52. name: 'hosts.for_quick_links',
  53. sender: this,
  54. data: {
  55. clusterName: App.get('clusterName'),
  56. masterHosts: masterHosts.join(','),
  57. urlParams: ',host_components/metrics/hbase/master/IsActiveMaster'
  58. },
  59. success: 'setQuickLinksSuccessCallback'
  60. });
  61. },
  62. actualTags: [],
  63. configProperties: [],
  64. /**
  65. * list of files that contains properties for enabling/disabling ssl
  66. */
  67. requiredSiteNames: ['hadoop-env','yarn-env','hbase-env','oozie-env','mapred-env','storm-env', 'falcon-env', 'core-site', 'hdfs-site', 'hbase-site', 'oozie-site', 'yarn-site', 'mapred-site', 'storm-site'],
  68. /**
  69. * Get public host name by its host name.
  70. *
  71. * @method getPublicHostName
  72. * @param {Object[]} hosts - list of hosts from response
  73. * @param {String} hostName
  74. * @return {String}
  75. **/
  76. getPublicHostName: function(hosts, hostName) {
  77. return Em.get(hosts.findProperty('Hosts.host_name', hostName), 'Hosts.public_host_name');
  78. },
  79. setConfigProperties: function () {
  80. this.get('configProperties').clear();
  81. var requiredSiteNames = this.get('requiredSiteNames');
  82. var tags = this.get('actualTags').filter(function (tag) {
  83. return requiredSiteNames.contains(tag.siteName);
  84. });
  85. return App.router.get('configurationController').getConfigsByTags(tags);
  86. },
  87. ambariProperties: function () {
  88. return App.router.get('clusterController.ambariProperties');
  89. },
  90. /**
  91. * Updated quick links. Here we put correct hostname to url
  92. */
  93. quickLinks: [],
  94. didInsertElement: function () {
  95. this.setQuickLinks();
  96. },
  97. findComponentHost: function (components, componentName) {
  98. var component = components.find(function (item) {
  99. return item.host_components.someProperty('HostRoles.component_name', componentName);
  100. });
  101. return component && component.Hosts.public_host_name;
  102. },
  103. setQuickLinks: function () {
  104. this.loadTags();
  105. }.observes('App.currentStackVersionNumber', 'App.singleNodeInstall'),
  106. setQuickLinksSuccessCallback: function (response) {
  107. var self = this;
  108. var quickLinks = [];
  109. var hosts = this.setHost(response, this.get('content.serviceName'));
  110. if (!hosts || !this.get('content.quickLinks')) {
  111. quickLinks = [{
  112. label: this.t('quick.links.error.label'),
  113. url: 'javascript:alert("' + this.t('contact.administrator') + '");return false;'
  114. }];
  115. this.set('quickLinks', quickLinks);
  116. this.set('isLoaded', true);
  117. /**
  118. * MAPREDUCE is only service that use 2 different masters in quick links
  119. * so we must work with this service as with one-master-service but set up
  120. * two hosts for two components. (JOBTRACKER and HISTORYSERVER)
  121. */
  122. } else if (hosts.length == 1 || this.get('content.serviceName') == "MAPREDUCE") {
  123. quickLinks = this.get('content.quickLinks').map(function (item) {
  124. var protocol = self.setProtocol(item.get('service_id'), self.get('configProperties'), self.ambariProperties());
  125. if (item.get('template')) {
  126. var port = item.get('http_config') && self.setPort(item, protocol);
  127. /**
  128. * setting other host for mapreduce (only for MAPREDUCE and JobHistory Server)!!!
  129. */
  130. if (self.get('content.serviceName') == "MAPREDUCE" && item.get('label') == "JobHistory Server") {
  131. item.set('url', item.get('template').fmt(protocol, hosts[1], port));
  132. } else {
  133. item.set('url', item.get('template').fmt(protocol, hosts[0], port));
  134. }
  135. }
  136. return item;
  137. });
  138. this.set('quickLinks', quickLinks);
  139. this.set('isLoaded', true);
  140. } else {
  141. // multiple hbase masters or HDFS HA enabled
  142. var quickLinksArray = [];
  143. hosts.forEach(function(host) {
  144. var quickLinks = [];
  145. self.get('content.quickLinks').forEach(function (item) {
  146. var newItem = {};
  147. var protocol = self.setProtocol(item.get('service_id'), self.get('configProperties'), self.ambariProperties());
  148. if (item.get('template')) {
  149. var port = item.get('http_config') && self.setPort(item, protocol);
  150. newItem.url = item.get('template').fmt(protocol, host.publicHostName, port);
  151. newItem.label = item.get('label');
  152. }
  153. quickLinks.push(newItem);
  154. });
  155. if (host.status) {
  156. quickLinks.set('publicHostNameLabel', Em.I18n.t('quick.links.publicHostName').format(host.publicHostName, host.status));
  157. } else {
  158. quickLinks.set('publicHostNameLabel', host.publicHostName);
  159. }
  160. quickLinksArray.push(quickLinks);
  161. }, this);
  162. this.set('quickLinksArray', quickLinksArray);
  163. this.set('isLoaded', true);
  164. }
  165. },
  166. /**
  167. * sets public host names for required masters of current service
  168. * @param {String} serviceName - selected serviceName
  169. * @param {JSON} response
  170. * @returns {Array} containing hostName(s)
  171. * @method setHost
  172. */
  173. setHost: function(response, serviceName) {
  174. if (App.get('singleNodeInstall')) {
  175. return [App.get('singleNodeAlias')];
  176. }
  177. var hosts = [];
  178. switch (serviceName) {
  179. case "HDFS":
  180. if (this.get('content.snameNode')) {
  181. // not HA
  182. hosts[0] = this.findComponentHost(response.items, 'NAMENODE');
  183. } else {
  184. // HA enabled, need both two namenodes hosts
  185. this.get('content.hostComponents').filterProperty('componentName', 'NAMENODE').forEach(function (component) {
  186. hosts.push({'publicHostName': response.items.findProperty('Hosts.host_name', component.get('hostName')).Hosts.public_host_name});
  187. });
  188. // assign each namenode status label
  189. if (this.get('content.activeNameNode')) {
  190. hosts.findProperty('publicHostName', this.getPublicHostName(response.items, this.get('content.activeNameNode.hostName'))).status = Em.I18n.t('quick.links.label.active');
  191. }
  192. if (this.get('content.standbyNameNode')) {
  193. hosts.findProperty('publicHostName', this.getPublicHostName(response.items, this.get('content.standbyNameNode.hostName'))).status = Em.I18n.t('quick.links.label.standby');
  194. }
  195. if (this.get('content.standbyNameNode2')) {
  196. hosts.findProperty('publicHostName', this.getPublicHostName(response.items, this.get('content.standbyNameNode2.hostName'))).status = Em.I18n.t('quick.links.label.standby');
  197. }
  198. }
  199. break;
  200. case "HBASE":
  201. var masterComponents = response.items.filter(function (item) {
  202. return item.host_components.someProperty('HostRoles.component_name', 'HBASE_MASTER');
  203. });
  204. var activeMaster, standbyMasters, otherMasters;
  205. activeMaster = masterComponents.filter(function (item) {
  206. return item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'true');
  207. });
  208. standbyMasters = masterComponents.filter(function (item) {
  209. return item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'false');
  210. });
  211. otherMasters = masterComponents.filter(function (item) {
  212. return !(item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'true') || item.host_components.someProperty('metrics.hbase.master.IsActiveMaster', 'false'));
  213. });
  214. if (masterComponents.length > 1) {
  215. // need all hbase_masters hosts in quick links
  216. if (activeMaster) {
  217. activeMaster.forEach(function (item) {
  218. hosts.push({'publicHostName': item.Hosts.public_host_name, 'status': Em.I18n.t('quick.links.label.active')});
  219. });
  220. }
  221. if (standbyMasters) {
  222. standbyMasters.forEach(function (item) {
  223. hosts.push({'publicHostName': item.Hosts.public_host_name, 'status': Em.I18n.t('quick.links.label.standby')});
  224. });
  225. }
  226. if (otherMasters) {
  227. otherMasters.forEach(function (item) {
  228. hosts.push({'publicHostName': item.Hosts.public_host_name});
  229. });
  230. }
  231. } else {
  232. hosts[0] = masterComponents[0].Hosts.public_host_name;
  233. }
  234. break;
  235. case "YARN":
  236. if (App.get('isRMHaEnabled')) {
  237. this.get('content.hostComponents').filterProperty('componentName', 'RESOURCEMANAGER').forEach(function (component) {
  238. var newHost = {'publicHostName': response.items.findProperty('Hosts.host_name', component.get('hostName')).Hosts.public_host_name};
  239. var status = '';
  240. switch (component.get('haStatus')) {
  241. case 'ACTIVE':
  242. status = Em.I18n.t('quick.links.label.active');
  243. break;
  244. case 'STANDBY':
  245. status = Em.I18n.t('quick.links.label.standby');
  246. break;
  247. }
  248. if (status) {
  249. newHost.status = status;
  250. }
  251. hosts.push(newHost);
  252. }, this);
  253. } else {
  254. hosts[0] = this.findComponentHost(response.items, 'RESOURCEMANAGER');
  255. }
  256. break;
  257. case "MAPREDUCE":
  258. hosts[0] = this.findComponentHost(response.items, "JOBTRACKER");
  259. hosts[1] = this.findComponentHost(response.items, "HISTORYSERVER");
  260. break;
  261. case "STORM":
  262. hosts[0] = this.findComponentHost(response.items, "STORM_UI_SERVER");
  263. break;
  264. default:
  265. if (App.StackService.find().findProperty('serviceName', serviceName).get('hasMaster')) {
  266. hosts[0] = this.findComponentHost(response.items, this.get('content.hostComponents') && this.get('content.hostComponents').findProperty('isMaster', true).get('componentName'));
  267. }
  268. break;
  269. }
  270. return hosts;
  271. },
  272. /**
  273. * services that supports security. this array is used to find out protocol.
  274. * becides GANGLIA, NAGIOS, YARN, MAPREDUCE2. These properties use
  275. * their properties to know protocol
  276. */
  277. servicesSupportsHttps: ["HDFS", "HBASE", "MAPREDUCE"],
  278. /**
  279. * setProtocol - if cluster is secure for some services (GANGLIA, NAGIOS, MAPREDUCE2, YARN and servicesSupportsHttps)
  280. * protocol becomes "https" otherwise "http" (by default)
  281. * @param {String} service_id - service name
  282. * @param {Object} configProperties
  283. * @param {Object} ambariProperties
  284. * @returns {string} "https" or "http" only!
  285. * @method setProtocol
  286. */
  287. setProtocol: function (service_id, configProperties, ambariProperties) {
  288. var hadoopSslEnabled = false;
  289. if (configProperties && configProperties.length > 0) {
  290. var coreSite = configProperties.findProperty('type', 'core-site');
  291. var hdfsSite = configProperties.findProperty('type', 'hdfs-site');
  292. if (App.get('isHadoop2Stack')) {
  293. hadoopSslEnabled = (Em.get(hdfsSite, 'properties') && hdfsSite.properties['dfs.http.policy'] === 'HTTPS_ONLY');
  294. } else {
  295. hadoopSslEnabled = (Em.get(coreSite, 'properties') && coreSite.properties['hadoop.ssl.enabled'] == true);
  296. }
  297. }
  298. switch (service_id) {
  299. case "GANGLIA":
  300. return (ambariProperties && ambariProperties['ganglia.https'] == true) ? "https" : "http";
  301. break;
  302. case "NAGIOS":
  303. return (ambariProperties && ambariProperties['nagios.https'] == true) ? "https" : "http";
  304. break;
  305. case "YARN":
  306. var yarnProperties = configProperties.findProperty('type', 'yarn-site');
  307. if (yarnProperties && yarnProperties.properties) {
  308. if (yarnProperties.properties['yarn.http.policy'] === 'HTTPS_ONLY') {
  309. return "https";
  310. } else if (yarnProperties.properties['yarn.http.policy'] === 'HTTP_ONLY') {
  311. return "http";
  312. }
  313. }
  314. return hadoopSslEnabled ? "https" : "http";
  315. break;
  316. case "MAPREDUCE2":
  317. var mapred2Properties = configProperties.findProperty('type', 'mapred-site');
  318. if (mapred2Properties && mapred2Properties.properties) {
  319. if (mapred2Properties.properties['mapreduce.jobhistory.http.policy'] === 'HTTPS_ONLY') {
  320. return "https";
  321. } else if (mapred2Properties.properties['mapreduce.jobhistory.http.policy'] === 'HTTP_ONLY') {
  322. return "http";
  323. }
  324. }
  325. return hadoopSslEnabled ? "https" : "http";
  326. break;
  327. default:
  328. return this.get('servicesSupportsHttps').contains(service_id) && hadoopSslEnabled ? "https" : "http";
  329. }
  330. },
  331. /**
  332. * sets the port of quick link
  333. * @param item
  334. * @param protocol
  335. * @returns {*}
  336. * @method setPort
  337. */
  338. setPort: function (item, protocol) {
  339. var configProperties = this.get('configProperties');
  340. var config = item.get('http_config');
  341. var defaultPort = item.get('default_http_port');
  342. if (protocol === 'https' && item.get('https_config')) {
  343. config = item.get('https_config');
  344. if (item.get('default_https_port')) {
  345. defaultPort = item.get('default_https_port');
  346. }
  347. }
  348. var site = configProperties.findProperty('type', item.get('site'));
  349. var propertyValue = site && site.properties[config];
  350. if (!propertyValue) {
  351. return defaultPort;
  352. }
  353. var re = new RegExp(item.get('regex'));
  354. var portValue = propertyValue.match(re);
  355. return portValue[1];
  356. },
  357. linkTarget: function () {
  358. switch (this.get('content.serviceName').toLowerCase()) {
  359. case "hdfs":
  360. case "yarn":
  361. case "mapreduce2":
  362. case "mapreduce":
  363. case "hbase":
  364. case "oozie":
  365. case "ganglia":
  366. case "nagios":
  367. case "storm":
  368. case "falcon":
  369. return "_blank";
  370. break;
  371. default:
  372. return "";
  373. break;
  374. }
  375. }.property('service')
  376. });