cluster_states.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  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('mixins/common/userPref');
  20. var LZString = require('utils/lz-string');
  21. App.clusterStatus = Em.Object.create(App.UserPref, {
  22. /**
  23. * Cluster name
  24. * @type {string}
  25. */
  26. clusterName: '',
  27. /**
  28. * List valid cluster states
  29. * @type {string[]}
  30. */
  31. validStates: [
  32. 'DEFAULT',
  33. 'CLUSTER_NOT_CREATED_1',
  34. 'CLUSTER_DEPLOY_PREP_2',
  35. 'CLUSTER_INSTALLING_3',
  36. 'SERVICE_STARTING_3',
  37. 'CLUSTER_INSTALLED_4',
  38. 'ADD_HOSTS_DEPLOY_PREP_2',
  39. 'ADD_HOSTS_INSTALLING_3',
  40. 'ADD_HOSTS_INSTALLED_4',
  41. 'ADD_SERVICES_DEPLOY_PREP_2',
  42. 'ADD_SERVICES_INSTALLING_3',
  43. 'ADD_SERVICES_INSTALLED_4',
  44. 'STOPPING_SERVICES',
  45. 'STACK_UPGRADING',
  46. 'STACK_UPGRADE_FAILED',
  47. 'STACK_UPGRADED',
  48. 'ADD_SECURITY_STEP_1',
  49. 'ADD_SECURITY_STEP_2',
  50. 'ADD_SECURITY_STEP_3',
  51. 'ADD_SECURITY_STEP_4',
  52. 'DISABLE_SECURITY',
  53. 'HIGH_AVAILABILITY_DEPLOY',
  54. 'ROLLBACK_HIGH_AVAILABILITY'],
  55. /**
  56. * Default cluster state
  57. * @type {string}
  58. */
  59. clusterState: 'CLUSTER_NOT_CREATED_1',
  60. /**
  61. * Current used wizard <code>controller.name</code>
  62. * @type {string|null}
  63. */
  64. wizardControllerName: null,
  65. /**
  66. * Local DB
  67. * @type {object|null}
  68. */
  69. localdb: null,
  70. /**
  71. * Persist key
  72. * @type {string}
  73. */
  74. key: 'CLUSTER_CURRENT_STATUS',
  75. /**
  76. * Is cluster installed
  77. * @type {bool}
  78. */
  79. isInstalled: Em.computed.notExistsIn('clusterState', ['CLUSTER_NOT_CREATED_1', 'CLUSTER_DEPLOY_PREP_2', 'CLUSTER_INSTALLING_3', 'SERVICE_STARTING_3']),
  80. /**
  81. * Stores instance of <code>App.ModalPopup</code> created by <code>postUserPrefErrorCallback</code>
  82. * @property {App.ModalPopup|null}
  83. */
  84. persistErrorModal: null,
  85. /**
  86. * General info about cluster
  87. * @type {{clusterName: string, clusterState: string, wizardControllerName: string, localdb: object}}
  88. */
  89. value: function () {
  90. return {
  91. clusterName: this.get('clusterName'),
  92. clusterState: this.get('clusterState'),
  93. wizardControllerName: this.get('wizardControllerName'),
  94. localdb: this.get('localdb')
  95. };
  96. }.property('clusterName', 'clusterState', 'localdb', 'wizardControllerName'),
  97. /**
  98. * get cluster data from server and update cluster status
  99. * @param {bool} overrideLocaldb
  100. * @return promise object for the get call
  101. * @method updateFromServer
  102. */
  103. updateFromServer: function (overrideLocaldb) {
  104. this.set('additionalData', {
  105. user: App.db.getUser(),
  106. login: App.db.getLoginName(),
  107. auth: App.db.getAuth(),
  108. overrideLocaldb: !overrideLocaldb
  109. });
  110. return this.getUserPref(this.get('key'));
  111. },
  112. /**
  113. * Success callback for get-persist request
  114. * @param {object} response
  115. * @param {object} opt
  116. * @param {object} params
  117. * @method getUserPrefSuccessCallback
  118. */
  119. getUserPrefSuccessCallback: function (response, opt, params) {
  120. if (response) {
  121. // decompress response
  122. if (typeof response != 'object') {
  123. response = JSON.parse(LZString.decompressFromBase64(response));
  124. }
  125. if (response.clusterState) {
  126. this.set('clusterState', response.clusterState);
  127. }
  128. if (response.clusterName) {
  129. this.set('clusterName', response.clusterName);
  130. }
  131. if (response.wizardControllerName) {
  132. this.set('wizardControllerName', response.wizardControllerName);
  133. }
  134. if (response.localdb && !$.isEmptyObject(response.localdb)) {
  135. this.set('localdb', response.localdb);
  136. // restore HAWizard data if process was started
  137. var isHAWizardStarted = App.isAuthorized('SERVICE.ENABLE_HA') && !App.isEmptyObject(response.localdb.HighAvailabilityWizard);
  138. // restore Kerberos Wizard is started
  139. var isKerberosWizardStarted = App.isAuthorized('CLUSTER.TOGGLE_KERBEROS') && !App.isEmptyObject(response.localdb.KerberosWizard);
  140. if (params.data.overrideLocaldb || isHAWizardStarted || isKerberosWizardStarted) {
  141. var localdbTables = (App.db.data.app && App.db.data.app.tables) ? App.db.data.app.tables : {};
  142. var authenticated = Em.get(App, 'db.data.app.authenticated') || false;
  143. App.db.data = response.localdb;
  144. App.db.setLocalStorage();
  145. App.db.setUser(params.data.user);
  146. App.db.setLoginName(params.data.login);
  147. App.db.setAuth(params.data.auth);
  148. App.db.setAuthenticated(authenticated);
  149. App.db.data.app.tables = localdbTables;
  150. }
  151. }
  152. }
  153. // this is to ensure that the local storage namespaces are initialized with all expected namespaces.
  154. // after upgrading ambari, loading local storage data from the "persist" data saved via an older version of
  155. // Ambari can result in missing namespaces that are defined in the new version of Ambari.
  156. App.db.mergeStorage();
  157. },
  158. /**
  159. * Error callback for get-persist request
  160. * @param {object} request
  161. * @param {object} ajaxOptions
  162. * @param {string} error
  163. * @method getUserPrefErrorCallback
  164. */
  165. getUserPrefErrorCallback: function (request, ajaxOptions, error) {
  166. if (request.status == 404) {
  167. // default status already set
  168. return;
  169. }
  170. App.ModalPopup.show({
  171. header: Em.I18n.t('common.error'),
  172. secondary: false,
  173. bodyClass: Em.View.extend({
  174. template: Em.Handlebars.compile('<p>{{t common.update.error}}</p>')
  175. })
  176. });
  177. },
  178. /**
  179. * update cluster status and post it on server.
  180. * This function should always be called by admin user
  181. * @param {object} newValue
  182. * @param {object} opt - Can have additional params for ajax callBacks and sender
  183. * opt.successCallback
  184. * opt.successCallbackData
  185. * opt.errorCallback
  186. * opt.errorCallbackData
  187. * opt.alwaysCallback
  188. * opt.alwaysCallbackData
  189. * opt.sender
  190. * @method setClusterStatus
  191. * @return {*}
  192. */
  193. setClusterStatus: function (newValue, opt) {
  194. if (App.get('testMode')) return false;
  195. var user = App.db.getUser();
  196. var auth = App.db.getAuth();
  197. var login = App.db.getLoginName();
  198. var val = {clusterName: this.get('clusterName')};
  199. if (newValue) {
  200. App.db.cleanTmp();
  201. //setter
  202. if (newValue.clusterName) {
  203. this.set('clusterName', newValue.clusterName);
  204. val.clusterName = newValue.clusterName;
  205. }
  206. if (newValue.clusterState) {
  207. this.set('clusterState', newValue.clusterState);
  208. val.clusterState = newValue.clusterState;
  209. }
  210. if (newValue.wizardControllerName) {
  211. this.set('wizardControllerName', newValue.wizardControllerName);
  212. val.wizardControllerName = newValue.wizardControllerName;
  213. }
  214. if (newValue.localdb) {
  215. if (newValue.localdb.app && newValue.localdb.app.user)
  216. delete newValue.localdb.app.user;
  217. if (newValue.localdb.app && newValue.localdb.app.auth)
  218. delete newValue.localdb.app.auth;
  219. if (newValue.localdb.app && newValue.localdb.app.loginName)
  220. delete newValue.localdb.app.loginName;
  221. if (newValue.localdb.app && newValue.localdb.app.tables)
  222. delete newValue.localdb.app.tables;
  223. if (newValue.localdb.app && newValue.localdb.app.authenticated)
  224. delete newValue.localdb.app.authenticated;
  225. this.set('localdb', newValue.localdb);
  226. val.localdb = newValue.localdb;
  227. } else {
  228. delete App.db.data.app.user;
  229. delete App.db.data.app.auth;
  230. delete App.db.data.app.loginName;
  231. delete App.db.data.app.tables;
  232. delete App.db.data.app.authenticated;
  233. val.localdb = App.db.data;
  234. App.db.setUser(user);
  235. App.db.setAuth(auth);
  236. App.db.setLoginName(login);
  237. }
  238. if (!$.mocho) {
  239. // compress val
  240. val = LZString.compressToBase64(JSON.stringify(val));
  241. this.postUserPref(this.get('key'), val)
  242. .done(function () {
  243. !!opt && Em.typeOf(opt.successCallback) === 'function' && opt.successCallback.call(opt.sender || this, opt.successCallbackData);
  244. })
  245. .fail(function () {
  246. !!opt && Em.typeOf(opt.errorCallback) === 'function' && opt.errorCallback.call(opt.sender || this, opt.errorCallbackData);
  247. })
  248. .always(function () {
  249. !!opt && Em.typeOf(opt.alwaysCallback) === 'function' && opt.alwaysCallback.call(opt.sender || this, opt.alwaysCallbackData);
  250. });
  251. }
  252. return newValue;
  253. }
  254. },
  255. /**
  256. * Error callback for post-persist request
  257. * @param {object} request
  258. * @param {object} ajaxOptions
  259. * @param {string} error
  260. * @method postUserPrefErrorCallback
  261. */
  262. postUserPrefErrorCallback: function (request, ajaxOptions, error) {
  263. var msg = '', doc;
  264. try {
  265. msg = 'Error ' + (request.status) + ' ';
  266. doc = $.parseXML(request.responseText);
  267. msg += $(doc).find("body p").text();
  268. } catch (e) {
  269. msg += JSON.parse(request.responseText).message;
  270. }
  271. if (this.get('persistErrorModal')) {
  272. if (this.get('persistErrorModal').get('state') === 'destroyed') {
  273. this.set('persistErrorModal', null);
  274. } else {
  275. this.get('persistErrorModal').onPrimary();
  276. this.set('persistErrorModal', null);
  277. }
  278. }
  279. var modal = App.ModalPopup.show({
  280. header: Em.I18n.t('common.error'),
  281. secondary: false,
  282. response: msg,
  283. bodyClass: Em.View.extend({
  284. template: Em.Handlebars.compile('<p>{{t common.persist.error}} {{response}}</p>')
  285. })
  286. });
  287. this.set('persistErrorModal', modal);
  288. }
  289. });