addSecurityConfigs.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  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. /**
  20. * Mixin for loading and setting secure configs
  21. *
  22. * @type {Ember.Mixin}
  23. */
  24. App.AddSecurityConfigs = Em.Mixin.create({
  25. kerberosDescriptor: {},
  26. secureProperties: require('data/HDP2/secure_properties').configProperties,
  27. secureMapping: require('data/HDP2/secure_mapping'),
  28. serviceUsersBinding: 'App.router.mainAdminSecurityController.serviceUsers',
  29. componentsConfig: [
  30. {
  31. serviceName: 'OOZIE',
  32. componentName: 'OOZIE_SERVER',
  33. configName: 'oozieserver_host'
  34. },
  35. {
  36. serviceName: 'HIVE',
  37. componentName: 'WEBHCAT_SERVER',
  38. configName: 'webhcat_server'
  39. }
  40. ],
  41. /**
  42. * mock users used in testMode
  43. */
  44. testModeUsers: [
  45. {
  46. name: 'hdfs_user',
  47. value: 'hdfs'
  48. },
  49. {
  50. name: 'mapred_user',
  51. value: 'mapred'
  52. },
  53. {
  54. name: 'hbase_user',
  55. value: 'hbase'
  56. },
  57. {
  58. name: 'hive_user',
  59. value: 'hive'
  60. }
  61. ],
  62. /**
  63. * security configs, which values should be modified after APPLY CONFIGURATIONS stage
  64. */
  65. secureConfigs: function () {
  66. var configs = [
  67. {
  68. name: 'zookeeper_principal_name',
  69. serviceName: 'ZOOKEEPER'
  70. },
  71. {
  72. name: 'knox_principal_name',
  73. serviceName: 'KNOX'
  74. },
  75. {
  76. name: 'storm_principal_name',
  77. serviceName: 'STORM'
  78. }
  79. ];
  80. if (App.get('isHadoop22Stack')) {
  81. configs.push({
  82. name: 'nimbus_principal_name',
  83. serviceName: 'STORM'
  84. });
  85. }
  86. return configs;
  87. }.property('App.isHadoop22Stack'),
  88. secureServices: function () {
  89. return this.get('content.services');
  90. }.property('content.services'),
  91. /**
  92. * prepare secure configs
  93. */
  94. prepareSecureConfigs: function () {
  95. var configs = this.get('content.serviceConfigProperties');
  96. this.set('configs', configs);
  97. this.loadStaticConfigs(); //Hack for properties which are declared in site_properties.js and not able to retrieve values declared in secure_properties.js
  98. this.loadUsersToConfigs();
  99. this.loadHostNames();
  100. this.loadPrimaryNames();
  101. var uiConfigs = this.loadUiSideSecureConfigs();
  102. this.set('configs', this.get('configs').concat(uiConfigs));
  103. },
  104. /**
  105. * push users to configs
  106. */
  107. loadUsersToConfigs: function () {
  108. if (!this.get('serviceUsers').length) {
  109. this.loadUsersFromServer();
  110. }
  111. App.router.get('mainAdminSecurityController.serviceUsers').forEach(function (_user) {
  112. this.get('configs').pushObject(_user);
  113. }, this);
  114. },
  115. /**
  116. * add component config that contain host name as value
  117. * @param serviceName
  118. * @param componentName
  119. * @param configName
  120. * @return {Boolean}
  121. */
  122. addHostConfig: function (serviceName, componentName, configName) {
  123. var service = App.Service.find(serviceName);
  124. var isServiceSecure = this.get('secureServices').someProperty('serviceName', serviceName);
  125. if (service.get('isLoaded') && isServiceSecure) {
  126. var hostComponent = service.get('hostComponents').findProperty('componentName', componentName);
  127. if (hostComponent) {
  128. var hostName = hostComponent.get('hostName');
  129. this.get('configs').push({
  130. id: 'puppet var',
  131. name: configName,
  132. value: hostName
  133. });
  134. return true;
  135. }
  136. }
  137. return false;
  138. },
  139. /**
  140. * add hosts' names to configs
  141. */
  142. loadHostNames: function () {
  143. var componentsConfig = this.get('componentsConfig');
  144. componentsConfig.forEach(function (host) {
  145. this.addHostConfig(host.serviceName, host.componentName, host.configName);
  146. }, this);
  147. },
  148. /**
  149. * load static configs
  150. */
  151. loadStaticConfigs: function () {
  152. this.get('configs').forEach(function (_property) {
  153. switch (_property.name) {
  154. case 'security_enabled':
  155. _property.value = 'true';
  156. break;
  157. }
  158. }, this);
  159. },
  160. /**
  161. * add principals to properties
  162. */
  163. loadPrimaryNames: function () {
  164. var principalProperties = this.getPrincipalNames();
  165. principalProperties.forEach(function (_principalProperty) {
  166. var name = _principalProperty.name.replace('principal', 'primary');
  167. var value = _principalProperty.value.split('/')[0];
  168. this.get('configs').push({name: name, value: value});
  169. }, this);
  170. },
  171. /**
  172. * gather and return properties with "principal_name"
  173. * @return {Array}
  174. */
  175. getPrincipalNames: function () {
  176. var principalNames = [];
  177. this.get('configs').forEach(function (_property) {
  178. if (/principal_name?$/.test(_property.name)) {
  179. principalNames.push(_property);
  180. }
  181. }, this);
  182. this.get('secureProperties').forEach(function (_secureProperty) {
  183. if (/principal_name?$/.test(_secureProperty.name)) {
  184. var principalName = principalNames.findProperty('name', _secureProperty.name);
  185. if (!principalName) {
  186. _secureProperty.value = _secureProperty.defaultValue;
  187. principalNames.push(_secureProperty);
  188. }
  189. }
  190. }, this);
  191. return principalNames;
  192. },
  193. /**
  194. * load users from server
  195. */
  196. loadUsersFromServer: function () {
  197. if (App.get('testMode')) {
  198. var serviceUsers = this.get('serviceUsers');
  199. this.get('testModeUsers').forEach(function (user) {
  200. user.id = 'puppet var';
  201. serviceUsers.push(user);
  202. }, this);
  203. } else {
  204. App.router.set('mainAdminSecurityController.serviceUsers', App.db.getSecureUserInfo());
  205. }
  206. },
  207. /**
  208. * load configs from UI side
  209. * @return {Array}
  210. */
  211. loadUiSideSecureConfigs: function () {
  212. var uiConfig = [];
  213. var configs = this.get('secureMapping').filterProperty('foreignKey', null).filter(function (_configProperty) {
  214. return (App.Service.find().mapProperty('serviceName').contains(_configProperty.serviceName));
  215. }, this);
  216. configs.forEach(function (_config) {
  217. var value = _config.value;
  218. if (_config.hasOwnProperty('dependedServiceName')) {
  219. value = this.checkServiceForConfigValue(value, _config.dependedServiceName);
  220. }
  221. value = this.getConfigValue(_config.templateName, value, _config.name);
  222. uiConfig.push({
  223. "id": "site property",
  224. "name": _config.name,
  225. "value": value,
  226. "filename": _config.filename
  227. });
  228. }, this);
  229. var dependentConfig = this.get('secureMapping').filterProperty('foreignKey');
  230. dependentConfig.forEach(function (_config) {
  231. if (App.Service.find().mapProperty('serviceName').contains(_config.serviceName)) {
  232. this.setConfigValue(_config);
  233. this.formatConfigName(uiConfig, _config);
  234. uiConfig.push({
  235. "id": "site property",
  236. "name": _config._name || _config.name,
  237. "value": _config.value,
  238. "filename": _config.filename
  239. });
  240. }
  241. }, this);
  242. return uiConfig;
  243. },
  244. /**
  245. * erase template rules from config value if service is not loaded
  246. * @param value
  247. * @param services
  248. * @return {*}
  249. */
  250. checkServiceForConfigValue: function (value, services) {
  251. services.forEach(function (_service) {
  252. if (!App.Service.find(_service.name).get('isLoaded')) {
  253. value = value.replace(_service.replace, '');
  254. }
  255. }, this);
  256. return value;
  257. },
  258. /**
  259. * Set all site property that are derived from other puppet-variable
  260. * @param templateName
  261. * @param expression
  262. * @param name
  263. * @return {String|null}
  264. */
  265. getConfigValue: function (templateName, expression, name) {
  266. var express = expression.match(/<(.*?)>/g);
  267. var value = expression;
  268. if (Em.isNone(express)) return expression;
  269. express.forEach(function (_express) {
  270. var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
  271. var configs = this.get('configs').findProperty('name', templateName[index]);
  272. var configValue = templateName[index] == 'hive_metastore' ?
  273. configs.value.map(function (hostName) {
  274. return 'thrift://' + hostName + ':9083';
  275. }).join(',') : configs.value;
  276. if (!!value) {
  277. value = (configs) ? App.config.replaceConfigValues(name, _express, value, configValue) : null;
  278. }
  279. }, this);
  280. return value;
  281. },
  282. /**
  283. * format name of config values of configs which match foreignKey
  284. * @param uiConfig
  285. * @param config
  286. * @return {Boolean}
  287. */
  288. formatConfigName: function (uiConfig, config) {
  289. if (Em.isNone(config.value)) return false;
  290. var fkValue = config.name.match(/<(foreignKey.*?)>/g);
  291. if (fkValue) {
  292. fkValue.forEach(function (_fkValue) {
  293. var index = parseInt(_fkValue.match(/\[([\d]*)(?=\])/)[1]);
  294. var value;
  295. if (uiConfig.someProperty('name', config.foreignKey[index])) {
  296. value = uiConfig.findProperty('name', config.foreignKey[index]).value;
  297. config._name = config.name.replace(_fkValue, value);
  298. } else if (this.get('configs').someProperty('name', config.foreignKey[index])) {
  299. value = this.get('configs').findProperty('name', config.foreignKey[index]).value;
  300. config._name = config.name.replace(_fkValue, value);
  301. }
  302. }, this);
  303. return true;
  304. }
  305. return false;
  306. },
  307. /**
  308. * Set config value with values of configs which match template
  309. * @param config
  310. * @return {Boolean}
  311. */
  312. setConfigValue: function (config) {
  313. if (Em.isNone(config.value)) return false;
  314. //For properties in the configMapping file having foreignKey and templateName properties.
  315. var templateValue = config.value.match(/<(templateName.*?)>/g);
  316. if (templateValue) {
  317. templateValue.forEach(function (_value) {
  318. var index = parseInt(_value.match(/\[([\d]*)(?=\])/)[1]);
  319. var cfg = this.get('configs').findProperty('name', config.templateName[index]);
  320. if (cfg) {
  321. var cfgValue = config.templateName[index] == 'hive_metastore' ? cfg.value.join(',') : cfg.value;
  322. config.value = config.value.replace(_value, cfgValue);
  323. } else {
  324. config.value = null;
  325. }
  326. }, this);
  327. return true;
  328. }
  329. return false;
  330. },
  331. /**
  332. * set value of principal property
  333. * @param serviceName
  334. * @param principalName
  335. * @return {Boolean}
  336. */
  337. setPrincipalValue: function (serviceName, principalName) {
  338. var siteProperties = this.get('configs');
  339. var realmName = siteProperties.findProperty('name', 'kerberos_domain');
  340. if (this.get('secureServices').someProperty('serviceName', serviceName)) {
  341. var principalProperty = siteProperties.findProperty('name', principalName);
  342. principalProperty.value = principalProperty.value + '@' + realmName.value;
  343. return true;
  344. }
  345. return false;
  346. },
  347. /**
  348. * Generate stack descriptor configs.
  349. *
  350. * @returns {$.Deferred}
  351. */
  352. getDescriptorConfigs: function () {
  353. return this.loadDescriptorConfigs().pipe(this.createServicesStackDescriptorConfigs.bind(this));
  354. },
  355. /**
  356. *
  357. * @param {object[]} items - stack descriptor json response
  358. * @returns {App.ServiceConfigProperty[]}
  359. */
  360. createServicesStackDescriptorConfigs: function (items) {
  361. var self = this;
  362. var configs = [];
  363. var clusterConfigs = [];
  364. var kerberosDescriptor = items.artifact_data;
  365. this.set('kerberosDescriptor', kerberosDescriptor);
  366. // generate configs for root level properties object, currently realm, keytab_dir
  367. clusterConfigs = clusterConfigs.concat(this.expandKerberosStackDescriptorProps(kerberosDescriptor.properties, 'Cluster', 'stackConfigs'));
  368. // generate configs for root level identities object, currently spnego property
  369. clusterConfigs = clusterConfigs.concat(this.createConfigsByIdentities(kerberosDescriptor.identities, 'Cluster'));
  370. kerberosDescriptor.services.forEach(function (service) {
  371. var serviceName = service.name;
  372. // generate configs for service level identity objects
  373. configs = configs.concat(self.createResourceConfigs(service, serviceName));
  374. // generate configs for service component level identity object
  375. service.components.forEach(function (component) {
  376. configs = configs.concat(self.createResourceConfigs(component, serviceName));
  377. });
  378. });
  379. // unite cluster, service and component configs
  380. configs = configs.concat(clusterConfigs);
  381. self.processConfigReferences(kerberosDescriptor, configs);
  382. return configs;
  383. },
  384. /**
  385. *
  386. * @param {Object} resource
  387. * @param {String} serviceName
  388. * @return {Array}
  389. */
  390. createResourceConfigs: function (resource, serviceName) {
  391. var identityConfigs = [];
  392. var resourceConfigs = [];
  393. if (resource.identities) {
  394. identityConfigs = this.createConfigsByIdentities(resource.identities, serviceName);
  395. }
  396. if (resource.configurations) {
  397. resource.configurations.forEach(function (_configuration) {
  398. for (var key in _configuration) {
  399. resourceConfigs = resourceConfigs.concat(this.expandKerberosStackDescriptorProps(_configuration[key], serviceName, key));
  400. }
  401. }, this);
  402. }
  403. return identityConfigs.concat(resourceConfigs);
  404. },
  405. /**
  406. * Create service properties based on component identity
  407. *
  408. * @param {object[]} identities
  409. * @param {string} serviceName
  410. * @returns {App.ServiceConfigProperty[]}
  411. */
  412. createConfigsByIdentities: function (identities, serviceName) {
  413. var self = this;
  414. var configs = [];
  415. identities.forEach(function (identity) {
  416. var defaultObject = {
  417. isOverridable: false,
  418. isVisible: true,
  419. isSecureConfig: true,
  420. serviceName: serviceName,
  421. name: identity.name,
  422. identityType: identity.principal && identity.principal.type
  423. };
  424. self.parseIdentityObject(identity).forEach(function (item) {
  425. configs.push(App.ServiceConfigProperty.create($.extend({}, defaultObject, item)));
  426. });
  427. });
  428. return configs;
  429. },
  430. /**
  431. * Bootstrap base object according to identity info. Generate objects will be converted to
  432. * App.ServiceConfigProperty model class instances.
  433. *
  434. * @param {object} identity
  435. * @returns {object[]}
  436. */
  437. parseIdentityObject: function (identity) {
  438. var result = [];
  439. var name = identity.name;
  440. var keys = Em.keys(identity).without('name');
  441. keys.forEach(function (item) {
  442. var configObject = {};
  443. var prop = identity[item];
  444. var itemValue = prop[{keytab: 'file', principal: 'value'}[item]];
  445. // skip inherited property without `configuration` and `keytab` or `file` values
  446. if (!prop.configuration && !itemValue) return;
  447. // inherited property with value should not observe value from reference
  448. if (name.startsWith('/') && !itemValue) {
  449. configObject.referenceProperty = name.substring(1) + ':' + item;
  450. configObject.isEditable = false;
  451. }
  452. configObject.defaultValue = configObject.value = itemValue;
  453. configObject.filename = prop.configuration ? prop.configuration.split('/')[0] : 'cluster-env';
  454. configObject.name = prop.configuration ? prop.configuration.split('/')[1] : name + '_' + item;
  455. configObject.displayName = configObject.filename == "cluster-env" ? App.format.normalizeName(configObject.name) : configObject.name;
  456. result.push(configObject);
  457. });
  458. return result;
  459. },
  460. /**
  461. * Wrap kerberos properties to App.ServiceConfigProperty model class instances.
  462. *
  463. * @param {object} kerberosProperties
  464. * @param {string} serviceName
  465. * @param {string} filename
  466. * @returns {App.ServiceConfigProperty[]}
  467. */
  468. expandKerberosStackDescriptorProps: function (kerberosProperties, serviceName, filename) {
  469. var configs = [];
  470. for (var propertyName in kerberosProperties) {
  471. var propertyObject = {
  472. name: propertyName,
  473. value: kerberosProperties[propertyName],
  474. defaultValue: kerberosProperties[propertyName],
  475. serviceName: serviceName,
  476. filename: filename,
  477. displayName: serviceName == "Cluster" ? App.format.normalizeName(propertyName) : propertyName,
  478. isOverridable: false,
  479. isEditable: propertyName != 'realm',
  480. isSecureConfig: true
  481. };
  482. configs.push(App.ServiceConfigProperty.create(propertyObject));
  483. }
  484. return configs;
  485. },
  486. /**
  487. * Take care about configs that should observe value from referenced configs.
  488. * Reference is set with `referenceProperty` key.
  489. *
  490. * @param {object[]} kerberosDescriptor
  491. * @param {App.ServiceConfigProperty[]} configs
  492. */
  493. processConfigReferences: function (kerberosDescriptor, configs) {
  494. var identities = kerberosDescriptor.identities;
  495. identities = identities.concat(kerberosDescriptor.services.map(function (service) {
  496. var _identities = service.identities || [];
  497. if (service.components && !!service.components.length) {
  498. identities = identities.concat(service.components.mapProperty('identities').reduce(function (p, c) {
  499. return p.concat(c);
  500. }, []));
  501. return identities;
  502. }
  503. }).reduce(function (p, c) {
  504. return p.concat(c);
  505. }, []));
  506. // clean up array
  507. identities = identities.compact().without(undefined);
  508. configs.forEach(function (item) {
  509. var reference = item.get('referenceProperty');
  510. if (!!reference) {
  511. var identity = identities.findProperty('name', reference.split(':')[0])[reference.split(':')[1]];
  512. if (identity && !!identity.configuration) {
  513. item.set('observesValueFrom', identity.configuration.split('/')[1]);
  514. } else {
  515. item.set('observesValueFrom', reference.replace(':', '_'));
  516. }
  517. }
  518. });
  519. },
  520. /**
  521. * update the kerberos descriptor to be put on cluster resource with user customizations
  522. * @param kerberosDescriptor {Object}
  523. * @param configs {Object}
  524. */
  525. updateKerberosDescriptor: function (kerberosDescriptor, configs) {
  526. configs.forEach(function (_config) {
  527. var isConfigUpdated;
  528. var isStackResouce = true;
  529. isConfigUpdated = this.updateResourceIdentityConfigs(kerberosDescriptor, _config, isStackResouce);
  530. if (!isConfigUpdated) {
  531. kerberosDescriptor.services.forEach(function (_service) {
  532. isConfigUpdated = this.updateResourceIdentityConfigs(_service, _config);
  533. if (!isConfigUpdated) {
  534. _service.components.forEach(function (_component) {
  535. isConfigUpdated = this.updateResourceIdentityConfigs(_component, _config);
  536. }, this);
  537. }
  538. }, this);
  539. }
  540. }, this);
  541. },
  542. /**
  543. * Updates the identity configs or configurations at a resource. A resource could be
  544. * 1) Stack
  545. * 2) Service
  546. * 3) Component
  547. * @param resource
  548. * @param config
  549. * @param isStackResource
  550. * @return boolean
  551. */
  552. updateResourceIdentityConfigs: function (resource, config, isStackResource) {
  553. var isConfigUpdated;
  554. var identities = resource.identities;
  555. var properties = !!isStackResource ? resource.properties : resource.configurations;
  556. isConfigUpdated = this.updateDescriptorConfigs(properties, config);
  557. if (!isConfigUpdated) {
  558. if (identities) {
  559. isConfigUpdated = this.updateDescriptorIdentityConfig(identities, config);
  560. }
  561. }
  562. return isConfigUpdated;
  563. },
  564. /**
  565. *
  566. * @param configurations
  567. * @param config
  568. * @return boolean
  569. */
  570. updateDescriptorConfigs: function (configurations, config) {
  571. var isConfigUpdated;
  572. if (!!configurations) {
  573. if (Array.isArray(configurations)) {
  574. configurations.forEach(function (_configuration) {
  575. for (var key in _configuration) {
  576. if (Object.keys(_configuration[key]).contains(config.name) && config.filename === key) {
  577. _configuration[key][config.name] = config.value;
  578. isConfigUpdated = true
  579. }
  580. }
  581. }, this);
  582. } else if (Object.keys(configurations).contains(config.name) && config.filename === 'stackConfigs') {
  583. configurations[config.name] = config.value;
  584. isConfigUpdated = true
  585. }
  586. }
  587. return isConfigUpdated;
  588. },
  589. /**
  590. *
  591. * @param identities
  592. * @param config
  593. * @return boolean
  594. */
  595. updateDescriptorIdentityConfig: function (identities, config) {
  596. var isConfigUpdated = false;
  597. identities.forEach(function (identity) {
  598. var keys = Em.keys(identity).without('name');
  599. keys.forEach(function (item) {
  600. var prop = identity[item];
  601. if (prop.configuration && prop.configuration.split('/')[0] === config.filename &&
  602. prop.configuration.split('/')[1] === config.name) {
  603. prop[{keytab: 'file', principal: 'value'}[item]] = config.value;
  604. isConfigUpdated = true;
  605. }
  606. });
  607. }, this);
  608. return isConfigUpdated;
  609. },
  610. /**
  611. * Make request for stack descriptor configs if cluster is not secure
  612. * or cluster descriptor configs if cluster is secure
  613. * @returns {$.ajax}
  614. * @method loadStackDescriptorConfigs
  615. */
  616. loadDescriptorConfigs: function() {
  617. if (App.router.get('mainAdminKerberosController.securityEnabled')) {
  618. return this.loadClusterDescriptorConfigs();
  619. } else {
  620. return this.loadStackDescriptorConfigs();
  621. }
  622. },
  623. /**
  624. * Make request for stack descriptor configs.
  625. * @returns {$.ajax}
  626. * @method loadStackDescriptorConfigs
  627. */
  628. loadStackDescriptorConfigs: function () {
  629. return App.ajax.send({
  630. sender: this,
  631. name: 'admin.kerberize.stack_descriptor',
  632. data: {
  633. stackName: App.get('currentStackName'),
  634. stackVersionNumber: App.get('currentStackVersionNumber')
  635. }
  636. });
  637. },
  638. /**
  639. * Make request for cluster descriptor configs.
  640. * @returns {$.ajax}
  641. * @method loadClusterDescriptorConfigs
  642. */
  643. loadClusterDescriptorConfigs: function () {
  644. return App.ajax.send({
  645. sender: this,
  646. name: 'admin.kerberize.cluster_descriptor'
  647. });
  648. }
  649. });