kerberos.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  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. require('controllers/main/admin/kerberos/step4_controller');
  20. App.MainAdminKerberosController = App.KerberosWizardStep4Controller.extend({
  21. name: 'mainAdminKerberosController',
  22. securityEnabled: false,
  23. dataIsLoaded: false,
  24. isRecommendedLoaded: true,
  25. kdc_type: 'none',
  26. getAddSecurityWizardStatus: function () {
  27. return App.db.getSecurityWizardStatus();
  28. },
  29. setAddSecurityWizardStatus: function (status) {
  30. App.db.setSecurityWizardStatus(status);
  31. },
  32. setDisableSecurityStatus: function (status) {
  33. App.db.setDisableSecurityStatus(status);
  34. },
  35. getDisableSecurityStatus: function (status) {
  36. return App.db.getDisableSecurityStatus();
  37. },
  38. notifySecurityOff: false,
  39. notifySecurityAdd: false,
  40. notifySecurityOffPopup: function () {
  41. var self = this;
  42. App.ModalPopup.show({
  43. header: Em.I18n.t('popup.confirmation.commonHeader'),
  44. primary: Em.I18n.t('ok'),
  45. onPrimary: function () {
  46. App.db.setSecurityDeployCommands(undefined);
  47. self.setDisableSecurityStatus("RUNNING");
  48. App.router.transitionTo('disableSecurity');
  49. this.hide();
  50. },
  51. bodyClass: Ember.View.extend({
  52. templateName: require('templates/main/admin/security/notify_security_off_popup')
  53. })
  54. });
  55. },
  56. /**
  57. * Show confirmation popup for regenerate keytabs
  58. * @method regenerateKeytabs
  59. * @return {App.ModalPopup}
  60. */
  61. regenerateKeytabs: function () {
  62. var self = this;
  63. return App.ModalPopup.show({
  64. /**
  65. * True - regenerate keytabs only for missing hosts and components, false - regenerate for all hosts and components
  66. * @type {boolean}
  67. */
  68. regenerateKeytabsOnlyForMissing: false,
  69. header: Em.I18n.t('admin.kerberos.button.regenerateKeytabs'),
  70. bodyClass: Em.View.extend({
  71. templateName: require('templates/main/admin/kerberos/regenerate_keytabs_popup_body')
  72. }),
  73. onPrimary: function () {
  74. this._super();
  75. return self.restartServicesAfterRegenerate(this.get('regenerateKeytabsOnlyForMissing'));
  76. }
  77. });
  78. },
  79. /**
  80. * Show confirmation popup for restarting all services and after confirmation regenerate keytabs
  81. *
  82. * @param regenerateKeytabsOnlyForMissing {Boolean}
  83. * @returns {*}
  84. */
  85. restartServicesAfterRegenerate: function (regenerateKeytabsOnlyForMissing) {
  86. var self = this;
  87. return App.ModalPopup.show({
  88. /**
  89. * True - automatically restart services, false - user will have to restart required services manually
  90. * @type {boolean}
  91. */
  92. restartComponents: false,
  93. header: Em.I18n.t('admin.kerberos.button.regenerateKeytabs'),
  94. bodyClass: Em.View.extend({
  95. templateName: require('templates/main/admin/kerberos/restart_services_after_regenerate_body')
  96. }),
  97. onPrimary: function () {
  98. this._super();
  99. self.regenerateKeytabsRequest(regenerateKeytabsOnlyForMissing, this.get('restartComponents'));
  100. }
  101. });
  102. },
  103. /**
  104. * Send request to regenerate keytabs
  105. * @param {boolean} missingOnly determines type of regeneration - missing|all
  106. * @param {boolean} withAutoRestart determines if the system should automatically restart all services or not after regeneration
  107. * @returns {$.ajax}
  108. */
  109. regenerateKeytabsRequest: function (missingOnly, withAutoRestart) {
  110. missingOnly = missingOnly || false;
  111. return App.ajax.send({
  112. name: "admin.kerberos_security.regenerate_keytabs",
  113. sender: this,
  114. data: {
  115. type: missingOnly ? 'missing' : 'all',
  116. withAutoRestart: withAutoRestart || false
  117. },
  118. success: "regenerateKeytabsSuccess"
  119. });
  120. },
  121. /**
  122. * Success callback of <code>regenerateKeytabs</code>
  123. * show background operations popup if appropriate option is set
  124. *
  125. * @param data
  126. * @param opt
  127. * @param params
  128. * @param request
  129. */
  130. regenerateKeytabsSuccess: function (data, opt, params, request) {
  131. var self = this;
  132. App.router.get('applicationController').dataLoading().done(function (initValue) {
  133. if (initValue) {
  134. App.router.get('backgroundOperationsController').showPopup();
  135. }
  136. self.set('needsRestartAfterRegenerate', params.withAutoRestart);
  137. });
  138. },
  139. /**
  140. * Do request to server for restarting all services
  141. * @method restartAllServices
  142. * @return {$.ajax}
  143. */
  144. restartAllServices: function () {
  145. if (!App.router.get('backgroundOperationsController.allOperationsCount')) {
  146. if (this.get('needsRestartAfterRegenerate')) {
  147. this.set('needsRestartAfterRegenerate', false);
  148. App.router.get('mainServiceController').restartAllServices();
  149. }
  150. }
  151. }.observes('controllers.backgroundOperationsController.allOperationsCount'),
  152. getUpdatedSecurityStatus: function () {
  153. this.getSecurityStatus();
  154. return this.get('securityEnabled');
  155. },
  156. /**
  157. * performs cluster check before kerbefos security
  158. * wizard starts if <code>preKerberizeCheck<code> supports is true
  159. * otherwise runs <code>startKerberosWizard<code>
  160. * @method checkAndStartKerberosWizard
  161. */
  162. checkAndStartKerberosWizard: function() {
  163. if (App.get('supports.preKerberizeCheck')) {
  164. App.ajax.send({
  165. name: "admin.kerberos_security.checks",
  166. sender: this,
  167. success: "runSecurityCheckSuccess"
  168. });
  169. } else {
  170. this.startKerberosWizard();
  171. }
  172. },
  173. /**
  174. * success callback of <code>checkAndStartKerberosWizard()</code>
  175. * if there are some fails - it shows popup else open security wizard
  176. * @param data {object}
  177. * @param opt {object}
  178. * @param params {object}
  179. * @returns {App.ModalPopup|undefined}
  180. */
  181. runSecurityCheckSuccess: function (data, opt, params) {
  182. //TODO correct check
  183. if (data.items.someProperty('UpgradeChecks.status', "FAIL")) {
  184. var header = Em.I18n.t('popup.clusterCheck.Security.header').format(params.label);
  185. var title = Em.I18n.t('popup.clusterCheck.Security.title');
  186. var alert = Em.I18n.t('popup.clusterCheck.Security.alert');
  187. App.showClusterCheckPopup(data, header, title, alert);
  188. } else {
  189. this.startKerberosWizard();
  190. }
  191. },
  192. startKerberosWizard: function () {
  193. this.setAddSecurityWizardStatus('RUNNING');
  194. App.router.get('kerberosWizardController').setDBProperty('onClosePath', 'main.admin.adminKerberos.index');
  195. App.router.transitionTo('adminKerberos.adminAddKerberos');
  196. },
  197. /**
  198. * Loads the security status from server (security_enabled property in cluster-env configuration)
  199. */
  200. loadSecurityStatusFromServer: function () {
  201. if (App.get('testMode')) {
  202. this.set('securityEnabled', !App.get('testEnableSecurity'));
  203. this.set('dataIsLoaded', true);
  204. } else {
  205. //get Security Status From Server
  206. this.getSecurityType();
  207. return this.getSecurityStatus();
  208. }
  209. },
  210. /**
  211. * Load security status from server.
  212. * @returns {$.Deferred}
  213. */
  214. getSecurityStatus: function () {
  215. var self = this;
  216. var dfd = $.Deferred();
  217. if (App.get('testMode')) {
  218. this.set('securityEnabled', !App.get('testEnableSecurity'));
  219. this.set('dataIsLoaded', true);
  220. dfd.resolve();
  221. } else {
  222. //get Security Status From Server
  223. App.ajax.send({
  224. name: 'admin.security_status',
  225. sender: this,
  226. success: 'getSecurityStatusSuccessCallback',
  227. error: 'errorCallback'
  228. }).always(function() {
  229. // check for kerberos descriptor artifact
  230. if (self.get('securityEnabled')) {
  231. self.loadClusterDescriptorConfigs().then(function() {
  232. dfd.resolve();
  233. }, function() {
  234. // if kerberos descriptor doesn't exist in cluster artifacts we have to kerberize cluster.
  235. // Show `Enable kerberos` button and set unsecure status.
  236. self.set('securityEnabled', false);
  237. dfd.resolve();
  238. });
  239. } else {
  240. dfd.resolve();
  241. }
  242. });
  243. }
  244. return dfd.promise();
  245. },
  246. getSecurityStatusSuccessCallback: function(data) {
  247. this.set('dataIsLoaded', true);
  248. var securityType = data.Clusters.security_type;
  249. this.set('securityEnabled', securityType === 'KERBEROS');
  250. },
  251. errorCallback: function (jqXHR) {
  252. this.set('dataIsLoaded', true);
  253. // Show the error popup if the API call received a response from the server.
  254. // jqXHR.status will be empty when browser cancels the request. Refer to AMBARI-5921 for more info
  255. if (!!jqXHR.status) {
  256. this.showSecurityErrorPopup();
  257. }
  258. },
  259. showSecurityErrorPopup: function () {
  260. App.ModalPopup.show({
  261. header: Em.I18n.t('common.error'),
  262. secondary: false,
  263. bodyClass: Ember.View.extend({
  264. template: Ember.Handlebars.compile('<p>{{t admin.security.status.error}}</p>')
  265. })
  266. });
  267. },
  268. /**
  269. * Override <code>App.KerberosWizardStep4Controller</code>
  270. *
  271. * @param {App.ServiceConfigProperty[]} properties
  272. */
  273. setStepConfigs: function (properties) {
  274. this.get('stepConfigs').clear();
  275. this._super(properties);
  276. },
  277. /**
  278. * Override <code>App.KerberosWizardStep4Controller</code>
  279. *
  280. * @param {App.ServiceConfigProperty[]} configs
  281. * @returns {App.ServiceConfigProperty[]}
  282. */
  283. prepareConfigProperties: function(configs) {
  284. var configProperties = configs.slice(0);
  285. var siteProperties = App.config.get('preDefinedSiteProperties');
  286. var installedServiceNames = ['Cluster'].concat(App.Service.find().mapProperty('serviceName'));
  287. configProperties = configProperties.filter(function(item) {
  288. return installedServiceNames.contains(item.get('serviceName'));
  289. });
  290. configProperties.setEach('isSecureConfig', false);
  291. configProperties.forEach(function(property, item, allConfigs) {
  292. if (property.get('observesValueFrom')) {
  293. var observedValue = allConfigs.findProperty('name', property.get('observesValueFrom')).get('value');
  294. property.set('value', observedValue);
  295. property.set('defaultValue', observedValue);
  296. }
  297. if (property.get('serviceName') == 'Cluster') {
  298. property.set('category', 'Global');
  299. } else {
  300. property.set('category', property.get('serviceName'));
  301. }
  302. // All user identity should be grouped under "Ambari Principals" category
  303. if (property.get('identityType') == 'user') property.set('category', 'Ambari Principals');
  304. var siteProperty = siteProperties.findProperty('name', property.get('name'));
  305. if (siteProperty) {
  306. if (siteProperty.category === property.get('category')) {
  307. property.set('displayName',siteProperty.displayName);
  308. if (siteProperty.index) {
  309. property.set('index', siteProperty.index);
  310. }
  311. }
  312. if (siteProperty.displayType) {
  313. property.set('displayType', siteProperty.displayType);
  314. }
  315. }
  316. });
  317. configProperties.setEach('isEditable', false);
  318. return configProperties;
  319. },
  320. getKDCSessionState: function(callback) {
  321. if (this.get('securityEnabled')) {
  322. App.ajax.send({
  323. name: 'kerberos.session.state',
  324. sender: this,
  325. data: {
  326. callback: callback
  327. },
  328. success: 'checkState'
  329. })
  330. } else {
  331. callback();
  332. }
  333. },
  334. getSecurityType: function () {
  335. if (this.get('securityEnabled')) {
  336. App.ajax.send({
  337. name: 'admin.security.cluster_configs.kerberos',
  338. sender: this,
  339. data: {
  340. clustName: 'c1'
  341. },
  342. success: 'getSecurityTypeSuccess'
  343. })
  344. }
  345. },
  346. getSecurityTypeSuccess: function (data, opt, params) {
  347. this.set('kdc_type', data.items && Em.get(data.items[0], 'properties.kdc_type') ? Em.get(data.items[0], 'properties.kdc_type') : 'none' );
  348. },
  349. isManualKerberos: function () {
  350. return this.get('kdc_type') === 'none';
  351. }.property('kdc_type'),
  352. checkState: function(data, opt, params) {
  353. var res = Em.get(data, 'Services.attributes.kdc_validation_result');
  354. var message = Em.get(data, 'Services.attributes.kdc_validation_failure_details');
  355. if (res.toUpperCase() === "OK") {
  356. params.callback();
  357. } else {
  358. App.showInvalidKDCPopup(opt, App.format.kdcErrorMsg(message, false));
  359. }
  360. }
  361. });