|  | // 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; | 
|  | }; | 
|  |  | 
|  | 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 item = args.context.item; | 
|  | var status = item.state; | 
|  |  | 
|  | if (status == 'Destroyed' || | 
|  | status == 'Releasing' || | 
|  | status == 'Released' || | 
|  | status == 'Creating' || | 
|  | status == 'Allocating' || | 
|  | item.account == 'system' || | 
|  | item.issystem == true ) { | 
|  | return []; | 
|  | } | 
|  |  | 
|  | if(item.networkOfferingConserveMode == false) { | 
|  | /* | 
|  | (1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added. | 
|  | */ | 
|  | if (item.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 { //item.issourcenat == false | 
|  | if (item.isstaticnat) { //1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer. | 
|  | disallowedActions.push('enableVPN'); | 
|  | } | 
|  | if (item.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: item.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: item.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(item.networkOfferingConserveMode == false) { | 
|  | /* | 
|  | (1) If IP is SourceNat, no StaticNat/VPN/PortForwarding/LoadBalancer can be enabled/added. | 
|  | */ | 
|  | if (item.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 { //item.issourcenat == false | 
|  | if (item.isstaticnat) { //1. Once StaticNat is enabled, hide VPN/PortForwarding/LoadBalancer. | 
|  | disallowedActions.push('enableVPN'); | 
|  | } | 
|  | if (item.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: item.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: item.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 (item.isstaticnat) { | 
|  | disallowedActions.push('enableStaticNAT'); | 
|  | } else { | 
|  | disallowedActions.push('disableStaticNAT'); | 
|  | } | 
|  |  | 
|  | if(item.networkOfferingHavingVpnService == true) { | 
|  | if (item.vpnenabled) { | 
|  | disallowedActions.push('enableVPN'); | 
|  | } else { | 
|  | disallowedActions.push('disableVPN'); | 
|  | } | 
|  | } else { //item.networkOfferingHavingVpnService == false | 
|  | disallowedActions.push('disableVPN'); | 
|  | disallowedActions.push('enableVPN'); | 
|  | } | 
|  |  | 
|  | if (item.issourcenat){ | 
|  | disallowedActions.push('enableStaticNAT'); | 
|  | disallowedActions.push('disableStaticNAT'); | 
|  | disallowedActions.push('remove'); | 
|  | } | 
|  |  | 
|  | 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 checkVpc=0; | 
|  | cloudStack.sections.network = { | 
|  | title: 'label.network', | 
|  | id: 'network', | 
|  | sectionSelect: { | 
|  | preFilter: function(args) { | 
|  | var havingSecurityGroupNetwork = false; | 
|  | var havingBasicZones = false; | 
|  | var havingAdvancedZones = true; | 
|  |  | 
|  | // Get zone types | 
|  | $.ajax({ | 
|  | url: createURL('listZones'), | 
|  | async: false, | 
|  | success: function(json) { | 
|  | var zones = json.listzonesresponse.zone ? | 
|  | json.listzonesresponse.zone : []; | 
|  | var basicZones = $.grep(zones, function(zone) { | 
|  | return zone.networktype == 'Basic'; | 
|  | }); | 
|  | var advancedZones = $.grep(zones, function(zone) { | 
|  | return zone.networktype == 'Advanced'; | 
|  | }); | 
|  |  | 
|  |  | 
|  | havingBasicZones = basicZones.length ? true : false; | 
|  | havingAdvancedZones = advancedZones.length ? true : false; | 
|  | } | 
|  | }); | 
|  |  | 
|  | $.ajax({ | 
|  | url: createURL('listNetworks', { ignoreProject: true }), | 
|  | data: { | 
|  | supportedServices: 'SecurityGroup', | 
|  | listAll: true, | 
|  | details: 'min' | 
|  | }, | 
|  | async: false, | 
|  | success: function(data) { | 
|  | if (data.listnetworksresponse.network != null && data.listnetworksresponse.network.length > 0) { | 
|  | havingSecurityGroupNetwork = true; | 
|  | } | 
|  | } | 
|  | }); | 
|  |  | 
|  | var sectionsToShow = ['networks']; | 
|  |  | 
|  | if (havingAdvancedZones) { | 
|  | sectionsToShow.push('vpc'); | 
|  | sectionsToShow.push('vpnCustomerGateway'); | 
|  | } | 
|  |  | 
|  |  | 
|  | if(havingSecurityGroupNetwork == true) | 
|  | 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.guest.network', | 
|  |  | 
|  | preFilter: function(args) { | 
|  | var advSgDisabledZones; | 
|  | $.ajax({ | 
|  | url: createURL('listZones'), | 
|  | async: false, | 
|  | success: function(json) { | 
|  | advSgDisabledZones = $.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) | 
|  | }); | 
|  | } | 
|  | }); | 
|  | return (advSgDisabledZones != null && advSgDisabledZones.length > 0); | 
|  | }, | 
|  |  | 
|  | createForm: { | 
|  | title: 'label.add.guest.network', | 
|  | desc: 'message.add.guest.network', | 
|  | 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) { | 
|  | $.ajax({ | 
|  | url: createURL('listVPCs'), | 
|  | data: { | 
|  | listAll: true | 
|  | }, | 
|  | success: function(json) { | 
|  | var items = json.listvpcsresponse.vpc; | 
|  | var baseUrl = 'listNetworkOfferings&zoneid=' + args.zoneId; | 
|  | var listUrl; | 
|  | if(items != null && items.length > 0) | 
|  | listUrl = baseUrl; | 
|  | else | 
|  | listUrl = baseUrl + '&forVpc=false'; | 
|  | $.ajax({ | 
|  | url: createURL(listUrl), | 
|  | data: { | 
|  | guestiptype: 'Isolated', | 
|  | supportedServices: 'SourceNat', | 
|  | specifyvlan: false, | 
|  | state: 'Enabled' | 
|  | }, | 
|  | success: function(json) { | 
|  | networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering; | 
|  | args.response.success({ | 
|  | data: $.map(networkOfferingObjs, function(zone) { | 
|  | return { | 
|  | id: zone.id, | 
|  | description: zone.name | 
|  | }; | 
|  | }) | 
|  | }); | 
|  | } | 
|  | }); | 
|  | } | 
|  | }); | 
|  | } | 
|  | }, | 
|  |  | 
|  | vpcid: { | 
|  | label: 'label.vpc', | 
|  | dependsOn: 'networkOfferingId', | 
|  | select: function(args) { | 
|  | var networkOfferingObj; | 
|  | var $form = args.$select.closest('form'); | 
|  | $(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: { | 
|  | listAll: true, | 
|  | details: 'min' | 
|  | }, | 
|  | 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' } | 
|  | } | 
|  | }, | 
|  | 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.data.networkDomain != null && args.data.networkDomain.length > 0 && args.$form.find('.form-item[rel=vpcid]').css("display") == "none") { | 
|  | $.extend(dataObj, { | 
|  | networkDomain: args.data.networkDomain | 
|  | }); | 
|  | } | 
|  |  | 
|  | $.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 'label.add.guest.network'; } | 
|  | } | 
|  | } | 
|  | }, | 
|  | id: 'networks', | 
|  | fields: { | 
|  | name: { label: 'label.name' }, | 
|  | account: { label: 'label.account' }, | 
|  | type: { label: 'label.type' }, | 
|  | cidr: { label: 'label.cidr' } | 
|  | }, | 
|  |  | 
|  | advSearchFields: { | 
|  | zoneid: { | 
|  | label: 'Zone', | 
|  | select: function(args) { | 
|  | $.ajax({ | 
|  | url: createURL('listZones'), | 
|  | data: { | 
|  | listAll: true | 
|  | }, | 
|  | success: function(json) { | 
|  | var zones = json.listzonesresponse.zone; | 
|  |  | 
|  | args.response.success({ | 
|  | data: $.map(zones, function(zone) { | 
|  | return { | 
|  | id: zone.id, | 
|  | description: zone.name | 
|  | }; | 
|  | }) | 
|  | }); | 
|  | } | 
|  | }); | 
|  | } | 
|  | }, | 
|  |  | 
|  | domainid: { | 
|  | 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: 'Account', | 
|  | isHidden: function(args) { | 
|  | if(isAdmin() || isDomainAdmin()) | 
|  | return false; | 
|  | else | 
|  | return true; | 
|  | } | 
|  | }, | 
|  | tagKey: { label: 'Tag Key' }, | 
|  | tagValue: { 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: '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 != args.context.networks[0].networkdomain) { | 
|  | $.extend(data, { | 
|  | networkdomain: args.data.networkdomain | 
|  | }); | 
|  | } | 
|  |  | 
|  | //args.data.networkofferingid is null when networkofferingid field is hidden | 
|  | if(args.data.networkofferingid != null && args.data.networkofferingid != args.context.networks[0].networkofferingid) { | 
|  | $.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'; | 
|  | }, | 
|  | 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 networkOfferingHavingELB = false; | 
|  | var hasNetworkACL = false; | 
|  | var hasSRXFirewall = false; | 
|  | var isVPC = false; | 
|  | var isAdvancedSGZone = false; | 
|  | var hiddenTabs = []; | 
|  |  | 
|  | // Get network offering data | 
|  | $.ajax({ | 
|  | url: createURL("listNetworkOfferings&id=" + args.context.networks[0].networkofferingid), | 
|  | dataType: "json", | 
|  | async: false, | 
|  | success: function(json) { | 
|  | var networkoffering = json.listnetworkofferingsresponse.networkoffering[0]; | 
|  |  | 
|  | if (networkoffering.forvpc) { | 
|  | isVPC = true; | 
|  | } | 
|  |  | 
|  | $(networkoffering.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") { | 
|  | networkOfferingHavingELB = 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 (!networkOfferingHavingELB) { | 
|  | hiddenTabs.push("addloadBalancer"); | 
|  | } | 
|  |  | 
|  | if (isVPC || isAdvancedSGZone || hasSRXFirewall) { | 
|  | 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' | 
|  | }, | 
|  |  | 
|  | ispersistent:{ | 
|  | label:'Persistent ', | 
|  | converter:cloudStack.converters.toBooleanText | 
|  |  | 
|  | }, | 
|  | restartrequired: { | 
|  | label: 'label.restart.required', | 
|  | converter: function(booleanValue) { | 
|  | if(booleanValue == true) | 
|  | return "<font color='red'>Yes</font>"; | 
|  | else if(booleanValue == false) | 
|  | return "No"; | 
|  | } | 
|  | }, | 
|  | vlan: { label: 'label.vlan.id' }, | 
|  |  | 
|  | 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}); | 
|  | }); | 
|  | } | 
|  | }); | 
|  | $.ajax({ | 
|  | url: createURL("listNetworkOfferings&id=" + args.context.networks[0].networkofferingid),  //include currently selected network offeirng to dropdown | 
|  | dataType: "json", | 
|  | async: false, | 
|  | success: function(json) { | 
|  | var networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering; | 
|  | $(networkOfferingObjs).each(function() { | 
|  | items.push({id: this.id, description: this.displaytext}); | 
|  | }); | 
|  | } | 
|  | }); | 
|  | args.response.success({data: items}); | 
|  | } | 
|  | }, | 
|  |  | 
|  | gateway: { label: 'label.gateway' }, | 
|  |  | 
|  | //netmask: { label: 'label.netmask' }, | 
|  | cidr: { label: 'label.cidr' }, | 
|  |  | 
|  | networkdomaintext: { | 
|  | label: 'label.network.domain.text' | 
|  | }, | 
|  | networkdomain: { | 
|  | label: 'label.network.domain', | 
|  | isEditable: true | 
|  | }, | 
|  |  | 
|  | domain: { label: 'label.domain' }, | 
|  | account: { label: 'label.account' }, | 
|  |  | 
|  | vpcid: { | 
|  | label: 'label.vpc.id', | 
|  | converter: function(args) { | 
|  | if(args != null) | 
|  | return args; | 
|  | else | 
|  | return 'N/A'; | 
|  | } | 
|  | } | 
|  | } | 
|  | ], | 
|  |  | 
|  | 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); | 
|  | 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: 'AutoScale', | 
|  | custom: { | 
|  | requireValidation: true, | 
|  | buttonLabel: 'label.configure', | 
|  | action: cloudStack.uiCustom.autoscaler(cloudStack.autoscaler) | 
|  | } | 
|  | }, | 
|  | 'add-vm': { | 
|  | label: 'label.add.vms', | 
|  | addButton: true | 
|  | } | 
|  | }, | 
|  |  | 
|  | 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: [] | 
|  | }); | 
|  | } | 
|  | } | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | }, | 
|  | 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; | 
|  | $.ajax({ | 
|  | url: createURL('listNetworkOfferings'), | 
|  | data: { | 
|  | id: args.context.networks[0].networkofferingid | 
|  | }, | 
|  | async: false, | 
|  | success: function(json) { | 
|  | $(json.listnetworkofferingsresponse.networkoffering[0].service).each(function(){ | 
|  | var thisService = this; | 
|  | if (thisService.name == "StaticNat") { | 
|  | $(thisService.capability).each(function(){ | 
|  | if (this.name == "ElasticIp" && this.value == "true") { | 
|  | havingEIP = true; | 
|  | return false; //break $.each() loop | 
|  | } | 
|  | }); | 
|  | } else if (thisService.name == "Lb") { | 
|  | $(thisService.capability).each(function(){ | 
|  | if (this.name == "ElasticLb" && this.value == "true") { | 
|  | havingELB = true; | 
|  | return false; //break $.each() loop | 
|  | } | 
|  | }); | 
|  | } | 
|  | }); | 
|  | } | 
|  | }); | 
|  | 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('networks' 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 | 
|  | return true; //VPC section, show Acquire IP button | 
|  | } | 
|  | }, | 
|  | messages: { | 
|  | confirm: function(args) { | 
|  | if(args.context.vpc) | 
|  | return 'message.acquire.new.ip.vpc'; | 
|  | else | 
|  | return 'message.acquire.new.ip'; | 
|  | }, | 
|  | notification: function(args) { | 
|  | return 'label.acquire.new.ip'; | 
|  | } | 
|  | }, | 
|  | action: function(args) { | 
|  | var dataObj = {}; | 
|  | 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 data = {}; | 
|  | listViewDataProvider(args, data); | 
|  |  | 
|  | if (g_supportELB == "guest") // IPs are allocated on guest network | 
|  | $.extend(data, { | 
|  | forvirtualnetwork: false, | 
|  | forloadbalancing: true | 
|  | }); | 
|  | else if(g_supportELB == "public") // IPs are allocated on public network | 
|  | $.extend(data, { | 
|  | forvirtualnetwork: true, | 
|  | forloadbalancing: true | 
|  | }); | 
|  |  | 
|  | 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: data, | 
|  | dataType: "json", | 
|  | async: true, | 
|  | success: function(json) { | 
|  | var items = json.listpublicipaddressesresponse.publicipaddress; | 
|  |  | 
|  | $(items).each(function() { | 
|  | getExtaPropertiesForIpObj(this, args); | 
|  | }); | 
|  |  | 
|  | args.response.success({ | 
|  | actionFilter: actionFilters.ipAddress, | 
|  | data: items | 
|  | }); | 
|  | }, | 
|  | error: function(data) { | 
|  | args.response.error(parseXMLHttpResponse(data)); | 
|  | } | 
|  | }); | 
|  | }, | 
|  |  | 
|  | // Detail view | 
|  | detailView: { | 
|  | name: 'IP address detail', | 
|  | tabFilter: function(args) { | 
|  | var item = args.context.ipAddresses[0]; | 
|  |  | 
|  | // Get VPN data | 
|  | $.ajax({ | 
|  | url: createURL('listRemoteAccessVpns'), | 
|  | data: { | 
|  | listAll: true, | 
|  | publicipid: item.id | 
|  | }, | 
|  | dataType: 'json', | 
|  | async: false, | 
|  | success: function(vpnResponse) { | 
|  | var isVPNEnabled = vpnResponse.listremoteaccessvpnsresponse.count; | 
|  | if (isVPNEnabled) { | 
|  | item.vpnenabled = true; | 
|  | item.remoteaccessvpn = vpnResponse.listremoteaccessvpnsresponse.remoteaccessvpn[0]; | 
|  | }; | 
|  | }, | 
|  | error: function(data) { | 
|  | args.response.error(parseXMLHttpResponse(data)); | 
|  | } | 
|  | }); | 
|  |  | 
|  | 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 && ipAddress.issourcenat) { | 
|  | 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: { | 
|  | filters: false, | 
|  | dataProvider: function(args) { | 
|  | var data = { | 
|  | page: args.page, | 
|  | pageSize: pageSize, | 
|  | listAll: true | 
|  | }; | 
|  |  | 
|  | 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('vpc' in args.context) { | 
|  | if($tierSelect.size() && $tierSelect.val() != '-1' ){ | 
|  | data.networkid = $tierSelect.val(); | 
|  | } | 
|  | $.extend(data, { | 
|  | vpcid: args.context.vpc[0].id | 
|  | }); | 
|  | } | 
|  | else if('networks' in args.context) { | 
|  | $.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('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' } | 
|  | }, | 
|  | { | 
|  | id: { label: 'label.id' }, | 
|  | associatednetworkid: { label: 'label.associated.network.id' }, | 
|  | networkname: { label: 'label.associated.network' }, | 
|  | 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' } | 
|  | } | 
|  | ], | 
|  |  | 
|  | tags: cloudStack.api.tags({ resourceType: 'PublicIpAddress', contextId: 'ipAddresses' }), | 
|  |  | 
|  | dataProvider: function(args) { | 
|  | var items = args.context.ipAddresses; | 
|  |  | 
|  | // Get network data | 
|  | $.ajax({ | 
|  | url: createURL('listPublicIpAddresses'), | 
|  | data: { | 
|  | id: args.context.ipAddresses[0].id, | 
|  | listAll: true | 
|  | }, | 
|  | 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: $.extend(ipObj, { | 
|  | networkname: network ? network.name : '' | 
|  | }) | 
|  | }); | 
|  | }, | 
|  | 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('networks' in args.context && args.context.networks[0].vpcid == null) { //a non-VPC network from Guest Network section | 
|  | $.ajax({ | 
|  | url: createURL('listNetworkOfferings'), | 
|  | data: { | 
|  | listAll: true, | 
|  | id: args.context.networks[0].networkofferingid | 
|  | }, | 
|  | async: false, | 
|  | success: function(json) { | 
|  | var networkoffering = json.listnetworkofferingsresponse.networkoffering[0]; | 
|  | $(networkoffering.service).each(function(){ | 
|  | var thisService = this; | 
|  | 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 { //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]; | 
|  | $.ajax({ | 
|  | url: createURL("listNetworkOfferings&id=" + networkObj.networkofferingid), | 
|  | async: false, | 
|  | success: function(json) { | 
|  | var networkoffering = json.listnetworkofferingsresponse.networkoffering[0]; | 
|  | $(networkoffering.service).each(function(){ | 
|  | var thisService = this; | 
|  | if(thisService.name == "PortForwarding") | 
|  | havingPortForwardingService = true; | 
|  | if(thisService.name == "Lb") | 
|  | havingLbService = true; | 
|  | }); | 
|  | } | 
|  | }); | 
|  | } | 
|  | }); | 
|  | } | 
|  | } | 
|  | if(args.context.ipAddresses[0].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 | 
|  | } | 
|  | }, | 
|  |  | 
|  | 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: { | 
|  | filters: false, | 
|  | dataProvider: function(args) { | 
|  | var itemData = $.isArray(args.context.multiRule) && args.context.multiRule[0]['_itemData'] ? | 
|  | args.context.multiRule[0]['_itemData'] : []; | 
|  |  | 
|  | 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; | 
|  |  | 
|  | 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, | 
|  |  | 
|  | fieldPreFilter: function(args) { | 
|  | var hiddenFields = []; | 
|  | if('vpc' in args.context) { //from VPC section | 
|  | hiddenFields.push('autoScale'); //autoScale is not supported in VPC | 
|  | } | 
|  | else { //from Guest Network section | 
|  | $.ajax({ | 
|  | url: createURL('listNetworkOfferings'), | 
|  | data: { | 
|  | id: args.context.networks[0].networkofferingid | 
|  | }, | 
|  | async: false, | 
|  | success: function(json) { | 
|  | var serviceArray = json.listnetworkofferingsresponse.networkoffering[0].service; | 
|  | var lbProviderArrayIncludesNetscaler = false; | 
|  | for(var i = 0; i < serviceArray.length; i++) { | 
|  | if(serviceArray[i].name == "Lb") { | 
|  | var providerArray = serviceArray[i].provider; | 
|  | for(var k = 0; k < providerArray.length; k++) { | 
|  | if(providerArray[k].name == "Netscaler") { | 
|  | lbProviderArrayIncludesNetscaler = true; | 
|  | break; | 
|  | } | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  | if(lbProviderArrayIncludesNetscaler == false) { | 
|  | hiddenFields.push('autoScale'); //autoScale is not supported in a network that is not using Netscaler provider for LB service (CS-16459) | 
|  | } | 
|  | } | 
|  | }); | 
|  | } | 
|  | return hiddenFields; // Returns fields to be hidden | 
|  | }, | 
|  | 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() | 
|  | } | 
|  | }, | 
|  | 'autoScale': { | 
|  | label: 'AutoScale', | 
|  | custom: { | 
|  | requireValidation: true, | 
|  | buttonLabel: 'label.configure', | 
|  | action: cloudStack.uiCustom.autoscaler(cloudStack.autoscaler) | 
|  | } | 
|  | }, | 
|  |  | 
|  | 'add-vm': { | 
|  | label: 'label.add.vms', | 
|  | addButton: true | 
|  | } | 
|  | }, | 
|  |  | 
|  | 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); | 
|  |  | 
|  | $.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; | 
|  |  | 
|  | $.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; | 
|  | 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: { | 
|  | add: { | 
|  | label: 'label.add.vms.to.lb', | 
|  | action: function(args) { | 
|  | $.ajax({ | 
|  | url: createURL('assignToLoadBalancerRule'), | 
|  | data: { | 
|  | id: args.multiRule.id, | 
|  | virtualmachineids: $.map(args.data, function(elem) { | 
|  | return elem.id; | 
|  | }).join(',') | 
|  | }, | 
|  | 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) { | 
|  | $.ajax({ | 
|  | url: createURL('removeFromLoadBalancerRule'), | 
|  | data: { | 
|  | id: args.multiRule.id, | 
|  | virtualmachineids: args.item.id | 
|  | }, | 
|  | 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 loadBalancerData = data.listloadbalancerrulesresponse.loadbalancerrule; | 
|  | var loadVMTotal = loadBalancerData ? loadBalancerData.length : 0; | 
|  | var loadVMCurrent = 0; | 
|  |  | 
|  | $(loadBalancerData).each(function() { | 
|  | loadVMCurrent++; | 
|  | var item = this; | 
|  | var stickyData = {}; | 
|  | var lbInstances = []; | 
|  |  | 
|  | // Passing _hideFields array will disable specified fields for this row | 
|  | //item._hideFields = ['autoScale']; | 
|  |  | 
|  | $.ajax({ | 
|  | url: createURL('listAutoScaleVmGroups'), | 
|  | data: { | 
|  | listAll: true, | 
|  | lbruleid: item.id | 
|  | }, | 
|  | async: false, | 
|  | success: function(json) { | 
|  | if(json.listautoscalevmgroupsresponse.autoscalevmgroup != null && json.listautoscalevmgroupsresponse.autoscalevmgroup.length > 0) { //from 'autoScale' button | 
|  | item._hideFields = ['add-vm']; | 
|  | } | 
|  | else { //from 'add-vm' button | 
|  | item._hideFields = ['autoScale']; | 
|  | } | 
|  | } | 
|  | }); | 
|  |  | 
|  | // Get sticky data | 
|  | $.ajax({ | 
|  | url: createURL('listLBStickinessPolicies'), | 
|  | async: false, | 
|  | data: { | 
|  | listAll: true, | 
|  | lbruleid: item.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: item.id | 
|  | }; | 
|  | $.extend(stickyData, stickyPolicy.params); | 
|  | } else { | 
|  | stickyData = { | 
|  | lbRuleID: item.id | 
|  | }; | 
|  | } | 
|  | }, | 
|  | error: function(json) { | 
|  | cloudStack.dialog.notice({ message: parseXMLHttpResponse(json) }); | 
|  | } | 
|  | }); | 
|  |  | 
|  | // Get instances | 
|  | $.ajax({ | 
|  | url: createURL('listLoadBalancerRuleInstances'), | 
|  | dataType: 'json', | 
|  | async: false, | 
|  | data: { | 
|  | listAll: true, | 
|  | id: item.id | 
|  | }, | 
|  | success: function(data) { | 
|  | lbInstances = data.listloadbalancerruleinstancesresponse.loadbalancerruleinstance ? | 
|  | data.listloadbalancerruleinstancesresponse.loadbalancerruleinstance : []; | 
|  |  | 
|  | $(lbInstances).each(function() { | 
|  | if(this.displayname.indexOf('AutoScale-LB-') > -1) //autoscale VM is not allowed to be deleted manually. So, hide destroy button | 
|  | this._hideActions = ['destroy']; | 
|  | }); | 
|  | }, | 
|  | error: function(data) { | 
|  | args.response.error(parseXMLHttpResponse(data)); | 
|  | } | 
|  | }); | 
|  |  | 
|  | $.extend(item, { | 
|  | _itemName: 'displayname', | 
|  | _itemData: lbInstances, | 
|  | _maxLength: { | 
|  | name: 7 | 
|  | }, | 
|  | sticky: stickyData, | 
|  | autoScale: { | 
|  | lbRuleID: item.id | 
|  | } | 
|  | }); | 
|  | }); | 
|  |  | 
|  | args.response.success({ | 
|  | data: loadBalancerData | 
|  | }); | 
|  | } | 
|  | }); | 
|  |  | 
|  | // 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, | 
|  | 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' } | 
|  | ] | 
|  | }); | 
|  | } | 
|  | }, | 
|  | '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('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 | 
|  | }, | 
|  | 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: vm.id == vm.displayname ? | 
|  | (vm.instancename ? vm.instancename : vm.name) | 
|  | : vm.displayname | 
|  | }); | 
|  | }), | 
|  | _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', | 
|  | 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: 'Tag Key' }, | 
|  | tagValue: { 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 | 
|  | }; | 
|  |  | 
|  | // TCP / ICMP | 
|  | if (args.data.icmptype && args.data.icmpcode) { // ICMP | 
|  | $.extend(data, { | 
|  | icmptype: args.data.icmptype, | 
|  | icmpcode: args.data.icmpcode | 
|  | }); | 
|  | } else { // TCP | 
|  | $.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.revokesecuritygroupingress.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: function(args) { | 
|  | var context = args.context; | 
|  |  | 
|  | return $('<div>').multiEdit({ | 
|  | context: context, | 
|  | noSelect: true, | 
|  | noHeaderActionsColumn: true, | 
|  | fields: { | 
|  | 'cidrlist': { edit: true, label: 'label.cidr' }, | 
|  | '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 { | 
|  | $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 }, | 
|  | 'add-rule': { | 
|  | label: 'label.add', | 
|  | addButton: true | 
|  | } | 
|  | }, | 
|  | add: { | 
|  | label: 'label.add', | 
|  | action: function(args) { | 
|  | var data = { | 
|  | protocol: args.data.protocol, | 
|  | cidrlist: args.data.cidrlist, | 
|  | trafficType: 'Egress' | 
|  | }; | 
|  |  | 
|  | 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 | 
|  | }); | 
|  | } | 
|  |  | 
|  | // Get Source NAT IP | 
|  | var sourceNATIP; | 
|  |  | 
|  | $.ajax({ | 
|  | url: createURL('listPublicIpAddresses'), | 
|  | data: { | 
|  | listAll: true, | 
|  | associatednetworkid: args.context.networks[0].id | 
|  | }, | 
|  | async: false, | 
|  | success: function(json) { | 
|  | var ipAddresses = json.listpublicipaddressesresponse.publicipaddress; | 
|  |  | 
|  | sourceNATIP = $.grep(ipAddresses, function(ipAddress) { | 
|  | return ipAddress.issourcenat; | 
|  | })[0]; | 
|  | } | 
|  | }); | 
|  |  | 
|  | data.ipaddressid = sourceNATIP.id; | 
|  |  | 
|  | $.ajax({ | 
|  | url: createURL('createFirewallRule'), | 
|  | data: data, | 
|  | dataType: 'json', | 
|  | async: true, | 
|  | success: function(json) { | 
|  | var jobId = json.createfirewallruleresponse.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('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.remove.egress.rule', | 
|  | poll: pollAsyncJobResult | 
|  | } | 
|  | }); | 
|  | }, | 
|  | error: function(json) { | 
|  | args.response.error(parseXMLHttpResponse(json)); | 
|  | } | 
|  | }); | 
|  | } | 
|  | } | 
|  | }, | 
|  | ignoreEmptyFields: true, | 
|  | dataProvider: function(args) { | 
|  | $.ajax({ | 
|  | url: createURL('listFirewallRules'), | 
|  | data: { | 
|  | listAll: true, | 
|  | networkid: args.context.networks[0].id, | 
|  | trafficType: 'Egress' | 
|  | }, | 
|  | dataType: 'json', | 
|  | async: true, | 
|  | success: function(json) { | 
|  | var response = json.listfirewallrulesresponse.firewallrule; | 
|  |  | 
|  | args.response.success({ | 
|  | data: response | 
|  | }); | 
|  | } | 
|  | }); | 
|  | } | 
|  | }); | 
|  | } | 
|  | } | 
|  | }, | 
|  |  | 
|  | 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' }, | 
|  | zonename: { label: 'label.zone' }, | 
|  | cidr: { label: 'label.cidr' }, | 
|  | state: {label: 'label.state', indicator: { 'Enabled': 'on', 'Disabled': 'off'}} | 
|  | }, | 
|  |  | 
|  | advSearchFields: { | 
|  | name: { label: 'Name' }, | 
|  | zoneid: { | 
|  | label: 'Zone', | 
|  | select: function(args) { | 
|  | $.ajax({ | 
|  | url: createURL('listZones'), | 
|  | data: { | 
|  | listAll: true | 
|  | }, | 
|  | success: function(json) { | 
|  | var zones = json.listzonesresponse.zone; | 
|  |  | 
|  | args.response.success({ | 
|  | data: $.map(zones, function(zone) { | 
|  | return { | 
|  | id: zone.id, | 
|  | description: zone.name | 
|  | }; | 
|  | }) | 
|  | }); | 
|  | } | 
|  | }); | 
|  | } | 
|  | }, | 
|  |  | 
|  | domainid: { | 
|  | 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: 'Account', | 
|  | isHidden: function(args) { | 
|  | if(isAdmin() || isDomainAdmin()) | 
|  | return false; | 
|  | else | 
|  | return true; | 
|  | } | 
|  | }, | 
|  | tagKey: { label: 'Tag Key' }, | 
|  | tagValue: { 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; | 
|  | 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; | 
|  | 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' | 
|  | } | 
|  | } | 
|  | }, | 
|  | action: function(args) { | 
|  | var defaultvpcofferingid; | 
|  | $.ajax({ | 
|  | url: createURL("listVPCOfferings"), | 
|  | dataType: "json", | 
|  | data: { | 
|  | isdefault: true | 
|  | }, | 
|  | async: false, | 
|  | success: function(json) { | 
|  | defaultvpcofferingid = json.listvpcofferingsresponse.vpcoffering[0].id; | 
|  | } | 
|  | }); | 
|  |  | 
|  | var dataObj = { | 
|  | name: args.data.name, | 
|  | displaytext: args.data.displaytext, | 
|  | zoneid: args.data.zoneid, | 
|  | cidr: args.data.cidr, | 
|  | vpcofferingid: defaultvpcofferingid | 
|  | }; | 
|  |  | 
|  | 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' }, | 
|  | 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: 'CIDR list', | 
|  | desc: 'Please enter a comma separated list of CIDRs if more than one', | 
|  | validation: { required: true } | 
|  | }, | 
|  | gateway: { | 
|  | label: 'label.gateway', | 
|  | docID: 'helpVPNGatewayGateway', | 
|  | validation: { required: true } | 
|  | }, | 
|  | cidrlist: { | 
|  | label: 'label.CIDR.list', | 
|  | desc:'Please enter a comma separated list of CIDRs if more than one', | 
|  | 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('networks' in args.context) { //from Guest Network section | 
|  | //get ipObj.networkOfferingConserveMode and ipObj.networkOfferingHavingVpnService from guest network's network offering | 
|  | $.ajax({ | 
|  | url: createURL('listNetworkOfferings'), | 
|  | data: { | 
|  | id: args.context.networks[0].networkofferingid | 
|  | }, | 
|  | async: false, | 
|  | success: function(json) { | 
|  | var networkOfferingObj = json.listnetworkofferingsresponse.networkoffering[0]; | 
|  | ipObj.networkOfferingConserveMode = networkOfferingObj.conservemode; | 
|  |  | 
|  | $(networkOfferingObj.service).each(function(){ | 
|  | var thisService = this; | 
|  | if(thisService.name == "Vpn") | 
|  | ipObj.networkOfferingHavingVpnService = true; | 
|  | }); | 
|  |  | 
|  | 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 { //from VPC section | 
|  | ipObj.networkOfferingConserveMode = false; //conserve mode of IP in VPC is always off, so hardcode it as false | 
|  | ipObj.networkOfferingHavingVpnService = false; //VPN is not supported in IP in VPC, so hardcode it as false | 
|  | } | 
|  | } | 
|  |  | 
|  | })(cloudStack, jQuery); | 
|  |  |