configureServicesUtils.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /*
  2. *
  3. * Licensed to the Apache Software Foundation (ASF) under one
  4. * or more contributor license agreements. See the NOTICE file
  5. * distributed with this work for additional information
  6. * regarding copyright ownership. The ASF licenses this file
  7. * to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing,
  14. * software distributed under the License is distributed on an
  15. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  16. * KIND, either express or implied. See the License for the
  17. * specific language governing permissions and limitations
  18. * under the License.
  19. *
  20. */
  21. function ConfigureServicesUtil() {
  22. var passwordsArray = [];
  23. function generateDivForService (option, type, service, property, unit, displayAttributes, isReconfigure) {
  24. var unitClass = (unit != null) ? 'unit' : '';
  25. var unitLabel = (unit != null && unit != 'int') ? unit : '';
  26. // default: if this is reconfiguration, default to NOT editable
  27. // if this is not reconfiguration (original config), default to editable
  28. var readOnlyFlag = isReconfigure;
  29. if (displayAttributes != null) {
  30. if (isReconfigure && displayAttributes.reconfigurable != null && displayAttributes.reconfigurable) {
  31. readOnlyFlag = false;
  32. } else if (!isReconfigure && displayAttributes.editable != null && !displayAttributes.editable) {
  33. readOnlyFlag = true;
  34. }
  35. }
  36. var checked = (type === 'checkbox' && option.value === 'true') ? 'checked' : '';
  37. var retString = '<div class="formElement">' +
  38. '<label for="' + service + '">' + option.displayName + '</label>' +
  39. '<input class="' + unitClass + '" type="' + type + '" id="' + property + '" name="' + service + '" value="' + option.value + '" ' + checked;
  40. if (readOnlyFlag) {
  41. retString += ' readonly="readonly" ';
  42. }
  43. retString += '><label class="unit">' + unitLabel + '</label>' +
  44. '<div class="contextualHelp">' + option.description + '</div>' +
  45. '<div class="formInputErrorReason" id="' + property + 'ErrorReason' + '" style="display:none"></div>' +
  46. '</div>';
  47. if (type == "password" && !isReconfigure) {
  48. retString += '<div class="formElement">' +
  49. '<label for="' + service + '"> Retype ' + option.displayName + '</label>' +
  50. '<input type="' + type + '" id="' + property + 'SecretService" class="retypePassword" name="' + service + '" value="' + option.value + '">' +
  51. '<div class="contextualHelp">' + option.description + '</div>' +
  52. '<div class="formInputErrorReason" id="' + property + 'SecretServiceErrorReason' + '" style="display:none"></div>' +
  53. '</div>';
  54. /// Put it in the global passwd array
  55. passwordsArray[passwordsArray.length] = {
  56. "passwordDivId" : property,
  57. "verificationDivId" : property + 'SecretService'
  58. };
  59. // Y.log("Global Passwords Array: " + Y.Lang.dump(passwordsArray));
  60. }
  61. return retString;
  62. }
  63. /**
  64. * isReconfigure: true if this is for reconfiguring parameters on services; false if this is on "Advanced Config" page
  65. */
  66. this.getOptionsSummaryMarkup = function(optionsInfo, isReconfigure) {
  67. /* Reset passwordsArray at the beginning of each render cycle to
  68. * avoid using stale data from the last run - this isn't a problem on the
  69. * Configure Services page, but it bites us on the Manage Services page
  70. * there is re-use of this module of code within the same JS memory.
  71. */
  72. passwordsArray = [];
  73. var tabs = '<ul id="configureServicesTabs" class="nav nav-tabs">';
  74. var optionsSummary = (isReconfigure) ? '<div>': '<div class="tab-content">';
  75. var setServiceMarkup = function(service) {
  76. if (service.isEnabled === '1') {
  77. var serviceNeedsRender = false;
  78. var propertiesMarkup = "";
  79. for (var property in service.properties) {
  80. // service has configs, so needs render
  81. var type = convertDisplayType(service.properties[property].type);
  82. // Y.log("TYPE: " + type + "Property: " + property);
  83. if (type === "NODISPLAY") {
  84. continue;
  85. }
  86. serviceNeedsRender = true;
  87. var unit = service.properties[property].unit;
  88. var displayAttributes = null;
  89. if (service.properties[property].displayAttributes) {
  90. displayAttributes = service.properties[property].displayAttributes;
  91. }
  92. propertiesMarkup += generateDivForService(service.properties[property], type, service.serviceName, property, unit, displayAttributes, isReconfigure);
  93. }
  94. if (serviceNeedsRender) {
  95. tabs += '<li><a data-toggle="tab" href="#' + service.serviceName + '">' + service.displayName + '<span id="' + service.serviceName + 'ErrorCount" class="serviceErrorCount"></span></a></li>';
  96. // optionsSummary += "<fieldset> <legend>" + service.serviceName + "</legend>";
  97. optionsSummary += '<div class="tab-pane" name=\"configureClusterAdvancedPerServiceDiv\" id=\"' + service.serviceName + '\">';
  98. optionsSummary += propertiesMarkup;
  99. // optionsSummary += '</fieldset></div>';
  100. optionsSummary += '</div>';
  101. }
  102. }
  103. };
  104. if (optionsInfo.services.NAGIOS !== undefined) {
  105. setServiceMarkup(optionsInfo.services.NAGIOS);
  106. }
  107. if (optionsInfo.services.HIVE !== undefined) {
  108. setServiceMarkup(optionsInfo.services.HIVE);
  109. }
  110. for (var servicesKey in optionsInfo.services) {
  111. if (servicesKey !== 'NAGIOS' && servicesKey !== 'HIVE') {
  112. setServiceMarkup(optionsInfo.services[servicesKey]);
  113. }
  114. }
  115. tabs += '</ul>';
  116. optionsSummary += '</div>';
  117. return (isReconfigure) ? optionsSummary : tabs + optionsSummary;
  118. };
  119. /////////////////// End of rendering related functions /////////////////////////////
  120. /////////////////// Submit related functions /////////////////////////////
  121. this.clearPasswordErrors = function () {
  122. for (var count = 0; count < passwordsArray.length; count++) {
  123. divId = "#" + passwordsArray[count]['verificationDivId'];
  124. this.clearErrorReason(divId);
  125. }
  126. };
  127. this.clearErrorReasons = function (opts) {
  128. for(serviceName in opts) {
  129. for (propKey in opts[serviceName]['properties']) {
  130. this.clearErrorReason('#' + propKey);
  131. }
  132. }
  133. // clear the error count displayed in all service tabs
  134. Y.all('.serviceErrorCount').setContent('');
  135. };
  136. this.setErrorReason = function(fieldDivId, errorReason) {
  137. Y.one(fieldDivId).addClass('formInputError');
  138. errorDivId = fieldDivId + 'ErrorReason';
  139. Y.one(errorDivId).setContent(errorReason);
  140. Y.one(errorDivId).show();
  141. };
  142. this.clearErrorReason = function(fieldDivId) {
  143. Y.one(fieldDivId).removeClass('formInputError');
  144. errorDivId = fieldDivId + 'ErrorReason';
  145. Y.one(errorDivId).setContent('');
  146. Y.one(errorDivId).hide();
  147. };
  148. this.checkPasswordCorrectness = function () {
  149. var count = 0;
  150. var focusId = '';
  151. var passwdMatch = true;
  152. var errCount = 0;
  153. var errString = ''; //"<ul>";
  154. for (count = 0; count < passwordsArray.length; count++) {
  155. var divId = "#" + passwordsArray[count]['passwordDivId'];
  156. var passwd = Y.one(divId).get('value');
  157. divId = "#" + passwordsArray[count]['verificationDivId'];
  158. var verifyPasswd = Y.one(divId).get('value');
  159. if (passwd !== verifyPasswd) {
  160. errCount++;
  161. errString = "Password does not match";
  162. this.setErrorReason(divId, errString);
  163. if (focusId === '') {
  164. focusId = divId;
  165. }
  166. passwdMatch = false;
  167. } else {
  168. this.clearErrorReason(divId, '');
  169. }
  170. }
  171. errString += ''; //"</ul>";
  172. retArray = {
  173. "passwdMatched" : passwdMatch,
  174. "focusOn" : focusId,
  175. "errorCount" : errCount,
  176. "errorString" : errString
  177. };
  178. return retArray;
  179. };
  180. this.generateUserOpts = function () {
  181. var desiredOptions = {};
  182. var temp = Y.all("#configureClusterAdvancedDynamicRenderDivId div[name=configureClusterAdvancedPerServiceDiv]");
  183. temp.each(function (selection) {
  184. var selectionStr = "#configureClusterAdvancedDynamicRenderDivId input[name=" + selection.get('id') + "]";
  185. var prop = Y.all(selectionStr);
  186. var properties = {};
  187. prop.each(function (proper) {
  188. for (var i = 0; i < passwordsArray.length; i++) {
  189. if (proper.get('id') == passwordsArray[i]['verificationDivId']) {
  190. return;
  191. }
  192. }
  193. var value = Y.Lang.trim(proper.get('value'));
  194. if ((proper.get('type') == "checkbox")) {
  195. value = proper.get('checked').toString();
  196. }
  197. var keyName = Y.Lang.trim(proper.get('id'));
  198. properties[keyName] = {
  199. "value" : value,
  200. };
  201. });
  202. desiredOptions[selection.get('id')] = {
  203. "properties" : properties,
  204. };
  205. });
  206. clearFormStatus();
  207. this.clearErrorReasons(desiredOptions);
  208. return desiredOptions;
  209. };
  210. // update the error count displayed in the tab for the specified service.
  211. // also toggle the disabled status of the submit button.
  212. this.updateServiceErrorCount = function (serviceName) {
  213. var errorCount = 0;
  214. var serviceDivId = '#' + serviceName;
  215. var serviceDiv = Y.one(serviceDivId);
  216. var errorFields = serviceDiv.all('.formInputErrorReason');
  217. errorFields.each(function (errorField) {
  218. if (errorField.getStyle('display') !== 'none') {
  219. errorCount++;
  220. }
  221. });
  222. var submitButton = Y.one('#configureClusterAdvancedSubmitButtonId');
  223. if (errorCount > 0) {
  224. Y.one(serviceDivId + 'ErrorCount').setContent('<span style="margin-left:4px" class="badge badge-important">' + errorCount + '</span>');
  225. // there is at least one error. disable the submit button
  226. submitButton.addClass('disabled');
  227. } else {
  228. Y.one(serviceDivId + 'ErrorCount').setContent('');
  229. // if no errors at all, enable the submit button and clear error message at the top
  230. if (this.getTotalErrorCount() === 0) {
  231. submitButton.removeClass('disabled');
  232. clearFormStatus();
  233. }
  234. }
  235. };
  236. this.getTotalErrorCount = function () {
  237. var totalErrorCount = 0;
  238. var tabsDiv = Y.one('#configureServicesTabs');
  239. var errorCountBadges = tabsDiv.all('span.badge');
  240. errorCountBadges.each(function (errorCountBadge) {
  241. totalErrorCount += parseInt(errorCountBadge.getHTML(), 10);
  242. });
  243. return totalErrorCount;
  244. };
  245. this.handleConfigureServiceErrors = function (errorResponse) {
  246. var errorCounts = {};
  247. var message = errorResponse.error;
  248. var serviceName = '';
  249. setFormStatus(message, true, true);
  250. for (propKey in errorResponse.properties) {
  251. var errorReason = errorResponse.properties[propKey].error;
  252. var propDom = Y.one('#' + propKey);
  253. serviceName = propDom.get('name');
  254. if (errorCounts[serviceName] == null) {
  255. errorCounts[serviceName] = 1;
  256. } else {
  257. errorCounts[serviceName] += 1;
  258. }
  259. this.setErrorReason('#' + propKey, errorReason);
  260. }
  261. var firstServiceName = null;
  262. // show error counts in the tab for each service that had errors
  263. for (serviceName in errorCounts) {
  264. if (firstServiceName === null) {
  265. firstServiceName = serviceName;
  266. }
  267. this.updateServiceErrorCount(serviceName, errorCounts[serviceName]);
  268. }
  269. // open the first tab that has an error
  270. $('#configureServicesTabs a[href="#' + firstServiceName + '"]').tab('show');
  271. Y.one('#formStatusDivId').scrollIntoView();
  272. }.bind(this);
  273. };
  274. var configureServicesUtil = new ConfigureServicesUtil();