mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
6389 lines
374 KiB
JavaScript
Executable File
6389 lines
374 KiB
JavaScript
Executable File
// 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 ingressEgressDataMap = function(elem) {
|
|
var elemData = {
|
|
id: elem.ruleid,
|
|
protocol: elem.protocol,
|
|
startport: elem.startport,
|
|
endport: elem.endport,
|
|
cidr: elem.cidr ? elem.cidr : ''.concat(elem.account, ' - ', elem.securitygroupname)
|
|
};
|
|
|
|
if (elemData.startport == 0 && elemData.endport) {
|
|
elemData.startport = '0';
|
|
} else if (elem.icmptype && elem.icmpcode) {
|
|
elemData.startport = elem.icmptype;
|
|
elemData.endport = elem.icmpcode;
|
|
}
|
|
|
|
return elemData;
|
|
};
|
|
|
|
//value of Primary IP in subselect dropdown is -1, for single VM selection (API parameter virtualmachineid + vmguestip), e.g. enableStaticNat API, createPortForwardingRule API.
|
|
var singleVmSecondaryIPSubselect = function(args) {
|
|
var instance = args.context.instances[0];
|
|
var network = args.context.networks[0];
|
|
|
|
if (args.context.ipAddresses[0].isportable) { //portable IP which has multiple NICs. Each NIC has a different network ID.
|
|
$.ajax({
|
|
url: createURL('listNics'),
|
|
data: {
|
|
virtualmachineid: instance.id
|
|
},
|
|
success: function(json) {
|
|
var nics = json.listnicsresponse.nic;
|
|
var ipSelection = [];
|
|
|
|
$(nics).map(function(index, nic) {
|
|
var primaryIp = nic.ipaddress;
|
|
var secondaryIps = nic.secondaryip ? nic.secondaryip : [];
|
|
var prefix = '[NIC ' + (index + 1) + '] ';
|
|
|
|
// Add primary IP as default
|
|
ipSelection.push({
|
|
id: nic.networkid + ',-1',
|
|
description: prefix + primaryIp + ' (Primary)'
|
|
});
|
|
|
|
// Add secondary IPs
|
|
$(secondaryIps).map(function(index, secondaryIp) {
|
|
ipSelection.push({
|
|
id: nic.networkid + ',' + secondaryIp.ipaddress,
|
|
description: prefix + secondaryIp.ipaddress
|
|
});
|
|
});
|
|
});
|
|
|
|
args.response.success({
|
|
data: ipSelection
|
|
});
|
|
}
|
|
});
|
|
|
|
} else { //non-portable IP which has only one NIC
|
|
/*
|
|
var nic = $.grep(instance.nic, function(nic) {
|
|
return nic.networkid == network.id;
|
|
})[0];
|
|
*/
|
|
|
|
// Get NIC IPs
|
|
$.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 = [];
|
|
|
|
// Add primary IP as default
|
|
ipSelection.push({
|
|
id: -1,
|
|
description: primaryIp + ' (Primary)'
|
|
});
|
|
|
|
// Add secondary IPs
|
|
$(secondaryIps).map(function(index, secondaryIp) {
|
|
ipSelection.push({
|
|
id: secondaryIp.ipaddress,
|
|
description: secondaryIp.ipaddress
|
|
});
|
|
});
|
|
|
|
args.response.success({
|
|
data: ipSelection
|
|
});
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
//value of Primary IP in subselect dropdown is itself (not -1), for multiple VM selection (API parameter vmidipmap), e.g. assignToLoadBalancerRule API.
|
|
var multipleVmSecondaryIPSubselect = function(args) {
|
|
var instance = args.context.instances[0];
|
|
var network = args.context.networks[0];
|
|
|
|
if (args.context.ipAddresses[0].isportable) { //portable IP which has multiple NICs. Each NIC has a different network ID.
|
|
$.ajax({
|
|
url: createURL('listNics'),
|
|
data: {
|
|
virtualmachineid: instance.id
|
|
},
|
|
success: function(json) {
|
|
var nics = json.listnicsresponse.nic;
|
|
var ipSelection = [];
|
|
|
|
//portable IP has multiple NICs. Each NIC has a different network ID.
|
|
$(nics).map(function(index, nic) {
|
|
var primaryIp = nic.ipaddress;
|
|
var secondaryIps = nic.secondaryip ? nic.secondaryip : [];
|
|
var prefix = '[NIC ' + (index + 1) + '] ';
|
|
|
|
// Add primary IP as default
|
|
ipSelection.push({
|
|
id: nic.networkid + ',' + primaryIp,
|
|
description: prefix + primaryIp + ' (Primary)'
|
|
});
|
|
|
|
// Add secondary IPs
|
|
$(secondaryIps).map(function(index, secondaryIp) {
|
|
ipSelection.push({
|
|
id: nic.networkid + ',' + secondaryIp.ipaddress,
|
|
description: prefix + secondaryIp.ipaddress
|
|
});
|
|
});
|
|
});
|
|
|
|
args.response.success({
|
|
data: ipSelection
|
|
});
|
|
}
|
|
});
|
|
|
|
} else { //non-portable IP which has only one NIC
|
|
/*
|
|
var nic = $.grep(instance.nic, function(nic) {
|
|
return nic.networkid == network.id;
|
|
})[0];
|
|
*/
|
|
|
|
// Get NIC IPs
|
|
$.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
|
|
});
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
var ipChangeNotice = function() {
|
|
cloudStack.dialog.confirm({
|
|
message: 'message.ip.address.changed',
|
|
action: function() {
|
|
$('#browser .container').cloudBrowser('selectPanel', {
|
|
panel: $('#browser .panel:last').prev(),
|
|
complete: function() {
|
|
$(window).trigger('cloudStack.fullRefresh');
|
|
}
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
var zoneObjs = [];
|
|
|
|
var actionFilters = {
|
|
ipAddress: function(args) {
|
|
var allowedActions = args.context.actions;
|
|
var disallowedActions = [];
|
|
var ipObj = args.context.item;
|
|
var status = ipObj.state;
|
|
|
|
//***** apply to both Isolated Guest Network IP, VPC IP (begin) *****
|
|
if (status == 'Destroyed' ||
|
|
status == 'Releasing' ||
|
|
status == 'Released' ||
|
|
status == 'Creating' ||
|
|
status == 'Allocating' ||
|
|
ipObj.account == 'system' ||
|
|
ipObj.issystem == true) {
|
|
return [];
|
|
}
|
|
|
|
if (ipObj.issourcenat) { //sourceNAT IP doesn't support staticNAT
|
|
disallowedActions.push('enableStaticNAT');
|
|
disallowedActions.push('disableStaticNAT');
|
|
disallowedActions.push('remove');
|
|
} else { //non-sourceNAT IP supports staticNAT
|
|
disallowedActions.push('enableVPN');
|
|
if (ipObj.isstaticnat) {
|
|
disallowedActions.push('enableStaticNAT');
|
|
} else {
|
|
disallowedActions.push('disableStaticNAT');
|
|
}
|
|
}
|
|
//***** apply to both Isolated Guest Network IP, VPC IP (end) *****
|
|
|
|
|
|
if (!('vpc' in args.context)) { //***** Guest Network section > Guest Network page > IP Address page *****
|
|
if (args.context.networks[0].networkofferingconservemode == false) {
|
|
/*
|
|
(1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added.
|
|
*/
|
|
if (ipObj.issourcenat == true) {
|
|
disallowedActions.push('enableStaticNAT');
|
|
disallowedActions.push('enableVPN');
|
|
}
|
|
|
|
/*
|
|
(2) If IP is non-SourceNat, show StaticNat/VPN/PortForwarding/LoadBalancer at first.
|
|
1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer.
|
|
2. Once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer.
|
|
3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer.
|
|
4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding.
|
|
*/
|
|
else { //ipObj.issourcenat == false
|
|
if (ipObj.isstaticnat) { //1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer.
|
|
disallowedActions.push('enableVPN');
|
|
}
|
|
if (ipObj.vpnenabled) { //2. Once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer.
|
|
disallowedActions.push('enableStaticNAT');
|
|
}
|
|
|
|
//3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer.
|
|
$.ajax({
|
|
url: createURL('listPortForwardingRules'),
|
|
data: {
|
|
ipaddressid: ipObj.id,
|
|
listAll: true
|
|
},
|
|
dataType: 'json',
|
|
async: false,
|
|
success: function(json) {
|
|
var rules = json.listportforwardingrulesresponse.portforwardingrule;
|
|
if (rules != null && rules.length > 0) {
|
|
disallowedActions.push('enableVPN');
|
|
disallowedActions.push('enableStaticNAT');
|
|
}
|
|
}
|
|
});
|
|
|
|
//4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding.
|
|
$.ajax({
|
|
url: createURL('listLoadBalancerRules'),
|
|
data: {
|
|
publicipid: ipObj.id,
|
|
listAll: true
|
|
},
|
|
dataType: 'json',
|
|
async: false,
|
|
success: function(json) {
|
|
var rules = json.listloadbalancerrulesresponse.loadbalancerrule;
|
|
if (rules != null && rules.length > 0) {
|
|
disallowedActions.push('enableVPN');
|
|
disallowedActions.push('enableStaticNAT');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
if (ipObj.networkOfferingHavingVpnService == true) {
|
|
if (ipObj.vpnenabled) {
|
|
disallowedActions.push('enableVPN');
|
|
} else {
|
|
disallowedActions.push('disableVPN');
|
|
}
|
|
} else { //ipObj.networkOfferingHavingVpnService == false
|
|
disallowedActions.push('disableVPN');
|
|
disallowedActions.push('enableVPN');
|
|
}
|
|
} else { //***** VPC section > Configuration VPC > Router > Public IP Addresses *****
|
|
if (ipObj.issourcenat) { //VPC sourceNAT IP: supports VPN
|
|
if (ipObj.vpnenabled) {
|
|
disallowedActions.push('enableVPN');
|
|
} else {
|
|
disallowedActions.push('disableVPN');
|
|
}
|
|
} else { //VPC non-sourceNAT IP: doesn't support VPN
|
|
disallowedActions.push('enableVPN');
|
|
disallowedActions.push('disableVPN');
|
|
}
|
|
}
|
|
|
|
allowedActions = $.grep(allowedActions, function(item) {
|
|
return $.inArray(item, disallowedActions) == -1;
|
|
});
|
|
|
|
return allowedActions;
|
|
},
|
|
|
|
securityGroups: function(args) {
|
|
var allowedActions = [];
|
|
var isSecurityGroupOwner = isAdmin() || isDomainAdmin() ||
|
|
args.context.item.account == args.context.users[0].account;
|
|
|
|
if (isSecurityGroupOwner &&
|
|
args.context.item.state != 'Destroyed' &&
|
|
args.context.item.name != 'default') {
|
|
allowedActions.push('remove');
|
|
}
|
|
|
|
return allowedActions;
|
|
}
|
|
};
|
|
|
|
var networkOfferingObjs = [];
|
|
var advZoneObjs;
|
|
|
|
cloudStack.sections.network = {
|
|
title: 'label.network',
|
|
id: 'network',
|
|
sectionSelect: {
|
|
preFilter: function(args) {
|
|
var sectionsToShow = ['networks'];
|
|
|
|
$.ajax({
|
|
url: createURL('listZones'),
|
|
data: {
|
|
networktype: 'Advanced'
|
|
},
|
|
async: false,
|
|
success: function(json) {
|
|
advZoneObjs = json.listzonesresponse.zone;
|
|
if (advZoneObjs != null && advZoneObjs.length > 0) {
|
|
sectionsToShow.push('vpc');
|
|
sectionsToShow.push('vpnCustomerGateway');
|
|
}
|
|
}
|
|
});
|
|
|
|
$.ajax({
|
|
url: createURL('listNetworks', {
|
|
ignoreProject: true
|
|
}),
|
|
data: {
|
|
supportedServices: 'SecurityGroup',
|
|
listAll: true,
|
|
details: 'min'
|
|
},
|
|
async: false,
|
|
success: function(json) {
|
|
if (json.listnetworksresponse.network != null && json.listnetworksresponse.network.length > 0) {
|
|
sectionsToShow.push('securityGroups');
|
|
}
|
|
}
|
|
});
|
|
|
|
return sectionsToShow;
|
|
},
|
|
|
|
label: 'label.select-view'
|
|
},
|
|
sections: {
|
|
networks: {
|
|
id: 'networks',
|
|
type: 'select',
|
|
title: 'label.guest.networks',
|
|
listView: {
|
|
actions: {
|
|
add: {
|
|
label: 'label.add.isolated.network',
|
|
|
|
preFilter: function(args) {
|
|
if (advZoneObjs != null && advZoneObjs.length > 0) {
|
|
for (var i = 0; i < advZoneObjs.length; i++) {
|
|
if (advZoneObjs[i].securitygroupsenabled != true) { //'Add Isolated Guest Network with SourceNat' is only supported in Advanced SG-disabled zone
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
} else {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
createForm: {
|
|
title: 'Add Isolated Guest Network with SourceNat',
|
|
fields: {
|
|
name: {
|
|
label: 'label.name',
|
|
validation: {
|
|
required: true
|
|
},
|
|
docID: 'helpGuestNetworkName'
|
|
},
|
|
displayText: {
|
|
label: 'label.display.text',
|
|
validation: {
|
|
required: true
|
|
},
|
|
docID: 'helpGuestNetworkDisplayText'
|
|
},
|
|
zoneId: {
|
|
label: 'label.zone',
|
|
validation: {
|
|
required: true
|
|
},
|
|
docID: 'helpGuestNetworkZone',
|
|
|
|
select: function(args) {
|
|
$.ajax({
|
|
url: createURL('listZones'),
|
|
success: function(json) {
|
|
var zones = $.grep(json.listzonesresponse.zone, function(zone) {
|
|
return (zone.networktype == 'Advanced' && zone.securitygroupsenabled != true); //Isolated networks can only be created in Advanced SG-disabled zone (but not in Basic zone nor Advanced SG-enabled zone)
|
|
});
|
|
|
|
args.response.success({
|
|
data: $.map(zones, function(zone) {
|
|
return {
|
|
id: zone.id,
|
|
description: zone.name
|
|
};
|
|
})
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
networkOfferingId: {
|
|
label: 'label.network.offering',
|
|
validation: {
|
|
required: true
|
|
},
|
|
dependsOn: 'zoneId',
|
|
docID: 'helpGuestNetworkNetworkOffering',
|
|
select: function(args) {
|
|
var data = {
|
|
zoneid: args.zoneId,
|
|
guestiptype: 'Isolated',
|
|
supportedServices: 'SourceNat',
|
|
state: 'Enabled'
|
|
};
|
|
|
|
if ('vpc' in args.context) { //from VPC section
|
|
$.extend(data, {
|
|
forVpc: true
|
|
});
|
|
}
|
|
else { //from guest network section
|
|
var vpcs;
|
|
$.ajax({
|
|
url: createURL('listVPCs'),
|
|
data: {
|
|
listAll: true
|
|
},
|
|
async: false,
|
|
success: function(json) {
|
|
vpcs = json.listvpcsresponse.vpc;
|
|
}
|
|
});
|
|
if (vpcs == null || vpcs.length == 0) { //if there is no VPC in the system
|
|
$.extend(data, {
|
|
forVpc: false
|
|
});
|
|
}
|
|
}
|
|
|
|
if(!isAdmin()) { //normal user is not aware of the VLANs in the system, so normal user is not allowed to create network with network offerings whose specifyvlan = true
|
|
$.extend(data, {
|
|
specifyvlan: false
|
|
});
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('listNetworkOfferings'),
|
|
data: data,
|
|
success: function(json) {
|
|
networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering;
|
|
args.$select.change(function() {
|
|
var $vlan = args.$select.closest('form').find('[rel=vlan]');
|
|
var networkOffering = $.grep(
|
|
networkOfferingObjs, function(netoffer) {
|
|
return netoffer.id == args.$select.val();
|
|
}
|
|
)[0];
|
|
|
|
if (networkOffering.specifyvlan) {
|
|
$vlan.css('display', 'inline-block');
|
|
} else {
|
|
$vlan.hide();
|
|
}
|
|
});
|
|
|
|
args.response.success({
|
|
data: $.map(networkOfferingObjs, function(zone) {
|
|
return {
|
|
id: zone.id,
|
|
description: zone.name
|
|
};
|
|
})
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
vlan: {
|
|
label: 'VLAN',
|
|
validation: {
|
|
required: true
|
|
},
|
|
isHidden: true
|
|
},
|
|
|
|
vpcid: {
|
|
label: 'label.vpc',
|
|
dependsOn: 'networkOfferingId',
|
|
select: function(args) {
|
|
var networkOfferingObj;
|
|
var $form = args.$select.closest('form');
|
|
var data = {
|
|
listAll: true,
|
|
details: 'min'
|
|
};
|
|
|
|
if (args.context.vpc) {
|
|
data.id = args.context.vpc[0].id;
|
|
}
|
|
|
|
$(networkOfferingObjs).each(function(key, value) {
|
|
if (value.id == args.networkOfferingId) {
|
|
networkOfferingObj = value;
|
|
return false; //break each loop
|
|
}
|
|
});
|
|
|
|
if (networkOfferingObj.forvpc == true) {
|
|
args.$select.closest('.form-item').css('display', 'inline-block');
|
|
$.ajax({
|
|
url: createURL('listVPCs'),
|
|
data: data,
|
|
success: function(json) {
|
|
var items = json.listvpcsresponse.vpc;
|
|
var data;
|
|
if (items != null && items.length > 0) {
|
|
data = $.map(items, function(item) {
|
|
return {
|
|
id: item.id,
|
|
description: item.name
|
|
}
|
|
});
|
|
}
|
|
args.response.success({
|
|
data: data
|
|
});
|
|
}
|
|
});
|
|
$form.find('.form-item[rel=networkDomain]').hide();
|
|
} else {
|
|
args.$select.closest('.form-item').hide();
|
|
$form.find('.form-item[rel=networkDomain]').show();
|
|
args.response.success({
|
|
data: null
|
|
});
|
|
}
|
|
}
|
|
},
|
|
|
|
guestGateway: {
|
|
label: 'label.guest.gateway',
|
|
docID: 'helpGuestNetworkGateway'
|
|
},
|
|
guestNetmask: {
|
|
label: 'label.guest.netmask',
|
|
docID: 'helpGuestNetworkNetmask'
|
|
},
|
|
networkDomain: {
|
|
label: 'label.network.domain'
|
|
},
|
|
domain: {
|
|
label: 'label.domain',
|
|
isHidden: function(args) {
|
|
if (isAdmin() || isDomainAdmin())
|
|
return false;
|
|
else
|
|
return true;
|
|
},
|
|
select: function(args) {
|
|
if (isAdmin() || isDomainAdmin()) {
|
|
$.ajax({
|
|
url: createURL("listDomains&listAll=true"),
|
|
success: function(json) {
|
|
var items = [];
|
|
items.push({
|
|
id: "",
|
|
description: ""
|
|
});
|
|
var domainObjs = json.listdomainsresponse.domain;
|
|
$(domainObjs).each(function() {
|
|
items.push({
|
|
id: this.id,
|
|
description: this.path
|
|
});
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
});
|
|
args.$select.change(function() {
|
|
var $form = $(this).closest('form');
|
|
if ($(this).val() == "") {
|
|
$form.find('.form-item[rel=account]').hide();
|
|
} else {
|
|
$form.find('.form-item[rel=account]').css('display', 'inline-block');
|
|
}
|
|
});
|
|
} else {
|
|
args.response.success({
|
|
data: null
|
|
});
|
|
}
|
|
},
|
|
},
|
|
account: {
|
|
label: 'label.account',
|
|
validation: {
|
|
required: true
|
|
},
|
|
isHidden: function(args) {
|
|
if (isAdmin() || isDomainAdmin())
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
},
|
|
action: function(args) {
|
|
var dataObj = {
|
|
zoneId: args.data.zoneId,
|
|
name: args.data.name,
|
|
displayText: args.data.displayText,
|
|
networkOfferingId: args.data.networkOfferingId
|
|
};
|
|
|
|
if (args.data.guestGateway != null && args.data.guestGateway.length > 0) {
|
|
$.extend(dataObj, {
|
|
gateway: args.data.guestGateway
|
|
});
|
|
}
|
|
if (args.data.guestNetmask != null && args.data.guestNetmask.length > 0) {
|
|
$.extend(dataObj, {
|
|
netmask: args.data.guestNetmask
|
|
});
|
|
}
|
|
if (args.$form.find('.form-item[rel=vpcid]').css("display") != "none") {
|
|
$.extend(dataObj, {
|
|
vpcid: args.data.vpcid
|
|
});
|
|
}
|
|
|
|
if (args.$form.find('.form-item[rel=vlan]').css('display') != 'none') {
|
|
$.extend(dataObj, {
|
|
vlan: args.data.vlan
|
|
});
|
|
}
|
|
|
|
if (args.data.networkDomain != null && args.data.networkDomain.length > 0 && args.$form.find('.form-item[rel=vpcid]').css("display") == "none") {
|
|
$.extend(dataObj, {
|
|
networkDomain: args.data.networkDomain
|
|
});
|
|
}
|
|
|
|
if (args.data.domain != null && args.data.domain.length > 0) {
|
|
$.extend(dataObj, {
|
|
domainid: args.data.domain
|
|
});
|
|
if (args.data.account != null && args.data.account.length > 0) {
|
|
$.extend(dataObj, {
|
|
account: args.data.account
|
|
});
|
|
}
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('createNetwork'),
|
|
data: dataObj,
|
|
success: function(json) {
|
|
args.response.success({
|
|
data: json.createnetworkresponse.network
|
|
});
|
|
},
|
|
error: function(json) {
|
|
args.response.error(parseXMLHttpResponse(json));
|
|
}
|
|
});
|
|
},
|
|
messages: {
|
|
notification: function() {
|
|
return 'Add Isolated Guest Network';
|
|
}
|
|
}
|
|
},
|
|
|
|
rootAdminAddGuestNetwork: $.extend({}, addGuestNetworkDialog.def, {
|
|
isHeader: true
|
|
})
|
|
|
|
},
|
|
id: 'networks',
|
|
fields: {
|
|
name: {
|
|
label: 'label.name'
|
|
},
|
|
account: {
|
|
label: 'label.account'
|
|
},
|
|
type: {
|
|
label: 'label.type'
|
|
},
|
|
cidr: {
|
|
label: 'label.cidr'
|
|
},
|
|
ip6cidr: {
|
|
label: 'label.ipv6.CIDR'
|
|
}
|
|
},
|
|
|
|
advSearchFields: {
|
|
zoneid: {
|
|
label: 'label.zone',
|
|
select: function(args) {
|
|
$.ajax({
|
|
url: createURL('listZones'),
|
|
data: {
|
|
listAll: true
|
|
},
|
|
success: function(json) {
|
|
var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : [];
|
|
|
|
args.response.success({
|
|
data: $.map(zones, function(zone) {
|
|
return {
|
|
id: zone.id,
|
|
description: zone.name
|
|
};
|
|
})
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
domainid: {
|
|
label: 'label.domain',
|
|
select: function(args) {
|
|
if (isAdmin() || isDomainAdmin()) {
|
|
$.ajax({
|
|
url: createURL('listDomains'),
|
|
data: {
|
|
listAll: true,
|
|
details: 'min'
|
|
},
|
|
success: function(json) {
|
|
var array1 = [{
|
|
id: '',
|
|
description: ''
|
|
}];
|
|
var domains = json.listdomainsresponse.domain;
|
|
if (domains != null && domains.length > 0) {
|
|
for (var i = 0; i < domains.length; i++) {
|
|
array1.push({
|
|
id: domains[i].id,
|
|
description: domains[i].path
|
|
});
|
|
}
|
|
}
|
|
args.response.success({
|
|
data: array1
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
args.response.success({
|
|
data: null
|
|
});
|
|
}
|
|
},
|
|
isHidden: function(args) {
|
|
if (isAdmin() || isDomainAdmin())
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
},
|
|
|
|
account: {
|
|
label: 'label.account',
|
|
isHidden: function(args) {
|
|
if (isAdmin() || isDomainAdmin())
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
},
|
|
tagKey: {
|
|
label: 'label.tag.key'
|
|
},
|
|
tagValue: {
|
|
label: 'label.tag.value'
|
|
}
|
|
},
|
|
|
|
dataProvider: function(args) {
|
|
var data = {};
|
|
listViewDataProvider(args, data);
|
|
|
|
$.ajax({
|
|
url: createURL('listNetworks'),
|
|
data: data,
|
|
async: false,
|
|
success: function(data) {
|
|
args.response.success({
|
|
data: data.listnetworksresponse.network
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
|
|
detailView: {
|
|
name: 'label.guest.network.details',
|
|
viewAll: {
|
|
path: 'network.ipAddresses',
|
|
label: 'label.menu.ipaddresses',
|
|
preFilter: function(args) {
|
|
if (args.context.networks[0].state == 'Destroyed')
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
},
|
|
actions: {
|
|
edit: {
|
|
label: 'label.edit',
|
|
messages: {
|
|
notification: function(args) {
|
|
return 'label.edit.network.details';
|
|
}
|
|
},
|
|
action: function(args) {
|
|
var data = {
|
|
id: args.context.networks[0].id,
|
|
name: args.data.name,
|
|
displaytext: args.data.displaytext
|
|
};
|
|
|
|
//args.data.networkdomain is null when networkdomain field is hidden
|
|
if (args.data.networkdomain != null && args.data.networkdomain.length > 0 && args.data.networkdomain != args.context.networks[0].networkdomain) {
|
|
$.extend(data, {
|
|
networkdomain: args.data.networkdomain
|
|
});
|
|
}
|
|
|
|
var oldcidr;
|
|
$.ajax({
|
|
url: createURL("listNetworks&id=" + args.context.networks[0].id),
|
|
dataType: "json",
|
|
async: false,
|
|
success: function(json) {
|
|
oldcidr = json.listnetworksresponse.network[0].cidr;
|
|
|
|
}
|
|
});
|
|
|
|
|
|
if (args.data.cidr != "" && args.data.cidr != oldcidr) {
|
|
$.extend(data, {
|
|
guestvmcidr: args.data.cidr
|
|
});
|
|
}
|
|
|
|
//args.data.networkofferingid is null when networkofferingid field is hidden
|
|
if (args.data.networkofferingid != null && args.data.networkofferingid != args.context.networks[0].networkofferingid) {
|
|
$.extend(data, {
|
|
networkofferingid: args.data.networkofferingid
|
|
});
|
|
|
|
if (args.context.networks[0].type == "Isolated") { //Isolated network
|
|
cloudStack.dialog.confirm({
|
|
message: 'Do you want to keep the current guest network CIDR unchanged?',
|
|
action: function() { //"Yes" button is clicked
|
|
$.extend(data, {
|
|
changecidr: false
|
|
});
|
|
|
|
$.ajax({
|
|
url: createURL('updateNetwork'),
|
|
data: data,
|
|
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
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
},
|
|
cancelAction: function() { //"Cancel" button is clicked
|
|
$.extend(data, {
|
|
changecidr: true
|
|
});
|
|
|
|
$.ajax({
|
|
url: createURL('updateNetwork'),
|
|
data: data,
|
|
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
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('updateNetwork'),
|
|
data: data,
|
|
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
|
|
};
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
},
|
|
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];
|
|
}
|
|
});
|
|
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';
|
|
},
|
|
isWarning: true,
|
|
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
|
|
}
|
|
}
|
|
},
|
|
|
|
tabFilter: function(args) {
|
|
var networkHavingELB = false;
|
|
var hasNetworkACL = false;
|
|
var hasSRXFirewall = false;
|
|
var isVPC = false;
|
|
var isAdvancedSGZone = false;
|
|
var hiddenTabs = [];
|
|
var isSharedNetwork;
|
|
|
|
var thisNetwork = args.context.networks[0];
|
|
if (thisNetwork.vpcid != null) {
|
|
isVPC = true;
|
|
}
|
|
if (thisNetwork.type == 'Shared') {
|
|
isSharedNetwork = true;
|
|
}
|
|
|
|
$(thisNetwork.service).each(function() {
|
|
var thisService = this;
|
|
|
|
if (thisService.name == 'NetworkACL') {
|
|
hasNetworkACL = true;
|
|
} else if (thisService.name == "Lb") {
|
|
$(thisService.capability).each(function() {
|
|
if (this.name == "ElasticLb" && this.value == "true") {
|
|
networkHavingELB = true;
|
|
}
|
|
});
|
|
}
|
|
|
|
if (thisService.name == 'Firewall') {
|
|
$(thisService.provider).each(function() {
|
|
if (this.name == 'JuniperSRX') {
|
|
hasSRXFirewall = true;
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
}
|
|
});
|
|
|
|
// Get zone data
|
|
$.ajax({
|
|
url: createURL('listZones'),
|
|
data: {
|
|
id: args.context.networks[0].zoneid
|
|
},
|
|
async: false,
|
|
success: function(json) {
|
|
var zone = json.listzonesresponse.zone[0];
|
|
|
|
isAdvancedSGZone = zone.securitygroupsenabled;
|
|
}
|
|
});
|
|
|
|
if (!networkHavingELB) {
|
|
hiddenTabs.push("addloadBalancer");
|
|
}
|
|
|
|
if (isVPC || isAdvancedSGZone || isSharedNetwork) {
|
|
hiddenTabs.push('egressRules');
|
|
}
|
|
|
|
return hiddenTabs;
|
|
},
|
|
|
|
isMaximized: true,
|
|
tabs: {
|
|
details: {
|
|
title: 'label.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");
|
|
}
|
|
|
|
if (!isAdmin()) {
|
|
hiddenFields.push("vlan");
|
|
}
|
|
|
|
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'
|
|
},
|
|
|
|
vpcid: {
|
|
label: 'label.vpc.id',
|
|
converter: function(args) {
|
|
if (args != null)
|
|
return args;
|
|
else
|
|
return 'N/A';
|
|
}
|
|
},
|
|
|
|
ispersistent: {
|
|
label: 'label.persistent',
|
|
converter: cloudStack.converters.toBooleanText
|
|
|
|
},
|
|
restartrequired: {
|
|
label: 'label.restart.required',
|
|
converter: function(booleanValue) {
|
|
if (booleanValue == true)
|
|
return "Yes";
|
|
else if (booleanValue == false)
|
|
return "No";
|
|
}
|
|
},
|
|
vlan: {
|
|
label: 'label.vnet.id'
|
|
},
|
|
|
|
broadcasturi: {
|
|
label: 'label.broadcasturi'
|
|
},
|
|
|
|
networkofferingid: {
|
|
label: 'label.network.offering',
|
|
isEditable: true,
|
|
select: function(args) {
|
|
if (args.context.networks[0].type == 'Shared') { //Shared network is not allowed to upgrade to a different network offering
|
|
args.response.success({
|
|
data: []
|
|
});
|
|
return;
|
|
}
|
|
|
|
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: 'label.netmask' },
|
|
cidr: {
|
|
label: 'label.cidr',
|
|
isEditable: true
|
|
},
|
|
|
|
networkcidr: {
|
|
label: 'label.network.cidr'
|
|
},
|
|
|
|
ip6gateway: {
|
|
label: 'label.ipv6.gateway'
|
|
},
|
|
|
|
ip6cidr: {
|
|
label: 'label.ipv6.CIDR'
|
|
},
|
|
|
|
|
|
reservediprange: {
|
|
label: 'label.reserved.ip.range'
|
|
},
|
|
|
|
|
|
networkdomaintext: {
|
|
label: 'label.network.domain.text'
|
|
},
|
|
networkdomain: {
|
|
label: 'label.network.domain',
|
|
isEditable: true
|
|
},
|
|
|
|
domain: {
|
|
label: 'label.domain'
|
|
},
|
|
account: {
|
|
label: 'label.account'
|
|
}
|
|
}],
|
|
|
|
tags: cloudStack.api.tags({
|
|
resourceType: 'Network',
|
|
contextId: 'networks'
|
|
}),
|
|
|
|
|
|
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];
|
|
addExtraPropertiesToGuestNetworkObject(jsonObj);
|
|
|
|
if (isModuleIncluded("dr")) {
|
|
cloudStack.dr.sharedFunctions.addExtraProperties(jsonObj, "Network");
|
|
}
|
|
|
|
args.response.success({
|
|
actionFilter: cloudStack.actionFilter.guestNetwork,
|
|
data: jsonObj
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
egressRules: {
|
|
title: 'label.egress.rules',
|
|
custom: function(args) {
|
|
var context = args.context;
|
|
|
|
return $('<div>').multiEdit({
|
|
context: context,
|
|
noSelect: true,
|
|
noHeaderActionsColumn: true,
|
|
fields: {
|
|
'cidrlist': {
|
|
edit: true,
|
|
label: 'label.cidr.list',
|
|
isOptional: true
|
|
},
|
|
'protocol': {
|
|
label: 'label.protocol',
|
|
select: function(args) {
|
|
args.$select.change(function() {
|
|
var $inputs = args.$form.find('th, td');
|
|
var $icmpFields = $inputs.filter(function() {
|
|
var name = $(this).attr('rel');
|
|
|
|
return $.inArray(name, [
|
|
'icmptype',
|
|
'icmpcode'
|
|
]) > -1;
|
|
});
|
|
var $otherFields = $inputs.filter(function() {
|
|
var name = $(this).attr('rel');
|
|
|
|
return name != 'cidrlist' &&
|
|
name != 'icmptype' &&
|
|
name != 'icmpcode' &&
|
|
name != 'protocol' &&
|
|
name != 'add-rule';
|
|
});
|
|
|
|
if ($(this).val() == 'icmp') {
|
|
$icmpFields.show();
|
|
$otherFields.hide();
|
|
} else if ($(this).val() == 'all') {
|
|
$icmpFields.hide();
|
|
$otherFields.hide();
|
|
} else {
|
|
$icmpFields.hide();
|
|
$otherFields.show();
|
|
}
|
|
});
|
|
|
|
args.response.success({
|
|
data: [{
|
|
name: 'tcp',
|
|
description: 'TCP'
|
|
}, {
|
|
name: 'udp',
|
|
description: 'UDP'
|
|
}, {
|
|
name: 'icmp',
|
|
description: 'ICMP'
|
|
}, {
|
|
name: 'all',
|
|
description: 'All'
|
|
}]
|
|
});
|
|
}
|
|
},
|
|
'startport': {
|
|
edit: true,
|
|
label: 'label.start.port',
|
|
isOptional: true
|
|
},
|
|
'endport': {
|
|
edit: true,
|
|
label: 'label.end.port',
|
|
isOptional: true
|
|
},
|
|
'icmptype': {
|
|
edit: true,
|
|
label: 'ICMP.type',
|
|
isHidden: true,
|
|
isOptional: true
|
|
},
|
|
'icmpcode': {
|
|
edit: true,
|
|
label: 'ICMP.code',
|
|
isHidden: true,
|
|
isOptional: true
|
|
},
|
|
'add-rule': {
|
|
label: 'label.add',
|
|
addButton: true
|
|
}
|
|
},
|
|
add: {
|
|
label: 'label.add',
|
|
action: function(args) {
|
|
var data = {
|
|
protocol: args.data.protocol,
|
|
cidrlist: args.data.cidrlist,
|
|
networkid: args.context.networks[0].id
|
|
};
|
|
|
|
if (args.data.icmptype && args.data.icmpcode) { // ICMP
|
|
$.extend(data, {
|
|
icmptype: args.data.icmptype,
|
|
icmpcode: args.data.icmpcode
|
|
});
|
|
} else { // TCP/UDP
|
|
$.extend(data, {
|
|
startport: args.data.startport,
|
|
endport: args.data.endport
|
|
});
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('createEgressFirewallRule'),
|
|
data: data,
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(json) {
|
|
var jobId = json.createegressfirewallruleresponse.jobid;
|
|
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobId
|
|
},
|
|
notification: {
|
|
label: 'label.add.egress.rule',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(json) {
|
|
args.response.error(parseXMLHttpResponse(json));
|
|
}
|
|
});
|
|
}
|
|
},
|
|
actions: {
|
|
destroy: {
|
|
label: 'label.remove.rule',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('deleteEgressFirewallRule'),
|
|
data: {
|
|
id: args.context.multiRule[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var jobID = data.deleteegressfirewallruleresponse.jobid;
|
|
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobID
|
|
},
|
|
notification: {
|
|
label: 'label.remove.egress.rule',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(json) {
|
|
args.response.error(parseXMLHttpResponse(json));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
ignoreEmptyFields: true,
|
|
dataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL('listEgressFirewallRules'),
|
|
data: {
|
|
listAll: true,
|
|
networkid: args.context.networks[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(json) {
|
|
var response = json.listegressfirewallrulesresponse.firewallrule ?
|
|
json.listegressfirewallrulesresponse.firewallrule : [];
|
|
|
|
args.response.success({
|
|
data: $.map(response, function(rule) {
|
|
if (rule.protocol == 'all') {
|
|
$.extend(rule, {
|
|
startport: 'All',
|
|
endport: 'All'
|
|
});
|
|
} else if (rule.protocol == 'tcp' || rule.protocol == 'udp') {
|
|
if (!rule.startport) {
|
|
rule.startport = ' ';
|
|
}
|
|
|
|
if (!rule.endport) {
|
|
rule.endport = ' ';
|
|
}
|
|
}
|
|
|
|
return rule;
|
|
})
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
addloadBalancer: { // EIP/ELB Basic zone: Add Load Balancer tab in network detailView
|
|
title: 'label.add.load.balancer',
|
|
custom: function(args) {
|
|
var context = args.context;
|
|
|
|
return $('<div>').addClass('loadBalancer').multiEdit({
|
|
context: context,
|
|
listView: $.extend(true, {}, cloudStack.sections.instances, {
|
|
listView: {
|
|
filters: false,
|
|
|
|
dataProvider: function(args) {
|
|
var data = {
|
|
page: args.page,
|
|
pageSize: pageSize,
|
|
domainid: g_domainid,
|
|
account: g_account,
|
|
networkid: args.context.networks[0].id,
|
|
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) {
|
|
var nonAutoScale = 0;
|
|
if (instance.displayname == null)
|
|
nonAutoScale = 1;
|
|
else {
|
|
if (instance.displayname.match(/AutoScale-LB-/) == null)
|
|
nonAutoScale = 1;
|
|
else {
|
|
if (instance.displayname.match(/AutoScale-LB-/).length)
|
|
nonAutoScale = 0;
|
|
}
|
|
}
|
|
var isActiveState = $.inArray(instance.state, ['Destroyed', 'Expunging']) == -1;
|
|
return nonAutoScale && isActiveState;
|
|
}
|
|
)
|
|
});
|
|
},
|
|
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.round.robin')
|
|
}, {
|
|
name: 'leastconn',
|
|
description: _l('label.least.connections')
|
|
}, {
|
|
name: 'source',
|
|
description: _l('label.source')
|
|
}]
|
|
});
|
|
}
|
|
},
|
|
'sticky': {
|
|
label: 'label.stickiness',
|
|
custom: {
|
|
buttonLabel: 'label.configure',
|
|
action: cloudStack.lbStickyPolicy.dialog()
|
|
}
|
|
},
|
|
'autoScale': {
|
|
label: 'label.autoscale',
|
|
custom: {
|
|
requireValidation: true,
|
|
buttonLabel: 'label.configure',
|
|
action: cloudStack.uiCustom.autoscaler(cloudStack.autoscaler)
|
|
}
|
|
},
|
|
'add-vm': {
|
|
label: 'label.add.vms',
|
|
addButton: true
|
|
},
|
|
'state' : {
|
|
edit: 'ignore',
|
|
label: 'label.state'
|
|
}
|
|
},
|
|
|
|
add: { //basic zone - elastic IP - Add Load Balancer tab - Add VMs button
|
|
label: 'label.add.vms',
|
|
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; //CS-16964: use jobid from assignToLoadBalancerRule instead of createLoadBalancerRule
|
|
|
|
$.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 jobID = data.assigntoloadbalancerruleresponse.jobid; //CS-16964: use jobid from assignToLoadBalancerRule instead of createLoadBalancerRule
|
|
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: []
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
secondaryNicIps: {
|
|
title: 'label.menu.ipaddresses',
|
|
listView: {
|
|
id: 'secondaryNicIps',
|
|
label: 'label.ips',
|
|
fields: {
|
|
virtualmachinedisplayname: {
|
|
label: 'label.vm.name'
|
|
},
|
|
ipaddress: {
|
|
label: 'label.ips',
|
|
converter: function(text, item) {
|
|
if (item.issourcenat) {
|
|
return text + ' [' + _l('label.source.nat') + ']';
|
|
}
|
|
|
|
return text;
|
|
}
|
|
}
|
|
},
|
|
actions: {
|
|
add: {
|
|
label: 'label.acquire.new.secondary.ip',
|
|
addRow: 'true',
|
|
createForm: {
|
|
title: 'label.acquire.new.secondary.ip',
|
|
desc: 'message.acquire.ip.nic',
|
|
fields: {
|
|
ipaddress: {
|
|
label: 'label.ip.address'
|
|
}
|
|
}
|
|
},
|
|
messages: {
|
|
notification: function(args) {
|
|
return 'label.acquire.new.secondary.ip';
|
|
}
|
|
},
|
|
action: function(args) {
|
|
var dataObj = {
|
|
nicId: args.context.nics[0].id
|
|
};
|
|
|
|
if (args.data.ipaddress) {
|
|
dataObj.ipaddress = args.data.ipaddress;
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('addIpToNic'),
|
|
data: dataObj,
|
|
success: function(json) {
|
|
args.response.success({
|
|
_custom: {
|
|
getUpdatedItem: function(data) {
|
|
return $.extend(
|
|
data.queryasyncjobresultresponse.jobresult.nicsecondaryip, {
|
|
zoneid: args.context.instances[0].zoneid,
|
|
virtualmachinedisplayname: args.context.instances[0].displayname ? args.context.instances[0].displayname : args.context.instances[0].name
|
|
}
|
|
);
|
|
},
|
|
jobId: json.addiptovmnicresponse.jobid
|
|
}
|
|
});
|
|
}
|
|
});
|
|
},
|
|
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
}
|
|
},
|
|
|
|
dataProvider: function(args) {
|
|
var data = {};
|
|
|
|
$.ajax({
|
|
url: createURL('listNics'),
|
|
data: {
|
|
nicId: args.context.nics[0].id,
|
|
virtualmachineid: args.context.instances[0].id
|
|
},
|
|
success: function(json) {
|
|
var ips = json.listnicsresponse.nic ? json.listnicsresponse.nic[0].secondaryip : [];
|
|
|
|
args.response.success({
|
|
data: $(ips).map(function(index, ip) {
|
|
return $.extend(ip, {
|
|
zoneid: args.context.instances[0].zoneid,
|
|
virtualmachinedisplayname: args.context.instances[0].displayname ? args.context.instances[0].displayname : args.context.instances[0].name
|
|
});
|
|
})
|
|
});
|
|
}
|
|
});
|
|
},
|
|
|
|
// Detail view
|
|
detailView: {
|
|
name: 'Secondary IP address detail',
|
|
actions: {
|
|
remove: {
|
|
label: 'label.action.release.ip',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('removeIpFromNic'),
|
|
data: {
|
|
id: args.context.secondaryNicIps[0].id
|
|
},
|
|
success: function(json) {
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: json.removeipfromnicresponse.jobid
|
|
}
|
|
});
|
|
}
|
|
});
|
|
},
|
|
messages: {
|
|
confirm: function(args) {
|
|
return 'message.action.release.ip';
|
|
},
|
|
notification: function(args) {
|
|
return 'label.action.release.ip';
|
|
}
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
}
|
|
},
|
|
tabs: {
|
|
details: {
|
|
title: 'label.details',
|
|
fields: [{
|
|
ipaddress: {
|
|
label: 'label.ip'
|
|
}
|
|
}, {
|
|
id: {
|
|
label: 'label.id'
|
|
},
|
|
virtualmachinedisplayname: {
|
|
label: 'label.vm.name'
|
|
},
|
|
zonename: {
|
|
label: 'label.zone.name'
|
|
}
|
|
}],
|
|
|
|
dataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL('listNics'),
|
|
data: {
|
|
nicId: args.context.nics[0].id,
|
|
virtualmachineid: args.context.instances[0].id
|
|
},
|
|
success: function(json) {
|
|
var ips = json.listnicsresponse.nic[0].secondaryip
|
|
|
|
args.response.success({
|
|
data: $.grep($(ips).map(function(index, ip) {
|
|
return $.extend(ip, {
|
|
zonename: args.context.instances[0].zonename,
|
|
virtualmachinedisplayname: args.context.instances[0].displayname
|
|
});
|
|
}), function(ip) {
|
|
return ip.ipaddress == args.context.secondaryNicIps[0].ipaddress;
|
|
})[0]
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
ipAddresses: {
|
|
type: 'select',
|
|
title: 'label.menu.ipaddresses',
|
|
listView: {
|
|
id: 'ipAddresses',
|
|
label: 'label.ips',
|
|
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'
|
|
}
|
|
}
|
|
},
|
|
actions: {
|
|
add: {
|
|
label: 'label.acquire.new.ip',
|
|
addRow: 'true',
|
|
preFilter: function(args) {
|
|
var zoneObj;
|
|
var dataObj = {};
|
|
|
|
if ('vpc' in args.context) { //from VPC section
|
|
$.extend(dataObj, {
|
|
id: args.context.vpc[0].zoneid
|
|
});
|
|
} else if ('networks' in args.context) { //from Guest Network section
|
|
$.extend(dataObj, {
|
|
id: args.context.networks[0].zoneid
|
|
});
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('listZones'),
|
|
data: dataObj,
|
|
// id: args.context.networks[0].zoneid
|
|
// },
|
|
async: false,
|
|
success: function(json) {
|
|
zoneObj = json.listzonesresponse.zone[0];
|
|
}
|
|
});
|
|
|
|
if (zoneObj.networktype == 'Advanced' && zoneObj.securitygroupsenabled) {
|
|
return false;
|
|
}
|
|
|
|
if (zoneObj.networktype == 'Basic') {
|
|
var havingEIP = false,
|
|
havingELB = false;
|
|
|
|
var services = args.context.networks[0].service;
|
|
if(services != null) {
|
|
for(var i = 0; i < services.length; i++) {
|
|
var thisService = services[i];
|
|
var capabilities = thisService.capability;
|
|
if (thisService.name == "StaticNat") {
|
|
if(capabilities != null) {
|
|
for(var k = 0; k < capabilities.length; k++) {
|
|
if (capabilities[k].name == "ElasticIp" && capabilities[k].value == "true") {
|
|
havingEIP = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else if (thisService.name == "Lb") {
|
|
if(capabilities != null) {
|
|
for(var k = 0; k < capabilities.length; k++) {
|
|
if (capabilities[k].name == "ElasticLb" && capabilities[k].value == "true") {
|
|
havingELB = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (havingEIP != true || havingELB != true) { //not EIP-ELB
|
|
return false; //acquire new IP is not allowed in non-EIP-ELB basic zone
|
|
}
|
|
}
|
|
|
|
//*** from Guest Network section ***
|
|
if (!('vpc' in args.context)) {
|
|
if (args.context.networks[0].vpcid == null) { //Guest Network section > non-VPC network, show Acquire IP button
|
|
return true;
|
|
} else { //Guest Network section > VPC network, hide Acquire IP button
|
|
return false;
|
|
}
|
|
}
|
|
//*** from VPC section ***
|
|
else { //'vpc' in args.context //args.context.networks[0] has only one property => name: 'Router'
|
|
return true; //VPC section, show Acquire IP button
|
|
}
|
|
},
|
|
messages: {
|
|
notification: function(args) {
|
|
return 'label.acquire.new.ip';
|
|
}
|
|
},
|
|
createForm: {
|
|
title: 'label.acquire.new.ip',
|
|
desc: 'Please confirm that you want to acquire new IP',
|
|
preFilter: function(args) {
|
|
$.ajax({
|
|
url: createURL('listRegions'),
|
|
success: function(json) {
|
|
var selectedRegionName = $(".region-switcher .title").text();
|
|
if ( selectedRegionName == undefined || selectedRegionName.length == 0) {
|
|
selectedRegionName = "Local";
|
|
}
|
|
var items = json.listregionsresponse.region;
|
|
if(items != null) {
|
|
for(var i = 0; i < items.length; i++) {
|
|
if(items[i].name == selectedRegionName) {
|
|
if(items[i].portableipserviceenabled == true) {
|
|
args.$form.find('.form-item[rel=isportable]').css('display', 'inline-block');
|
|
} else {
|
|
args.$form.find('.form-item[rel=isportable]').hide();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
},
|
|
fields: {
|
|
isportable: {
|
|
label: 'label.cross.zones',
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: "false",
|
|
description: _l('label.no')
|
|
});
|
|
items.push({
|
|
id: "true",
|
|
description: _l('label.yes')
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
},
|
|
isHidden: true
|
|
}
|
|
}
|
|
},
|
|
action: function(args) {
|
|
var dataObj = {};
|
|
if (args.$form.find('.form-item[rel=isportable]').css("display") != "none") {
|
|
$.extend(dataObj, {
|
|
isportable: args.data.isportable
|
|
});
|
|
}
|
|
|
|
if ('vpc' in args.context) { //from VPC section
|
|
$.extend(dataObj, {
|
|
vpcid: args.context.vpc[0].id
|
|
});
|
|
} else if ('networks' in args.context) { //from Guest Network section
|
|
$.extend(dataObj, {
|
|
networkid: args.context.networks[0].id
|
|
});
|
|
|
|
if (args.context.networks[0].type == "Shared" && !args.context.projects) {
|
|
$.extend(dataObj, {
|
|
domainid: g_domainid,
|
|
account: g_account
|
|
});
|
|
}
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('associateIpAddress'),
|
|
data: dataObj,
|
|
success: function(data) {
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: data.associateipaddressresponse.jobid,
|
|
getUpdatedItem: function(data) {
|
|
var newIP = data.queryasyncjobresultresponse.jobresult.ipaddress;
|
|
return $.extend(newIP, {
|
|
state: 'Allocated'
|
|
});
|
|
},
|
|
getActionFilter: function() {
|
|
return actionFilters.ipAddress;
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
error: function(json) {
|
|
args.response.error(parseXMLHttpResponse(json));
|
|
}
|
|
});
|
|
},
|
|
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
}
|
|
},
|
|
|
|
dataProvider: function(args) {
|
|
var items = [];
|
|
var data = {};
|
|
listViewDataProvider(args, data);
|
|
if (args.context.networks) {
|
|
$.extend(data, {
|
|
associatedNetworkId: args.context.networks[0].id
|
|
});
|
|
}
|
|
if ("vpc" in args.context) {
|
|
$.extend(data, {
|
|
vpcid: args.context.vpc[0].id
|
|
});
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('listPublicIpAddresses'),
|
|
data: $.extend({}, data, {
|
|
forvirtualnetwork: true //IPs are allocated on public network
|
|
}),
|
|
dataType: "json",
|
|
async: false,
|
|
success: function(json) {
|
|
var ips = json.listpublicipaddressesresponse.publicipaddress;
|
|
if(ips != null) {
|
|
for(var i = 0; i < ips.length; i++) {
|
|
getExtaPropertiesForIpObj(ips[i], args);
|
|
items.push(ips[i]);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
if (g_supportELB == "guest") {
|
|
$.ajax({
|
|
url: createURL('listPublicIpAddresses'),
|
|
data: $.extend({}, data, {
|
|
forvirtualnetwork: false, // ELB IPs are allocated on guest network
|
|
forloadbalancing: true
|
|
}),
|
|
dataType: "json",
|
|
async: false,
|
|
success: function(json) {
|
|
var ips = json.listpublicipaddressesresponse.publicipaddress;
|
|
if(ips != null) {
|
|
for(var i = 0; i < ips.length; i++) {
|
|
getExtaPropertiesForIpObj(ips[i], args);
|
|
items.push(ips[i]);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
args.response.success({
|
|
actionFilter: actionFilters.ipAddress,
|
|
data: items
|
|
});
|
|
},
|
|
|
|
// Detail view
|
|
detailView: {
|
|
name: 'IP address detail',
|
|
tabFilter: function(args) {
|
|
var item = args.context.ipAddresses[0];
|
|
|
|
var disabledTabs = [];
|
|
var ipAddress = args.context.ipAddresses[0];
|
|
var disableVpn = false,
|
|
disableIpRules = false;
|
|
|
|
if (!ipAddress.vpnenabled) {
|
|
disableVpn = true;
|
|
}
|
|
|
|
if (ipAddress.issystem == true) {
|
|
disableVpn = true;
|
|
|
|
if (ipAddress.isstaticnat == true || ipAddress.virtualmachineid != null) {
|
|
disableIpRules = true;
|
|
}
|
|
}
|
|
|
|
if (ipAddress.vpcid != null && ipAddress.issourcenat) { //don't show Configuration(ipRules) tab on VPC sourceNAT IP
|
|
disableIpRules = true;
|
|
}
|
|
|
|
if (('vpc' in args.context) == false && ipAddress.vpcid != null) { //from Guest Network section, don't show Configuration(ipRules) tab on VPC IP
|
|
disableIpRules = true;
|
|
}
|
|
|
|
if (disableVpn)
|
|
disabledTabs.push('vpn');
|
|
if (disableIpRules)
|
|
disabledTabs.push('ipRules');
|
|
|
|
return disabledTabs;
|
|
},
|
|
actions: {
|
|
enableVPN: {
|
|
label: 'label.enable.vpn',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('createRemoteAccessVpn'),
|
|
data: {
|
|
publicipid: args.context.ipAddresses[0].id,
|
|
domainid: args.context.ipAddresses[0].domainid,
|
|
account: args.context.ipAddresses[0].account
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success({
|
|
_custom: {
|
|
getUpdatedItem: function(json) {
|
|
return {
|
|
vpn: json.queryasyncjobresultresponse.jobresult.remoteaccessvpn,
|
|
vpnenabled: true
|
|
};
|
|
},
|
|
getActionFilter: function() {
|
|
return actionFilters.ipAddress;
|
|
},
|
|
jobId: data.createremoteaccessvpnresponse.jobid
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
messages: {
|
|
confirm: function(args) {
|
|
return 'message.enable.vpn';
|
|
},
|
|
notification: function(args) {
|
|
return 'label.enable.vpn';
|
|
},
|
|
complete: function(args) {
|
|
return _l('message.enabled.vpn') + ' ' + args.vpn.publicip + '.' + '<br/>' + _l('message.enabled.vpn.ip.sec') + '<br/>' + args.vpn.presharedkey;
|
|
}
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
},
|
|
disableVPN: {
|
|
label: 'label.disable.vpn',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('deleteRemoteAccessVpn'),
|
|
data: {
|
|
publicipid: args.context.ipAddresses[0].id,
|
|
domainid: args.context.ipAddresses[0].domainid
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success({
|
|
_custom: {
|
|
getUpdatedItem: function(data) {
|
|
return {
|
|
vpnenabled: false
|
|
};
|
|
},
|
|
getActionFilter: function() {
|
|
return actionFilters.ipAddress;
|
|
},
|
|
jobId: data.deleteremoteaccessvpnresponse.jobid
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
messages: {
|
|
confirm: function(args) {
|
|
return 'message.disable.vpn';
|
|
},
|
|
notification: function(args) {
|
|
return 'label.disable.vpn';
|
|
}
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
},
|
|
enableStaticNAT: {
|
|
label: 'label.action.enable.static.NAT',
|
|
|
|
action: {
|
|
noAdd: true,
|
|
custom: cloudStack.uiCustom.enableStaticNAT({
|
|
tierSelect: function(args) {
|
|
if ('vpc' in args.context) { //from VPC section
|
|
args.$tierSelect.show(); //show tier dropdown
|
|
|
|
$.ajax({ //populate tier dropdown
|
|
url: createURL("listNetworks"),
|
|
async: false,
|
|
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,
|
|
supportedservices: 'StaticNat'
|
|
},
|
|
success: function(json) {
|
|
var networks = json.listnetworksresponse.network;
|
|
var items = [{
|
|
id: -1,
|
|
description: 'Please select a tier'
|
|
}];
|
|
$(networks).each(function() {
|
|
items.push({
|
|
id: this.id,
|
|
description: this.displaytext
|
|
});
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
});
|
|
} else { //from Guest Network section
|
|
args.$tierSelect.hide();
|
|
}
|
|
|
|
args.$tierSelect.change(function() {
|
|
args.$tierSelect.closest('.list-view').listView('refresh');
|
|
});
|
|
args.$tierSelect.closest('.list-view').listView('refresh');
|
|
},
|
|
|
|
listView: $.extend(true, {}, cloudStack.sections.instances, {
|
|
listView: {
|
|
advSearchFields: null, // Not supported in dialogs right now due to display issues
|
|
filters: false,
|
|
subselect: {
|
|
label: 'label.use.vm.ip',
|
|
dataProvider: singleVmSecondaryIPSubselect
|
|
},
|
|
dataProvider: function(args) {
|
|
var data = {
|
|
page: args.page,
|
|
pageSize: pageSize,
|
|
listAll: true
|
|
};
|
|
|
|
if (args.filterBy.search.value) {
|
|
data.keyword = args.filterBy.search.value;
|
|
}
|
|
|
|
var $tierSelect = $(".ui-dialog-content").find('.tier-select select');
|
|
|
|
// if $tierSelect is not initialized, return; tierSelect() will refresh listView and come back here later
|
|
if ($tierSelect.size() == 0) {
|
|
args.response.success({
|
|
data: null
|
|
});
|
|
return;
|
|
}
|
|
|
|
// if no tier is selected
|
|
if ($tierSelect.val() == '-1') {
|
|
args.response.success({
|
|
data: null
|
|
});
|
|
return;
|
|
}
|
|
|
|
if ('vpc' in args.context) {
|
|
$.extend(data, {
|
|
networkid: $tierSelect.val(),
|
|
vpcid: args.context.vpc[0].id
|
|
});
|
|
} else if ('networks' in args.context && !args.context.ipAddresses[0].isportable) {
|
|
$.extend(data, {
|
|
networkid: args.context.networks[0].id
|
|
});
|
|
}
|
|
|
|
if (!args.context.projects) {
|
|
$.extend(data, {
|
|
account: args.context.ipAddresses[0].account,
|
|
domainid: args.context.ipAddresses[0].domainid
|
|
});
|
|
}
|
|
|
|
$.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', 'Expunging'
|
|
]) == -1;
|
|
}
|
|
)
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}),
|
|
action: function(args) {
|
|
var data = {
|
|
ipaddressid: args.context.ipAddresses[0].id,
|
|
virtualmachineid: args.context.instances[0].id
|
|
};
|
|
|
|
if (args.context.ipAddresses[0].isportable) {
|
|
var subselect = args._subselect.split(',');
|
|
var networkid = subselect[0];
|
|
var vmguestip = subselect[1];
|
|
|
|
data.networkid = subselect[0];
|
|
|
|
if (parseInt(vmguestip) !== -1) {
|
|
data.vmguestip = vmguestip;
|
|
}
|
|
} else if (args._subselect && args._subselect != -1) {
|
|
data.vmguestip = args._subselect;
|
|
}
|
|
|
|
if ('vpc' in args.context) {
|
|
if (args.tierID == '-1') {
|
|
args.response.error('Tier is required');
|
|
return;
|
|
}
|
|
$.extend(data, {
|
|
networkid: args.tierID
|
|
});
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('enableStaticNat'),
|
|
data: data,
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success({});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
})
|
|
},
|
|
messages: {
|
|
notification: function(args) {
|
|
return 'label.action.enable.static.NAT';
|
|
}
|
|
},
|
|
notification: {
|
|
poll: function(args) {
|
|
args.complete({
|
|
data: {
|
|
isstaticnat: true
|
|
}
|
|
});
|
|
|
|
if (args._custom.$detailView.is(':visible')) {
|
|
ipChangeNotice();
|
|
}
|
|
}
|
|
}
|
|
},
|
|
disableStaticNAT: {
|
|
label: 'label.action.disable.static.NAT',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('disableStaticNat'),
|
|
data: {
|
|
ipaddressid: args.context.ipAddresses[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: data.disablestaticnatresponse.jobid,
|
|
getUpdatedItem: function() {
|
|
return {
|
|
isstaticnat: false,
|
|
virtualmachinedisplayname: ""
|
|
};
|
|
},
|
|
getActionFilter: function() {
|
|
return function(args) {
|
|
return ['enableStaticNAT'];
|
|
};
|
|
},
|
|
onComplete: function(args, _custom) {
|
|
if (_custom.$detailView.is(':visible')) {
|
|
ipChangeNotice();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
messages: {
|
|
confirm: function(args) {
|
|
return 'message.action.disable.static.NAT';
|
|
},
|
|
notification: function(args) {
|
|
return 'label.action.disable.static.NAT';
|
|
}
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
},
|
|
remove: {
|
|
label: 'label.action.release.ip',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('disassociateIpAddress'),
|
|
data: {
|
|
id: args.context.ipAddresses[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: data.disassociateipaddressresponse.jobid,
|
|
getActionFilter: function() {
|
|
return function(args) {
|
|
var allowedActions = ['enableStaticNAT'];
|
|
|
|
return allowedActions;
|
|
};
|
|
},
|
|
getUpdatedItem: function(args) {
|
|
return {
|
|
state: 'Released'
|
|
};
|
|
},
|
|
onComplete: function() {
|
|
$(window).trigger('cloudStack.fullRefresh');
|
|
}
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
messages: {
|
|
confirm: function(args) {
|
|
return 'message.action.release.ip';
|
|
},
|
|
notification: function(args) {
|
|
return 'label.action.release.ip';
|
|
}
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
}
|
|
},
|
|
tabs: {
|
|
details: {
|
|
title: 'label.details',
|
|
preFilter: function(args) {
|
|
var hiddenFields = [];
|
|
var zoneObj;
|
|
$.ajax({
|
|
url: createURL("listZones&id=" + args.context.ipAddresses[0].zoneid),
|
|
dataType: "json",
|
|
async: false,
|
|
success: function(json) {
|
|
zoneObj = json.listzonesresponse.zone[0];
|
|
}
|
|
});
|
|
if (zoneObj.networktype == "Advanced") {
|
|
hiddenFields.push("issystem");
|
|
hiddenFields.push("purpose");
|
|
}
|
|
|
|
if (!isAdmin()) {
|
|
hiddenFields.push("vlanname");
|
|
}
|
|
return hiddenFields;
|
|
},
|
|
fields: [{
|
|
ipaddress: {
|
|
label: 'label.ip'
|
|
}
|
|
}, {
|
|
isportable: {
|
|
label: 'label.cross.zones',
|
|
converter: function(data) {
|
|
return data ? _l('label.yes') : _l('label.no');
|
|
}
|
|
},
|
|
id: {
|
|
label: 'label.id'
|
|
},
|
|
associatednetworkid: {
|
|
label: 'label.associated.network.id'
|
|
},
|
|
associatednetworkname: {
|
|
label: 'label.network.name'
|
|
},
|
|
state: {
|
|
label: 'label.state'
|
|
},
|
|
networkid: {
|
|
label: 'label.network.id'
|
|
},
|
|
issourcenat: {
|
|
label: 'label.source.nat',
|
|
converter: cloudStack.converters.toBooleanText
|
|
},
|
|
isstaticnat: {
|
|
label: 'label.static.nat',
|
|
converter: cloudStack.converters.toBooleanText
|
|
},
|
|
issystem: {
|
|
label: 'label.is.system',
|
|
converter: cloudStack.converters.toBooleanText
|
|
}, //(basic zone only)
|
|
purpose: {
|
|
label: 'label.purpose'
|
|
}, //(basic zone only) When an IP is system-generated, the purpose it serves can be Lb or static nat.
|
|
virtualmachinedisplayname: {
|
|
label: 'label.vm.name'
|
|
},
|
|
domain: {
|
|
label: 'label.domain'
|
|
},
|
|
account: {
|
|
label: 'label.account'
|
|
},
|
|
zonename: {
|
|
label: 'label.zone'
|
|
},
|
|
vlanname: {
|
|
label: 'label.vlan.only'
|
|
}
|
|
}],
|
|
|
|
tags: cloudStack.api.tags({
|
|
resourceType: 'PublicIpAddress',
|
|
contextId: 'ipAddresses'
|
|
}),
|
|
|
|
dataProvider: function(args) {
|
|
var items = args.context.ipAddresses;
|
|
|
|
$.ajax({
|
|
url: createURL('listPublicIpAddresses'),
|
|
data: {
|
|
id: args.context.ipAddresses[0].id
|
|
},
|
|
dataType: "json",
|
|
async: true,
|
|
success: function(json) {
|
|
var ipObj = json.listpublicipaddressesresponse.publicipaddress[0];
|
|
getExtaPropertiesForIpObj(ipObj, args);
|
|
|
|
var network = $.grep(
|
|
args.context.vpc ?
|
|
args.context.vpc[0].network : args.context.networks,
|
|
function(network) {
|
|
return network.id = ipObj.associatednetworkid;
|
|
})[0];
|
|
|
|
args.response.success({
|
|
actionFilter: actionFilters.ipAddress,
|
|
data: ipObj
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
ipRules: { //Configuration tab
|
|
title: 'label.configuration',
|
|
custom: cloudStack.ipRules({
|
|
preFilter: function(args) {
|
|
var disallowedActions = [];
|
|
if (args.context.ipAddresses[0].isstaticnat)
|
|
disallowedActions.push("nonStaticNATChart"); //tell ipRules widget to show staticNAT chart instead of non-staticNAT chart.
|
|
|
|
var havingFirewallService = false;
|
|
var havingPortForwardingService = false;
|
|
var havingLbService = false;
|
|
var havingVpnService = false;
|
|
|
|
if (!('vpc' in args.context)) { //from Guest Network section
|
|
var services = args.context.networks[0].service;
|
|
if(services != null) {
|
|
for(var i = 0; i < services.length; i++) {
|
|
var thisService = services[i];
|
|
if (thisService.name == "Firewall")
|
|
havingFirewallService = true;
|
|
if (thisService.name == "PortForwarding")
|
|
havingPortForwardingService = true;
|
|
if (thisService.name == "Lb")
|
|
havingLbService = true;
|
|
if (thisService.name == "Vpn")
|
|
havingVpnService = true;
|
|
}
|
|
}
|
|
} else { //from VPC section
|
|
//a VPC network from Guest Network section or from VPC section
|
|
// Firewall is not supported in IP from VPC section
|
|
// (because ACL has already supported in tier from VPC section)
|
|
havingFirewallService = false;
|
|
disallowedActions.push("firewall");
|
|
|
|
havingVpnService = false; //VPN is not supported in IP from VPC section
|
|
|
|
if (args.context.ipAddresses[0].associatednetworkid == null) { //IP is not associated with any tier yet
|
|
havingPortForwardingService = true;
|
|
havingLbService = true;
|
|
} else { //IP is associated with a tier
|
|
$.ajax({
|
|
url: createURL('listNetworks'),
|
|
data: {
|
|
listAll: true,
|
|
id: args.context.ipAddresses[0].associatednetworkid
|
|
},
|
|
async: false,
|
|
success: function(json) {
|
|
var networkObj = json.listnetworksresponse.network[0];
|
|
var services = networkObj.service;
|
|
if(services != null) {
|
|
for(var i = 0; i < services.length; i++) {
|
|
if (services[i].name == "PortForwarding")
|
|
havingPortForwardingService = true;
|
|
if (services[i].name == "Lb")
|
|
havingLbService = true;
|
|
}
|
|
}
|
|
|
|
if (networkObj.networkofferingconservemode == false) {
|
|
/*
|
|
(1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added.
|
|
*/
|
|
if (args.context.ipAddresses[0].issourcenat) {
|
|
if (havingFirewallService == false) { //firewall is not supported in IP from VPC section (because ACL has already supported in tier from VPC section)
|
|
disallowedActions.push("firewall");
|
|
}
|
|
|
|
disallowedActions.push("portForwarding");
|
|
disallowedActions.push("loadBalancing");
|
|
}
|
|
|
|
/*
|
|
(2) If IP is non-SourceNat, show StaticNat/VPN/PortForwarding/LoadBalancer at first.
|
|
1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer.
|
|
2. If VPN service is supported (i.e. IP comes from Guest Network section, not from VPC section), once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer.
|
|
3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer.
|
|
4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding.
|
|
*/
|
|
else { //args.context.ipAddresses[0].issourcenat == false
|
|
if (havingFirewallService == false)
|
|
disallowedActions.push("firewall");
|
|
if (havingPortForwardingService == false)
|
|
disallowedActions.push("portForwarding");
|
|
if (havingLbService == false)
|
|
disallowedActions.push("loadBalancing");
|
|
|
|
if (args.context.ipAddresses[0].isstaticnat) { //1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer.
|
|
disallowedActions.push("portForwarding");
|
|
disallowedActions.push("loadBalancing");
|
|
}
|
|
if (havingVpnService && args.context.ipAddresses[0].vpnenabled) { //2. If VPN service is supported (i.e. IP comes from Guest Network section, not from VPC section), once VPN is enabled, hide StaticNat/PortForwarding/LoadBalancer.
|
|
disallowedActions.push("portForwarding");
|
|
disallowedActions.push("loadBalancing");
|
|
}
|
|
|
|
//3. Once a PortForwarding rule is added, hide StaticNat/VPN/LoadBalancer.
|
|
$.ajax({
|
|
url: createURL('listPortForwardingRules'),
|
|
data: {
|
|
ipaddressid: args.context.ipAddresses[0].id,
|
|
listAll: true
|
|
},
|
|
dataType: 'json',
|
|
async: false,
|
|
success: function(json) {
|
|
// Get instance
|
|
var rules = json.listportforwardingrulesresponse.portforwardingrule;
|
|
if (rules != null && rules.length > 0) {
|
|
disallowedActions.push("loadBalancing");
|
|
}
|
|
}
|
|
});
|
|
|
|
//4. Once a LoadBalancer rule is added, hide StaticNat/VPN/PortForwarding.
|
|
$.ajax({
|
|
url: createURL('listLoadBalancerRules'),
|
|
data: {
|
|
publicipid: args.context.ipAddresses[0].id,
|
|
listAll: true
|
|
},
|
|
dataType: 'json',
|
|
async: false,
|
|
success: function(json) {
|
|
var rules = json.listloadbalancerrulesresponse.loadbalancerrule;
|
|
if (rules != null && rules.length > 0) {
|
|
disallowedActions.push("portForwarding");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
return disallowedActions;
|
|
},
|
|
|
|
// Firewall rules
|
|
firewall: {
|
|
noSelect: true,
|
|
fields: {
|
|
'cidrlist': {
|
|
edit: true,
|
|
label: 'label.cidr.list'
|
|
},
|
|
'protocol': {
|
|
label: 'label.protocol',
|
|
select: function(args) {
|
|
args.$select.change(function() {
|
|
var $inputs = args.$form.find('input');
|
|
var $icmpFields = $inputs.filter(function() {
|
|
var name = $(this).attr('name');
|
|
|
|
return $.inArray(name, [
|
|
'icmptype',
|
|
'icmpcode'
|
|
]) > -1;
|
|
});
|
|
var $otherFields = $inputs.filter(function() {
|
|
var name = $(this).attr('name');
|
|
|
|
return name != 'icmptype' && name != 'icmpcode' && name != 'cidrlist';
|
|
});
|
|
|
|
if ($(this).val() == 'icmp') {
|
|
$icmpFields.show();
|
|
$icmpFields.attr('disabled', false);
|
|
$otherFields.attr('disabled', 'disabled');
|
|
$otherFields.hide();
|
|
$otherFields.parent().find('label.error').hide();
|
|
} 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();
|
|
}
|
|
});
|
|
|
|
args.response.success({
|
|
data: [{
|
|
name: 'tcp',
|
|
description: 'TCP'
|
|
}, {
|
|
name: 'udp',
|
|
description: 'UDP'
|
|
}, {
|
|
name: 'icmp',
|
|
description: 'ICMP'
|
|
}]
|
|
});
|
|
}
|
|
},
|
|
'startport': {
|
|
edit: true,
|
|
label: 'label.start.port',
|
|
isOptional: true
|
|
},
|
|
'endport': {
|
|
edit: true,
|
|
label: 'label.end.port',
|
|
isOptional: true
|
|
},
|
|
'icmptype': {
|
|
edit: true,
|
|
label: 'ICMP.type',
|
|
isDisabled: true
|
|
},
|
|
'icmpcode': {
|
|
edit: true,
|
|
label: 'ICMP.code',
|
|
isDisabled: true
|
|
},
|
|
'add-rule': {
|
|
label: 'label.add.rule',
|
|
addButton: true
|
|
},
|
|
'state' : {
|
|
edit: 'ignore',
|
|
label: 'label.state'
|
|
}
|
|
},
|
|
|
|
tags: cloudStack.api.tags({
|
|
resourceType: 'FirewallRule',
|
|
contextId: 'multiRule'
|
|
}),
|
|
|
|
add: {
|
|
label: 'label.add',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('createFirewallRule'),
|
|
data: $.extend(args.data, {
|
|
ipaddressid: args.context.ipAddresses[0].id
|
|
}),
|
|
dataType: 'json',
|
|
success: function(data) {
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: data.createfirewallruleresponse.jobid
|
|
},
|
|
notification: {
|
|
label: 'label.add.firewall',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
},
|
|
actions: {
|
|
destroy: {
|
|
label: 'label.action.delete.firewall',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('deleteFirewallRule'),
|
|
data: {
|
|
id: args.context.multiRule[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var jobID = data.deletefirewallruleresponse.jobid;
|
|
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobID
|
|
},
|
|
notification: {
|
|
label: 'label.action.delete.firewall',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
dataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL('listFirewallRules'),
|
|
data: {
|
|
listAll: true,
|
|
ipaddressid: args.context.ipAddresses[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success({
|
|
data: data.listfirewallrulesresponse.firewallrule
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
staticNATDataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL('listPublicIpAddresses'),
|
|
data: {
|
|
id: args.context.ipAddresses[0].id,
|
|
listAll: true
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var ipObj = data.listpublicipaddressesresponse.publicipaddress[0];
|
|
getExtaPropertiesForIpObj(ipObj, args);
|
|
|
|
args.response.success({
|
|
data: ipObj
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
|
|
vmDataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL('listVirtualMachines'),
|
|
data: {
|
|
id: args.context.ipAddresses[0].virtualmachineid,
|
|
listAll: true
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success({
|
|
data: data.listvirtualmachinesresponse.virtualmachine[0]
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
|
|
vmDetails: cloudStack.sections.instances.listView.detailView,
|
|
|
|
|
|
//"NAT Port Range" multiEdit screen for StaticNAT is obsolete in cloudstack 3.0 because createIpForwardingRule/deleteIpForwardingRule/listIpForwardingRules API are obsolete in cloudstack 3.0.
|
|
//cloudstack 3.0 is using createFirewallRule/listFirewallRules/deleteFirewallRule API for both staticNAT and non-staticNAT .
|
|
/*
|
|
staticNAT: {
|
|
noSelect: true,
|
|
fields: {
|
|
'protocol': {
|
|
label: 'label.protocol',
|
|
select: function(args) {
|
|
args.response.success({
|
|
data: [
|
|
{ name: 'tcp', description: 'TCP' },
|
|
{ name: 'udp', description: 'UDP' }
|
|
]
|
|
});
|
|
}
|
|
},
|
|
'startport': { edit: true, label: 'label.start.port' },
|
|
'endport': { edit: true, label: 'label.end.port' },
|
|
'add-rule': {
|
|
label: 'label.add.rule',
|
|
addButton: true
|
|
}
|
|
},
|
|
add: {
|
|
label: 'label.add',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('createIpForwardingRule'),
|
|
data: $.extend(args.data, {
|
|
ipaddressid: args.context.ipAddresses[0].id
|
|
}),
|
|
dataType: 'json',
|
|
success: function(data) {
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: data.createipforwardingruleresponse.jobid
|
|
},
|
|
notification: {
|
|
label: 'label.add.static.nat.rule',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
},
|
|
actions: {
|
|
destroy: {
|
|
label: 'label.remove.rule',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('deleteIpForwardingRule'),
|
|
data: {
|
|
id: args.context.multiRule[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var jobID = data.deleteipforwardingruleresponse.jobid;
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobID
|
|
},
|
|
notification: {
|
|
label: 'label.remove.static.nat.rule',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
dataProvider: function(args) {
|
|
setTimeout(function() {
|
|
$.ajax({
|
|
url: createURL('listIpForwardingRules'),
|
|
data: {
|
|
listAll: true,
|
|
ipaddressid: args.context.ipAddresses[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success({
|
|
data: data.listipforwardingrulesresponse.ipforwardingrule
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}, 100);
|
|
}
|
|
},
|
|
*/
|
|
|
|
|
|
// Load balancing rules
|
|
loadBalancing: {
|
|
listView: $.extend(true, {}, cloudStack.sections.instances, {
|
|
listView: {
|
|
fields: {
|
|
name: {
|
|
label: 'label.name'
|
|
},
|
|
displayname: {
|
|
label: 'label.display.name'
|
|
},
|
|
zonename: {
|
|
label: 'label.zone.name'
|
|
},
|
|
state: {
|
|
label: 'label.state',
|
|
indicator: {
|
|
'Running': 'on',
|
|
'Stopped': 'off',
|
|
'Destroyed': 'off',
|
|
'Error': 'off'
|
|
}
|
|
}
|
|
},
|
|
filters: false,
|
|
|
|
//when server-side change of adding new parameter "vmidipmap" to assignToLoadBalancerRule API is in, uncomment the following commented 4 lines.
|
|
subselect: {
|
|
isMultiple: true,
|
|
label: 'label.use.vm.ips',
|
|
dataProvider: multipleVmSecondaryIPSubselect
|
|
},
|
|
|
|
dataProvider: function(args) {
|
|
var itemData = $.isArray(args.context.multiRule) && args.context.subItemData ? args.context.subItemData : [];
|
|
|
|
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
|
|
};
|
|
|
|
if (!args.context.projects) {
|
|
$.extend(data, {
|
|
account: args.context.ipAddresses[0].account,
|
|
domainid: args.context.ipAddresses[0].domainid
|
|
});
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('listVirtualMachines'),
|
|
data: data,
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var vmData = $.grep(
|
|
data.listvirtualmachinesresponse.virtualmachine ?
|
|
data.listvirtualmachinesresponse.virtualmachine : [],
|
|
function(instance) {
|
|
//Hiding the autoScale VMs
|
|
var nonAutoScale = 0;
|
|
if (instance.displayname == null)
|
|
nonAutoScale = 1
|
|
else {
|
|
if (instance.displayname.match(/AutoScale-LB-/) == null)
|
|
nonAutoScale = 1;
|
|
else {
|
|
if (instance.displayname.match(/AutoScale-LB-/).length)
|
|
nonAutoScale = 0;
|
|
}
|
|
}
|
|
var isActiveState = $.inArray(instance.state, ['Destroyed', 'Expunging']) == -1;
|
|
var notExisting = !$.grep(itemData, function(item) {
|
|
return item.id == instance.id;
|
|
}).length;
|
|
|
|
// Check if there are any remaining IPs
|
|
if (!notExisting) {
|
|
$.ajax({
|
|
url: createURL('listNics'),
|
|
async: false,
|
|
data: {
|
|
virtualmachineid: instance.id
|
|
},
|
|
success: function(json) {
|
|
var nics = json.listnicsresponse.nic;
|
|
|
|
$(nics).map(function (index, nic) {
|
|
if (nic.secondaryip) {
|
|
var targetIPs = $(nic.secondaryip).map(function (index, sip) {
|
|
return sip.ipaddress;
|
|
});
|
|
|
|
var lbIPs = $(itemData).map(function(index, item) { return item.itemIp; });
|
|
|
|
targetIPs.push(nic.ipaddress);
|
|
|
|
var matchingIPs = $.grep(targetIPs, function(item) {
|
|
return $.inArray(item, lbIPs) > -1;
|
|
});
|
|
|
|
if (targetIPs.length - matchingIPs.length) {
|
|
notExisting = true;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
})
|
|
}
|
|
|
|
return nonAutoScale && isActiveState && notExisting;
|
|
}
|
|
);
|
|
|
|
args.response.success({
|
|
data: vmData
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}),
|
|
headerFields: {
|
|
tier: {
|
|
label: 'label.tier',
|
|
select: function(args) {
|
|
if ('vpc' in args.context) {
|
|
var data = {
|
|
//listAll: true, //do not pass listAll to listNetworks under VPC
|
|
supportedservices: 'Lb'
|
|
};
|
|
if (args.context.ipAddresses[0].associatednetworkid == null) {
|
|
$.extend(data, {
|
|
vpcid: args.context.vpc[0].id,
|
|
domainid: args.context.vpc[0].domainid,
|
|
account: args.context.vpc[0].account
|
|
});
|
|
} else {
|
|
$.extend(data, {
|
|
id: args.context.ipAddresses[0].associatednetworkid
|
|
});
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL("listNetworks"),
|
|
data: data,
|
|
success: function(json) {
|
|
var networks = json.listnetworksresponse.network;
|
|
var items = [];
|
|
$(networks).each(function() {
|
|
items.push({
|
|
id: this.id,
|
|
description: this.displaytext
|
|
});
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
},
|
|
multipleAdd: true,
|
|
|
|
fields: {
|
|
'name': {
|
|
edit: true,
|
|
label: 'label.name',
|
|
isEditable: true
|
|
},
|
|
'publicport': {
|
|
edit: true,
|
|
label: 'label.public.port'
|
|
},
|
|
'privateport': {
|
|
edit: true,
|
|
label: 'label.private.port'
|
|
},
|
|
'algorithm': {
|
|
label: 'label.algorithm',
|
|
isEditable: true,
|
|
select: function(args) {
|
|
args.response.success({
|
|
data: [{
|
|
id: 'roundrobin',
|
|
name: 'roundrobin',
|
|
description: _l('label.round.robin')
|
|
}, {
|
|
id: 'leastconn',
|
|
name: 'leastconn',
|
|
description: _l('label.least.connections')
|
|
}, {
|
|
id: 'source',
|
|
name: 'source',
|
|
description: _l('label.source')
|
|
}]
|
|
});
|
|
}
|
|
},
|
|
|
|
'sticky': {
|
|
label: 'label.stickiness',
|
|
custom: {
|
|
buttonLabel: 'label.configure',
|
|
action: cloudStack.lbStickyPolicy.dialog()
|
|
}
|
|
},
|
|
|
|
'health-check': {
|
|
label: 'label.health.check',
|
|
custom: {
|
|
requireValidation: true,
|
|
buttonLabel: 'Configure',
|
|
action: cloudStack.uiCustom.healthCheck()
|
|
|
|
}
|
|
},
|
|
|
|
'autoScale': {
|
|
label: 'label.autoscale',
|
|
custom: {
|
|
requireValidation: true,
|
|
buttonLabel: 'label.configure',
|
|
action: cloudStack.uiCustom.autoscaler(cloudStack.autoscaler)
|
|
},
|
|
isHidden: function(args) {
|
|
if (!('vpc' in args.context)) { //from Guest Network section
|
|
var lbProviderIsNetscaler = false;
|
|
$.ajax({
|
|
url: createURL('listNetworkOfferings'),
|
|
data: {
|
|
id: args.context.networks[0].networkofferingid
|
|
},
|
|
async: false,
|
|
success: function(json) {
|
|
var networkOffering = json.listnetworkofferingsresponse.networkoffering[0];
|
|
var services = networkOffering.service;
|
|
if (services != null) {
|
|
for (var i = 0; i < services.length; i++) {
|
|
if (services[i].name == 'Lb') {
|
|
var providers = services[i].provider;
|
|
if (providers != null) {
|
|
for (var k = 0; k < providers.length; k++) {
|
|
if (providers[k].name == 'Netscaler') {
|
|
lbProviderIsNetscaler = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
if (lbProviderIsNetscaler == true) { //AutoScale is only supported on Netscaler (but not on any other provider like VirtualRouter)
|
|
return false; //show AutoScale button
|
|
} else {
|
|
return 2; //hide Autoscale button (both header and form)
|
|
}
|
|
} else { //from VPC section
|
|
//VPC doesn't support autoscale
|
|
return 2;
|
|
}
|
|
}
|
|
},
|
|
|
|
'add-vm': {
|
|
label: 'label.add.vms',
|
|
addButton: true
|
|
},
|
|
|
|
'state' : {
|
|
edit: 'ignore',
|
|
label: 'label.state'
|
|
}
|
|
},
|
|
|
|
tags: cloudStack.api.tags({
|
|
resourceType: 'LoadBalancer',
|
|
contextId: 'multiRule'
|
|
}),
|
|
|
|
add: {
|
|
label: 'label.add.vms',
|
|
action: function(args) {
|
|
var networkid;
|
|
if ('vpc' in args.context) { //from VPC section
|
|
if (args.data.tier == null) {
|
|
args.response.error('Tier is required');
|
|
return;
|
|
}
|
|
networkid = args.data.tier;
|
|
} else if ('networks' in args.context) { //from Guest Network section
|
|
networkid = args.context.networks[0].id;
|
|
}
|
|
var data = {
|
|
algorithm: args.data.algorithm,
|
|
name: args.data.name,
|
|
privateport: args.data.privateport,
|
|
publicport: args.data.publicport,
|
|
openfirewall: false,
|
|
networkid: networkid,
|
|
publicipid: args.context.ipAddresses[0].id
|
|
};
|
|
|
|
var stickyData = $.extend(true, {}, args.data.sticky);
|
|
|
|
//***** create new LB rule > Add VMs *****
|
|
$.ajax({
|
|
url: createURL('createLoadBalancerRule'),
|
|
data: data,
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var itemData = args.itemData;
|
|
var jobID = data.createloadbalancerruleresponse.jobid;
|
|
var lbID = data.createloadbalancerruleresponse.id;
|
|
|
|
var inputData = {
|
|
id: data.createloadbalancerruleresponse.id
|
|
};
|
|
|
|
/*
|
|
var inputData = {
|
|
id: data.createloadbalancerruleresponse.id,
|
|
virtualmachineids: $.map(itemData, function(elem) {
|
|
return elem.id;
|
|
}).join(',')
|
|
};
|
|
*/
|
|
//virtualmachineids parameter has been replaced with vmidipmap parameter, so comment out the 6 lines above.
|
|
|
|
|
|
/*
|
|
* 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 = args.itemData;
|
|
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;
|
|
|
|
if (args.context.ipAddresses[0].isportable) {
|
|
inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex].split(',')[1];
|
|
} else {
|
|
inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex];
|
|
}
|
|
|
|
vmidipmapIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('assignToLoadBalancerRule'),
|
|
data: inputData,
|
|
success: function(data) {
|
|
var jobID = data.assigntoloadbalancerruleresponse.jobid;
|
|
var lbStickyCreated = 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: {
|
|
jobId: jobID
|
|
},
|
|
complete: function(args) {
|
|
if (lbStickyCreated) return;
|
|
|
|
lbStickyCreated = true;
|
|
|
|
// Create stickiness policy
|
|
if (stickyData &&
|
|
stickyData.methodname &&
|
|
stickyData.methodname != 'None') {
|
|
cloudStack.lbStickyPolicy.actions.add(lbID,
|
|
stickyData,
|
|
complete, error);
|
|
} else {
|
|
complete();
|
|
}
|
|
},
|
|
error: error
|
|
});
|
|
}
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
},
|
|
actions: {
|
|
edit: {
|
|
label: 'label.edit',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('updateLoadBalancerRule'),
|
|
data: $.extend(args.data, {
|
|
id: args.context.multiRule[0].id
|
|
}),
|
|
success: function(json) {
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: json.updateloadbalancerruleresponse.jobid
|
|
},
|
|
notification: {
|
|
label: 'label.edit.lb.rule',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
destroy: {
|
|
label: 'label.action.delete.load.balancer',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('deleteLoadBalancerRule'),
|
|
data: {
|
|
id: args.context.multiRule[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var jobID = data.deleteloadbalancerruleresponse.jobid;
|
|
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobID
|
|
},
|
|
notification: {
|
|
label: 'label.action.delete.load.balancer',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
|
|
itemActions: {
|
|
//***** update existing LB rule > Add VMs *****
|
|
add: {
|
|
label: 'label.add.vms.to.lb',
|
|
action: function(args) {
|
|
var inputData = {
|
|
id: args.multiRule.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 = args.data;
|
|
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;
|
|
|
|
if (args.context.ipAddresses[0].isportable) {
|
|
inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex].split(',')[1];
|
|
} else {
|
|
inputData['vmidipmap[' + vmidipmapIndex + '].vmip'] = selectedIPs[ipIndex];
|
|
}
|
|
|
|
vmidipmapIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('assignToLoadBalancerRule'),
|
|
data: inputData,
|
|
success: function(json) {
|
|
args.response.success({
|
|
notification: {
|
|
_custom: {
|
|
jobId: json.assigntoloadbalancerruleresponse.jobid
|
|
},
|
|
desc: 'label.add.vms.to.lb',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(json) {
|
|
args.response.error();
|
|
cloudStack.dialog.notice({
|
|
message: parseXMLHttpResponse(json)
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
destroy: {
|
|
label: 'label.remove.vm.from.lb',
|
|
action: function(args) {
|
|
var inputData;
|
|
if (args.item.itemIp == undefined) {
|
|
inputData = {
|
|
id: args.multiRule.id,
|
|
virtualmachineids: args.item.id
|
|
};
|
|
} else {
|
|
inputData = {
|
|
id: args.multiRule.id,
|
|
"vmidipmap[0].vmid": args.item.id,
|
|
"vmidipmap[0].vmip": args.item.itemIp
|
|
};
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('removeFromLoadBalancerRule'),
|
|
data: inputData,
|
|
success: function(json) {
|
|
args.response.success({
|
|
notification: {
|
|
_custom: {
|
|
jobId: json.removefromloadbalancerruleresponse.jobid
|
|
},
|
|
desc: 'label.remove.vm.from.lb',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(json) {
|
|
args.response.error();
|
|
cloudStack.dialog.notice({
|
|
message: parseXMLHttpResponse(json)
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
dataProvider: function(args) {
|
|
var $multi = args.$multi;
|
|
|
|
$.ajax({
|
|
url: createURL('listLoadBalancerRules'),
|
|
data: {
|
|
publicipid: args.context.ipAddresses[0].id,
|
|
listAll: true
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var loadbalancerrules = data.listloadbalancerrulesresponse.loadbalancerrule;
|
|
|
|
$(loadbalancerrules).each(function() {
|
|
var lbRule = this;
|
|
var stickyData = {};
|
|
|
|
//var lbInstances = [];
|
|
var itemData = [];
|
|
|
|
// Passing _hideFields array will disable specified fields for this row
|
|
//lbRule._hideFields = ['autoScale'];
|
|
|
|
$.ajax({
|
|
url: createURL('listAutoScaleVmGroups'),
|
|
data: {
|
|
listAll: true,
|
|
lbruleid: lbRule.id
|
|
},
|
|
async: false,
|
|
success: function(json) {
|
|
if (json.listautoscalevmgroupsresponse.autoscalevmgroup != null && json.listautoscalevmgroupsresponse.autoscalevmgroup.length > 0) { //from 'autoScale' button
|
|
lbRule._hideFields = ['add-vm'];
|
|
} else { //from 'add-vm' button
|
|
lbRule._hideFields = ['autoScale'];
|
|
}
|
|
}
|
|
});
|
|
|
|
// Get sticky data
|
|
$.ajax({
|
|
url: createURL('listLBStickinessPolicies'),
|
|
async: false,
|
|
data: {
|
|
listAll: true,
|
|
lbruleid: lbRule.id
|
|
},
|
|
success: function(json) {
|
|
var stickyPolicy = json.listlbstickinesspoliciesresponse.stickinesspolicies ?
|
|
json.listlbstickinesspoliciesresponse.stickinesspolicies[0].stickinesspolicy : null;
|
|
|
|
if (stickyPolicy && stickyPolicy.length) {
|
|
stickyPolicy = stickyPolicy[0];
|
|
|
|
if (!stickyPolicy.methodname) stickyPolicy.methodname = 'None';
|
|
|
|
stickyData = {
|
|
_buttonLabel: stickyPolicy.methodname,
|
|
methodname: stickyPolicy.methodname,
|
|
stickyName: stickyPolicy.name,
|
|
id: stickyPolicy.id,
|
|
lbRuleID: lbRule.id
|
|
};
|
|
$.extend(stickyData, stickyPolicy.params);
|
|
} else {
|
|
stickyData = {
|
|
lbRuleID: lbRule.id
|
|
};
|
|
}
|
|
},
|
|
error: function(json) {
|
|
cloudStack.dialog.notice({
|
|
message: parseXMLHttpResponse(json)
|
|
});
|
|
}
|
|
});
|
|
|
|
// Get instances
|
|
$.ajax({
|
|
url: createURL('listLoadBalancerRuleInstances'),
|
|
dataType: 'json',
|
|
async: false,
|
|
data: {
|
|
listAll: true,
|
|
lbvmips: true,
|
|
id: lbRule.id
|
|
},
|
|
success: function(data) {
|
|
//when "lbvmips: true" is not passed to API
|
|
//lbVMs = data.listloadbalancerruleinstancesresponse.loadbalancerruleinstance;
|
|
|
|
//when "lbvmips: true" is passed to API
|
|
lbrulevmidips = data.listloadbalancerruleinstancesresponse.lbrulevmidip;
|
|
|
|
if (lbrulevmidips != null) {
|
|
for (var k = 0; k < lbrulevmidips.length; k++) {
|
|
var lbrulevmidip = lbrulevmidips[k];
|
|
var lbVM = lbrulevmidip.loadbalancerruleinstance;
|
|
if (lbVM.displayname.indexOf('AutoScale-LB-') > -1) //autoscale VM is not allowed to be deleted manually. So, hide destroy button
|
|
lbVM._hideActions = ['destroy'];
|
|
|
|
if (lbVM.servicestate) {
|
|
lbVM._itemStateLabel = 'label.service.state';
|
|
lbVM._itemState = lbVM.servicestate;
|
|
}
|
|
|
|
if (lbrulevmidip.lbvmipaddresses != null) {
|
|
for (var m = 0 ; m < lbrulevmidip.lbvmipaddresses.length; m++) {
|
|
var ip = lbrulevmidip.lbvmipaddresses[m];
|
|
itemData.push($.extend({}, lbVM, {
|
|
itemIp: ip
|
|
}));
|
|
}
|
|
} else {
|
|
itemData.push(lbVM);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
|
|
$.extend(lbRule, {
|
|
_itemName: 'name',
|
|
_itemIp: 'itemIp',
|
|
_itemData: itemData,
|
|
_maxLength: {
|
|
name: 7
|
|
},
|
|
sticky: stickyData,
|
|
autoScale: {
|
|
lbRuleID: lbRule.id
|
|
}
|
|
});
|
|
});
|
|
|
|
args.response.success({
|
|
data: loadbalancerrules
|
|
});
|
|
}
|
|
});
|
|
|
|
// Check if tiers are present; hide/show header drop-down (begin) ***
|
|
//dataProvider() is called when a LB rule is added in multiEdit. However, adding a LB rule might change parent object (IP Address object). So, we have to force to refresh args.context.ipAddresses[0] here
|
|
$.ajax({
|
|
url: createURL('listPublicIpAddresses'),
|
|
data: {
|
|
id: args.context.ipAddresses[0].id,
|
|
listAll: true
|
|
},
|
|
success: function(json) {
|
|
var ipObj = json.listpublicipaddressesresponse.publicipaddress[0];
|
|
getExtaPropertiesForIpObj(ipObj, args);
|
|
|
|
args.context.ipAddresses.shift(); //remove the first element in args.context.ipAddresses
|
|
args.context.ipAddresses.push(ipObj);
|
|
|
|
var $headerFields = $multi.find('.header-fields');
|
|
if ('vpc' in args.context) {
|
|
if (args.context.ipAddresses[0].associatednetworkid == null) {
|
|
$headerFields.show();
|
|
} else {
|
|
$headerFields.hide();
|
|
}
|
|
} else if ('networks' in args.context) {
|
|
$headerFields.hide();
|
|
}
|
|
}
|
|
});
|
|
// Check if tiers are present; hide/show header drop-down (end) ***
|
|
}
|
|
},
|
|
|
|
// Port forwarding rules
|
|
portForwarding: {
|
|
headerFields: {
|
|
tier: {
|
|
label: 'label.tier',
|
|
select: function(args) {
|
|
if ('vpc' in args.context) {
|
|
var data = {
|
|
//listAll: true, //do not pass listAll to listNetworks under VPC
|
|
supportedservices: 'PortForwarding'
|
|
};
|
|
if (args.context.ipAddresses[0].associatednetworkid == null) {
|
|
$.extend(data, {
|
|
vpcid: args.context.vpc[0].id,
|
|
domainid: args.context.vpc[0].domainid,
|
|
account: args.context.vpc[0].account
|
|
});
|
|
} else {
|
|
$.extend(data, {
|
|
id: args.context.ipAddresses[0].associatednetworkid
|
|
});
|
|
}
|
|
$.ajax({
|
|
url: createURL("listNetworks"),
|
|
data: data,
|
|
success: function(json) {
|
|
var networks = json.listnetworksresponse.network;
|
|
var items = [];
|
|
$(networks).each(function() {
|
|
items.push({
|
|
id: this.id,
|
|
description: this.displaytext
|
|
});
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
},
|
|
listView: $.extend(true, {}, cloudStack.sections.instances, {
|
|
listView: {
|
|
filters: false,
|
|
subselect: {
|
|
label: 'label.use.vm.ip',
|
|
dataProvider: singleVmSecondaryIPSubselect
|
|
},
|
|
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,
|
|
listAll: true,
|
|
networkid: networkid
|
|
};
|
|
|
|
if (!args.context.projects) {
|
|
$.extend(data, {
|
|
account: args.context.ipAddresses[0].account,
|
|
domainid: args.context.ipAddresses[0].domainid
|
|
});
|
|
}
|
|
|
|
$.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', 'Expunging'
|
|
]) == -1;
|
|
}
|
|
)
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}),
|
|
fields: {
|
|
//'private-ports': {
|
|
privateport: {
|
|
edit: true,
|
|
label: 'label.private.port',
|
|
//range: ['privateport', 'privateendport'] //Bug 13427 - Don't allow port forwarding ranges in the CreatePortForwardingRule API
|
|
range: ['privateport', 'privateendport'] //Bug 16344 (restore port range back) (http://bugs.cloudstack.org/browse/CS-16344)
|
|
},
|
|
//'public-ports': {
|
|
publicport: {
|
|
edit: true,
|
|
label: 'label.public.port',
|
|
//range: ['publicport', 'publicendport'] //Bug 13427 - Don't allow port forwarding ranges in the CreatePortForwardingRule API
|
|
range: ['publicport', 'publicendport'] //Bug 16344 (restore port range back) (http://bugs.cloudstack.org/browse/CS-16344)
|
|
},
|
|
'protocol': {
|
|
label: 'label.protocol',
|
|
select: function(args) {
|
|
args.response.success({
|
|
data: [{
|
|
name: 'tcp',
|
|
description: 'TCP'
|
|
}, {
|
|
name: 'udp',
|
|
description: 'UDP'
|
|
}]
|
|
});
|
|
}
|
|
},
|
|
'state' : {
|
|
edit: 'ignore',
|
|
label: 'label.state'
|
|
},
|
|
'add-vm': {
|
|
label: 'label.add.vm',
|
|
addButton: true
|
|
}
|
|
},
|
|
|
|
tags: cloudStack.api.tags({
|
|
resourceType: 'PortForwardingRule',
|
|
contextId: 'multiRule'
|
|
}),
|
|
|
|
add: {
|
|
label: 'label.add.vm',
|
|
|
|
action: function(args) {
|
|
var data = {
|
|
ipaddressid: args.context.ipAddresses[0].id,
|
|
privateport: args.data.privateport,
|
|
privateendport: args.data.privateendport,
|
|
publicport: args.data.publicport,
|
|
publicendport: args.data.publicendport,
|
|
protocol: args.data.protocol,
|
|
virtualmachineid: args.itemData[0].id,
|
|
openfirewall: false
|
|
};
|
|
|
|
if (args.context.ipAddresses[0].isportable) {
|
|
var subselect = args.itemData[0]._subselect.split(',');
|
|
//var networkid = subselect[0];
|
|
var vmguestip = subselect[1];
|
|
|
|
//data.networkid = networkid;
|
|
|
|
if (parseInt(vmguestip) !== -1) {
|
|
data.vmguestip = vmguestip;
|
|
}
|
|
} else if (args.itemData[0]._subselect && args.itemData[0]._subselect != -1) {
|
|
data.vmguestip = args.itemData[0]._subselect;
|
|
}
|
|
|
|
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
|
|
});
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('createPortForwardingRule'),
|
|
data: data,
|
|
success: function(data) {
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: data.createportforwardingruleresponse.jobid,
|
|
getUpdatedItem: function(json) {
|
|
return json.queryasyncjobresultresponse.jobresult.portforwardingrule;
|
|
}
|
|
},
|
|
notification: {
|
|
label: 'label.add.port.forwarding.rule',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
},
|
|
actions: {
|
|
destroy: {
|
|
label: 'label.remove.pf',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('deletePortForwardingRule'),
|
|
data: {
|
|
id: args.context.multiRule[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var jobID = data.deleteportforwardingruleresponse.jobid;
|
|
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobID
|
|
},
|
|
notification: {
|
|
label: 'label.remove.pf',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
dataProvider: function(args) {
|
|
var $multi = args.$multi;
|
|
|
|
$.ajax({
|
|
url: createURL('listPortForwardingRules'),
|
|
data: {
|
|
ipaddressid: args.context.ipAddresses[0].id,
|
|
listAll: true
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
// Get instance
|
|
var portForwardingData = data
|
|
.listportforwardingrulesresponse.portforwardingrule;
|
|
var loadTotal = portForwardingData ? portForwardingData.length : 0;
|
|
var loadCurrent = 0;
|
|
|
|
$(portForwardingData).each(function() {
|
|
var item = this;
|
|
|
|
item._itemName = '_displayName';
|
|
|
|
$.ajax({
|
|
url: createURL('listVirtualMachines'),
|
|
dataType: 'json',
|
|
async: true,
|
|
data: {
|
|
listAll: true,
|
|
id: item.virtualmachineid
|
|
},
|
|
success: function(data) {
|
|
loadCurrent++;
|
|
$.extend(item, {
|
|
_itemData: $.map(data.listvirtualmachinesresponse.virtualmachine, function(vm) {
|
|
return $.extend(vm, {
|
|
_displayName: '<p>VM: ' + vm.name + '</p>' + '<p>IP: ' + item.vmguestip + '</p>' // Also display attached IP
|
|
});
|
|
}),
|
|
_context: {
|
|
instances: data.listvirtualmachinesresponse.virtualmachine
|
|
}
|
|
});
|
|
|
|
if (loadCurrent == loadTotal) {
|
|
args.response.success({
|
|
data: portForwardingData
|
|
});
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
// Check if tiers are present; hide/show header drop-down (begin) ***
|
|
//dataProvider() is called when a PF rule is added in multiEdit. However, adding a LB rule might change parent object (IP Address object). So, we have to force to refresh args.context.ipAddresses[0] here
|
|
$.ajax({
|
|
url: createURL('listPublicIpAddresses'),
|
|
data: {
|
|
id: args.context.ipAddresses[0].id,
|
|
listAll: true
|
|
},
|
|
success: function(json) {
|
|
var ipObj = json.listpublicipaddressesresponse.publicipaddress[0];
|
|
getExtaPropertiesForIpObj(ipObj, args);
|
|
|
|
args.context.ipAddresses.shift(); //remove the first element in args.context.ipAddresses
|
|
args.context.ipAddresses.push(ipObj);
|
|
|
|
var $headerFields = $multi.find('.header-fields');
|
|
if ('vpc' in args.context) {
|
|
if (args.context.ipAddresses[0].associatednetworkid == null) {
|
|
$headerFields.show();
|
|
} else {
|
|
$headerFields.hide();
|
|
}
|
|
} else if ('networks' in args.context) {
|
|
$headerFields.hide();
|
|
}
|
|
}
|
|
});
|
|
// Check if tiers are present; hide/show header drop-down (end) ***
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
})
|
|
},
|
|
vpn: {
|
|
title: 'VPN',
|
|
custom: function(args) {
|
|
var ipAddress = args.context.ipAddresses[0].ipaddress;
|
|
var psk = "";
|
|
if (args.context.ipAddresses[0].remoteaccessvpn != null)
|
|
psk = args.context.ipAddresses[0].remoteaccessvpn.presharedkey;
|
|
|
|
return $('<div>')
|
|
.append(
|
|
$('<ul>').addClass('info')
|
|
.append(
|
|
// VPN IP
|
|
$('<li>').addClass('ip').html(_l('message.enabled.vpn') + ' ')
|
|
.append($('<strong>').html(ipAddress))
|
|
)
|
|
.append(
|
|
// PSK
|
|
$('<li>').addClass('psk').html(_l('message.enabled.vpn.ip.sec') + ' ')
|
|
.append($('<strong>').html(psk))
|
|
)
|
|
).multiEdit({
|
|
context: args.context,
|
|
noSelect: true,
|
|
fields: {
|
|
'username': {
|
|
edit: true,
|
|
label: 'label.username'
|
|
},
|
|
'password': {
|
|
edit: true,
|
|
isPassword: true,
|
|
label: 'label.password'
|
|
},
|
|
'add-user': {
|
|
addButton: true,
|
|
label: 'label.add.user'
|
|
}
|
|
},
|
|
add: {
|
|
label: 'label.add.user',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('addVpnUser'),
|
|
data: $.extend(args.data, {
|
|
domainid: args.context.ipAddresses[0].domainid,
|
|
account: args.context.ipAddresses[0].account
|
|
}),
|
|
dataType: 'json',
|
|
type: "POST",
|
|
success: function(data) {
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: data.addvpnuserresponse.jobid
|
|
},
|
|
notification: {
|
|
label: 'label.add.vpn.user',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
}
|
|
},
|
|
actions: {
|
|
destroy: {
|
|
label: 'label.action.delete.user',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('removeVpnUser'),
|
|
data: {
|
|
domainid: args.context.multiRule[0].domainid,
|
|
account: args.context.multiRule[0].account,
|
|
username: args.context.multiRule[0].username
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var jobID = data.removevpnuserresponse.jobid;
|
|
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobID
|
|
},
|
|
notification: {
|
|
label: 'label.delete.vpn.user',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
dataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL('listVpnUsers'),
|
|
data: {
|
|
domainid: args.context.ipAddresses[0].domainid,
|
|
account: args.context.ipAddresses[0].account
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success({
|
|
data: data.listvpnusersresponse.vpnuser
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
securityGroups: {
|
|
type: 'select',
|
|
title: 'label.menu.security.groups',
|
|
id: 'securityGroups',
|
|
listView: {
|
|
id: 'securityGroups',
|
|
label: 'label.menu.security.groups',
|
|
fields: {
|
|
name: {
|
|
label: 'label.name',
|
|
editable: true
|
|
},
|
|
description: {
|
|
label: 'label.description'
|
|
},
|
|
domain: {
|
|
label: 'label.domain'
|
|
},
|
|
account: {
|
|
label: 'label.account'
|
|
}
|
|
},
|
|
actions: {
|
|
add: {
|
|
label: 'label.add.security.group',
|
|
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('createSecurityGroup'),
|
|
data: {
|
|
name: args.data.name,
|
|
description: args.data.description
|
|
},
|
|
success: function(data) {
|
|
args.response.success({
|
|
data: data.createsecuritygroupresponse.securitygroup
|
|
});
|
|
},
|
|
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
|
|
notification: {
|
|
poll: function(args) {
|
|
args.complete({
|
|
actionFilter: actionFilters.securityGroups
|
|
});
|
|
}
|
|
},
|
|
|
|
messages: {
|
|
confirm: function(args) {
|
|
return 'Are you sure you want to add ' + args.name + '?';
|
|
},
|
|
notification: function(args) {
|
|
return 'label.add.security.group';
|
|
}
|
|
},
|
|
|
|
createForm: {
|
|
title: 'label.add.security.group',
|
|
desc: 'label.add.security.group',
|
|
fields: {
|
|
name: {
|
|
label: 'label.name'
|
|
},
|
|
description: {
|
|
label: 'label.description'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
advSearchFields: {
|
|
tagKey: {
|
|
label: 'label.tag.key'
|
|
},
|
|
tagValue: {
|
|
label: 'label.tag.value'
|
|
}
|
|
},
|
|
|
|
dataProvider: function(args) {
|
|
var data = {};
|
|
listViewDataProvider(args, data);
|
|
|
|
$.ajax({
|
|
url: createURL('listSecurityGroups'),
|
|
data: data,
|
|
success: function(json) {
|
|
var items = json.listsecuritygroupsresponse.securitygroup;
|
|
args.response.success({
|
|
actionFilter: actionFilters.securityGroups,
|
|
data: items
|
|
});
|
|
}
|
|
});
|
|
},
|
|
|
|
detailView: {
|
|
name: 'Security group details',
|
|
tabs: {
|
|
details: {
|
|
title: 'label.details',
|
|
fields: [{
|
|
name: {
|
|
label: 'label.name'
|
|
}
|
|
}, {
|
|
id: {
|
|
label: 'label.id'
|
|
},
|
|
description: {
|
|
label: 'label.description'
|
|
},
|
|
domain: {
|
|
label: 'label.domain'
|
|
},
|
|
account: {
|
|
label: 'label.account'
|
|
}
|
|
}],
|
|
|
|
tags: cloudStack.api.tags({
|
|
resourceType: 'SecurityGroup',
|
|
contextId: 'securityGroups'
|
|
}),
|
|
|
|
|
|
dataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL("listSecurityGroups&id=" + args.id),
|
|
dataType: "json",
|
|
async: true,
|
|
success: function(json) {
|
|
var items = json.listsecuritygroupsresponse.securitygroup;
|
|
if (items != null && items.length > 0) {
|
|
args.response.success({
|
|
actionFilter: actionFilters.securityGroups,
|
|
data: items[0]
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
},
|
|
ingressRules: {
|
|
title: 'label.ingress.rule',
|
|
custom: cloudStack.uiCustom.securityRules({
|
|
noSelect: true,
|
|
noHeaderActionsColumn: true,
|
|
fields: {
|
|
'protocol': {
|
|
label: 'label.protocol',
|
|
select: function(args) {
|
|
args.$select.change(function() {
|
|
var $inputs = args.$form.find('th, td');
|
|
var $icmpFields = $inputs.filter(function() {
|
|
var name = $(this).attr('rel');
|
|
|
|
return $.inArray(name, [
|
|
'icmptype',
|
|
'icmpcode'
|
|
]) > -1;
|
|
});
|
|
var $otherFields = $inputs.filter(function() {
|
|
var name = $(this).attr('rel');
|
|
|
|
return name != 'icmptype' &&
|
|
name != 'icmpcode' &&
|
|
name != 'protocol' &&
|
|
name != 'add-rule' &&
|
|
name != 'cidr' &&
|
|
name != 'accountname' &&
|
|
name != 'securitygroup';
|
|
});
|
|
|
|
if ($(this).val() == 'icmp') {
|
|
$icmpFields.show();
|
|
$otherFields.hide();
|
|
} else {
|
|
$icmpFields.hide();
|
|
$otherFields.show();
|
|
}
|
|
});
|
|
|
|
args.response.success({
|
|
data: [{
|
|
name: 'tcp',
|
|
description: 'TCP'
|
|
}, {
|
|
name: 'udp',
|
|
description: 'UDP'
|
|
}, {
|
|
name: 'icmp',
|
|
description: 'ICMP'
|
|
}]
|
|
});
|
|
}
|
|
},
|
|
'startport': {
|
|
edit: true,
|
|
label: 'label.start.port'
|
|
},
|
|
'endport': {
|
|
edit: true,
|
|
label: 'label.end.port'
|
|
},
|
|
'icmptype': {
|
|
edit: true,
|
|
label: 'ICMP.type',
|
|
isHidden: true
|
|
},
|
|
'icmpcode': {
|
|
edit: true,
|
|
label: 'ICMP.code',
|
|
isHidden: true
|
|
},
|
|
'cidr': {
|
|
edit: true,
|
|
label: 'label.cidr',
|
|
isHidden: true
|
|
},
|
|
'accountname': {
|
|
edit: true,
|
|
label: 'label.account.and.security.group',
|
|
isHidden: true,
|
|
range: ['accountname', 'securitygroup']
|
|
},
|
|
'add-rule': {
|
|
label: 'label.add',
|
|
addButton: true
|
|
}
|
|
},
|
|
add: {
|
|
label: 'label.add',
|
|
action: function(args) {
|
|
var data = {
|
|
securitygroupid: args.context.securityGroups[0].id,
|
|
protocol: args.data.protocol,
|
|
domainid: args.context.securityGroups[0].domainid,
|
|
account: args.context.securityGroups[0].account
|
|
};
|
|
|
|
if (args.data.icmptype && args.data.icmpcode) { // ICMP
|
|
$.extend(data, {
|
|
icmptype: args.data.icmptype,
|
|
icmpcode: args.data.icmpcode
|
|
});
|
|
} else { // TCP/UDP
|
|
$.extend(data, {
|
|
startport: args.data.startport,
|
|
endport: args.data.endport
|
|
});
|
|
}
|
|
|
|
// CIDR / account
|
|
if (args.data.cidr) {
|
|
data.cidrlist = args.data.cidr;
|
|
} else {
|
|
data['usersecuritygrouplist[0].account'] = args.data.accountname;
|
|
data['usersecuritygrouplist[0].group'] = args.data.securitygroup;
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('authorizeSecurityGroupIngress'),
|
|
data: data,
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var jobId = data.authorizesecuritygroupingressresponse.jobid;
|
|
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobId
|
|
},
|
|
notification: {
|
|
label: 'label.add.ingress.rule',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
actions: {
|
|
destroy: {
|
|
label: 'label.remove.rule',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('revokeSecurityGroupIngress'),
|
|
data: {
|
|
domainid: args.context.securityGroups[0].domainid,
|
|
account: args.context.securityGroups[0].account,
|
|
id: args.context.multiRule[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var jobID = data.revokesecuritygroupingressresponse.jobid;
|
|
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobID
|
|
},
|
|
notification: {
|
|
label: 'label.remove.ingress.rule',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(json) {
|
|
args.response.error(parseXMLHttpResponse(json));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
ignoreEmptyFields: true,
|
|
dataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL('listSecurityGroups'),
|
|
data: {
|
|
id: args.context.securityGroups[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success({
|
|
data: $.map(
|
|
data.listsecuritygroupsresponse.securitygroup[0].ingressrule ?
|
|
data.listsecuritygroupsresponse.securitygroup[0].ingressrule : [],
|
|
ingressEgressDataMap
|
|
)
|
|
});
|
|
}
|
|
});
|
|
}
|
|
})
|
|
},
|
|
|
|
egressRules: {
|
|
title: 'label.egress.rule',
|
|
custom: cloudStack.uiCustom.securityRules({
|
|
noSelect: true,
|
|
noHeaderActionsColumn: true,
|
|
fields: {
|
|
'protocol': {
|
|
label: 'label.protocol',
|
|
select: function(args) {
|
|
args.$select.change(function() {
|
|
var $inputs = args.$form.find('th, td');
|
|
var $icmpFields = $inputs.filter(function() {
|
|
var name = $(this).attr('rel');
|
|
|
|
return $.inArray(name, [
|
|
'icmptype',
|
|
'icmpcode'
|
|
]) > -1;
|
|
});
|
|
var $otherFields = $inputs.filter(function() {
|
|
var name = $(this).attr('rel');
|
|
|
|
return name != 'icmptype' &&
|
|
name != 'icmpcode' &&
|
|
name != 'protocol' &&
|
|
name != 'add-rule' &&
|
|
name != 'cidr' &&
|
|
name != 'accountname' &&
|
|
name != 'securitygroup';
|
|
});
|
|
|
|
if ($(this).val() == 'icmp') {
|
|
$icmpFields.show();
|
|
$otherFields.hide();
|
|
} else {
|
|
$icmpFields.hide();
|
|
$otherFields.show();
|
|
}
|
|
});
|
|
|
|
args.response.success({
|
|
data: [{
|
|
name: 'tcp',
|
|
description: 'TCP'
|
|
}, {
|
|
name: 'udp',
|
|
description: 'UDP'
|
|
}, {
|
|
name: 'icmp',
|
|
description: 'ICMP'
|
|
}]
|
|
});
|
|
}
|
|
},
|
|
'startport': {
|
|
edit: true,
|
|
label: 'label.start.port'
|
|
},
|
|
'endport': {
|
|
edit: true,
|
|
label: 'label.end.port'
|
|
},
|
|
'icmptype': {
|
|
edit: true,
|
|
label: 'ICMP.type',
|
|
isHidden: true
|
|
},
|
|
'icmpcode': {
|
|
edit: true,
|
|
label: 'ICMP.code',
|
|
isHidden: true
|
|
},
|
|
'cidr': {
|
|
edit: true,
|
|
label: 'label.cidr',
|
|
isHidden: true
|
|
},
|
|
'accountname': {
|
|
edit: true,
|
|
label: 'label.account.and.security.group',
|
|
isHidden: true,
|
|
range: ['accountname', 'securitygroup']
|
|
},
|
|
'add-rule': {
|
|
label: 'label.add',
|
|
addButton: true
|
|
}
|
|
},
|
|
add: {
|
|
label: 'label.add',
|
|
action: function(args) {
|
|
var data = {
|
|
securitygroupid: args.context.securityGroups[0].id,
|
|
protocol: args.data.protocol,
|
|
domainid: args.context.securityGroups[0].domainid,
|
|
account: args.context.securityGroups[0].account
|
|
};
|
|
|
|
if (args.data.icmptype && args.data.icmpcode) { // ICMP
|
|
$.extend(data, {
|
|
icmptype: args.data.icmptype,
|
|
icmpcode: args.data.icmpcode
|
|
});
|
|
} else { // TCP/UDP
|
|
$.extend(data, {
|
|
startport: args.data.startport,
|
|
endport: args.data.endport
|
|
});
|
|
}
|
|
|
|
// CIDR / account
|
|
if (args.data.cidr) {
|
|
data.cidrlist = args.data.cidr;
|
|
} else {
|
|
data['usersecuritygrouplist[0].account'] = args.data.accountname;
|
|
data['usersecuritygrouplist[0].group'] = args.data.securitygroup;
|
|
}
|
|
|
|
$.ajax({
|
|
url: createURL('authorizeSecurityGroupEgress'),
|
|
data: data,
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var jobId = data.authorizesecuritygroupegressresponse.jobid;
|
|
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobId
|
|
},
|
|
notification: {
|
|
label: 'label.add.egress.rule',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
actions: {
|
|
destroy: {
|
|
label: 'label.remove.rule',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('revokeSecurityGroupEgress'),
|
|
data: {
|
|
domainid: args.context.securityGroups[0].domainid,
|
|
account: args.context.securityGroups[0].account,
|
|
id: args.context.multiRule[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
var jobID = data.revokesecuritygroupegressresponse.jobid;
|
|
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobID
|
|
},
|
|
notification: {
|
|
label: 'label.remove.egress.rule',
|
|
poll: pollAsyncJobResult
|
|
}
|
|
});
|
|
},
|
|
error: function(json) {
|
|
args.response.error(parseXMLHttpResponse(json));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
ignoreEmptyFields: true,
|
|
dataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL('listSecurityGroups'),
|
|
data: {
|
|
id: args.context.securityGroups[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success({
|
|
data: $.map(
|
|
data.listsecuritygroupsresponse.securitygroup[0].egressrule ?
|
|
data.listsecuritygroupsresponse.securitygroup[0].egressrule : [],
|
|
ingressEgressDataMap
|
|
)
|
|
});
|
|
}
|
|
});
|
|
}
|
|
})
|
|
}
|
|
},
|
|
|
|
actions: {
|
|
remove: {
|
|
label: 'label.action.delete.security.group',
|
|
messages: {
|
|
confirm: function(args) {
|
|
return 'message.action.delete.security.group';
|
|
},
|
|
notification: function(args) {
|
|
return 'label.action.delete.security.group';
|
|
}
|
|
},
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('deleteSecurityGroup'),
|
|
data: {
|
|
id: args.context.securityGroups[0].id
|
|
},
|
|
dataType: 'json',
|
|
async: true,
|
|
success: function(data) {
|
|
args.response.success();
|
|
},
|
|
error: function(json) {
|
|
args.response.error(parseXMLHttpResponse(json));
|
|
}
|
|
});
|
|
},
|
|
|
|
notification: {
|
|
poll: function(args) {
|
|
args.complete({
|
|
data: {
|
|
state: 'Destroyed'
|
|
},
|
|
actionFilter: actionFilters.securityGroups
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
vpc: {
|
|
type: 'select',
|
|
title: 'label.vpc',
|
|
id: 'vpc',
|
|
listView: {
|
|
id: 'vpc',
|
|
label: 'label.vpc',
|
|
fields: {
|
|
name: {
|
|
label: 'label.name'
|
|
},
|
|
displaytext: {
|
|
label: 'label.description',
|
|
truncate: true
|
|
},
|
|
zonename: {
|
|
label: 'label.zone',
|
|
truncate: true
|
|
},
|
|
cidr: {
|
|
label: 'label.cidr'
|
|
},
|
|
state: {
|
|
label: 'label.state',
|
|
indicator: {
|
|
'Enabled': 'on',
|
|
'Disabled': 'off'
|
|
}
|
|
}
|
|
},
|
|
|
|
advSearchFields: {
|
|
name: {
|
|
label: 'label.name'
|
|
},
|
|
zoneid: {
|
|
label: 'label.zone',
|
|
select: function(args) {
|
|
$.ajax({
|
|
url: createURL('listZones'),
|
|
data: {
|
|
listAll: true
|
|
},
|
|
success: function(json) {
|
|
var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : [];
|
|
|
|
args.response.success({
|
|
data: $.map(zones, function(zone) {
|
|
return {
|
|
id: zone.id,
|
|
description: zone.name
|
|
};
|
|
})
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
domainid: {
|
|
label: 'label.domain',
|
|
select: function(args) {
|
|
if (isAdmin() || isDomainAdmin()) {
|
|
$.ajax({
|
|
url: createURL('listDomains'),
|
|
data: {
|
|
listAll: true,
|
|
details: 'min'
|
|
},
|
|
success: function(json) {
|
|
var array1 = [{
|
|
id: '',
|
|
description: ''
|
|
}];
|
|
var domains = json.listdomainsresponse.domain;
|
|
if (domains != null && domains.length > 0) {
|
|
for (var i = 0; i < domains.length; i++) {
|
|
array1.push({
|
|
id: domains[i].id,
|
|
description: domains[i].path
|
|
});
|
|
}
|
|
}
|
|
args.response.success({
|
|
data: array1
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
args.response.success({
|
|
data: null
|
|
});
|
|
}
|
|
},
|
|
isHidden: function(args) {
|
|
if (isAdmin() || isDomainAdmin())
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
},
|
|
|
|
account: {
|
|
label: 'label.account',
|
|
isHidden: function(args) {
|
|
if (isAdmin() || isDomainAdmin())
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
},
|
|
tagKey: {
|
|
label: 'label.tag.key'
|
|
},
|
|
tagValue: {
|
|
label: 'label.tag.value'
|
|
}
|
|
},
|
|
|
|
dataProvider: function(args) {
|
|
var data = {};
|
|
listViewDataProvider(args, data);
|
|
|
|
$.ajax({
|
|
url: createURL('listVPCs'),
|
|
data: data,
|
|
success: function(json) {
|
|
var items = json.listvpcsresponse.vpc ? json.listvpcsresponse.vpc : { };
|
|
|
|
//If we are coming from Home > Regions, show only regional vpcs
|
|
if (args.context.regions)
|
|
items = $.grep(
|
|
items,
|
|
function (vpc, i) {
|
|
return vpc.regionlevelvpc;
|
|
});
|
|
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
});
|
|
},
|
|
actions: {
|
|
add: {
|
|
label: 'label.add.vpc',
|
|
messages: {
|
|
notification: function(args) {
|
|
return 'label.add.vpc';
|
|
}
|
|
},
|
|
createForm: {
|
|
title: 'label.add.vpc',
|
|
messages: {
|
|
notification: function(args) {
|
|
return 'label.add.vpc';
|
|
}
|
|
},
|
|
fields: {
|
|
name: {
|
|
label: 'label.name',
|
|
docID: 'helpVPCName',
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
displaytext: {
|
|
label: 'label.description',
|
|
docID: 'helpVPCDescription',
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
zoneid: {
|
|
label: 'label.zone',
|
|
docID: 'helpVPCZone',
|
|
validation: {
|
|
required: true
|
|
},
|
|
select: function(args) {
|
|
var data = {
|
|
listAll: true
|
|
};
|
|
$.ajax({
|
|
url: createURL('listZones'),
|
|
data: data,
|
|
success: function(json) {
|
|
var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : [];
|
|
var advZones = $.grep(zones, function(zone) {
|
|
return zone.networktype == 'Advanced' && !zone.securitygroupsenabled;
|
|
});
|
|
args.response.success({
|
|
data: $.map(advZones, function(zone) {
|
|
return {
|
|
id: zone.id,
|
|
description: zone.name
|
|
};
|
|
})
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
cidr: {
|
|
label: 'label.super.cidr.for.guest.networks',
|
|
docID: 'helpVPCSuperCIDR',
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
networkdomain: {
|
|
docID: 'helpVPCDomain',
|
|
label: 'label.DNS.domain.for.guest.networks'
|
|
},
|
|
publicLoadBalancerProvider: {
|
|
label: 'label.public.load.balancer.provider',
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: 'VpcVirtualRouter',
|
|
description: 'VpcVirtualRouter'
|
|
});
|
|
items.push({
|
|
id: 'Netscaler',
|
|
description: 'Netscaler'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
vpcoffering: {
|
|
label: 'label.vpc.offering',
|
|
validation: {
|
|
required: true
|
|
},
|
|
|
|
select: function(args) {
|
|
var data = {
|
|
listAll: true
|
|
};
|
|
$.ajax({
|
|
url: createURL('listVPCOfferings'),
|
|
data: {
|
|
listAll: true
|
|
},
|
|
success: function(json) {
|
|
var offerings = json.listvpcofferingsresponse.vpcoffering ? json.listvpcofferingsresponse.vpcoffering : [];
|
|
var filteredofferings = $.grep(offerings, function(offering) {
|
|
return offering.state == 'Enabled';
|
|
});
|
|
args.response.success({
|
|
data: $.map(filteredofferings, function(vpco) {
|
|
return {
|
|
id: vpco.id,
|
|
description: vpco.name
|
|
};
|
|
})
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
},
|
|
action: function(args) {
|
|
var vpcOfferingName = args.data.vpcoffering
|
|
var dataObj = {
|
|
name: args.data.name,
|
|
displaytext: args.data.displaytext,
|
|
zoneid: args.data.zoneid,
|
|
cidr: args.data.cidr,
|
|
vpcofferingid: args.data.vpcoffering
|
|
};
|
|
|
|
if (args.data.networkdomain != null && args.data.networkdomain.length > 0)
|
|
$.extend(dataObj, {
|
|
networkdomain: args.data.networkdomain
|
|
});
|
|
|
|
$.ajax({
|
|
url: createURL("createVPC"),
|
|
dataType: "json",
|
|
data: dataObj,
|
|
async: true,
|
|
success: function(json) {
|
|
var jid = json.createvpcresponse.jobid;
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jid,
|
|
getUpdatedItem: function(json) {
|
|
return json.queryasyncjobresultresponse.jobresult.vpc;
|
|
}
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
|
|
},
|
|
configureVpc: {
|
|
label: 'label.configure.vpc',
|
|
textLabel: 'label.configure',
|
|
action: {
|
|
custom: cloudStack.uiCustom.vpc(cloudStack.vpc)
|
|
}
|
|
}
|
|
},
|
|
|
|
detailView: {
|
|
name: 'label.details',
|
|
actions: {
|
|
configureVpc: {
|
|
label: 'label.configure',
|
|
textLabel: 'label.configure',
|
|
action: {
|
|
custom: cloudStack.uiCustom.vpc(cloudStack.vpc)
|
|
},
|
|
messages: {
|
|
notification: function() {
|
|
return '';
|
|
}
|
|
}
|
|
},
|
|
|
|
edit: {
|
|
label: 'label.edit',
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL('updateVPC'),
|
|
data: {
|
|
id: args.context.vpc[0].id,
|
|
name: args.data.name,
|
|
displaytext: args.data.displaytext
|
|
},
|
|
success: function(json) {
|
|
var jid = json.updatevpcresponse.jobid;
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jid,
|
|
getUpdatedItem: function(json) {
|
|
return json.queryasyncjobresultresponse.jobresult.vpc;
|
|
}
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
},
|
|
|
|
restart: {
|
|
label: 'label.restart.vpc',
|
|
messages: {
|
|
confirm: function(args) {
|
|
return 'message.restart.vpc';
|
|
},
|
|
notification: function(args) {
|
|
return 'label.restart.vpc';
|
|
}
|
|
},
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL("restartVPC"),
|
|
data: {
|
|
id: args.context.vpc[0].id
|
|
},
|
|
success: function(json) {
|
|
var jid = json.restartvpcresponse.jobid;
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jid,
|
|
getUpdatedItem: function(json) {
|
|
return json.queryasyncjobresultresponse.jobresult.vpc;
|
|
}
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
},
|
|
|
|
remove: {
|
|
label: 'label.remove.vpc',
|
|
messages: {
|
|
confirm: function(args) {
|
|
return 'message.remove.vpc';
|
|
},
|
|
notification: function(args) {
|
|
return 'label.remove.vpc';
|
|
}
|
|
},
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL("deleteVPC"),
|
|
data: {
|
|
id: args.context.vpc[0].id
|
|
},
|
|
success: function(json) {
|
|
var jid = json.deletevpcresponse.jobid;
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jid
|
|
}
|
|
});
|
|
},
|
|
error: function(data) {
|
|
args.response.error(parseXMLHttpResponse(data));
|
|
}
|
|
});
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
}
|
|
},
|
|
|
|
tabFilter: function(args) {
|
|
var hiddenTabs = [];
|
|
var isRouterOwner = isAdmin();
|
|
if (!isRouterOwner)
|
|
hiddenTabs.push("router");
|
|
return hiddenTabs;
|
|
},
|
|
|
|
tabs: {
|
|
details: {
|
|
title: 'label.details',
|
|
fields: [{
|
|
name: {
|
|
label: 'label.name',
|
|
isEditable: true
|
|
}
|
|
}, {
|
|
displaytext: {
|
|
label: 'label.description',
|
|
isEditable: true
|
|
},
|
|
account: {
|
|
label: 'label.account'
|
|
},
|
|
domain: {
|
|
label: 'label.domain'
|
|
},
|
|
zonename: {
|
|
label: 'label.zone'
|
|
},
|
|
cidr: {
|
|
label: 'label.cidr'
|
|
},
|
|
networkdomain: {
|
|
label: 'label.network.domain'
|
|
},
|
|
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>";
|
|
}
|
|
|
|
return "No";
|
|
}
|
|
},
|
|
id: {
|
|
label: 'label.id'
|
|
}
|
|
}],
|
|
|
|
tags: cloudStack.api.tags({
|
|
resourceType: 'Vpc',
|
|
contextId: 'vpc'
|
|
}),
|
|
|
|
dataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL("listVPCs"),
|
|
dataType: "json",
|
|
data: {
|
|
id: args.context.vpc[0].id
|
|
},
|
|
async: true,
|
|
success: function(json) {
|
|
var item = json.listvpcsresponse.vpc[0];
|
|
args.response.success({
|
|
data: item
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
router: {
|
|
title: 'VPC Router Details',
|
|
fields: [{
|
|
name: {
|
|
label: 'label.name'
|
|
}
|
|
}, {
|
|
id: {
|
|
label: 'label.id'
|
|
},
|
|
zonename: {
|
|
label: 'label.zone'
|
|
},
|
|
dns1: {
|
|
label: 'label.dns'
|
|
},
|
|
gateway: {
|
|
label: 'label.gateway'
|
|
},
|
|
publicip: {
|
|
label: 'label.public.ip'
|
|
},
|
|
guestipaddress: {
|
|
label: 'label.guest.ip'
|
|
},
|
|
linklocalip: {
|
|
label: 'label.linklocal.ip'
|
|
},
|
|
state: {
|
|
label: 'label.state'
|
|
},
|
|
serviceofferingname: {
|
|
label: 'label.service.offering'
|
|
},
|
|
isredundantrouter: {
|
|
label: 'label.redundant.router',
|
|
converter: function(booleanValue) {
|
|
if (booleanValue == true) {
|
|
return "<font color='red'>Yes</font>";
|
|
}
|
|
return "No";
|
|
}
|
|
},
|
|
account: {
|
|
label: 'label.account'
|
|
},
|
|
domain: {
|
|
label: 'label.domain'
|
|
}
|
|
}],
|
|
dataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL("listRouters&listAll=true&vpcid=" + args.context.vpc[0].id),
|
|
dataType: "json",
|
|
async: true,
|
|
success: function(json) {
|
|
var item = json.listroutersresponse.router[0];
|
|
|
|
args.response.success({
|
|
actionFilter: cloudStack.sections.system.routerActionFilter,
|
|
data: item
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
vpnCustomerGateway: {
|
|
type: 'select',
|
|
title: 'label.vpn.customer.gateway',
|
|
listView: {
|
|
id: 'vpnCustomerGateway',
|
|
label: 'label.vpn.customer.gateway',
|
|
fields: {
|
|
name: {
|
|
label: 'label.name'
|
|
},
|
|
gateway: {
|
|
label: 'label.gateway'
|
|
},
|
|
cidrlist: {
|
|
label: 'label.CIDR.list'
|
|
},
|
|
ipsecpsk: {
|
|
label: 'label.IPsec.preshared.key'
|
|
}
|
|
},
|
|
|
|
dataProvider: function(args) {
|
|
var data = {};
|
|
listViewDataProvider(args, data);
|
|
|
|
$.ajax({
|
|
url: createURL('listVpnCustomerGateways'),
|
|
data: data,
|
|
async: true,
|
|
success: function(json) {
|
|
var items = json.listvpncustomergatewaysresponse.vpncustomergateway;
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
});
|
|
},
|
|
|
|
actions: {
|
|
add: {
|
|
label: 'label.add.vpn.customer.gateway',
|
|
messages: {
|
|
notification: function(args) {
|
|
return 'label.add.vpn.customer.gateway';
|
|
}
|
|
},
|
|
createForm: {
|
|
title: 'label.add.vpn.customer.gateway',
|
|
fields: {
|
|
name: {
|
|
label: 'label.name',
|
|
docID: 'helpVPNGatewayName',
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
gateway: {
|
|
label: 'label.gateway',
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
cidrlist: {
|
|
label: 'label.CIDR.list',
|
|
desc: 'message.enter.seperated.list.multiple.cidrs',
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
gateway: {
|
|
label: 'label.gateway',
|
|
docID: 'helpVPNGatewayGateway',
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
cidrlist: {
|
|
label: 'label.CIDR.list',
|
|
desc: 'message.enter.seperated.list.multiple.cidrs',
|
|
docID: 'helpVPNGatewayCIDRList',
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
ipsecpsk: {
|
|
label: 'label.IPsec.preshared.key',
|
|
docID: 'helpVPNGatewayIPsecPresharedKey',
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
|
|
//IKE Policy
|
|
ikeEncryption: {
|
|
label: 'label.IKE.encryption',
|
|
docID: 'helpVPNGatewayIKEEncryption',
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: '3des',
|
|
description: '3des'
|
|
});
|
|
items.push({
|
|
id: 'aes128',
|
|
description: 'aes128'
|
|
});
|
|
items.push({
|
|
id: 'aes192',
|
|
description: 'aes192'
|
|
});
|
|
items.push({
|
|
id: 'aes256',
|
|
description: 'aes256'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
ikeHash: {
|
|
label: 'label.IKE.hash',
|
|
docID: 'helpVPNGatewayIKEHash',
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: 'md5',
|
|
description: 'md5'
|
|
});
|
|
items.push({
|
|
id: 'sha1',
|
|
description: 'sha1'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
ikeDh: {
|
|
label: 'label.IKE.DH',
|
|
docID: 'helpVPNGatewayIKEDH',
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: '',
|
|
description: 'None'
|
|
});
|
|
items.push({
|
|
id: 'modp1024',
|
|
description: 'Group 2(modp1024)'
|
|
});
|
|
items.push({
|
|
id: 'modp1536',
|
|
description: 'Group 5(modp1536)'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
|
|
//ESP Policy
|
|
espEncryption: {
|
|
label: 'label.ESP.encryption',
|
|
docID: 'helpVPNGatewayESPLifetime',
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: '3des',
|
|
description: '3des'
|
|
});
|
|
items.push({
|
|
id: 'aes128',
|
|
description: 'aes128'
|
|
});
|
|
items.push({
|
|
id: 'aes192',
|
|
description: 'aes192'
|
|
});
|
|
items.push({
|
|
id: 'aes256',
|
|
description: 'aes256'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
espHash: {
|
|
label: 'label.ESP.hash',
|
|
docID: 'helpVPNGatewayESPHash',
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: 'md5',
|
|
description: 'md5'
|
|
});
|
|
items.push({
|
|
id: 'sha1',
|
|
description: 'sha1'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
perfectForwardSecrecy: {
|
|
label: 'label.perfect.forward.secrecy',
|
|
docID: 'helpVPNGatewayPerfectForwardSecrecy',
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: '',
|
|
description: 'None'
|
|
});
|
|
items.push({
|
|
id: 'modp1024',
|
|
description: 'Group 2(modp1024)'
|
|
});
|
|
items.push({
|
|
id: 'modp1536',
|
|
description: 'Group 5(modp1536)'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
|
|
ikelifetime: {
|
|
label: 'label.IKE.lifetime',
|
|
docID: 'helpVPNGatewayIKELifetime',
|
|
defaultValue: '86400',
|
|
validation: {
|
|
required: false,
|
|
number: true
|
|
}
|
|
},
|
|
esplifetime: {
|
|
label: 'label.ESP.lifetime',
|
|
docID: 'helpVPNGatewayESPLifetime',
|
|
defaultValue: '3600',
|
|
validation: {
|
|
required: false,
|
|
number: true
|
|
}
|
|
},
|
|
|
|
dpd: {
|
|
label: 'label.dead.peer.detection',
|
|
docID: 'helpVPNGatewayDeadPeerDetection',
|
|
isBoolean: true,
|
|
isChecked: false
|
|
}
|
|
}
|
|
},
|
|
action: function(args) {
|
|
var data = {
|
|
name: args.data.name,
|
|
gateway: args.data.gateway,
|
|
cidrlist: args.data.cidrlist,
|
|
ipsecpsk: args.data.ipsecpsk,
|
|
ikelifetime: args.data.ikelifetime,
|
|
esplifetime: args.data.esplifetime,
|
|
dpd: (args.data.dpd == "on")
|
|
};
|
|
|
|
var ikepolicy = args.data.ikeEncryption + '-' + args.data.ikeHash;
|
|
if (args.data.ikeDh != null && args.data.ikeDh.length > 0)
|
|
ikepolicy += ';' + args.data.ikeDh;
|
|
|
|
$.extend(data, {
|
|
ikepolicy: ikepolicy
|
|
});
|
|
|
|
var esppolicy = args.data.espEncryption + '-' + args.data.espHash;
|
|
if (args.data.perfectForwardSecrecy != null && args.data.perfectForwardSecrecy.length > 0)
|
|
esppolicy += ';' + args.data.perfectForwardSecrecy;
|
|
|
|
$.extend(data, {
|
|
esppolicy: esppolicy
|
|
});
|
|
|
|
$.ajax({
|
|
url: createURL('createVpnCustomerGateway'),
|
|
data: data,
|
|
dataType: 'json',
|
|
success: function(json) {
|
|
var jid = json.createvpncustomergatewayresponse.jobid;
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jid,
|
|
getUpdatedItem: function(json) {
|
|
return json.queryasyncjobresultresponse.jobresult.vpncustomergateway;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
}
|
|
},
|
|
|
|
detailView: {
|
|
name: 'label.details',
|
|
actions: {
|
|
edit: {
|
|
label: 'label.edit',
|
|
action: function(args) {
|
|
var data = {
|
|
id: args.context.vpnCustomerGateway[0].id,
|
|
name: args.data.name,
|
|
gateway: args.data.gateway,
|
|
cidrlist: args.data.cidrlist,
|
|
ipsecpsk: args.data.ipsecpsk,
|
|
ikelifetime: args.data.ikelifetime,
|
|
esplifetime: args.data.esplifetime,
|
|
dpd: (args.data.dpd == "on")
|
|
};
|
|
|
|
var ikepolicy = args.data.ikeEncryption + '-' + args.data.ikeHash;
|
|
if (args.data.ikeDh != null && args.data.ikeDh.length > 0)
|
|
ikepolicy += ';' + args.data.ikeDh;
|
|
|
|
$.extend(data, {
|
|
ikepolicy: ikepolicy
|
|
});
|
|
|
|
var esppolicy = args.data.espEncryption + '-' + args.data.espHash;
|
|
if (args.data.perfectForwardSecrecy != null && args.data.perfectForwardSecrecy.length > 0)
|
|
esppolicy += ';' + args.data.perfectForwardSecrecy;
|
|
|
|
$.extend(data, {
|
|
esppolicy: esppolicy
|
|
});
|
|
|
|
$.ajax({
|
|
url: createURL('updateVpnCustomerGateway'),
|
|
data: data,
|
|
success: function(json) {
|
|
var jobId = json.updatecustomergatewayresponse.jobid;
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jobId,
|
|
getUpdatedItem: function(json) {
|
|
var item = json.queryasyncjobresultresponse.jobresult.vpncustomergateway;
|
|
args.response.success({
|
|
data: item
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
},
|
|
|
|
remove: {
|
|
label: 'label.delete.VPN.customer.gateway',
|
|
messages: {
|
|
confirm: function(args) {
|
|
return 'message.delete.VPN.customer.gateway';
|
|
},
|
|
notification: function(args) {
|
|
return 'label.delete.VPN.customer.gateway';
|
|
}
|
|
},
|
|
action: function(args) {
|
|
$.ajax({
|
|
url: createURL("deleteVpnCustomerGateway"),
|
|
data: {
|
|
id: args.context.vpnCustomerGateway[0].id
|
|
},
|
|
success: function(json) {
|
|
var jid = json.deletevpncustomergatewayresponse.jobid;
|
|
args.response.success({
|
|
_custom: {
|
|
jobId: jid
|
|
}
|
|
});
|
|
}
|
|
});
|
|
},
|
|
notification: {
|
|
poll: pollAsyncJobResult
|
|
}
|
|
}
|
|
},
|
|
|
|
tabs: {
|
|
details: {
|
|
title: 'label.details',
|
|
fields: [{
|
|
name: {
|
|
label: 'label.name',
|
|
isEditable: true,
|
|
validation: {
|
|
required: true
|
|
}
|
|
}
|
|
}, {
|
|
gateway: {
|
|
label: 'label.gateway',
|
|
isEditable: true,
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
cidrlist: {
|
|
label: 'label.CIDR.list',
|
|
isEditable: true,
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
ipsecpsk: {
|
|
label: 'label.IPsec.preshared.key',
|
|
isEditable: true,
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
|
|
//IKE Policy
|
|
ikeEncryption: {
|
|
label: 'label.IKE.encryption',
|
|
isEditable: true,
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: '3des',
|
|
description: '3des'
|
|
});
|
|
items.push({
|
|
id: 'aes128',
|
|
description: 'aes128'
|
|
});
|
|
items.push({
|
|
id: 'aes192',
|
|
description: 'aes192'
|
|
});
|
|
items.push({
|
|
id: 'aes256',
|
|
description: 'aes256'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
ikeHash: {
|
|
label: 'label.IKE.hash',
|
|
isEditable: true,
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: 'md5',
|
|
description: 'md5'
|
|
});
|
|
items.push({
|
|
id: 'sha1',
|
|
description: 'sha1'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
ikeDh: {
|
|
label: 'label.IKE.DH',
|
|
isEditable: true,
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: '',
|
|
description: 'None'
|
|
});
|
|
items.push({
|
|
id: 'modp1024',
|
|
description: 'Group 2(modp1024)'
|
|
});
|
|
items.push({
|
|
id: 'modp1536',
|
|
description: 'Group 5(modp1536)'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
|
|
//ESP Policy
|
|
espEncryption: {
|
|
label: 'label.ESP.encryption',
|
|
isEditable: true,
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: '3des',
|
|
description: '3des'
|
|
});
|
|
items.push({
|
|
id: 'aes128',
|
|
description: 'aes128'
|
|
});
|
|
items.push({
|
|
id: 'aes192',
|
|
description: 'aes192'
|
|
});
|
|
items.push({
|
|
id: 'aes256',
|
|
description: 'aes256'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
espHash: {
|
|
label: 'label.ESP.hash',
|
|
isEditable: true,
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: 'md5',
|
|
description: 'md5'
|
|
});
|
|
items.push({
|
|
id: 'sha1',
|
|
description: 'sha1'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
perfectForwardSecrecy: {
|
|
label: 'label.perfect.forward.secrecy',
|
|
isEditable: true,
|
|
select: function(args) {
|
|
var items = [];
|
|
items.push({
|
|
id: '',
|
|
description: 'None'
|
|
});
|
|
items.push({
|
|
id: 'modp1024',
|
|
description: 'Group 2(modp1024)'
|
|
});
|
|
items.push({
|
|
id: 'modp1536',
|
|
description: 'Group 5(modp1536)'
|
|
});
|
|
args.response.success({
|
|
data: items
|
|
});
|
|
}
|
|
},
|
|
|
|
ikelifetime: {
|
|
label: 'label.IKE.lifetime',
|
|
isEditable: true,
|
|
validation: {
|
|
required: false,
|
|
number: true
|
|
}
|
|
},
|
|
esplifetime: {
|
|
label: 'label.ESP.lifetime',
|
|
isEditable: true,
|
|
validation: {
|
|
required: false,
|
|
number: true
|
|
}
|
|
},
|
|
|
|
dpd: {
|
|
label: 'label.dead.peer.detection',
|
|
isBoolean: true,
|
|
isEditable: true,
|
|
converter: cloudStack.converters.toBooleanText
|
|
},
|
|
|
|
id: {
|
|
label: 'label.id'
|
|
},
|
|
domain: {
|
|
label: 'label.domain'
|
|
},
|
|
account: {
|
|
label: 'label.account'
|
|
}
|
|
}],
|
|
|
|
dataProvider: function(args) {
|
|
$.ajax({
|
|
url: createURL("listVpnCustomerGateways"),
|
|
data: {
|
|
id: args.context.vpnCustomerGateway[0].id
|
|
},
|
|
success: function(json) {
|
|
var item = json.listvpncustomergatewaysresponse.vpncustomergateway[0];
|
|
|
|
//IKE POlicy
|
|
var a1 = item.ikepolicy.split('-'); //e.g. item.ikepolicy == '3des-md5' or '3des-md5;modp1024'
|
|
item.ikeEncryption = a1[0];
|
|
if (a1[1].indexOf(';') == -1) {
|
|
item.ikeHash = a1[1];
|
|
} else {
|
|
var a2 = a1[1].split(';');
|
|
item.ikeHash = a2[0];
|
|
item.ikeDh = a2[1];
|
|
}
|
|
|
|
//ESP Policy
|
|
var a1 = item.esppolicy.split('-'); //e.g. item.esppolicy == '3des-md5' or '3des-md5;modp1024'
|
|
item.espEncryption = a1[0];
|
|
if (a1[1].indexOf(';') == -1) {
|
|
item.espHash = a1[1];
|
|
} else {
|
|
var a2 = a1[1].split(';');
|
|
item.espHash = a2[0];
|
|
item.perfectForwardSecrecy = a2[1];
|
|
}
|
|
|
|
args.response.success({
|
|
data: item
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
function getExtaPropertiesForIpObj(ipObj, args) {
|
|
if (!('vpc' in args.context)) { //***** Guest Network section > Guest Network page > IP Address page *****
|
|
var services = args.context.networks[0].service;
|
|
if(services != null) {
|
|
for(var i = 0; i < services.length; i++) {
|
|
var thisService = services[i];
|
|
if (thisService.name == "Vpn") {
|
|
ipObj.networkOfferingHavingVpnService = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (ipObj.networkOfferingHavingVpnService == true) {
|
|
$.ajax({
|
|
url: createURL('listRemoteAccessVpns'),
|
|
data: {
|
|
listAll: true,
|
|
publicipid: ipObj.id
|
|
},
|
|
async: false,
|
|
success: function(vpnResponse) {
|
|
var isVPNEnabled = vpnResponse.listremoteaccessvpnsresponse.count;
|
|
if (isVPNEnabled) {
|
|
ipObj.vpnenabled = true;
|
|
ipObj.remoteaccessvpn = vpnResponse.listremoteaccessvpnsresponse.remoteaccessvpn[0];
|
|
} else {
|
|
ipObj.vpnenabled = false;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
} else { //***** VPC section > Configuration VPC > Router > Public IP Addresses *****
|
|
if (ipObj.issourcenat) { //VPC sourceNAT IP: supports VPN
|
|
$.ajax({
|
|
url: createURL('listRemoteAccessVpns'),
|
|
data: {
|
|
listAll: true,
|
|
publicipid: ipObj.id
|
|
},
|
|
async: false,
|
|
success: function(vpnResponse) {
|
|
var isVPNEnabled = vpnResponse.listremoteaccessvpnsresponse.count;
|
|
if (isVPNEnabled) {
|
|
ipObj.vpnenabled = true;
|
|
ipObj.remoteaccessvpn = vpnResponse.listremoteaccessvpnsresponse.remoteaccessvpn[0];
|
|
} else {
|
|
ipObj.vpnenabled = false;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
})(cloudStack, jQuery);
|