(function(cloudStack, $, testData) { var actionFilters = { ipAddress: function(args) { var allowedActions = args.context.actions; var disallowedActions = []; var item = args.context.item; var status = item.state; if (status == 'Released') { return []; } if (status == 'Destroyed' || status == 'Releasing' || status == 'Released' || status == 'Creating' || status == 'Allocating' || item.account == 'system') { disallowedActions = allowedActions; } if (item.isstaticnat) { disallowedActions.push('enableStaticNAT'); } else { disallowedActions.push('disableStaticNAT'); } if (item.vpnenabled) { disallowedActions.push('enableVPN'); } else { disallowedActions.push('disableVPN'); } if (item.issourcenat){ disallowedActions.push('enableStaticNAT'); disallowedActions.push('disableStaticNAT'); disallowedActions.push('destroy'); } else { disallowedActions.push('enableVPN'); disallowedActions.push('disableVPN'); } allowedActions = $.grep(allowedActions, function(item) { return $.inArray(item, disallowedActions) == -1; }); return allowedActions; }, securityGroups: function(args) { var allowedActions = []; var isSecurityGroupOwner = isAdmin() || args.context.item.account == args.context.users[0].account; if (isSecurityGroupOwner && args.context.item.state != 'Destroyed' && args.context.item.name != 'default') { allowedActions.push('destroy'); } return allowedActions; } }; cloudStack.sections.network = { title: 'Network', id: 'network', sectionSelect: { preFilter: function(args) { var isSecurityGroupEnabled = false; var hasIsolatedNetworks = false; $.ajax({ url: createURL('listNetworks'), data: { supportedServices: 'SecurityGroup' }, async: false, success: function(data) { $.ajax({ url: createURL('listNetworks'), data: { type: 'isolated', supportedServices: 'SourceNat' }, async: false, success: function(data) { if (data.listnetworksresponse.network && data.listnetworksresponse.network.length) { hasIsolatedNetworks = true; } } }); if (data.listnetworksresponse.network && data.listnetworksresponse.network.length) { isSecurityGroupEnabled = true; } } }); if (isSecurityGroupEnabled && !hasIsolatedNetworks) return ['securityGroups']; if (isSecurityGroupEnabled && hasIsolatedNetworks) return ['securityGroups', 'networks']; return ['networks']; }, label: 'Select view' }, sections: { networks: { id: 'networks', type: 'select', title: 'Guest Networks', listView: { actions: { add: { label: 'Add guest network', createForm: { title: 'Add new guest network', desc: 'Please specify name and zone for this network; note that network will be isolated and source NAT-enabled.', fields: { name: { label: 'Name', validation: { required: true } }, displayText: { label: 'Display Text', validation: { required: true }}, zoneId: { label: 'Zone', validation: { required: true }, select: function(args) { $.ajax({ url: createURL('listZones'), data: { type: 'Advanced' }, success: function(json) { var zones = $.grep(json.listzonesresponse.zone, function(zone) { return zone.networktype == 'Advanced'; }); args.response.success({ data: $.map(zones, function(zone) { return { id: zone.id, description: zone.name }; }) }); } }); } }, networkOfferingId: { label: 'Network Offering', validation: { required: true }, select: function(args) { $.ajax({ url: createURL('listNetworkOfferings'), data: { supportedServices: 'SourceNat', type: 'isolated', state: 'Enabled' }, success: function(json) { var networkOfferings = json.listnetworkofferingsresponse.networkoffering; args.response.success({ data: $.map(networkOfferings, function(zone) { return { id: zone.id, description: zone.name }; }) }); } }); } } } }, action: function(args) { $.ajax({ url: createURL('createNetwork'), data: args.data, success: function(json) { args.response.success({ data: json.createnetworkresponse.network }); }, error: function(json) { args.response.error(parseXMLHttpResponse(json)); } }); }, messages: { notification: function() { return 'Added guest network'; } } } }, id: 'networks', fields: { name: { label: 'Name' }, zonename: { label: 'Zone' }, type: { label: 'Type' }, vlan: { label: 'VLAN' }, cidr: { label: 'CIDR' }, state: { label: 'State', indicator: { 'Implemented': 'on', 'Setup': 'on', 'Allocated': 'on', 'Destroyed': 'off' } } }, dataProvider: function(args) { $.ajax({ url: createURL('listNetworks'), data: { type: 'isolated', supportedServices: 'SourceNat' }, dataType: 'json', async: true, 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: 'IP addresses', preFilter: function(args) { if (args.context.networks[0].state == 'Destroyed') return false; return true; } }, actions: { edit: { label: 'Edit', messages: { confirm: function(args) { return 'Are you sure you want to edit network?'; }, success: function(args) { return 'Network is being edited.'; }, notification: function(args) { return 'Editing network'; }, complete: function(args) { return 'Network has been edited.'; } }, action: function(args) { var array1 = []; array1.push("&name=" + todb(args.data.name)); array1.push("&displaytext=" + todb(args.data.displaytext)); //args.data.networkofferingid is null when networkofferingid field is hidden if(args.data.networkofferingid != null && args.data.networkofferingid != args.context.networks[0].networkofferingid) array1.push("&networkofferingid=" + todb(args.data.networkofferingid)); //args.data.networkdomain is null when networkdomain field is hidden if(args.data.networkdomain != null && args.data.networkdomain != args.context.networks[0].networkdomain) array1.push("&networkdomain=" + todb(args.data.networkdomain)); $.ajax({ url: createURL("updateNetwork&id=" + args.context.networks[0].id + array1.join("")), dataType: "json", success: function(json) { var jid = json.updatenetworkresponse.jobid; args.response.success( {_custom: {jobId: jid, getUpdatedItem: function(json) { var item = json.queryasyncjobresultresponse.jobresult.network; return {data: item}; } } } ); } }); }, notification: { poll: pollAsyncJobResult } }, 'restart': { label: 'Restart network', action: function(args) { $.ajax({ url: createURL("restartNetwork&cleanup=true&id=" + args.context.networks[0].id), 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; } } } ); } }); }, messages: { confirm: function(args) { return 'Please confirm that you want to restart network'; }, notification: function(args) { return 'Restarting network'; } }, notification: { poll: pollAsyncJobResult } }, destroy: { label: 'Delete network', messages: { confirm: function(args) { return 'Are you sure you want to delete network ?'; }, notification: function(args) { return 'Deleting 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, getUpdatedItem: function(json) { return { state: 'Destroyed' }; //nothing in this network needs to be updated, in fact, this whole template has being deleted } } } ); } }); }, notification: { poll: pollAsyncJobResult } } }, tabs: { details: { title: '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("netmask"); } if(args.context.networks[0].type == "Isolated") { hiddenFields.push("networkofferingdisplaytext"); hiddenFields.push("networkdomaintext"); hiddenFields.push("gateway"); //hiddenFields.push("netmask"); } else { //selectedGuestNetworkObj.type == "Shared" hiddenFields.push("networkofferingid"); hiddenFields.push("networkdomain"); } return hiddenFields; }, fields: [ { name: { label: 'Name', isEditable: true } }, { id: { label: 'ID' }, displaytext: { label: 'Description', isEditable: true }, type: { label: 'Type' }, state: { label: 'State' }, restartrequired: { label: 'Restart required', converter: function(booleanValue) { if(booleanValue == true) return "Yes"; else if(booleanValue == false) return "No"; } }, vlan: { label: 'VLAN ID' }, scope: { label: 'Scope' }, //networkofferingdisplaytext: { label: 'Network offering' }, networkofferingid: { label: 'Network offering', isEditable: true, select: function(args){ if (args.context.networks[0].state == 'Destroyed') { args.response.success({ data: [] }); return; } var items = []; $.ajax({ url: createURL("listNetworkOfferings&networkid=" + args.context.networks[0].id), dataType: "json", async: false, success: function(json) { var networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering; $(networkOfferingObjs).each(function() { items.push({id: this.id, description: this.displaytext}); }); } }); $.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: 'Gateway' }, //netmask: { label: 'Netmask' }, cidr: { label: 'CIDR' }, networkdomaintext: { label: 'Network domain' }, networkdomain: { label: 'Network domain', isEditable: true } } ], dataProvider: function(args) { args.response.success({ actionFilter: function(args) { if (args.context.networks[0].state == 'Destroyed') return []; return args.context.actions; }, data: args.context.networks[0] }); } } } } } }, ipAddresses: { type: 'select', title: 'IP Addresses', listView: { id: 'ipAddresses', label: 'IPs', filters: { allocated: { label: 'Allocated ' }, mine: { label: 'My network' } }, fields: { ipaddress: { label: 'IP', converter: function(text, item) { if (item.issourcenat) { return text + ' [Source NAT]'; } return text; } }, zonename: { label: 'Zone' }, vlanname: { label: 'VLAN' }, account: { label: 'Account' }, state: { label: 'State', indicator: { 'Allocated': 'on', 'Released': 'off' } } }, actions: { add: { label: 'Acquire new IP', addRow: 'true', action: function(args) { $.ajax({ url: createURL('associateIpAddress'), data: { networkId: args.context.networks[0].id }, dataType: 'json', async: true, 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)); } }); }, messages: { confirm: function(args) { return 'Please confirm that you would like to acquire a net IP for this network.'; }, notification: function(args) { return 'Allocated IP'; } }, notification: { poll: pollAsyncJobResult } }, enableStaticNAT: { label: 'Enable static NAT', action: { noAdd: true, custom: cloudStack.uiCustom.enableStaticNAT({ listView: $.extend(true, {}, cloudStack.sections.instances, { listView: { dataProvider: function(args) { $.ajax({ url: createURL('listVirtualMachines'), data: { networkid: args.context.networks[0].id }, dataType: 'json', async: true, success: function(data) { args.response.success({ data: $.grep( data.listvirtualmachinesresponse.virtualmachine ? data.listvirtualmachinesresponse.virtualmachine : [], function(instance) { return $.inArray(instance.state, [ 'Destroyed' ]) == -1; } ) }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } } }), action: function(args) { $.ajax({ url: createURL('enableStaticNat'), data: { ipaddressid: args.context.ipAddresses[0].id, virtualmachineid: args.context.instances[0].id }, dataType: 'json', async: true, success: function(data) { args.response.success(); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } }) }, messages: { confirm: function(args) { return 'Are you sure you want to enable static NAT?'; }, notification: function(args) { return 'Enabled Static NAT'; } }, notification: { poll: function(args) { args.complete({ data: { isstaticnat: true } }); } } }, disableStaticNAT: { label: '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(json) { return $.extend(args.context.ipAddresses[0], { isstaticnat: false }); }, getActionFilter: function() { return actionFilters.ipAddresses; } } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); }, messages: { confirm: function(args) { return 'Are you sure you want to disable static NAT?'; }, notification: function(args) { return 'Disable Static NAT'; } }, notification: { poll: pollAsyncJobResult } }, destroy: { label: '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 = []; return allowedActions; }; }, getUpdatedItem: function(args) { return { state: 'Released' }; } } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); }, messages: { confirm: function(args) { return 'Are you sure you want to release this IP?'; }, notification: function(args) { return 'Release IP'; } }, notification: { poll: pollAsyncJobResult } } }, dataProvider: function(args) { var data = { page: args.page, pageSize: pageSize }; 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 }); } $.ajax({ url: createURL('listPublicIpAddresses'), data: data, dataType: "json", async: true, success: function(json) { var items = json.listpublicipaddressesresponse.publicipaddress; var processedItems = 0; if (!items) { args.response.success({ data: [] }); return; } 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: { 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]; if (!ipAddress.issourcenat || (ipAddress.issourcenat && !ipAddress.vpnenabled)) { disabledTabs.push('vpn'); } return disabledTabs; }, actions: { enableVPN: { label: 'Enable VPN', action: function(args) { $.ajax({ url: createURL('createRemoteAccessVpn'), 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(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 'Please confirm that you want VPN enabled for this IP address.'; }, notification: function(args) { return 'Enabled VPN'; }, complete: function(args) { return 'VPN is now enabled for IP ' + args.vpn.publicip + '.' + '
Your IPsec pre-shared key is:
' + args.vpn.presharedkey; } }, notification: { poll: pollAsyncJobResult } }, disableVPN: { 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 'Are you sure you want to disable VPN?'; }, notification: function(args) { return 'Disabled VPN'; } }, notification: { poll: pollAsyncJobResult } }, enableStaticNAT: { label: 'Enable static NAT', action: { noAdd: true, custom: cloudStack.uiCustom.enableStaticNAT({ listView: $.extend(true, {}, cloudStack.sections.instances, { listView: { dataProvider: function(args) { $.ajax({ url: createURL('listVirtualMachines'), data: { networkid: args.context.networks[0].id }, dataType: 'json', async: true, success: function(data) { args.response.success({ data: $.grep( data.listvirtualmachinesresponse.virtualmachine ? data.listvirtualmachinesresponse.virtualmachine : [], function(instance) { return $.inArray(instance.state, [ 'Destroyed' ]) == -1; } ) }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } } }), action: function(args) { $.ajax({ url: createURL('enableStaticNat'), data: { ipaddressid: args.context.ipAddresses[0].id, virtualmachineid: args.context.instances[0].id }, dataType: 'json', async: true, success: function(data) { args.response.success(); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } }) }, messages: { notification: function(args) { return 'Enabled Static NAT'; } }, notification: { poll: function(args) { args.complete({ data: { isstaticnat: true } }); } } }, disableStaticNAT: { label: '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 }; }, getActionFilter: function() { return function(args) { return ['enableStaticNAT']; }; } } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); }, messages: { confirm: function(args) { return 'Are you sure you want to disable static NAT?'; }, notification: function(args) { return 'Disable Static NAT'; } }, notification: { poll: pollAsyncJobResult } }, destroy: { label: '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' }; } } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); }, messages: { confirm: function(args) { return 'Are you sure you want to release this IP?'; }, notification: function(args) { return 'Release IP'; } }, notification: { poll: pollAsyncJobResult } } }, tabs: { details: { title: 'Details', fields: [ { ipaddress: { label: 'IP' } }, { id: { label: 'id' }, networkname: { label: 'Network' }, networktype: { label: 'Network Type' }, networkid: { label: 'Network ID' }, associatednetworkid: { label: 'Assoc. Network ID' }, state: { label: 'State' }, domain: { label: 'Domain' }, account: { label: 'Account' }, zonename: { label: 'Zone' }, vlanname: { label: 'VLAN' }, issourcenat: { label: 'Source NAT', isBoolean: true, converter: function(value) { return value ? 'Yes' : 'No'; } }, isstaticnat: { label: 'Static NAT', isBoolean: true, converter: function(value) { return value ? 'Yes' : 'No'; } } } ], //dataProvider: testData.dataProvider.detailView('network') dataProvider: function(args) { var items = args.context.ipAddresses; // Get network data $.ajax({ url: createURL("listPublicIpAddresses&id="+args.id), dataType: "json", async: true, success: function(json) { var item = items[0]; $.ajax({ url: createURL('listNetworks'), data: { networkid: this.associatednetworkid }, dataType: 'json', async: true, success: function(data) { // Get VPN data $.ajax({ url: createURL('listRemoteAccessVpns'), data: { publicipid: item.id }, dataType: 'json', async: true, success: function(vpnResponse) { var isVPNEnabled = vpnResponse.listremoteaccessvpnsresponse.count; if (isVPNEnabled) { item.vpnenabled = true; item.remoteaccessvpn = vpnResponse.listremoteaccessvpnsresponse.remoteaccessvpn[0]; }; // Check if data retrieval complete item.network = data.listnetworksresponse.network[0]; item.networkname = item.network.name; item.networktype = item.network.type; args.response.success({ actionFilter: actionFilters.ipAddress, data: item }); } }); } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } }, ipRules: { title: 'Configuration', custom: cloudStack.ipRules({ preFilter: function(args) { if (args.context.ipAddresses[0].isstaticnat) { return args.items; // All items filtered means static NAT } if (g_firewallRuleUiEnabled != 'true') { return ['firewall']; } return []; }, // Firewall rules firewall: { noSelect: true, fields: { 'cidrlist': { edit: true, label: 'Source CIDR' }, 'protocol': { 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.attr('disabled', false); $otherFields.attr('disabled', 'disabled'); } else { $otherFields.attr('disabled', false); $icmpFields.attr('disabled', 'disabled'); } }); args.response.success({ data: [ { name: 'tcp', description: 'TCP' }, { name: 'udp', description: 'UDP' }, { name: 'icmp', description: 'ICMP' } ] }); } }, 'startport': { edit: true, label: 'Start Port' }, 'endport': { edit: true, label: 'End Port' }, 'icmptype': { edit: true, label: 'ICMP Type', isDisabled: true }, 'icmpcode': { edit: true, label: 'ICMP Code', isDisabled: true }, 'add-rule': { label: 'Add Rule', addButton: true } }, add: { 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: 'Add firewall rule', poll: pollAsyncJobResult } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } }, actions: { destroy: { 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: 'Remove firewall rule ' + args.context.multiRule[0].id, poll: pollAsyncJobResult } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } } }, dataProvider: function(args) { $.ajax({ url: createURL('listFirewallRules'), data: { 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 }, dataType: 'json', async: true, success: function(data) { var ipAddress = data.listpublicipaddressesresponse.publicipaddress[0]; args.response.success({ data: ipAddress }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); }, vmDataProvider: function(args) { $.ajax({ url: createURL('listVirtualMachines'), data: { id: args.context.ipAddresses[0].virtualmachineid }, 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, staticNAT: { noSelect: true, fields: { 'protocol': { label: 'Protocol', select: function(args) { args.response.success({ data: [ { name: 'tcp', description: 'TCP' }, { name: 'udp', description: 'UDP' } ] }); } }, 'startport': { edit: true, label: 'Start Port' }, 'endport': { edit: true, label: 'End Port' }, 'add-rule': { label: 'Add Rule', addButton: true } }, add: { 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: 'Added static NAT rule', poll: pollAsyncJobResult } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } }, actions: { destroy: { 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: 'Removed static NAT rule', poll: pollAsyncJobResult } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } } }, dataProvider: function(args) { setTimeout(function() { $.ajax({ url: createURL('listIpForwardingRules'), data: { 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: { dataProvider: function(args) { $.ajax({ url: createURL('listVirtualMachines'), data: { networkid: args.context.ipAddresses[0].associatednetworkid }, dataType: 'json', async: true, success: function(data) { args.response.success({ data: $.grep( data.listvirtualmachinesresponse.virtualmachine ? data.listvirtualmachinesresponse.virtualmachine : [], function(instance) { return $.inArray(instance.state, [ 'Destroyed' ]) == -1; } ) }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } } }), multipleAdd: true, fields: { 'name': { edit: true, label: 'Name' }, 'publicport': { edit: true, label: 'Public Port' }, 'privateport': { edit: true, label: 'Private Port' }, 'algorithm': { label: 'Algorithm', select: function(args) { args.response.success({ data: [ { name: 'roundrobin', description: 'Round-robin' }, { name: 'leastconn', description: 'Least connections' }, { name: 'source', description: 'Source' } ] }); } }, 'add-vm': { label: 'Add VMs', addButton: true } }, add: { label: 'Add VMs', action: function(args) { var openFirewall = g_firewallRuleUiEnabled == "true" ? false : true; $.ajax({ url: createURL('createLoadBalancerRule'), data: $.extend(args.data, { openfirewall: openFirewall, publicipid: args.context.ipAddresses[0].id }), dataType: 'json', async: true, success: function(data) { var itemData = args.itemData; var jobID = data.createloadbalancerruleresponse.jobid; $.ajax({ url: createURL('assignToLoadBalancerRule'), data: { id: data.createloadbalancerruleresponse.id, virtualmachineids: $.map(itemData, function(elem) { return elem.id; }).join(',') }, dataType: 'json', async: true, success: function(data) { args.response.success({ _custom: { jobId: jobID }, notification: { label: 'Add load balancer rule', poll: pollAsyncJobResult } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } }, actions: { destroy: { label: 'Remove load balancer rule', 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: 'Remove load balancer rule ' + args.context.multiRule[0].id, poll: pollAsyncJobResult } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } } }, dataProvider: function(args) { $.ajax({ url: createURL('listLoadBalancerRules'), data: { publicipid: args.context.ipAddresses[0].id }, dataType: 'json', async: true, success: function(data) { var loadBalancerData = data.listloadbalancerrulesresponse.loadbalancerrule; var loadVMTotal = loadBalancerData ? loadBalancerData.length : 0; var loadVMCurrent = 0; $(loadBalancerData).each(function() { var item = this; // Get instances $.ajax({ url: createURL('listLoadBalancerRuleInstances'), dataType: 'json', async: true, data: { id: item.id }, success: function(data) { loadVMCurrent++; $.extend(item, { _itemData: data .listloadbalancerruleinstancesresponse.loadbalancerruleinstance }); if (loadVMCurrent == loadVMTotal) { args.response.success({ data: loadBalancerData }); } }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); }); } }); } }, // Port forwarding rules portForwarding: { listView: $.extend(true, {}, cloudStack.sections.instances, { listView: { dataProvider: function(args) { $.ajax({ url: createURL('listVirtualMachines'), data: { networkid: args.context.ipAddresses[0].associatednetworkid }, dataType: 'json', async: true, success: function(data) { args.response.success({ data: $.grep( data.listvirtualmachinesresponse.virtualmachine ? data.listvirtualmachinesresponse.virtualmachine : [], function(instance) { return $.inArray(instance.state, [ 'Destroyed' ]) == -1; } ) }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } } }), fields: { 'private-ports': { edit: true, label: 'Private Ports', range: ['privateport', 'privateendport'] }, 'public-ports': { edit: true, label: 'Public Ports', range: ['publicport', 'publicendport'] }, 'protocol': { label: 'Protocol', select: function(args) { args.response.success({ data: [ { name: 'tcp', description: 'TCP' }, { name: 'udp', description: 'UDP' } ] }); } }, 'add-vm': { label: 'Add VM', addButton: true } }, add: { label: 'Add VM', action: function(args) { var openFirewall = g_firewallRuleUiEnabled == "true" ? false : true; $.ajax({ url: createURL('createPortForwardingRule'), data: $.extend(args.data, { openfirewall: openFirewall, ipaddressid: args.context.ipAddresses[0].id, virtualmachineid: args.itemData[0].id }), dataType: 'json', async: true, success: function(data) { args.response.success({ _custom: { jobId: data.createportforwardingruleresponse.jobid }, notification: { label: 'Add port forwarding rule', poll: pollAsyncJobResult } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } }, actions: { destroy: { label: 'Remove port forwarding rule', 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: 'Remove port forwarding rule ' + args.context.multiRule[0].id, poll: pollAsyncJobResult } }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } } }, dataProvider: function(args) { $.ajax({ url: createURL('listPortForwardingRules'), data: { ipaddressid: args.context.ipAddresses[0].id }, 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; $.ajax({ url: createURL('listVirtualMachines'), dataType: 'json', async: true, data: { id: item.virtualmachineid }, success: function(data) { loadCurrent++; $.extend(item, { _itemData: data.listvirtualmachinesresponse.virtualmachine, _context: { instances: data.listvirtualmachinesresponse.virtualmachine } }); if (loadCurrent == loadTotal) { args.response.success({ data: portForwardingData }); } } }); }); }, error: function(data) { args.response.error(parseXMLHttpResponse(data)); } }); } } }) }, vpn: { title: 'VPN', custom: function(args) { var ipAddress = args.context.ipAddresses[0].ipaddress; var psk = args.context.ipAddresses[0].remoteaccessvpn.presharedkey; return $('
') .append( $('