diff --git a/ui/scripts/lbStickyPolicy.js b/ui/scripts/lbStickyPolicy.js index 3768b8b2c30..685b5a673c2 100644 --- a/ui/scripts/lbStickyPolicy.js +++ b/ui/scripts/lbStickyPolicy.js @@ -1,132 +1,258 @@ (function($, cloudStack) { - cloudStack.lbStickyPolicy = function(args) { - return function(args) { - var success = args.response.success; - var context = args.context; - var network = args.context.networks[0]; - var $item = args.$item; + cloudStack.lbStickyPolicy = { + dialog: function(args) { + return function(args) { + var success = args.response.success; + var context = args.context; + var network = args.context.networks[0]; + var $item = args.$item; - var lbService = $.grep(network.service, function(service) { - return service.name == 'Lb'; - })[0]; - var stickinessCapabilities = JSON.parse( - $.grep(lbService.capability, function(capability) { - return capability.name == 'SupportedStickinessMethods'; - })[0].value - ); - - var baseFields = { - name: { label: 'Name', validation: { required: true }, isHidden: true }, - mode: { label: 'Mode', isHidden: true }, - length: { label: 'Length', validation: { required: true }, isHidden: true }, - holdtime: { label: 'Hold Time', validation: { required: true }, isHidden: true }, - tablesize: { label: 'Table size', isHidden: true }, - expire: { label: 'Expire', isHidden: true }, - requestlearn: { label: 'Request-Learn', isBoolean: true, isHidden: true }, - prefix: { label: 'Prefix', isBoolean: true, isHidden: true }, - nocache: { label: 'No cache', isBoolean: true, isHidden: true }, - indirect: { label: 'Indirect', isBoolean: true, isHidden: true }, - postonly: { label: 'Is post-only', isBoolean: true, isHidden: true }, - domain: { label: 'Domain', isBoolean: true, isHidden: true } - }; - - var conditionalFields = { - methodname: { - label: 'Stickiness method', - select: function(args) { - var $select = args.$select; - var $form = $select.closest('form'); - var stickyOptions = []; - - stickinessCapabilities.push({ methodname: 'None', paramlist: [] }); - $(stickinessCapabilities).each(function() { - var stickyCapability = this; - - stickyOptions.push({ - id: stickyCapability.methodname, - description: stickyCapability.methodname - }); - }); - - stickyOptions = stickyOptions.sort(function() { - return this.id != 'None'; - }) - - args.response.success({ - data: stickyOptions - }, 500); - - $select.change(function() { - var value = $select.val(); - var showFields = []; - var targetMethod = $.grep(stickinessCapabilities, function(stickyCapability) { - return stickyCapability.methodname == value; - })[0]; - var visibleParams = $.map(targetMethod.paramlist, function(param) { - return param.paramname - }); - - $select.closest('.form-item').siblings('.form-item').each(function() { - var $field = $(this); - var id = $field.attr('rel'); - - if ($.inArray(id, visibleParams) > -1) { - $field.css('display', 'inline-block'); - } else { - $field.hide(); - } - }); - - $select.closest(':ui-dialog').dialog('option', 'position', 'center'); - }); - } - } - }; - - var fields = $.extend(conditionalFields, baseFields); - - if (args.data) { - var populatedFields = $.map(fields, function(field, id) { - return id; - }); + var lbService = $.grep(network.service, function(service) { + return service.name == 'Lb'; + })[0]; - $(populatedFields).each(function() { - var id = this; - var field = fields[id]; - var dataItem = args.data[id]; + var stickinessCapabilities = JSON.parse($.grep( + lbService.capability, + function(capability) { + return capability.name == 'SupportedStickinessMethods'; + } + )[0].value); - if (field.isBoolean) { - field.isChecked = dataItem ? true : false; - } else { - field.defaultValue = dataItem; + var baseFields = { + stickyName: { label: 'Sticky Name', validation: { required: true } }, + name: { label: 'Name', validation: { required: true }, isHidden: true }, + mode: { label: 'Mode', isHidden: true }, + length: { label: 'Length', validation: { required: true }, isHidden: true }, + holdtime: { label: 'Hold Time', validation: { required: true }, isHidden: true }, + tablesize: { label: 'Table size', isHidden: true }, + expire: { label: 'Expire', isHidden: true }, + requestlearn: { label: 'Request-Learn', isBoolean: true, isHidden: true }, + prefix: { label: 'Prefix', isBoolean: true, isHidden: true }, + nocache: { label: 'No cache', isBoolean: true, isHidden: true }, + indirect: { label: 'Indirect', isBoolean: true, isHidden: true }, + postonly: { label: 'Is post-only', isBoolean: true, isHidden: true }, + domain: { label: 'Domain', isBoolean: true, isHidden: true } + }; + + var conditionalFields = { + methodname: { + label: 'Stickiness method', + select: function(args) { + var $select = args.$select; + var $form = $select.closest('form'); + var stickyOptions = []; + + stickinessCapabilities.push({ methodname: 'None', paramlist: [] }); + $(stickinessCapabilities).each(function() { + var stickyCapability = this; + + stickyOptions.push({ + id: stickyCapability.methodname, + description: stickyCapability.methodname + }); + }); + + stickyOptions = stickyOptions.sort(function() { + return this.id != 'None'; + }); + + args.response.success({ + data: stickyOptions + }, 500); + + $select.change(function() { + var value = $select.val(); + var showFields = []; + var targetMethod = $.grep(stickinessCapabilities, function(stickyCapability) { + return stickyCapability.methodname == value; + })[0]; + var visibleParams = $.map(targetMethod.paramlist, function(param) { + return param.paramname; + }); + + $select.closest('.form-item').siblings('.form-item').each(function() { + var $field = $(this); + var id = $field.attr('rel'); + + if ($.inArray(id, visibleParams) > -1) { + $field.css('display', 'inline-block'); + $field.attr('sticky-method', value); + } else { + $field.hide(); + $field.attr('sticky-method', null); + } + }); + + // Name always is required + if ($select.val() != 'None') { + $select.closest('.form-item').siblings('.form-item[rel=stickyName]') + .css('display', 'inline-block'); + } + + $select.closest(':ui-dialog').dialog('option', 'position', 'center'); + }); + } + } + }; + + var fields = $.extend(conditionalFields, baseFields); + + if (args.data) { + var populatedFields = $.map(fields, function(field, id) { + return id; + }); + + $(populatedFields).each(function() { + var id = this; + var field = fields[id]; + var dataItem = args.data[id]; + + if (field.isBoolean) { + field.isChecked = dataItem ? true : false; + } else { + field.defaultValue = dataItem; + } + }); + } + + cloudStack.dialog.createForm({ + form: { + title: 'Configure Sticky Policy', + desc: 'Please complete the following fields', + fields: fields + }, + after: function(args) { + // Remove fields not applicable to sticky method + args.$form.find('.form-item:hidden').remove() + + var data = cloudStack.serializeForm(args.$form); + + /* $item indicates that this is an existing sticky rule; + re-create sticky rule with new parameters */ + if ($item) { + var $loading = $('
').addClass('loading-overlay'); + + $loading.prependTo($item); + cloudStack.lbStickyPolicy.actions.recreate( + $item.data('multi-custom-data').id, + $item.data('multi-custom-data').lbRuleID, + data, + function() { // Complete + $(window).trigger('cloudStack.fullRefresh'); + }, + function(error) { // Error + $(window).trigger('cloudStack.fullRefresh'); + } + ); + } else { + success({ + data: data + }); + } } }); - } + }; + }, - cloudStack.dialog.createForm({ - form: { - title: 'Configure Sticky Policy', - desc: 'Please complete the following fields', - fields: fields - }, - after: function(args) { - var data = cloudStack.serializeForm(args.$form); + actions: { + add: function(lbRuleID, data, complete, error) { + var stickyURLData = ''; + var stickyParams = $.map(data, function(value, key) { + return key; + }); - if ($item) { - $.ajax({ - url: createURL('') - }); - - $(window).trigger('cloudStack.fullRefresh'); - } else { - success({ - data: $.extend(data, { - _buttonLabel: data.methodname - }) - }); + var notParams = ['methodname', 'stickyName']; + + $(stickyParams).each(function(index) { + var param = '¶m[' + index + ']'; + var name = this.toString(); + var value = data[name]; + + if (!value || $.inArray(name, notParams) > -1) return true; + if (value == 'on') value = true; + + stickyURLData += param + '.name=' + name + param + '.value=' + value; + + return true; + }); + + $.ajax({ + url: createURL('createLBStickinessPolicy' + stickyURLData), + data: { + lbruleid: lbRuleID, + name: data.stickyName, + methodname: data.methodname + }, + success: function(json) { + cloudStack.ui.notifications.add( + { + desc: 'Add new LB sticky rule', + section: 'Network', + poll: pollAsyncJobResult, + _custom: { + jobId: json.createLBStickinessPolicy.jobid + } + }, + complete, {}, + error, {} + ); + }, + error: function(json) { + complete(); + cloudStack.dialog.notice({ message: parseXMLHttpResponse(json) }); } + }); + }, + recreate: function(stickyRuleID, lbRuleID, data, complete, error) { + var addStickyPolicy = function() { + cloudStack.lbStickyPolicy.actions.add( + lbRuleID, + data, + complete, + error + ); + }; + + // Delete existing rule + if (stickyRuleID) { + $.ajax({ + url: createURL('deleteLBStickinessPolicy'), + data: { + id: stickyRuleID + }, + success: function(json) { + cloudStack.ui.notifications.add( + { + desc: 'Remove previous LB sticky rule', + section: 'Network', + poll: pollAsyncJobResult, + _custom: { + jobId: json.deleteLBstickinessrruleresponse.jobid + } + }, + function() { + if (data.methodname != 'None') { + addStickyPolicy(); + } else { + complete(); + } + }, {}, + error, {} + ); + }, + error: function(json) { + cloudStack.dialog.notice({ + message: parseXMLHttpResponse(json) + }); + error(); + } + }); + } else if (data.methodname != 'None') { + addStickyPolicy(); + } else { + complete(); } - }); - }; + } + } }; }(jQuery, cloudStack)); diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 73687dcfcaf..8fd3df45cda 100644 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -637,7 +637,7 @@ label: 'Stickiness', custom: { buttonLabel: 'Configure', - action: cloudStack.lbStickyPolicy() + action: cloudStack.lbStickyPolicy.dialog() } }, 'add-vm': { @@ -707,68 +707,20 @@ } lbCreationComplete = true; - alert("The load balancer rule has been added under IP " + args.data.loadbalancer.publicip ); - - // Create stickiness policy + cloudStack.dialog.notice({ + message: "The load balancer rule has been added under IP " + + args.data.loadbalancer.publicip + }); + if (stickyData && stickyData.methodname && - stickyData.methodname != 'none') { - var stickyURLData = ''; - var stickyParams; - - switch (stickyData.methodname) { - case 'LbCookie': - stickyParams = ['name', 'mode', 'nocache', 'indirect', 'postonly', 'domain']; - break; - case 'AppCookie': - stickyParams = ['name', 'length', 'holdtime', 'request-learn', 'prefix', 'mode']; - break; - case 'SourceBased': - stickyParams = ['tablesize', 'expire']; - break; - } - - $(stickyParams).each(function(index) { - var param = '¶m[' + index + ']'; - var name = this; - var value = stickyData[name]; - - if (!value) return true; - if (value == 'on') value = true; - - stickyURLData += param + '.name=' + name + param + '.value=' + value; - }); - - $.ajax({ - url: createURL('createLBStickinessPolicy' + stickyURLData), - data: { - lbruleid: args.data.loadbalancer.id, - name: stickyData.name, - methodname: stickyData.methodname - }, - success: function(json) { - var addStickyCheck = setInterval(function() { - pollAsyncJobResult({ - _custom: { - jobId: json.createLBStickinessPolicy.jobid, - }, - complete: function(args) { - complete(); - clearInterval(addStickyCheck); - }, - error: function(args) { - complete(); - cloudStack.dialog.notice({ message: args.message }); - clearInterval(addStickyCheck); - } - }); - }, 1000); - }, - error: function(json) { - complete(); - cloudStack.dialog.notice({ message: parseXMLHttpResponse(json) }); - } - }); + stickyData.methodname != 'None') { + cloudStack.lbStickyPolicy.actions.add( + args.data.loadbalancer.id, + stickyData, + complete, // Complete + complete // Error + ); } else { complete(); } @@ -1668,7 +1620,7 @@ label: 'Stickiness', custom: { buttonLabel: 'Configure', - action: cloudStack.lbStickyPolicy() + action: cloudStack.lbStickyPolicy.dialog() } }, 'add-vm': { @@ -1742,62 +1694,12 @@ if (stickyData && stickyData.methodname && stickyData.methodname != 'None') { - var stickyURLData = ''; - var stickyParams; - - switch (stickyData.methodname) { - case 'LbCookie': - stickyParams = ['name', 'mode', 'nocache', 'indirect', 'postonly', 'domain']; - break; - case 'AppCookie': - stickyParams = ['name', 'length', 'holdtime', 'request-learn', 'prefix', 'mode']; - break; - case 'SourceBased': - stickyParams = ['tablesize', 'expire']; - break; - } - - $(stickyParams).each(function(index) { - var param = '¶m[' + index + ']'; - var name = this; - var value = stickyData[name]; - - if (!value) return true; - if (value == 'on') value = true; - - stickyURLData += param + '.name=' + name + param + '.value=' + value; - }); - - $.ajax({ - url: createURL('createLBStickinessPolicy' + stickyURLData), - data: { - lbruleid: args.data.loadbalancer.id, - name: stickyData.name, - methodname: stickyData.methodname - }, - success: function(json) { - var addStickyCheck = setInterval(function() { - pollAsyncJobResult({ - _custom: { - jobId: json.createLBStickinessPolicy.jobid, - }, - complete: function(args) { - complete(); - clearInterval(addStickyCheck); - }, - error: function(args) { - complete(); - cloudStack.dialog.notice({ message: args.message }); - clearInterval(addStickyCheck); - } - }); - }, 1000); - }, - error: function(json) { - complete(); - cloudStack.dialog.notice({ message: parseXMLHttpResponse(json) }); - } - }); + cloudStack.lbStickyPolicy.actions.add( + args.data.loadbalancer.id, + stickyData, + complete, // Complete + complete // Error + ); } else { complete(); } @@ -1891,11 +1793,15 @@ stickyData = { _buttonLabel: stickyPolicy.methodname, methodname: stickyPolicy.methodname, - id: stickyPolicy.id + stickyName: stickyPolicy.name, + id: stickyPolicy.id, + lbRuleID: item.id }; $.extend(stickyData, stickyPolicy.params); } else { - stickyData = {}; + stickyData = { + lbRuleID: item.id + }; } }, error: function(json) {