Rafael Weingärtner 689715504c [CLOUDSTACK-10293] Single view network ACL rules listing
The ACL rules editing/addition page is not user-friendly. Users are not able to see in a single view all of the detail of the ACL rule (they need to use a scroll bar on the horizontal). The problem becomes worse when there are a considerable number of rules. Therefore, we are proposing the following changes:

1- Instead of using the table to create new ACL, we can create a button like the one presented in attached pictures, where users can click, and then a modal popup would appear and users would be able to create the new ACL there. This is similar to the workings of the ACL edit button.
2 - Remove the ability to add new ACL via table where they are presented. All ACLs should be entered via the “New ACL” button. Therefore, the section “Add ACL” would be removed as well;
3 - Move the action section of the list ACL table to the most left position;

These changes would reduce the information in the table and facilitate users to add new rules and easily edit them as well.
2018-02-18 22:47:13 -03:00

4421 lines
221 KiB
JavaScript

// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
var assignVMAction = function() {
return {
label: 'label.assign.vms',
messages: {
notification: function(args) {
return 'label.assign.vms';
}
},
needsRefresh: true,
listView: $.extend(true, {}, cloudStack.sections.instances.listView, {
type: 'checkbox',
filters: false,
multiSelect: false,
subselect: {
isMultiple: true,
label: 'label.use.vm.ip',
dataProvider: function(args) {
var instance = args.context.instances[0];
var network = args.context.networks[0];
$.ajax({
url: createURL('listNics'),
data: {
virtualmachineid: instance.id,
nicId: instance.nic[0].id
},
success: function(json) {
var nic = json.listnicsresponse.nic[0];
var primaryIp = nic.ipaddress;
var secondaryIps = nic.secondaryip ? nic.secondaryip : [];
var ipSelection = [];
var existingIps = $(args.context.subItemData).map(
function(index, item) { return item.itemIp; }
);
// Add primary IP as default
if ($.inArray(primaryIp, existingIps) == -1) {
ipSelection.push({
id: primaryIp,
description: primaryIp + ' (Primary)'
});
}
// Add secondary IPs
$(secondaryIps).map(function(index, secondaryIp) {
if ($.inArray(secondaryIp.ipaddress, existingIps) == -1) {
ipSelection.push({
id: secondaryIp.ipaddress,
description: secondaryIp.ipaddress
});
}
});
args.response.success({
data: ipSelection
});
}
});
}
},
dataProvider: function(args) {
var assignedInstances;
$.ajax({
url: createURL('listLoadBalancers'),
data: {
id: args.context.internalLoadBalancers[0].id
},
async: false,
success: function(json) {
assignedInstances = json.listloadbalancersresponse.loadbalancer[0].loadbalancerinstance;
if (assignedInstances == null)
assignedInstances = [];
}
});
$.ajax({
url: createURL('listVirtualMachines'),
data: {
networkid: args.context.networks[0].id,
listAll: true
},
success: function(json) {
var instances = json.listvirtualmachinesresponse.virtualmachine;
// Pre-select existing instances in LB rule
$(instances).map(function(index, instance) {
instance._isSelected = $.grep(assignedInstances,
function(assignedInstance) {
return assignedInstance.id == instance.id;
}
).length ? true : false;
});
//remove assigned VMs (i.e. instance._isSelected == true)
var items = [];
if (instances != null) {
for (var i = 0; i < instances.length; i++) {
if (instances[i]._isSelected == true)
continue;
else
items.push(instances[i]);
}
}
args.response.success({
data: items
});
}
});
}
}),
action: function(args) {
/*
* path 1: Network > VPC (list) > click "Configure" > pick an internal LB tier > click "Internal LB" (list) > click on a grid row (Details tab) > click "Assign VMs" tab > click Assign VMs" button on top of list
* path 2: Network > VPC (list) > click "Configure" > pick an internal LB tier > click "Internal LB" (list) > "QuickView" on a grid row > click "Assign VMs" button in QuickView
*/
var $rows = $(':ui-dialog .list-view tbody tr');
var vms = args.context.instances;
// Assign subselect values
$(vms).each(function() {
var vm = this;
var $vmRow = $rows.filter(function() {
return $(this).data('json-obj') === vm;
});
$.extend(vm, { _subselect: $vmRow.find('.subselect select').val() });
});
var inputData = {
id: args.context.internalLoadBalancers[0].id
};
/*
* e.g. first VM(xxx) has two IPs(10.1.1.~), second VM(yyy) has three IPs(10.2.2.~):
* vmidipmap[0].vmid=xxx vmidipmap[0].vmip=10.1.1.11
* vmidipmap[1].vmid=xxx vmidipmap[1].vmip=10.1.1.12
* vmidipmap[2].vmid=yyy vmidipmap[2].vmip=10.2.2.77
* vmidipmap[3].vmid=yyy vmidipmap[3].vmip=10.2.2.78
* vmidipmap[4].vmid=yyy vmidipmap[4].vmip=10.2.2.79
*/
var selectedVMs = vms;
if (selectedVMs != null) {
var vmidipmapIndex = 0;
for (var vmIndex = 0; vmIndex < selectedVMs.length; vmIndex++) {
var selectedIPs = selectedVMs[vmIndex]._subselect;
for (var ipIndex = 0; ipIndex < selectedIPs.length; ipIndex++) {
inputData['vmidipmap[' + vmidipmapIndex + '].vmid'] = selectedVMs[vmIndex].id;
inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex];
vmidipmapIndex++;
}
}
}
$.ajax({
url: createURL('assignToLoadBalancerRule'),
data: inputData,
dataType: 'json',
async: true,
success: function(data) {
var jid = data.assigntoloadbalancerruleresponse.jobid;
args.response.success({
_custom: {
jobId: jid
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
};
};
var aclRuleFields = {
'number': {
label: 'label.rule.number.short',
desc: 'label.rule.number',
edit: true,
isEditable: true
},
'cidrlist': {
edit: true,
label: 'label.cidr',
isEditable: true
},
action: {
label: 'label.action',
isEditable: true,
select: function(args) {
args.response.success({
data: [{
name: 'Allow',
description: 'Allow'
}, {
name: 'Deny',
description: 'Deny'
}]
});
}
},
'protocol': {
label: 'label.protocol',
isEditable: true,
select: function(args) {
var isEditDialog = args.type === 'createForm';
args.$select.change(function() {
var $inputs, $icmpFields, $otherFields, $portFields, $protocolFields, $protocolinput;
//
// Editing existing rules in createForm dialog
//
if (isEditDialog) {
$inputs = args.$form.find('.form-item');
$icmpFields = $inputs.filter(function() {
var name = $(this).attr('rel');
return $.inArray(name, [
'icmptype',
'icmpcode'
]) > -1;
});
$otherFields = $inputs.filter(function() {
var name = $(this).attr('rel');
return name != 'protocolnumber' &&
name != 'icmptype' &&
name != 'icmpcode' &&
name != 'cidrlist' &&
name != 'number';
});
$portFields = $inputs.filter(function() {
var name = $(this).attr('rel');
return $.inArray(name, [
'startport',
'endport'
]) > -1;
});
$protocolFields = $inputs.filter(function() {
var name = $(this).attr('rel');
return $.inArray(name, ['protocolnumber']) > -1;
});
if ($(this).val() == 'protocolnumber') {
$icmpFields.show();
$portFields.show();
$protocolFields.show();
$portFields.show();
} else if ($(this).val() == 'icmp') {
$icmpFields.show();
$protocolFields.hide();
$portFields.hide();
} else if ($(this).val() == 'all') {
$portFields.hide();
$portFields.attr('disabled', 'disabled');
$icmpFields.hide();
$icmpFields.attr('disabled', 'disabled');
$protocolFields.attr('disabled', 'disabled');
$protocolFields.hide();
} else {
$otherFields.show();
$icmpFields.hide();
$protocolFields.hide();
}
} else {
//
// Add new form
//
$inputs = args.$form.find('input');
$icmpFields = $inputs.filter(function() {
var name = $(this).attr('name');
return $.inArray(name, [
'icmptype',
'icmpcode'
]) > -1;
});
$otherFields = $inputs.filter(function() {
var name = $(this).attr('name');
return name != 'protocolnumber' &&
name != 'icmptype' &&
name != 'icmpcode' &&
name != 'cidrlist' &&
name != 'number';
});
$portFields = $inputs.filter(function() {
var name = $(this).attr('name');
return $.inArray(name, [
'startport',
'endport'
]) > -1;
});
$protocolinput = args.$form.find('td input');
$protocolFields = $protocolinput.filter(function() {
var name = $(this).attr('name');
return $.inArray(name, ['protocolnumber']) > -1;
});
if ($(this).val() == 'protocolnumber') {
$icmpFields.show();
$otherFields.hide();
$protocolFields.show().addClass('required');
$inputs.filter('[name=startport],[name=endport]').show().attr('disabled', false);
} else if ($(this).val() == 'icmp') {
$icmpFields.show();
$icmpFields.attr('disabled', false);
$protocolFields.hide().removeClass('required');
$otherFields.attr('disabled', 'disabled');
$otherFields.hide();
$otherFields.parent().find('label.error').hide();
} else if ($(this).val() == 'all') {
$portFields.hide();
$portFields.attr('disabled', 'disabled');
$icmpFields.hide();
$icmpFields.attr('disabled', 'disabled');
$protocolFields.hide();
$protocolFields.attr('disabled', 'disabled');
} else {
$otherFields.show();
$otherFields.parent().find('label.error').hide();
$otherFields.attr('disabled', false);
$icmpFields.attr('disabled', 'disabled');
$icmpFields.hide();
$icmpFields.parent().find('label.error').hide();
$protocolFields.hide().removeClass('required');
}
}
});
args.response.success({
data: [{
name: 'tcp',
description: 'TCP'
}, {
name: 'udp',
description: 'UDP'
}, {
name: 'icmp',
description: 'ICMP'
}, {
name: 'all',
description: 'ALL'
}, {
name: 'protocolnumber',
description: 'Protocol Number'
}
]
});
setTimeout(function() {
args.$select.trigger('change');
}, 100);
}
},
'protocolnumber': {
label: 'label.protocol.number.short',
desc: 'label.protocol.number',
edit: true,
isEditable: true
},
'startport': {
edit: true,
label: 'label.start.port',
isOptional: true,
isEditable: true
},
'endport': {
edit: true,
label: 'label.end.port',
isOptional: true,
isEditable: true
},
'icmptype': {
edit: true,
label: 'ICMP.type',
desc: 'Please specify -1 if you want to allow all ICMP types',
defaultValue: '-1',
isEditable: true
},
'icmpcode': {
edit: true,
label: 'ICMP.code',
desc: 'Please specify -1 if you want to allow all ICMP codes',
defaultValue: '-1',
isEditable: true
},
'traffictype': {
label: 'label.traffic.type',
isEditable: true,
select: function(args) {
args.response.success({
data: [{
name: 'Ingress',
description: 'Ingress'
}, {
name: 'Egress',
description: 'Egress'
}]
});
}
}
};
var aclRuleFieldsForMultiEdit = {
'networkid': {
label: 'label.select.tier',
select: function(args) {
var data = {
listAll: true,
vpcid: args.context.vpc[0].id
};
// Only show selected tier, if viewing from detail view
if (args.context.networks &&
args.context.networks[0] &&
args.context.networks[0].vpcid) {
$.extend(data, {
id: args.context.networks[0].id
});
}
// Ajax Call to display the Tiers
$.ajax({
url: createURL('listNetworks'),
data: data,
success: function(json) {
var networks = json.listnetworksresponse.network;
args.response.success({
data: $(networks).map(function(index, network) {
return {
name: network.id,
description: network.name
};
})
});
}
});
}
},
};
jQuery.extend(aclRuleFieldsForMultiEdit, aclRuleFields);
var aclMultiEdit = {
doNotShowInputTable: true,
editOptionsFirst: true,
noSelect: true,
reorder: {
moveDrag: {
action: function(args) {
var rule = args.context.multiRule[0];
var number = 0;
var prevItem = args.prevItem ? args.prevItem.number : null;
var nextItem = args.nextItem ? args.nextItem.number : null;
if (!nextItem) { // Last item
number = prevItem + 100;
} else {
if (nextItem - prevItem <= 10) {
number = nextItem - parseInt(((nextItem - prevItem) / 2));
} else {
number = nextItem > 1 ? nextItem - 10 : 1;
}
}
$.ajax({
url: createURL('updateNetworkACLItem'),
data: {
id: rule.id,
number: number
},
success: function(json) {
var pollTimer = setInterval(function() {
pollAsyncJobResult({
_custom: {
jobId: json.createnetworkaclresponse.jobid
},
complete: function() {
clearInterval(pollTimer);
args.response.success();
},
error: function(errorMsg) {
clearInterval(pollTimer);
args.response.error(errorMsg);
}
});
}, 1000);
}
});
}
}
},
fields: aclRuleFieldsForMultiEdit,
tags: cloudStack.api.tags({
resourceType: 'NetworkACL',
contextId: 'multiRule'
}),
add: {
label: 'label.add',
action: function(args) {
var $multi = args.$multi;
//Support for Protocol Number between 0 to 255
if (args.data.protocol === 'protocolnumber') {
$.extend(args.data, {
protocol: args.data.protocolnumber
});
delete args.data.protocolnumber;
delete args.data.icmptype;
delete args.data.icmpcode;
} else {
delete args.data.protocolnumber;
}
if ((args.data.protocol == 'tcp' || args.data.protocol == 'udp') && (args.data.startport == "" || args.data.startport == undefined)) {
cloudStack.dialog.notice({
message: _l('Start Port or End Port value should not be blank')
});
$(window).trigger('cloudStack.fullRefresh');
} else if ((args.data.protocol == 'tcp' || args.data.protocol == 'udp') && (args.data.endport == "" || args.data.endport == undefined)) {
cloudStack.dialog.notice({
message: _l('Start Port or End Port value should not be blank')
});
$(window).trigger('cloudStack.fullRefresh');
} else {
$.ajax({
url: createURL('createNetworkACL'),
data: $.extend(args.data, {
aclid: args.context.aclLists[0].id
}),
dataType: 'json',
success: function(data) {
args.response.success({
_custom: {
jobId: data.createnetworkaclresponse.jobid,
getUpdatedItem: function(json) {
$(window).trigger('cloudStack.fullRefresh');
return data;
}
},
notification: {
label: 'label.add.ACL',
poll: pollAsyncJobResult
}
});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
}
});
}
}
},
actions: {
edit: {
label: 'label.edit',
action: function(args) {
var data = {
id: args.context.multiRule[0].id,
cidrlist: args.data.cidrlist,
number: args.data.number,
protocol: args.data.protocol,
traffictype: args.data.traffictype,
action: args.data.action
};
if (data.protocol === 'tcp' || data.protocol === 'udp') {
$.extend(data, {
startport: args.data.startport,
endport: args.data.endport
});
} else if (data.protocol === 'icmp') {
$.extend(data, {
icmptype: args.data.icmptype,
icmpcode: args.data.icmpcode
});
} else if (data.protocol === 'protocolnumber') {
$.extend(data, {
protocol: args.data.protocolnumber,
startport: args.data.startport,
endport: args.data.endport
});
delete args.data.protocolnumber;
}
$.ajax({
url: createURL('updateNetworkACLItem'),
data: data,
success: function(json) {
args.response.success({
_custom: {
jobId: json.createnetworkaclresponse.jobid
}, // API response obj name needs to be fixed
notification: {
label: 'label.edit.acl.rule',
poll: pollAsyncJobResult
}
});
},
error: function(error) {
args.response.error(parseXMLHttpResponse(error));
}
});
}
},
destroy: {
label: 'label.remove.ACL',
action: function(args) {
$.ajax({
url: createURL('deleteNetworkACL'),
data: {
id: args.context.multiRule[0].id
},
dataType: 'json',
async: true,
success: function(data) {
var jobID = data.deletenetworkaclresponse.jobid;
args.response.success({
_custom: {
jobId: jobID,
getUpdatedItem: function() {
$(window).trigger('cloudStack.fullRefresh');
}
},
notification: {
label: 'label.remove.ACL',
poll: pollAsyncJobResult
}
});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
}
});
}
}
},
dataProvider: function(args) {
var $multi = args.$multi;
var data = {
vpcid: args.context.vpc[0].id,
listAll: true
};
if (!$multi.data('acl-rules')) {
$multi.data('acl-rules', []);
}
if (args.context.networks &&
args.context.networks[0] &&
args.context.networks[0].vpcid) {
data.networkid = args.context.networks[0].id;
$.ajax({
url: createURL('listNetworkACLs'),
data: data,
dataType: 'json',
async: true,
success: function(json) {
args.response.success({
data: $(json.listnetworkaclsresponse.networkacl).map(function(index, acl) {
return $.extend(acl, {
networkid: args.context.networks[0].name
});
})
});
},
error: function(XMLHttpResponse) {
args.response.error(parseXMLHttpResponse(XMLHttpResponse));
}
});
} else {
args.response.success({
data: $multi.data('acl-rules')
});
}
}
};
cloudStack.vpc = {
// nTier sections
sections: {
tierVMs: function() {
var list = $.extend(true, {}, cloudStack.sections.instances);
list.listView.actions.add.action.custom = cloudStack.uiCustom.instanceWizard(
$.extend(true, {}, cloudStack.instanceWizard, {
pluginForm: {
name: 'vpcTierInstanceWizard'
}
})
);
return list;
},
tierPortForwarders: function() {
return cloudStack.vpc.ipAddresses.listView();
},
tierStaticNATs: function() {
return cloudStack.vpc.staticNatIpAddresses.listView();
},
// Internal load balancers
internalLoadBalancers: {
title: 'label.internal.lb',
listView: {
id: 'internalLoadBalancers',
fields: {
name: {
label: 'label.name'
},
sourceipaddress: {
label: 'label.source.ip.address'
},
sourceport: {
label: 'label.source.port'
},
instanceport: {
label: 'label.instance.port'
},
algorithm: {
label: 'label.algorithm'
}
},
dataProvider: function(args) {
var data = {
page: args.page,
pageSize: pageSize,
networkid: args.context.networks[0].id,
listAll: true
};
var keyword = (((args || {}).filterBy || {}).search || {}).value;
if (keyword) {
data.keyword = keyword;
}
$.ajax({
url: createURL('listLoadBalancers'),
data: data,
success: function(json) {
var items = json.listloadbalancersresponse.loadbalancer;
if (items != null) {
for (var i = 0; i < items.length; i++) {
var item = items[i];
//there is only one element in loadbalancerrul array property.
item.sourceport = item.loadbalancerrule[0].sourceport;
item.instanceport = item.loadbalancerrule[0].instanceport;
}
}
args.response.success({
data: items
});
}
});
},
actions: {
add: {
label: 'label.add.internal.lb',
createForm: {
title: 'label.add.internal.lb',
fields: {
name: {
label: 'label.name',
validation: {
required: true
}
},
description: {
label: 'label.description',
validation: {
required: false
}
},
sourceipaddress: {
label: 'label.source.ip.address',
validation: {
required: false
}
},
sourceport: {
label: 'label.source.port',
validation: {
required: true
}
},
instanceport: {
label: 'label.instance.port',
validation: {
required: true
}
},
algorithm: {
label: 'label.algorithm',
validation: {
required: true
},
select: function(args) {
args.response.success({
data: [{
id: 'source',
description: _l('label.lb.algorithm.source')
}, {
id: 'roundrobin',
description: _l('label.lb.algorithm.roundrobin')
}, {
id: 'leastconn',
description: _l('label.lb.algorithm.leastconn')
}]
});
}
}
}
},
messages: {
notification: function(args) {
return 'label.add.internal.lb';
}
},
action: function(args) {
var data = {
name: args.data.name,
sourceport: args.data.sourceport,
instanceport: args.data.instanceport,
algorithm: args.data.algorithm,
networkid: args.context.networks[0].id,
sourceipaddressnetworkid: args.context.networks[0].id,
scheme: 'Internal'
};
if (args.data.description != null && args.data.description.length > 0) {
$.extend(data, {
description: args.data.description
});
}
if (args.data.sourceipaddress != null && args.data.sourceipaddress.length > 0) {
$.extend(data, {
sourceipaddress: args.data.sourceipaddress
});
}
$.ajax({
url: createURL('createLoadBalancer'),
data: data,
success: function(json) {
var jid = json.createloadbalancerresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.loadbalancer;
}
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
detailView: {
isMaximized: true,
name: 'label.internal.lb.details',
actions: {
assignVMs: assignVMAction(),
remove: {
label: 'label.delete.internal.lb',
messages: {
confirm: function(args) {
return 'message.confirm.delete.internal.lb';
},
notification: function(args) {
return 'label.delete.internal.lb';
}
},
action: function(args) {
var data = {
id: args.context.internalLoadBalancers[0].id
};
$.ajax({
url: createURL('deleteLoadBalancer'),
data: data,
async: true,
success: function(json) {
var jid = json.deleteloadbalancerresponse.jobid;
args.response.success({
_custom: {
jobId: jid
}
});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
tabs: {
details: {
title: 'label.details',
fields: [{
name: {
label: 'label.name'
}
}, {
id: {
label: 'label.id'
},
description: {
label: 'label.description'
},
sourceipaddress: {
label: 'label.source.ip.address'
},
sourceport: {
label: 'label.source.port'
},
instanceport: {
label: 'label.instance.port'
},
algorithm: {
label: 'label.algorithm'
},
loadbalancerinstance: {
label: 'label.assigned.vms',
converter: function(objArray) {
var s = '';
if (objArray != null) {
for (var i = 0; i < objArray.length; i++) {
if (i > 0) {
s += ', ';
}
s += objArray[i].name + ' (' + objArray[i].ipaddress + ')';
}
}
return s;
}
}
}],
dataProvider: function(args) {
$.ajax({
url: createURL('listLoadBalancers'),
data: {
id: args.context.internalLoadBalancers[0].id
},
success: function(json) {
var item = json.listloadbalancersresponse.loadbalancer[0];
//remove Rules tab and add sourceport, instanceport at Details tab because there is only one element in loadbalancerrul array property.
item.sourceport = item.loadbalancerrule[0].sourceport;
item.instanceport = item.loadbalancerrule[0].instanceport;
args.response.success({
data: item
});
}
});
}
},
assignedVms: {
title: 'label.assigned.vms',
listView: {
id: 'assignedVms',
fields: {
name: {
label: 'label.name'
},
ipaddress: {
label: 'label.ip.address'
}
},
dataProvider: function(args) {
$.ajax({
url: createURL('listLoadBalancers'),
data: {
id: args.context.internalLoadBalancers[0].id
},
success: function(json) {
var item = json.listloadbalancersresponse.loadbalancer[0];
args.response.success({
data: item.loadbalancerinstance
});
}
});
},
actions: {
add: assignVMAction()
},
detailView: {
actions: {
remove: {
label: 'label.remove.vm.load.balancer',
addRow: 'false',
messages: {
confirm: function(args) {
return 'message.confirm.remove.load.balancer';
},
notification: function(args) {
return 'label.remove.vm.load.balancer';
}
},
action: function(args) {
$.ajax({
url: createURL('removeFromLoadBalancerRule'),
data: {
id: args.context.internalLoadBalancers[0].id,
virtualmachineids: args.context.assignedVms[0].id
},
success: function(json) {
var jid = json.removefromloadbalancerruleresponse.jobid;
args.response.success({
_custom: {
jobId: jid
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
tabs: {
details: {
title: 'label.details',
fields: [{
name: {
label: 'label.name'
}
}, {
ipaddress: {
label: 'label.ip.address'
}
}],
dataProvider: function(args) {
setTimeout(function() {
args.response.success({
data: args.context.assignedVms[0]
});
});
}
}
}
}
}
}
}
}
}
},
publicLbIps: {
title: 'label.public.ip',
listView: {
id: 'publicLbIps',
fields: {
ipaddress: {
label: 'label.ips',
converter: function(text, item) {
if (item.issourcenat) {
return text + ' [' + _l('label.source.nat') + ']';
}
return text;
}
},
zonename: {
label: 'label.zone'
},
virtualmachinedisplayname: {
label: 'label.vm.name'
},
state: {
converter: function(str) {
// For localization
return str;
},
label: 'label.state',
indicator: {
'Allocated': 'on',
'Released': 'off'
}
}
},
dataProvider: function(args) {
$.ajax({
url: createURL('listPublicIpAddresses'),
async: false,
data: {
associatednetworkid: args.context.networks[0].id,
forloadbalancing: true,
listall: true
},
success: function(json) {
var items = json.listpublicipaddressesresponse.publicipaddress;
args.response.success({
data: items
});
}
});
}
}
},
// Private gateways
privateGateways: function() {
return cloudStack.vpc.gateways.listView()
},
// Public IP Addresses
publicIPs: function() {
return cloudStack.vpc.ipAddresses.listView()
},
// Network ACL lists
networkACLLists: {
listView: {
id: 'aclLists',
fields: {
name: {
label: 'label.name'
},
description: {
label: 'label.description'
},
id: {
label: 'label.id'
}
},
dataProvider: function(args) {
var data = {
vpcid: args.context.vpc[0].id
};
listViewDataProvider(args, data);
$.ajax({
url: createURL('listNetworkACLLists'),
data: data,
success: function(json) {
var items = json.listnetworkacllistsresponse.networkacllist;
args.response.success({
data: items
});
}
});
},
actions: {
add: {
label: 'label.add.acl.list',
createForm: {
label: 'label.add.acl.list',
fields: {
name: {
label: 'label.add.list.name',
validation: {
required: true
}
},
description: {
label: 'label.description',
validation: {
required: true
}
}
}
},
messages: {
notification: function(args) {
return 'label.add.network.acl.list';
}
},
action: function(args) {
var data = {
name: args.data.name,
description: args.data.description
};
$.ajax({
url: createURL('createNetworkACLList&vpcid=' + args.context.vpc[0].id),
data: data,
success: function(json) {
args.response.success({
_custom: {
jobId: json.createnetworkacllistresponse.jobid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.networkacllist;
}
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
detailView: {
isMaximized: true,
actions: {
remove: {
label: 'label.delete.acl.list',
messages: {
confirm: function(args) {
return 'message.confirm.delete.acl.list';
},
notification: function(args) {
return 'label.delete.acl.list';
}
},
action: function(args) {
$.ajax({
url: createURL('deleteNetworkACLList&id=' + args.context.aclLists[0].id),
success: function(json) {
var jid = json.deletenetworkacllistresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function() {
$(window).trigger('cloudStack.fullRefresh');
}
}
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
tabs: {
details: {
title: 'label.details',
fields: [{
name: {
label: 'label.name',
isEditable: true
},
description: {
label: 'label.description'
},
id: {
label: 'label.id'
}
}],
dataProvider: function(args) {
var items = args.context.aclLists[0];
setTimeout(function() {
args.response.success({
data: items,
actionFilter: function(args) {
var allowedActions = [];
if (items.vpcid != null) {
allowedActions.push("remove");
}
return allowedActions;
}
});
});
}
},
aclRules: {
title: 'label.acl.list.rules',
custom: function(args) {
return $('<div>').multiEdit($.extend(true, {}, aclMultiEdit, {
context: args.context,
fields: {
networkid: false
},
dataProvider: function(args) {
$.ajax({
url: createURL('listNetworkACLs&aclid=' + args.context.aclLists[0].id),
success: function(json) {
var items = json.listnetworkaclsresponse.networkacl;
if(items){
items.sort(function(a, b) {
return a.number >= b.number;
}).map(function(acl) {
if (parseInt(acl.protocol)) { // protocol number
acl.protocolnumber = acl.protocol;
acl.protocol = "protocolnumber";
}
return acl;
});
}
args.response.success({
data: items
});
if(jQuery('#details-tab-aclRules').siblings('div.toolbar').children('div.add').size() === 0){
var $addAclRuleDivButton = jQuery('<div>').addClass('button add');
var $spanAddAclRuleButtonMessage = jQuery('<span>').html(_l('label.add.ACL'));
$addAclRuleDivButton.html($spanAddAclRuleButtonMessage);
$addAclRuleDivButton.click(function(){
cloudStack.dialog.createForm({
form: {
title: 'label.add.rule',
desc: 'Create a new ACL rule',
fields: aclRuleFields
},
after: function(argsLocal) {
var data = argsLocal.data;
data.aclid = argsLocal.context.aclLists[0].id;
if(data.protocol != 'icmp'){
data.icmpcode = undefined;
data.icmptype = undefined;
}
if(data.protocol != 'protocolnumber'){
data.protocolnumber = undefined;
}
if(data.protocol === 'all'){
data.startport = undefined;
data.endport = undefined;
}
$.ajax({
url: createURL('createNetworkACL'),
data: argsLocal.data,
type: "POST",
success: function(json) {
jQuery('button.cancel:visible').click();
jQuery('div.toolbar:visible div.refresh').click();
}
});
},
context: args.context
});
});
jQuery('#details-tab-aclRules').siblings('div.toolbar').append($addAclRuleDivButton);
}
}
});
}
}));
}
}
}
}
}
},
siteToSiteVPNs: function() {
return $.extend(true, {}, cloudStack.vpc.siteToSiteVPN, {
// siteToSiteVPN is multi-section so doesn't have an explicit
// 'listView' block
//
// -- use this as a flag for VPC chart to render as a list view
listView: true,
before: {
messages: {
confirm: 'Please confirm that you would like to create a site-to-site VPN gateway for this VPC.',
notification: 'Create site-to-site VPN gateway'
},
check: function(args) {
var items;
$.ajax({
url: createURL('listVpnGateways&listAll=true'),
data: {
vpcid: args.context.vpc[0].id
},
success: function(json) {
var items = json.listvpngatewaysresponse.vpngateway;
args.response.success(items && items.length);
}
});
},
action: function(args) {
$.ajax({
url: createURL("createVpnGateway"),
data: {
vpcid: args.context.vpc[0].id
},
success: function(json) {
var jid = json.createvpngatewayresponse.jobid;
var pollTimer = setInterval(function() {
pollAsyncJobResult({
_custom: {
jobId: jid
},
complete: function() {
clearInterval(pollTimer);
args.response.success();
}
});
}, g_queryAsyncJobResultInterval);
}
});
}
}
});
}
},
routerDetailView: function() {
return {
title: 'label.VPC.router.details',
updateContext: function(args) {
var router;
$.ajax({
url: createURL("listRouters&listAll=true&vpcid=" + args.context.vpc[0].id),
dataType: "json",
async: false,
success: function(json) {
router = json.listroutersresponse.router[0];
}
});
return {
routers: [router]
};
},
actions: cloudStack.sections.system.subsections.virtualRouters
.listView.detailView.actions,
tabs: {
routerDetails: cloudStack.sections.network.sections.vpc
.listView.detailView.tabs.router
}
};
},
vmListView: {
id: 'vpcTierInstances',
listView: {
filters: {
all: {
label: 'label.menu.all.instances'
},
running: {
label: 'label.menu.running.instances'
},
stopped: {
label: 'label.menu.stopped.instances'
},
destroyed: {
label: 'label.menu.destroyed.instances'
}
},
fields: {
name: {
label: 'label.name',
editable: true
},
account: {
label: 'label.account'
},
zonename: {
label: 'label.zone'
},
state: {
label: 'label.status',
indicator: {
'Running': 'on',
'Stopped': 'off',
'Destroyed': 'off'
}
}
},
// List view actions
actions: {
start: {
label: 'label.action.start.instance',
action: function(args) {
$.ajax({
url: createURL("startVirtualMachine&id=" + args.context.vpcTierInstances[0].id),
dataType: "json",
async: true,
success: function(json) {
var jid = json.startvirtualmachineresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.virtualmachine;
},
getActionFilter: function() {
return cloudStack.actionFilter.vmActionFilter;
}
}
});
}
});
},
messages: {
confirm: function(args) {
return 'message.action.start.instance';
},
notification: function(args) {
return 'label.action.start.instance';
},
complete: function(args) {
if (args.password != null) {
cloudStack.dialog.notice({
message: 'Password of the VM is ' + args.password
});
}
return 'label.action.start.instance';
}
},
notification: {
poll: pollAsyncJobResult
}
},
stop: {
label: 'label.action.stop.instance',
addRow: 'false',
createForm: {
title: 'label.action.stop.instance',
desc: 'message.action.stop.instance',
fields: {
forced: {
label: 'force.stop',
isBoolean: true,
isChecked: false
}
}
},
action: function(args) {
var array1 = [];
array1.push("&forced=" + (args.data.forced == "on"));
$.ajax({
url: createURL("stopVirtualMachine&id=" + args.context.vpcTierInstances[0].id + array1.join("")),
dataType: "json",
async: true,
success: function(json) {
var jid = json.stopvirtualmachineresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.virtualmachine;
},
getActionFilter: function() {
return cloudStack.actionFilter.vmActionFilter;
}
}
});
}
});
},
messages: {
confirm: function(args) {
return 'message.action.stop.instance';
},
notification: function(args) {
return 'label.action.stop.instance';
}
},
notification: {
poll: pollAsyncJobResult
}
},
restart: {
label: 'instances.actions.reboot.label',
action: function(args) {
$.ajax({
url: createURL("rebootVirtualMachine&id=" + args.context.vpcTierInstances[0].id),
dataType: "json",
async: true,
success: function(json) {
var jid = json.rebootvirtualmachineresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.virtualmachine;
},
getActionFilter: function() {
return cloudStack.actionFilter.vmActionFilter;
}
}
});
}
});
},
messages: {
confirm: function(args) {
return 'message.action.reboot.instance';
},
notification: function(args) {
return 'instances.actions.reboot.label';
}
},
notification: {
poll: pollAsyncJobResult
}
},
destroy: {
label: 'label.action.destroy.instance',
messages: {
confirm: function(args) {
return 'message.action.destroy.instance';
},
notification: function(args) {
return 'label.action.destroy.instance';
}
},
action: function(args) {
$.ajax({
url: createURL("destroyVirtualMachine&id=" + args.context.vpcTierInstances[0].id),
dataType: "json",
async: true,
success: function(json) {
var jid = json.destroyvirtualmachineresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.virtualmachine;
},
getActionFilter: function() {
return cloudStack.actionFilter.vmActionFilter;
}
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
restore: {
label: 'label.action.restore.instance',
messages: {
confirm: function(args) {
return 'message.action.restore.instance';
},
notification: function(args) {
return 'label.action.restore.instance';
}
},
action: function(args) {
$.ajax({
url: createURL("recoverVirtualMachine&id=" + args.context.vpcTierInstances[0].id),
dataType: "json",
async: true,
success: function(json) {
var item = json.recovervirtualmachineresponse.virtualmachine;
args.response.success({
data: item
});
}
});
}
},
viewConsole: {
label: 'label.view.console',
action: {
externalLink: {
url: function(args) {
return clientConsoleUrl + '?cmd=access&vm=' + args.context.vpcTierInstances[0].id;
},
title: function(args) {
return args.context.vpcTierInstances[0].id.substr(0, 8); //title in window.open() can't have space nor longer than 8 characters. Otherwise, IE browser will have error.
},
width: 820,
height: 640
}
}
}
},
dataProvider: function(args) {
var array1 = [];
if (args.filterBy != null) {
if (args.filterBy.kind != null) {
switch (args.filterBy.kind) {
case "all":
array1.push("&listAll=true");
break;
case "mine":
if (!args.context.projects) array1.push("&domainid=" + g_domainid + "&account=" + g_account);
break;
case "running":
array1.push("&listAll=true&state=Running");
break;
case "stopped":
array1.push("&listAll=true&state=Stopped");
break;
case "destroyed":
array1.push("&listAll=true&state=Destroyed");
break;
}
}
if (args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) {
switch (args.filterBy.search.by) {
case "name":
if (args.filterBy.search.value.length > 0)
array1.push("&keyword=" + args.filterBy.search.value);
break;
}
}
}
$.ajax({
url: createURL('listVirtualMachines' + array1.join("")),
data: {
networkid: args.context.networks[0].id
},
success: function(json) {
args.response.success({
data: json.listvirtualmachinesresponse.virtualmachine,
actionFilter: cloudStack.actionFilter.vmActionFilter
});
}
});
}
}
},
ipAddresses: {
listView: function() {
var listView = $.extend(true, {}, cloudStack.sections.network.sections.ipAddresses);
listView.listView.fields = {
ipaddress: listView.listView.fields.ipaddress,
zonename: listView.listView.fields.zonename,
associatednetworkname: {
label: 'label.network.name'
},
state: listView.listView.fields.state
};
return listView;
}
},
staticNatIpAddresses: {
listView: function() {
var listView = $.extend(true, {}, cloudStack.sections.network.sections.ipAddresses);
listView.listView.fields = {
ipaddress: listView.listView.fields.ipaddress,
zonename: listView.listView.fields.zonename,
associatednetworkname: {
label: 'label.network.name'
},
state: listView.listView.fields.state
};
listView.listView.dataProvider = function(args) {
$.ajax({
url: createURL('listPublicIpAddresses'),
data: {
associatednetworkid: args.context.networks[0].id,
isstaticnat: true,
listall: true
},
success: function(json) {
args.response.success({
data: json.listpublicipaddressesresponse.publicipaddress
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
};
return listView;
}
},
acl: {
multiEdit: aclMultiEdit,
listView: {
listView: {
id: 'networks',
fields: {
tierName: {
label: 'label.tier'
},
aclTotal: {
label: 'label.network.ACL.total'
}
},
dataProvider: function(args) {
$.ajax({
url: createURL('listNetworks'),
data: {
listAll: true,
vpcid: args.context.vpc[0].id
},
success: function(json) {
var networks = json.listnetworksresponse.network ?
json.listnetworksresponse.network : [];
args.response.success({
data: $.map(networks, function(tier) {
var aclTotal = 0;
// Get ACL total
$.ajax({
url: createURL('listNetworkACLs'),
async: false,
data: {
listAll: true,
networkid: tier.id
},
success: function(json) {
aclTotal = json.listnetworkaclsresponse.networkacl ?
json.listnetworkaclsresponse.networkacl.length : 0;
}
});
return $.extend(tier, {
tierName: tier.name,
aclTotal: aclTotal
});
})
});
}
});
}
}
}
},
gateways: {
add: {
preCheck: function(args) {
if (isAdmin()) { //root-admin
var items;
$.ajax({
url: createURL('listPrivateGateways'),
async: false,
data: {
vpcid: args.context.vpc[0].id,
listAll: true
},
success: function(json) {
items = json.listprivategatewaysresponse.privategateway;
}
});
if (items && items.length) {
return true; //show private gateway listView
} else {
return false; //show create private gateway dialog
}
} else { //regular-user, domain-admin
return true; //show private gateway listView instead of create private gateway dialog because only root-admin is allowed to create private gateway
}
},
label: 'label.add.new.gateway',
messages: {
notification: function(args) {
return 'label.add.new.gateway';
}
},
createForm: {
title: 'label.add.new.gateway',
desc: 'message.add.new.gateway.to.vpc',
fields: {
physicalnetworkid: {
docID: 'helpVPCGatewayPhysicalNetwork',
label: 'label.physical.network',
select: function(args) {
$.ajax({
url: createURL("listPhysicalNetworks"),
data: {
zoneid: args.context.vpc[0].zoneid
},
success: function(json) {
var objs = json.listphysicalnetworksresponse.physicalnetwork;
var items = [];
$(objs).each(function() {
items.push({
id: this.id,
description: this.name
});
});
args.response.success({
data: items
});
}
});
}
},
vlan: {
label: 'label.vlan',
validation: {
required: true
},
docID: 'helpVPCGatewayVLAN'
},
ipaddress: {
label: 'label.ip.address',
validation: {
required: true
},
docID: 'helpVPCGatewayIP'
},
gateway: {
label: 'label.gateway',
validation: {
required: true
},
docID: 'helpVPCGatewayGateway'
},
netmask: {
label: 'label.netmask',
validation: {
required: true
},
docID: 'helpVPCGatewayNetmask'
},
sourceNat: {
label: 'label.source.nat',
isBoolean: true,
isChecked: false
},
aclid: {
label: 'label.acl',
select: function(args) {
$.ajax({
url: createURL('listNetworkACLLists'),
dataType: 'json',
async: true,
success: function(json) {
var objs = json.listnetworkacllistsresponse.networkacllist;
var items = [];
$(objs).each(function() {
if (this.name == "default_deny")
items.unshift({
id: this.id,
description: this.name
});
else
items.push({
id: this.id,
description: this.name
});
});
args.response.success({
data: items
});
}
});
}
}
}
},
action: function(args) {
var array1 = [];
if (args.$form.find('.form-item[rel=sourceNat]').find('input[type=checkbox]').is(':Checked') == true) {
array1.push("&sourcenatsupported=true");
} else
array1.push("&sourcenatsupported=false");
$.ajax({
url: createURL('createPrivateGateway' + array1.join("")),
data: {
physicalnetworkid: args.data.physicalnetworkid,
vpcid: args.context.vpc[0].id,
ipaddress: args.data.ipaddress,
gateway: args.data.gateway,
netmask: args.data.netmask,
vlan: args.data.vlan,
aclid: args.data.aclid
},
success: function(json) {
var jid = json.createprivategatewayresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.privategateway;
}
}
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
listView: function() {
return {
listView: {
id: 'vpcGateways',
fields: {
ipaddress: {
label: 'label.ip.address',
validation: {
required: true
}
},
gateway: {
label: 'label.gateway',
validation: {
required: true
}
},
netmask: {
label: 'label.netmask',
validation: {
required: true
}
},
vlan: {
label: 'label.vlan',
validation: {
required: true
}
}
},
actions: {
add: {
label: 'label.add.private.gateway',
preFilter: function(args) {
if (isAdmin() || isDomainAdmin())
return true;
else
return false;
},
createForm: {
title: 'label.add.new.gateway',
desc: 'message.add.new.gateway.to.vpc',
fields: {
physicalnetworkid: {
docID: 'helpVPCGatewayPhysicalNetwork',
label: 'label.physical.network',
select: function(args) {
$.ajax({
url: createURL("listPhysicalNetworks"),
data: {
zoneid: args.context.vpc[0].zoneid
},
success: function(json) {
var objs = json.listphysicalnetworksresponse.physicalnetwork;
var items = [];
$(objs).each(function() {
items.push({
id: this.id,
description: this.name
});
});
args.response.success({
data: items
});
}
});
}
},
vlan: {
label: 'label.vlan',
validation: {
required: true
},
docID: 'helpVPCGatewayVLAN'
},
ipaddress: {
label: 'label.ip.address',
validation: {
required: true
},
docID: 'helpVPCGatewayIP'
},
gateway: {
label: 'label.gateway',
validation: {
required: true
},
docID: 'helpVPCGatewayGateway'
},
netmask: {
label: 'label.netmask',
validation: {
required: true
},
docID: 'helpVPCGatewayNetmask'
},
sourceNat: {
label: 'label.source.nat',
isBoolean: true,
isChecked: false
},
aclid: {
label: 'label.acl',
select: function(args) {
$.ajax({
url: createURL('listNetworkACLLists'),
data: {
vpcid: args.context.vpc[0].id
},
success: function(json) {
var objs = json.listnetworkacllistsresponse.networkacllist;
var items = [];
$(objs).each(function() {
if (this.name == "default_deny")
items.unshift({
id: this.id,
description: this.name
});
else
items.push({
id: this.id,
description: this.name
});
});
args.response.success({
data: items
});
}
});
}
}
}
},
action: function(args) {
var array1 = [];
if (args.$form.find('.form-item[rel=sourceNat]').find('input[type=checkbox]').is(':Checked') == true) {
array1.push("&sourcenatsupported=true");
} else
array1.push("&sourcenatsupported=false");
$.ajax({
url: createURL('createPrivateGateway' + array1.join("")),
data: {
physicalnetworkid: args.data.physicalnetworkid,
vpcid: args.context.vpc[0].id,
ipaddress: args.data.ipaddress,
gateway: args.data.gateway,
netmask: args.data.netmask,
vlan: args.data.vlan,
aclid: args.data.aclid
},
success: function(json) {
var jid = json.createprivategatewayresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.privategateway;
}
}
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
dataProvider: function(args) {
$.ajax({
url: createURL('listPrivateGateways'),
data: {
vpcid: args.context.vpc[0].id,
listAll: true
},
success: function(json) {
var items = json.listprivategatewaysresponse.privategateway;
args.response.success({
data: items
});
}
});
},
detailView: {
name: 'label.details',
actions: {
remove: {
label: 'label.delete.gateway',
messages: {
confirm: function(args) {
return 'message.delete.gateway';
},
notification: function(args) {
return 'label.delete.gateway';
}
},
action: function(args) {
$.ajax({
url: createURL("deletePrivateGateway&id=" + args.context.vpcGateways[0].id),
dataType: "json",
async: true,
success: function(json) {
var jid = json.deleteprivategatewayresponse.jobid;
args.response.success({
_custom: {
jobId: jid
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
replaceACL: {
label: 'label.replace.acl',
createForm: {
title: 'label.replace.acl',
label: 'label.replace.acl',
fields: {
aclid: {
label: 'label.acl',
select: function(args) {
$.ajax({
url: createURL('listNetworkACLLists'),
data: {
vpcid: args.context.vpc[0].id
},
dataType: 'json',
async: true,
success: function(json) {
var objs = json.listnetworkacllistsresponse.networkacllist;
var items = [];
$(objs).each(function() {
if (this.id == args.context.vpcGateways[0].aclid) {
return true;
}
items.push({
id: this.id,
description: this.name
});
return true;
});
args.response.success({
data: items
});
}
});
}
}
}
},
action: function(args) {
$.ajax({
url: createURL("replaceNetworkACLList&gatewayid=" + args.context.vpcGateways[0].id + "&aclid=" + args.data.aclid),
dataType: "json",
success: function(json) {
var jid = json.replacenetworkacllistresponse.jobid;
args.response.success(
{
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
var item = json.queryasyncjobresultresponse.jobresult.aclid;
return {
aclid: args.data.aclid
};
}
}
}
)
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
notification: {
poll: pollAsyncJobResult
},
messages: {
confirm: function(args) {
return 'message.confirm.replace.acl.new.one';
},
notification: function(args) {
return 'label.acl.replaced';
}
}
}
},
tabs: {
details: {
title: 'label.details',
fields: [{
ipaddress: {
label: 'label.ip.address'
}
}, {
gateway: {
label: 'label.gateway'
},
netmask: {
label: 'label.netmask'
},
vlan: {
label: 'label.vlan'
},
state: {
label: 'label.state'
},
id: {
label: 'label.id'
},
zonename: {
label: 'label.zone'
},
domain: {
label: 'label.domain'
},
account: {
label: 'label.account'
},
sourcenatsupported: {
label: 'label.source.nat.supported',
converter: function(str) {
return str ? 'Yes' : 'No';
}
},
aclName: {
label: 'label.acl.name'
},
aclid: {
label: 'label.acl.id'
}
}],
dataProvider: function(args) {
$.ajax({
url: createURL('listPrivateGateways'),
data: {
id: args.context.vpcGateways[0].id,
listAll: true
},
success: function(json) {
var item = json.listprivategatewaysresponse.privategateway[0];
// Get ACL name
$.ajax({
url: createURL('listNetworkACLLists'),
async: false,
data: {
vpcid: args.context.vpc[0].id
},
success: function(json) {
var objs = json.listnetworkacllistsresponse.networkacllist;
var acl = $.grep(objs, function(obj) {
return obj.id === args.context.vpcGateways[0].aclid;
});
item.aclName = acl[0] ? acl[0].name : 'None';
}
});
args.response.success({
data: item,
actionFilter: function(args) {
var allowedActions = [];
if (isAdmin()) {
allowedActions.push("remove");
allowedActions.push("replaceACL");
}
return allowedActions;
}
});
}
});
}
},
staticRoutes: {
title: 'label.static.routes',
custom: function(args) {
return $('<div>').multiEdit({
noSelect: true,
context: args.context,
fields: {
cidr: {
edit: true,
label: 'label.CIDR.of.destination.network'
},
'add-rule': {
label: 'label.add.route',
addButton: true
}
},
tags: cloudStack.api.tags({
resourceType: 'StaticRoute',
contextId: 'multiRule'
}),
add: {
label: 'label.add',
action: function(args) {
$.ajax({
url: createURL('createStaticRoute'),
data: {
gatewayid: args.context.vpcGateways[0].id,
cidr: args.data.cidr
},
success: function(data) {
args.response.success({
_custom: {
jobId: data.createstaticrouteresponse.jobid
},
notification: {
label: 'label.add.static.route',
poll: pollAsyncJobResult
}
});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
}
});
}
},
actions: {
destroy: {
label: 'label.remove.static.route',
action: function(args) {
$.ajax({
url: createURL('deleteStaticRoute'),
data: {
id: args.context.multiRule[0].id
},
dataType: 'json',
async: true,
success: function(data) {
var jobID = data.deletestaticrouteresponse.jobid;
args.response.success({
_custom: {
jobId: jobID
},
notification: {
label: 'label.remove.static.route',
poll: pollAsyncJobResult
}
});
}
});
}
}
},
dataProvider: function(args) {
$.ajax({
url: createURL('listStaticRoutes'),
data: {
gatewayid: args.context.vpcGateways[0].id,
listAll: true
},
success: function(json) {
var items = json.liststaticroutesresponse.staticroute;
args.response.success({
data: items
});
}
});
}
});
}
}
}
}
}
};
}
},
siteToSiteVPN: {
title: 'label.site.to.site.VPN',
id: 'siteToSiteVpn',
sectionSelect: {
preFilter: function(args) {
return ["vpnGateway", "vpnConnection"];
},
label: 'label.select-view'
},
// This is a custom add function -- does not show in list view
add: {
// Check if VPN gateways exist
// -- if false, don't show list view
preCheck: function(args) {
var items;
$.ajax({
url: createURL('listVpnGateways&listAll=true'),
data: {
vpcid: args.context.vpc[0].id
},
async: false,
success: function(json) {
items = json.listvpngatewaysresponse.vpngateway;
}
});
if (items && items.length) {
return true;
}
return false;
},
label: 'label.add.VPN.gateway',
messages: {
notification: function(args) {
return 'label.add.VPN.gateway';
}
},
createForm: {
title: 'label.add.VPN.gateway',
desc: 'message.add.VPN.gateway',
fields: {}
},
action: function(args) {
$.ajax({
url: createURL("createVpnGateway"),
data: {
vpcid: args.context.vpc[0].id
},
success: function(json) {
var jid = json.createvpngatewayresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.vpngateway;
}
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
sections: {
vpnGateway: {
type: 'select',
title: 'label.VPN.gateway',
listView: {
id: 'vpnGateway',
label: 'label.VPN.gateway',
fields: {
publicip: {
label: 'label.ip.address'
},
account: {
label: 'label.account'
},
domain: {
label: 'label.domain'
}
},
dataProvider: function(args) {
var array1 = [];
if (args.filterBy != null) {
if (args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) {
switch (args.filterBy.search.by) {
case "name":
if (args.filterBy.search.value.length > 0)
array1.push("&keyword=" + args.filterBy.search.value);
break;
}
}
}
$.ajax({
url: createURL("listVpnGateways&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")),
data: {
vpcid: args.context.vpc[0].id
},
async: false,
success: function(json) {
var items = json.listvpngatewaysresponse.vpngateway;
args.response.success({
data: items
});
}
});
},
detailView: {
name: 'label.details',
actions: {
remove: {
label: 'label.delete.VPN.gateway',
messages: {
confirm: function(args) {
return 'message.delete.VPN.gateway';
},
notification: function(args) {
return 'label.delete.VPN.gateway';
}
},
action: function(args) {
$.ajax({
url: createURL("deleteVpnGateway"),
data: {
id: args.context.vpnGateway[0].id
},
success: function(json) {
var jid = json.deletevpngatewayresponse.jobid;
args.response.success({
_custom: {
jobId: jid
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
tabs: {
details: {
title: 'label.details',
fields: [{
publicip: {
label: 'label.ip.address'
}
}, {
id: {
label: 'label.id'
},
domain: {
label: 'label.domain'
},
account: {
label: 'label.account'
}
}],
dataProvider: function(args) {
$.ajax({
url: createURL("listVpnGateways"),
data: {
listAll: true,
id: args.context.vpnGateway[0].id
},
async: true,
success: function(json) {
var item = json.listvpngatewaysresponse.vpngateway[0];
args.response.success({
data: item
});
}
});
}
}
}
}
}
},
vpnConnection: {
type: 'select',
title: 'label.VPN.connection',
listView: {
id: 'vpnConnection',
label: 'label.VPN.connection',
fields: {
publicip: {
label: 'label.ip.address'
},
gateway: {
label: 'label.gateway'
},
state: {
label: 'label.state',
indicator: {
'Connected': 'on',
'Disconnected': 'off',
'Error': 'off'
}
},
ipsecpsk: {
label: 'label.IPsec.preshared.key'
},
ikepolicy: {
label: 'label.IKE.policy'
},
esppolicy: {
label: 'label.ESP.policy'
}
},
dataProvider: function(args) {
var array1 = [];
if (args.filterBy != null) {
if (args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) {
switch (args.filterBy.search.by) {
case "name":
if (args.filterBy.search.value.length > 0)
array1.push("&keyword=" + args.filterBy.search.value);
break;
}
}
}
$.ajax({
url: createURL("listVpnConnections&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("")),
data: {
vpcid: args.context.vpc[0].id
},
success: function(json) {
var items = json.listvpnconnectionsresponse.vpnconnection;
args.response.success({
data: items
});
}
});
},
actions: {
add: {
label: 'label.create.VPN.connection',
messages: {
notification: function(args) {
return 'label.create.VPN.connection';
}
},
createForm: {
title: 'label.create.VPN.connection',
fields: {
vpncustomergatewayid: {
label: 'label.VPN.customer.gateway',
validation: {
required: true
},
select: function(args) {
$.ajax({
url: createURL("listVpnCustomerGateways"),
data: {
listAll: true
},
success: function(json) {
var items = json.listvpncustomergatewaysresponse.vpncustomergateway ? json.listvpncustomergatewaysresponse.vpncustomergateway : [];
args.response.success({
data: $.map(items, function(item) {
return {
id: item.id,
description: item.name
};
})
});
}
});
}
},
passive: {
label: 'label.passive',
isBoolean: true,
isChecked: false
}
}
},
action: function(args) {
var vpngatewayid = null;
$.ajax({
url: createURL('listVpnGateways'),
data: {
listAll: true,
vpcid: args.context.vpc[0].id
},
async: false,
success: function(json) {
var items = json.listvpngatewaysresponse.vpngateway;
if (items != null && items.length > 0) {
vpngatewayid = items[0].id;
}
}
});
if (vpngatewayid == null) {
args.response.error('The selected VPC does not have a VPN gateway. Please create a VPN gateway for the VPC first.');
return;
}
$.ajax({
url: createURL('createVpnConnection'),
data: {
s2svpngatewayid: vpngatewayid,
s2scustomergatewayid: args.data.vpncustomergatewayid,
passive: (args.data.passive == 'on'? true: false)
},
success: function(json) {
var jid = json.createvpnconnectionresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.vpnconnection;
}
}
});
},
error: function(xmlHttpResponse) {
args.response.error(parseXMLHttpResponse(xmlHttpResponse));
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
detailView: {
name: 'label.details',
tabs: {
details: {
title: 'label.details',
fields: [{
id: {
label: 'label.id'
},
passive: {
label: 'label.passive',
converter: cloudStack.converters.toBooleanText
},
publicip: {
label: 'label.ip.address'
},
gateway: {
label: 'label.gateway'
},
cidrlist: {
label: 'label.CIDR.list'
},
ipsecpsk: {
label: 'label.IPsec.preshared.key'
},
ikepolicy: {
label: 'label.IKE.policy'
},
esppolicy: {
label: 'label.ESP.policy'
},
ikelifetime: {
label: 'label.IKE.lifetime'
},
esplifetime: {
label: 'label.ESP.lifetime'
},
dpd: {
label: 'label.dead.peer.detection',
converter: function(str) {
return str ? 'Yes' : 'No';
}
},
forceencap: {
label: 'label.vpn.force.encapsulation',
converter: function(str) {
return str ? 'Yes' : 'No';
}
},
state: {
label: 'label.state'
},
created: {
label: 'label.date',
converter: cloudStack.converters.toLocalDate
}
}],
dataProvider: function(args) {
$.ajax({
url: createURL("listVpnConnections&id=" + args.context.vpnConnection[0].id),
dataType: "json",
async: true,
success: function(json) {
var item = json.listvpnconnectionsresponse.vpnconnection[0];
args.response.success({
data: item
});
}
});
}
}
},
actions: {
restart: {
label: 'label.reset.VPN.connection',
messages: {
confirm: function(args) {
return 'message.reset.VPN.connection';
},
notification: function(args) {
return 'label.reset.VPN.connection';
}
},
action: function(args) {
$.ajax({
url: createURL("resetVpnConnection"),
data: {
id: args.context.vpnConnection[0].id
},
dataType: "json",
async: true,
success: function(json) {
var jid = json.resetvpnconnectionresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.vpnconnection;
}
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
remove: {
label: 'label.delete.VPN.connection',
messages: {
confirm: function(args) {
return 'message.delete.VPN.connection';
},
notification: function(args) {
return 'label.delete.VPN.connection';
}
},
action: function(args) {
$.ajax({
url: createURL("deleteVpnConnection"),
dataType: "json",
data: {
id: args.context.vpnConnection[0].id
},
async: true,
success: function(json) {
var jid = json.deletevpnconnectionresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.vpnconnection;
}
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
}
}
}
}
}
},
tiers: {
detailView: { //duplicate from cloudStack.sections.network.sections.networks.listView.detailView (begin)
name: 'Guest network details',
viewAll: {
path: 'network.ipAddresses',
label: 'label.menu.ipaddresses',
preFilter: function(args) {
return false;
/// Disabled
if (args.context.networks[0].state == 'Destroyed')
return false;
var services = args.context.networks[0].service;
if (services == null)
return false;
if (args.context.networks[0].type == "Isolated") {
for (var i = 0; i < services.length; i++) {
var service = services[i];
if (service.name == "SourceNat") {
return true;
}
}
} else if (args.context.networks[0].type == "Shared") {
var havingSecurityGroupService = false;
var havingElasticIpCapability = false;
var havingElasticLbCapability = false;
for (var i = 0; i < services.length; i++) {
var service = services[i];
if (service.name == "SecurityGroup") {
havingSecurityGroupService = true;
} else if (service.name == "StaticNat") {
$(service.capability).each(function() {
if (this.name == "ElasticIp" && this.value == "true") {
havingElasticIpCapability = true;
return false; //break $.each() loop
}
});
} else if (service.name == "Lb") {
$(service.capability).each(function() {
if (this.name == "ElasticLb" && this.value == "true") {
havingElasticLbCapability = true;
return false; //break $.each() loop
}
});
}
}
if (havingSecurityGroupService == true && havingElasticIpCapability == true && havingElasticLbCapability == true)
return true;
else
return false;
}
return false;
}
},
actions: {
edit: {
label: 'label.edit',
messages: {
notification: function(args) {
return 'label.edit.network.details';
}
},
action: function(args) {
var array1 = [];
array1.push("&name=" + todb(args.data.name));
array1.push("&displaytext=" + todb(args.data.displaytext));
//args.data.networkdomain is null when networkdomain field is hidden
if (args.data.networkdomain != null && args.data.networkdomain != args.context.networks[0].networkdomain)
array1.push("&networkdomain=" + todb(args.data.networkdomain));
//args.data.networkofferingid is null when networkofferingid field is hidden
if (args.data.networkofferingid != null && args.data.networkofferingid != args.context.networks[0].networkofferingid) {
array1.push("&networkofferingid=" + todb(args.data.networkofferingid));
if (args.context.networks[0].type == "Isolated") { //Isolated network
cloudStack.dialog.confirm({
message: 'message.confirm.current.guest.CIDR.unchanged',
action: function() { //"Yes" button is clicked
array1.push("&changecidr=false");
$.ajax({
url: createURL("updateNetwork&id=" + args.context.networks[0].id + array1.join("")),
dataType: "json",
success: function(json) {
var jid = json.updatenetworkresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
var item = json.queryasyncjobresultresponse.jobresult.network;
return {
data: item
};
}
}
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
cancelAction: function() { //"Cancel" button is clicked
array1.push("&changecidr=true");
$.ajax({
url: createURL("updateNetwork&id=" + args.context.networks[0].id + array1.join("")),
dataType: "json",
success: function(json) {
var jid = json.updatenetworkresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
var item = json.queryasyncjobresultresponse.jobresult.network;
return {
data: item
};
}
}
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
}
});
return;
}
}
$.ajax({
url: createURL("updateNetwork&id=" + args.context.networks[0].id + array1.join("")),
dataType: "json",
success: function(json) {
var jid = json.updatenetworkresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
var item = json.queryasyncjobresultresponse.jobresult.network;
return {
data: item
};
}
}
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
'restart': {
label: 'label.restart.network',
createForm: {
title: 'label.restart.network',
desc: 'message.restart.network',
preFilter: function(args) {
var zoneObj;
$.ajax({
url: createURL("listZones&id=" + args.context.networks[0].zoneid),
dataType: "json",
async: false,
success: function(json) {
zoneObj = json.listzonesresponse.zone[0];
}
});
if (zoneObj.networktype == "Basic") {
args.$form.find('.form-item[rel=cleanup]').find('input').removeAttr('checked'); //unchecked
args.$form.find('.form-item[rel=cleanup]').hide(); //hidden
} else {
args.$form.find('.form-item[rel=cleanup]').find('input').attr('checked', 'checked'); //checked
args.$form.find('.form-item[rel=cleanup]').css('display', 'inline-block'); //shown
}
},
fields: {
cleanup: {
label: 'label.clean.up',
isBoolean: true
}
}
},
messages: {
notification: function(args) {
return 'label.restart.network';
}
},
action: function(args) {
var array1 = [];
array1.push("&cleanup=" + (args.data.cleanup == "on"));
$.ajax({
url: createURL("restartNetwork&id=" + args.context.networks[0].id + array1.join("")),
dataType: "json",
async: true,
success: function(json) {
var jid = json.restartnetworkresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
return json.queryasyncjobresultresponse.jobresult.network;
}
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
remove: {
label: 'label.action.delete.network',
messages: {
confirm: function(args) {
return 'message.action.delete.network';
},
notification: function(args) {
return 'label.action.delete.network';
}
},
action: function(args) {
$.ajax({
url: createURL("deleteNetwork&id=" + args.context.networks[0].id),
dataType: "json",
async: true,
success: function(json) {
var jid = json.deletenetworkresponse.jobid;
args.response.success({
_custom: {
jobId: jid
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
},
replaceacllist: {
label: 'label.replace.acl.list',
createForm: {
title: 'label.replace.acl.list',
label: 'label.replace.acl.list',
fields: {
aclid: {
label: 'label.acl',
select: function(args) {
$.ajax({
url: createURL('listNetworkACLLists&vpcid=' + args.context.vpc[0].id),
dataType: 'json',
async: true,
success: function(json) {
var objs = json.listnetworkacllistsresponse.networkacllist;
var items = [];
$(objs).each(function() {
if (this.id == args.context.networks[0].aclid) {
return true;
}
items.push({
id: this.id,
description: this.name
});
return true;
});
args.response.success({
data: items
});
}
});
}
}
}
},
action: function(args) {
$.ajax({
url: createURL("replaceNetworkACLList&networkid=" + args.context.networks[0].id + "&aclid=" + args.data.aclid),
dataType: "json",
success: function(json) {
var jid = json.replacenetworkacllistresponse.jobid;
args.response.success({
_custom: {
jobId: jid,
getUpdatedItem: function(json) {
var network = args.context.networks[0];
network.aclid = args.data.aclid;
return {
aclid: args.data.aclid
};
}
}
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
},
notification: {
poll: pollAsyncJobResult
},
messages: {
confirm: function(args) {
return 'message.confirm.replace.acl.new.one';
},
notification: function(args) {
return 'label.acl.replaced';
}
}
}
},
tabFilter: function(args) {
var hiddenTabs = ['ipAddresses', 'acl']; // Disable IP address tab; it is redundant with 'view all' button
var networkOfferingHavingELB = false;
var services = args.context.networks[0].service;
if(services != null) {
for(var i = 0; i < services.length; i++) {
if (services[i].name == "Lb") {
var capabilities = services[i].capability;
if(capabilities != null) {
for(var k = 0; k < capabilities.length; k++) {
if(capabilities[k].name == "ElasticLb") {
networkOfferingHavingELB = true;
break;
}
}
}
break;
}
}
}
if (networkOfferingHavingELB == false) {
hiddenTabs.push("addloadBalancer");
}
return hiddenTabs;
},
isMaximized: true,
tabs: {
details: {
title: 'label.network.details',
preFilter: function(args) {
var hiddenFields = [];
var zone;
$.ajax({
url: createURL('listZones'),
data: {
id: args.context.networks[0].zoneid
},
async: false,
success: function(json) {
zone = json.listzonesresponse.zone[0];
}
});
if (zone.networktype == "Basic") {
hiddenFields.push("account");
hiddenFields.push("gateway");
hiddenFields.push("vlan");
hiddenFields.push("cidr");
//hiddenFields.push("netmask");
}
if (args.context.networks[0].type == "Isolated") {
hiddenFields.push("networkofferingdisplaytext");
hiddenFields.push("networkdomaintext");
hiddenFields.push("gateway");
hiddenFields.push("networkofferingname");
//hiddenFields.push("netmask");
} else { //selectedGuestNetworkObj.type == "Shared"
hiddenFields.push("networkofferingid");
hiddenFields.push("networkdomain");
}
return hiddenFields;
},
fields: [{
name: {
label: 'label.name',
isEditable: true
}
}, {
id: {
label: 'label.id'
},
zonename: {
label: 'label.zone'
},
displaytext: {
label: 'label.description',
isEditable: true
},
type: {
label: 'label.type'
},
state: {
label: 'label.state'
},
ispersistent: {
label: 'label.persistent',
converter: cloudStack.converters.toBooleanText
},
restartrequired: {
label: 'label.restart.required',
converter: function(booleanValue) {
if (booleanValue == true)
return "<font color='red'>Yes</font>";
else if (booleanValue == false)
return "No";
}
},
vlan: {
label: 'label.vlan.id'
},
networkofferingname: {
label: 'label.network.offering'
},
networkofferingid: {
label: 'label.network.offering',
isEditable: true,
select: function(args) {
if (args.context.networks[0].state == 'Destroyed') {
args.response.success({
data: []
});
return;
}
var items = [];
$.ajax({
url: createURL("listNetworkOfferings&networkid=" + args.context.networks[0].id),
dataType: "json",
async: false,
success: function(json) {
var networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering;
$(networkOfferingObjs).each(function() {
items.push({
id: this.id,
description: this.displaytext
});
});
}
});
//include currently selected network offeirng to dropdown
items.push({
id: args.context.networks[0].networkofferingid,
description: args.context.networks[0].networkofferingdisplaytext
});
args.response.success({
data: items
});
}
},
gateway: {
label: 'label.gateway'
},
//netmask: { label: 'Netmask' },
cidr: {
label: 'label.cidr'
},
networkdomaintext: {
label: 'label.network.domain.text'
},
networkdomain: {
label: 'label.network.domain',
isEditable: true
},
aclname: {
label: 'label.acl.name'
},
//aclid:{label:'ACL id'},
domain: {
label: 'label.domain'
},
account: {
label: 'label.account'
}
}],
dataProvider: function(args) {
$.ajax({
url: createURL("listNetworks&id=" + args.context.networks[0].id + "&listAll=true"), //pass "&listAll=true" to "listNetworks&id=xxxxxxxx" for now before API gets fixed.
data: {
listAll: true
},
dataType: "json",
async: true,
success: function(json) {
var jsonObj = json.listnetworksresponse.network[0];
if (jsonObj.aclid != null) {
$.ajax({
url: createURL("listNetworkACLLists&id=" + jsonObj.aclid),
dataType: "json",
success: function(json) {
var aclObj = json.listnetworkacllistsresponse.networkacllist[0];
args.response.success({
actionFilter: cloudStack.actionFilter.guestNetwork,
data: $.extend(jsonObj, {
aclname: aclObj.name
})
});
},
error: function(json) {
args.response.error(parseXMLHttpResponse(json));
}
});
} else {
args.response.success({
actionFilter: cloudStack.actionFilter.guestNetwork,
data: $.extend(jsonObj, {
aclname: 'None'
})
});
}
}
});
}
},
acl: {
title: 'label.network.ACL',
custom: function(args) {
// Widget renders ACL multi-edit, overriding this fn
return $('<div>');
}
},
ipAddresses: {
title: 'label.menu.ipaddresses',
custom: function(args) {
// Widget renders IP addresses, overriding this fn
return $('<div>');
}
},
addloadBalancer: {
title: 'label.add.load.balancer',
custom: function(args) {
var context = args.context;
return $('<div>').multiEdit({
context: context,
listView: $.extend(true, {}, cloudStack.sections.instances, {
listView: {
dataProvider: function(args) {
var networkid;
if ('vpc' in args.context)
networkid = args.context.multiData.tier;
else
networkid = args.context.ipAddresses[0].associatednetworkid;
var data = {
page: args.page,
pageSize: pageSize,
networkid: networkid,
listAll: true
};
$.ajax({
url: createURL('listVirtualMachines'),
data: data,
dataType: 'json',
async: true,
success: function(data) {
args.response.success({
data: $.grep(
data.listvirtualmachinesresponse.virtualmachine ?
data.listvirtualmachinesresponse.virtualmachine : [],
function(instance) {
return $.inArray(instance.state, [
'Destroyed'
]) == -1;
}
)
});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
}
});
}
}
}),
multipleAdd: true,
fields: {
'name': {
edit: true,
label: 'label.name'
},
'publicport': {
edit: true,
label: 'label.public.port'
},
'privateport': {
edit: true,
label: 'label.private.port'
},
'algorithm': {
label: 'label.algorithm',
select: function(args) {
args.response.success({
data: [{
name: 'roundrobin',
description: _l('label.lb.algorithm.roundrobin')
}, {
name: 'leastconn',
description: _l('label.lb.algorithm.leastconn')
}, {
name: 'source',
description: _l('label.lb.algorithm.source')
}]
});
}
},
'sticky': {
label: 'label.stickiness',
custom: {
buttonLabel: 'label.configure',
action: cloudStack.lbStickyPolicy.dialog()
}
},
'add-vm': {
label: 'label.add.vm',
addButton: true
}
},
add: {
label: 'label.add.vm',
action: function(args) {
var data = {
algorithm: args.data.algorithm,
name: args.data.name,
privateport: args.data.privateport,
publicport: args.data.publicport,
openfirewall: false,
domainid: g_domainid,
account: g_account
};
if ('vpc' in args.context) { //from VPC section
if (args.data.tier == null) {
args.response.error('Tier is required');
return;
}
$.extend(data, {
networkid: args.data.tier
});
} else { //from Guest Network section
$.extend(data, {
networkid: args.context.networks[0].id
});
}
var stickyData = $.extend(true, {}, args.data.sticky);
$.ajax({
url: createURL('createLoadBalancerRule'),
data: data,
dataType: 'json',
async: true,
success: function(data) {
var itemData = args.itemData;
var jobID = data.createloadbalancerruleresponse.jobid;
$.ajax({
url: createURL('assignToLoadBalancerRule'),
data: {
id: data.createloadbalancerruleresponse.id,
virtualmachineids: $.map(itemData, function(elem) {
return elem.id;
}).join(',')
},
dataType: 'json',
async: true,
success: function(data) {
var lbCreationComplete = false;
args.response.success({
_custom: {
jobId: jobID
},
notification: {
label: 'label.add.load.balancer',
poll: function(args) {
var complete = args.complete;
var error = args.error;
pollAsyncJobResult({
_custom: args._custom,
complete: function(args) {
if (lbCreationComplete) {
return;
}
lbCreationComplete = true;
cloudStack.dialog.notice({
message: _l('message.add.load.balancer.under.ip') + args.data.loadbalancer.publicip
});
if (stickyData &&
stickyData.methodname &&
stickyData.methodname != 'None') {
cloudStack.lbStickyPolicy.actions.add(
args.data.loadbalancer.id,
stickyData,
complete, // Complete
complete // Error
);
} else {
complete();
}
},
error: error
});
}
}
});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
}
});
},
error: function(data) {
args.response.error(parseXMLHttpResponse(data));
}
});
}
},
dataProvider: function(args) {
args.response.success({ //no LB listing in AddLoadBalancer tab
data: []
});
}
});
}
}
}
}, //duplicate from cloudStack.sections.network.sections.networks.listView.detailView (begin)
actionPreFilter: function(args) {
var tier = args.context.networks[0];
var state = tier.state;
return state == 'Running' ? ['start'] : ['stop'];
},
actions: {
add: {
label: 'label.add.new.tier',
createForm: {
title: 'label.add.new.tier',
fields: {
name: {
label: 'label.name',
validation: {
required: true
},
docID: 'helpTierName'
},
networkOfferingId: {
label: 'label.network.offering',
docID: 'helpTierNetworkOffering',
validation: {
required: true
},
dependsOn: 'zoneId',
select: function(args) {
var publicLbNetworkExists = false;
$.ajax({
url: createURL('listNetworks'),
data: {
vpcid: args.context.vpc[0].id,
supportedservices: 'LB'
},
success: function(json) {
var publicLbNetworkExists = false;
var lbNetworks = json.listnetworksresponse.network;
if (lbNetworks != null) {
for (var i = 0; i < lbNetworks.length; i++) {
var thisNetworkOfferingIncludesPublicLbService = false;
$.ajax({
url: createURL('listNetworkOfferings'),
data: {
id: lbNetworks[i].networkofferingid
},
async: false,
success: function(json) {
var networkOffering = json.listnetworkofferingsresponse.networkoffering[0];
$(networkOffering.service).each(function() {
var thisService = this;
if (thisService.name == "Lb" && lbProviderMap.publicLb.vpc.indexOf(thisService.provider[0].name) != -1) {
thisNetworkOfferingIncludesPublicLbService = true;
return false; //break $.each() loop
}
});
}
});
if (thisNetworkOfferingIncludesPublicLbService == true) {
publicLbNetworkExists = true;
break; //break for loop
}
}
}
$.ajax({
url: createURL('listNetworkOfferings'),
data: {
forvpc: true,
zoneid: args.zoneId,
guestiptype: 'Isolated',
supportedServices: 'SourceNat',
state: 'Enabled'
},
success: function(json) {
var networkOfferings = json.listnetworkofferingsresponse.networkoffering;
args.$select.change(function() {
var $vlan = args.$select.closest('form').find('[rel=vlan]');
var networkOffering = $.grep(
networkOfferings, function(netoffer) {
return netoffer.id == args.$select.val();
}
)[0];
if (networkOffering.specifyvlan) {
$vlan.css('display', 'inline-block');
} else {
$vlan.hide();
}
});
//only one network(tier) is allowed to have PublicLb (i.e. provider is PublicLb provider like "VpcVirtualRouter", "Netscaler") in a VPC
var items;
if (publicLbNetworkExists == true) { //so, if a PublicLb network(tier) already exists in the vpc, exclude PublicLb network offerings from dropdown
items = $.grep(networkOfferings, function(networkOffering) {
var thisNetworkOfferingIncludesPublicLbService = false;
$(networkOffering.service).each(function() {
var thisService = this;
if (thisService.name == "Lb" && lbProviderMap.publicLb.vpc.indexOf(thisService.provider[0].name) != -1) {
thisNetworkOfferingIncludesPublicLbService = true;
return false; //break $.each() loop
}
});
return !thisNetworkOfferingIncludesPublicLbService;
});
} else {
items = networkOfferings;
}
args.response.success({
data: $.map(items, function(item) {
return {
id: item.id,
description: item.name
};
})
});
}
});
}
});
}
},
vlan: {
label: 'label.vlan',
validation: {
required: true
},
isHidden: true
},
gateway: {
label: 'label.gateway',
docID: 'helpTierGateway',
validation: {
required: true
}
},
netmask: {
label: 'label.netmask',
docID: 'helpTierNetmask',
validation: {
required: true
}
},
externalId: {
label: 'label.guest.externalId'
},
aclid: {
label: 'label.acl',
select: function(args) {
$.ajax({
url: createURL('listNetworkACLLists&vpcid=' + args.context.vpc[0].id),
dataType: 'json',
async: true,
success: function(json) {
var objs = json.listnetworkacllistsresponse.networkacllist;
var items = [];
items.push({
id: '',
description: ''
});
$(objs).each(function() {
items.push({
id: this.id,
description: this.name
});
});
args.response.success({
data: items
});
}
});
}
},
zoneid: {
label: 'label.zone',
validation: {
required: true
},
isHidden: true,
select: function(args) {
//var $zoneSelect = $(".ui-dialog-content").find('select.zoneid');
var $zoneSelect = args.$select.closest('form').find('[rel=zoneid]');
if (!args.context.regions) {
$zoneSelect.hide();
args.response.success({
data: []
});
}
else {
$zoneSelect.css('display', 'inline-block');
$.ajax({
url: createURL('listZones'),
success: function(json) {
var zones = $.grep(json.listzonesresponse.zone, function(zone) {
return (zone.networktype == 'Advanced');
});
args.response.success({
data: $.map(zones, function(zone) {
return {
id: zone.id,
description: zone.name
};
})
});
}
});
}
}
}
}
},
action: function(args) {
var dataObj = {
vpcid: args.context.vpc[0].id,
domainid: args.context.vpc[0].domainid,
account: args.context.vpc[0].account,
networkOfferingId: args.data.networkOfferingId,
name: args.data.name,
displayText: args.data.name,
gateway: args.data.gateway,
netmask: args.data.netmask
};
if (args.context.regions)
$.extend(dataObj, {
zoneId: args.data.zoneid
})
else
$.extend(dataObj, {
zoneId: args.context.vpc[0].zoneid
});
if (args.data.externalId != null && args.data.externalId.length > 0) {
$.extend(dataObj, {
externalid: args.data.externalId
});
}
if (args.data.aclid != '') {
$.extend(dataObj, {
aclid: args.data.aclid
});
}
if (args.$form.find('.form-item[rel=vlan]').is(':visible')) {
$.extend(dataObj, {
vlan: args.data.vlan
});
}
$.ajax({
url: createURL('createNetwork'),
dataType: 'json',
data: dataObj,
success: function(json) {
args.response.success({
data: json.createnetworkresponse.network
});
},
error: function(XMLHttpResponse) {
args.response.error(parseXMLHttpResponse(XMLHttpResponse));
}
});
},
messages: {
notification: function() {
return 'label.add.new.tier';
}
}
},
/*
start: {
label: 'Start tier',
shortLabel: 'Start',
action: function(args) {
args.response.success();
},
notification: {
poll: function(args) { args.complete({ data: { state: 'Running' } }); }
}
},
*/
/*
stop: {
label: 'Stop tier',
shortLabel: 'Stop',
action: function(args) {
args.response.success();
},
notification: {
poll: function(args) { args.complete({ data: { state: 'Stopped' } }); }
}
},
*/
addVM: {
label: 'label.add.VM.to.tier',
shortLabel: 'label.add.vm',
action: cloudStack.uiCustom.instanceWizard(
$.extend(true, {}, cloudStack.instanceWizard, {
pluginForm: {
name: 'vpcTierInstanceWizard'
}
})
),
notification: {
poll: pollAsyncJobResult
}
},
// Removing ACL buttons from the tier chart
/* acl: {
label: 'Configure ACL for tier',
shortLabel: 'ACL',
multiEdit: aclMultiEdit
}, */
remove: {
label: 'label.remove.tier',
action: function(args) {
$.ajax({
url: createURL('deleteNetwork'),
dataType: "json",
data: {
id: args.context.networks[0].id
},
success: function(json) {
var jid = json.deletenetworkresponse.jobid;
args.response.success({
_custom: {
jobId: jid
}
});
}
});
},
notification: {
poll: pollAsyncJobResult
}
}
},
// Get tiers
dataProvider: function(args) {
$.ajax({
url: createURL("listNetworks"),
dataType: "json",
data: {
vpcid: args.context.vpc[0].id,
//listAll: true, //do not pass listAll to listNetworks under VPC
domainid: args.context.vpc[0].domainid,
account: args.context.vpc[0].account
},
async: true,
success: function(json) {
var networks = json.listnetworksresponse.network;
var networkACLLists, publicIpAddresses, privateGateways, vpnGateways;
var error = false;
// Get network ACL lists
$.ajax({
url: createURL('listNetworkACLLists'),
data: {
'vpcid': args.context.vpc[0].id
},
async: false,
success: function(json) {
networkACLLists = json.listnetworkacllistsresponse;
},
error: function(json) {
error = true;
}
});
// Get public IPs
$.ajax({
url: createURL('listPublicIpAddresses'),
async: false,
data: {
vpcid: args.context.vpc[0].id,
listAll: true
},
success: function(json) {
publicIpAddresses = json.listpublicipaddressesresponse;
},
error: function(json) {
error = true;
}
});
// Get private gateways
$.ajax({
url: createURL('listPrivateGateways'),
async: false,
data: {
'vpcid': args.context.vpc[0].id,
listAll: true
},
success: function(json) {
privateGateways = json.listprivategatewaysresponse;
},
error: function(json) {
error = true;
}
});
// Get VPN gateways
$.ajax({
url: createURL('listVpnGateways'),
async: false,
data: {
listAll: true,
'vpcid': args.context.vpc[0].id
},
success: function(json) {
vpnGateways = json.listvpngatewaysresponse;
},
error: function(json) {
error = true;
}
});
args.response.success({
routerDashboard: [{
id: 'privateGateways',
name: 'Private gateways',
total: privateGateways.count
}, {
id: 'publicIPs',
name: 'Public IP addresses',
total: publicIpAddresses.count
}, {
id: 'siteToSiteVPNs',
name: 'Site-to-site VPNs',
total: vpnGateways.count
}, {
id: 'networkACLLists',
name: 'Network ACL lists',
total: networkACLLists.count
}],
tiers: $(networks).map(function(index, tier) {
var internalLoadBalancers, publicLbIps, virtualMachines, staticNatIps;
// Get internal load balancers
$.ajax({
url: createURL('listLoadBalancers&listAll=true'),
async: false,
data: {
networkid: tier.id
},
success: function(json) {
internalLoadBalancers = json.listloadbalancersresponse;
},
error: function(json) {
error = true;
}
});
// Get Public LB IPs
$.ajax({
url: createURL('listPublicIpAddresses&listAll=true'),
async: false,
data: {
associatednetworkid: tier.id,
forloadbalancing: true
},
success: function(json) {
publicLbIps = json.listpublicipaddressesresponse;
},
error: function(json) {
error = true;
}
});
// Get static NAT IPs
$.ajax({
url: createURL('listPublicIpAddresses&listAll=true'),
async: false,
data: {
associatednetworkid: tier.id,
isstaticnat: true
},
success: function(json) {
staticNatIps = json.listpublicipaddressesresponse;
},
error: function(json) {
error = true;
}
});
// Get VMs
$.ajax({
url: createURL('listVirtualMachines&listAll=true'),
async: false,
data: {
networkid: tier.id
},
success: function(json) {
virtualMachines = json.listvirtualmachinesresponse;
},
error: function(json) {
error = true;
}
});
// Highlight if any tier VM contains guest network
$.grep(
virtualMachines.virtualmachine ? virtualMachines.virtualmachine : [],
function(vm) {
return $.grep(vm.nic,
function(nic) {
return nic.type == 'Shared';
}).length;
}
).length ? tier._highlighted = true : tier._highlighted = false;
// Get LB capabilities
var lbSchemes = $.grep(
tier.service,
function(service) {
return service.name == 'Lb';
}
).length ? $.grep($.grep(
tier.service,
function(service) {
return service.name == 'Lb';
}
)[0].capability, function(capability) {
return capability.name == 'LbSchemes';
}) : [];
/* var lbSchemes = $.grep(
$.grep(
tier.service,
function(service) {
return service.name == 'Lb';
}
)[0].capability,
function(capability) {
return capability.name == 'LbSchemes';
}
);*/
var hasLbScheme = function(schemeVal) {
return $.grep(
lbSchemes,
function(scheme) {
return scheme.value == schemeVal;
}
).length ? true : false;
};
return $.extend(tier, {
_dashboardItems: [{
id: 'internalLoadBalancers',
name: 'Internal LB',
total: internalLoadBalancers.count,
_disabled: !hasLbScheme('Internal')
}, {
id: 'publicLbIps',
name: 'Public LB IP',
total: publicLbIps.count,
_disabled: !hasLbScheme('Public')
}, {
id: 'tierStaticNATs',
name: 'Static NATs',
total: staticNatIps.count
}, {
id: 'tierVMs',
name: 'Virtual Machines',
total: virtualMachines.count
}]
});
})
});
if (error) {
cloudStack.dialog.notice({
message: 'Error loading dashboard data.'
});
}
}
});
}
}
};
}(jQuery, cloudStack));