mirror of https://github.com/apache/cloudstack.git
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/cloudstack
This commit is contained in:
commit
89fa121a0c
|
|
@ -0,0 +1,22 @@
|
|||
<!-- 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.
|
||||
-->
|
||||
|
||||
<!ENTITY PRODUCT "CloudStack">
|
||||
<!ENTITY BOOKID "Technical Documentation">
|
||||
<!ENTITY YEAR "2013">
|
||||
<!ENTITY HOLDER "Apache Software Foundation">
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
<!ENTITY % BOOK_ENTITIES SYSTEM "CloudStack_GSoC_Guide.ent">
|
||||
%BOOK_ENTITIES;
|
||||
<!ENTITY % xinclude SYSTEM "http://www.docbook.org/xml/4.4/xinclude.mod">
|
||||
%xinclude;
|
||||
]>
|
||||
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<book>
|
||||
<bookinfo id="cloudstack_gsoc_2013">
|
||||
<title>&PRODUCT; Guide for the 2013 Google Summer of Code</title>
|
||||
<productname>Apache CloudStack</productname>
|
||||
<productnumber>4.3.0</productnumber>
|
||||
<edition>1</edition>
|
||||
<pubsnumber></pubsnumber>
|
||||
<abstract>
|
||||
<para>
|
||||
Guide for 2013 Google Summer of Code Projects.
|
||||
</para>
|
||||
</abstract>
|
||||
<corpauthor>
|
||||
<inlinemediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="Common_Content/images/title_logo.svg" format="SVG" />
|
||||
</imageobject>
|
||||
</inlinemediaobject>
|
||||
</corpauthor>
|
||||
<xi:include href="Common_Content/Legal_Notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
<xi:include href="Author_Group.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
</bookinfo>
|
||||
<xi:include href="gsoc-tuna.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
|
||||
|
||||
</book>
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
<!ENTITY % BOOK_ENTITIES SYSTEM "CloudStack_GSoC_Guide.ent">
|
||||
%BOOK_ENTITIES;
|
||||
]>
|
||||
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<chapter id="gsoc-tuna">
|
||||
<title>Nguyen's 2013 GSoC Proposal</title>
|
||||
<para>This chapter describes Nguyen 2013 Google Summer of Code project within the &PRODUCT; ASF project. It is a copy paste of the submitted proposal.</para>
|
||||
</chapter>
|
||||
|
|
@ -27,7 +27,8 @@
|
|||
Basic zones and security groups-enabled Advanced zones. For security groups-enabled Advanced
|
||||
zones, it implies multiple subnets can be added to the same VLAN. With the addition of this
|
||||
feature, you will be able to add IP address ranges from the same subnet or from a different one
|
||||
when IP address are exhausted. To support this feature, the capability of
|
||||
when IP address are exhausted. This would in turn allows you to employ higher number of subnets
|
||||
and thus reduce the address management overhead. To support this feature, the capability of
|
||||
<code>createVlanIpRange</code> API is extended to add IP ranges also from a different
|
||||
subnet.</para>
|
||||
<para>Ensure that you manually configure the gateway of the new subnet before adding the IP range.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
|
||||
%BOOK_ENTITIES;
|
||||
]>
|
||||
|
||||
<!-- 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.
|
||||
-->
|
||||
<section id="pvlan">
|
||||
<title>Isolation in Advanced Zone Using Private VLAN</title>
|
||||
<para/>
|
||||
<section id="about-pvlan">
|
||||
<title>About Private VLAN</title>
|
||||
<para>In an Ethernet switch, a VLAN is a broadcast domain in which hosts can establish direct
|
||||
communication with each another at Layer 2. Private VLAN is designed as an extension of VLAN
|
||||
standard to add further segmentation of the logical broadcast domain. A regular VLAN is a
|
||||
single broadcast domain, whereas a private VLAN partitions a larger VLAN broadcast domain into
|
||||
smaller sub-domains. A sub-domain is represented by a pair of VLANs: a Primary VLAN and a
|
||||
Secondary VLAN. The original VLAN that is being divided into smaller groups is called
|
||||
Primary, That implies all VLAN pairs in a private VLAN share the same Primary VLAN. All the
|
||||
secondary VLANs exist only inside the Primary. Each Secondary VLAN has a specific VLAN ID
|
||||
associated to it, which differentiates one sub-domain from another.</para>
|
||||
<para>For further reading:</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><ulink
|
||||
url="http://www.cisco.com/en/US/docs/switches/lan/catalyst3750/software/release/12.2_25_see/configuration/guide/swpvlan.html#wp1038379"
|
||||
>Understanding Private VLANs</ulink></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><ulink url="http://tools.ietf.org/html/rfc5517">Cisco Systems' Private VLANs: Scalable
|
||||
Security in a Multi-Client Environment</ulink></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><ulink url="http://kb.vmware.com">Private VLAN (PVLAN) on vNetwork Distributed Switch
|
||||
- Concept Overview (1010691)</ulink></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section id="prereq-pvlan">
|
||||
<title>Prerequisites</title>
|
||||
<para>Ensure that you configure private VLAN on your physical switches out-of-band.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# Publican configuration file for CloudStack Complete Documentation Set
|
||||
# Contains all technical docs except release notes
|
||||
# Config::Simple 4.58
|
||||
# Tue May 29 00:57:27 2012
|
||||
#
|
||||
# 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.
|
||||
|
||||
xml_lang: en-US
|
||||
type: Book
|
||||
docname: CloudStack_GSoC_Guide
|
||||
brand: cloudstack
|
||||
chunk_first: 1
|
||||
chunk_section_depth: 1
|
||||
|
|
@ -54,10 +54,9 @@ public interface UserVmDao extends GenericDao<UserVmVO, Long> {
|
|||
/**
|
||||
* List user vm instances with virtualized networking (i.e. not direct attached networking) for the given account and datacenter
|
||||
* @param accountId will search for vm instances belonging to this account
|
||||
* @param dcId will search for vm instances in this zone
|
||||
* @return the list of vm instances owned by the account in the given data center that have virtualized networking (not direct attached networking)
|
||||
*/
|
||||
List<UserVmVO> listVirtualNetworkInstancesByAcctAndZone(long accountId, long dcId, long networkId);
|
||||
List<UserVmVO> listVirtualNetworkInstancesByAcctAndNetwork(long accountId, long networkId);
|
||||
|
||||
List<UserVmVO> listByNetworkIdAndStates(long networkId, State... states);
|
||||
|
||||
|
|
|
|||
|
|
@ -283,11 +283,10 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<UserVmVO> listVirtualNetworkInstancesByAcctAndZone(long accountId, long dcId, long networkId) {
|
||||
public List<UserVmVO> listVirtualNetworkInstancesByAcctAndNetwork(long accountId, long networkId) {
|
||||
|
||||
SearchCriteria<UserVmVO> sc = AccountDataCenterVirtualSearch.create();
|
||||
sc.setParameters("account", accountId);
|
||||
sc.setParameters("dc", dcId);
|
||||
sc.setJoinParameters("nicSearch", "networkId", networkId);
|
||||
|
||||
return listBy(sc);
|
||||
|
|
|
|||
|
|
@ -1835,9 +1835,8 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
|||
}
|
||||
}
|
||||
|
||||
IPAddressVO addr = _ipAddressDao.findById(loadBalancer.getSourceIpAddressId());
|
||||
List<UserVmVO> userVms = _vmDao.listVirtualNetworkInstancesByAcctAndZone(loadBalancer.getAccountId(),
|
||||
addr.getDataCenterId(), loadBalancer.getNetworkId());
|
||||
List<UserVmVO> userVms = _vmDao.listVirtualNetworkInstancesByAcctAndNetwork(loadBalancer.getAccountId(),
|
||||
loadBalancer.getNetworkId());
|
||||
|
||||
for (UserVmVO userVm : userVms) {
|
||||
// if the VM is destroyed, being expunged, in an error state, or in
|
||||
|
|
|
|||
|
|
@ -4709,7 +4709,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
|
||||
@Override
|
||||
public void prepareStop(VirtualMachineProfile<UserVmVO> profile) {
|
||||
UserVmVO vm = profile.getVirtualMachine();
|
||||
UserVmVO vm = _vmDao.findById(profile.getId());
|
||||
if (vm.getState() == State.Running)
|
||||
collectVmDiskStatistics(vm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,10 +170,10 @@ class TestInternalLb(cloudstackTestCase):
|
|||
networkid=ntwk.id)
|
||||
|
||||
#5) Assign the VM to the Internal Load Balancer
|
||||
applb.assign(self.apiclient, vms=[vm.id])
|
||||
applb.assign(self.apiclient, vms=[vm])
|
||||
|
||||
#6) Remove the vm from the Interanl Load Balancer
|
||||
applb.remove(self.apiclient, vms=[vm.id])
|
||||
applb.remove(self.apiclient, vms=[vm])
|
||||
|
||||
#7) Delete the Load Balancer
|
||||
applb.delete(self.apiclient)
|
||||
|
|
|
|||
|
|
@ -485,7 +485,7 @@ class TestISO(cloudstackTestCase):
|
|||
if len(self.zones) <= 1:
|
||||
self.skipTest("Not enough zones available to perform copy template")
|
||||
|
||||
self.services["destzoneid"] = filter(lambda z: z.id != self.zone.id, self.zones)[0]
|
||||
self.services["destzoneid"] = filter(lambda z: z.id != self.zone.id, self.zones)[0].id
|
||||
|
||||
self.debug("Copy ISO from %s to %s" % (
|
||||
self.zone.id,
|
||||
|
|
|
|||
|
|
@ -24,96 +24,154 @@ from marvin.integration.lib.base import *
|
|||
from marvin.integration.lib.common import *
|
||||
from nose.plugins.attrib import attr
|
||||
|
||||
class Services:
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"account": {
|
||||
"email": "test@test.com",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "test",
|
||||
"password": "password",
|
||||
},
|
||||
"virtual_machine": {
|
||||
"displayname": "Test VM",
|
||||
"username": "root",
|
||||
"password": "password",
|
||||
"ssh_port": 22,
|
||||
"hypervisor": 'XenServer',
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"protocol": 'TCP',
|
||||
},
|
||||
"ostype": 'CentOS 5.3 (64-bit)',
|
||||
"service_offering": {
|
||||
"name": "Tiny Instance",
|
||||
"displaytext": "Tiny Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
"memory": 256,
|
||||
},
|
||||
"network_offering": {
|
||||
"name": "Network offering for internal lb service",
|
||||
"displaytext": "Network offering for internal lb service",
|
||||
"guestiptype": "Isolated",
|
||||
"traffictype": "Guest",
|
||||
"supportedservices": "Vpn,Dhcp,Dns,Lb,UserData,SourceNat,StaticNat,PortForwarding,NetworkACL",
|
||||
"serviceProviderList": {
|
||||
"Dhcp": "VpcVirtualRouter",
|
||||
"Dns": "VpcVirtualRouter",
|
||||
"Vpn": "VpcVirtualRouter",
|
||||
"UserData": "VpcVirtualRouter",
|
||||
"Lb": "InternalLbVM",
|
||||
"SourceNat": "VpcVirtualRouter",
|
||||
"StaticNat": "VpcVirtualRouter",
|
||||
"PortForwarding": "VpcVirtualRouter",
|
||||
"NetworkACL": "VpcVirtualRouter",
|
||||
},
|
||||
"serviceCapabilityList": {
|
||||
"SourceNat": {"SupportedSourceNatTypes": "peraccount"},
|
||||
"Lb": {"lbSchemes": "internal", "SupportedLbIsolation": "dedicated"}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TestNetworkACL(cloudstackTestCase):
|
||||
networkOfferingId = 11
|
||||
networkId = None
|
||||
vmId = None
|
||||
vpcId = None
|
||||
aclId = None
|
||||
|
||||
zoneId = 1
|
||||
serviceOfferingId = 1
|
||||
templateId = 5
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.apiclient = super(TestNetworkACL, cls).getClsTestClient().getApiClient()
|
||||
cls.services = Services().services
|
||||
cls.zone = get_zone(cls.apiclient, cls.services)
|
||||
cls.domain = get_domain(cls.apiclient)
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
cls.account = Account.create(cls.apiclient, services=cls.services["account"])
|
||||
cls.template = get_template(
|
||||
cls.apiclient,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"]
|
||||
)
|
||||
cls.debug("Successfully created account: %s, id: \
|
||||
%s" % (cls.account.name,\
|
||||
cls.account.id))
|
||||
cls.cleanup = [cls.account]
|
||||
|
||||
def setUp(self):
|
||||
self.apiClient = self.testClient.getApiClient()
|
||||
|
||||
|
||||
|
||||
@attr(tags=["advanced"])
|
||||
def test_networkAcl(self):
|
||||
def test_network_acl(self):
|
||||
"""Test network ACL lists and items in VPC"""
|
||||
|
||||
# 0) Get the default network offering for VPC
|
||||
networkOffering = NetworkOffering.list(self.apiclient, name="DefaultIsolatedNetworkOfferingForVpcNetworks")
|
||||
self.assert_(networkOffering is not None and len(networkOffering) > 0, "No VPC based network offering")
|
||||
|
||||
# 1) Create VPC
|
||||
self.createVPC()
|
||||
vpcOffering = VpcOffering.list(self.apiclient)
|
||||
self.assert_(vpcOffering is not None and len(vpcOffering)>0, "No VPC offerings found")
|
||||
self.services["vpc"] = {}
|
||||
self.services["vpc"]["name"] = "vpc-networkacl"
|
||||
self.services["vpc"]["displaytext"] = "vpc-networkacl"
|
||||
self.services["vpc"]["cidr"] = "10.1.1.0/24"
|
||||
vpc = VPC.create(
|
||||
apiclient=self.apiclient,
|
||||
services=self.services["vpc"],
|
||||
networkDomain="vpc.networkacl",
|
||||
vpcofferingid=vpcOffering[0].id,
|
||||
zoneid=self.zone.id,
|
||||
account=self.account.name,
|
||||
domainid=self.domain.id
|
||||
)
|
||||
self.assert_(vpc is not None, "VPC creation failed")
|
||||
|
||||
# 2) Create ACl
|
||||
self.createACL()
|
||||
# 2) Create ACL
|
||||
aclgroup = NetworkACLList.create(apiclient=self.apiclient, services={}, name="acl", description="acl", vpcid=vpc.id)
|
||||
self.assertIsNotNone(aclgroup, "Failed to create NetworkACL list")
|
||||
self.debug("Created a network ACL list %s" % aclgroup.name)
|
||||
|
||||
# 3) Create ACl Item
|
||||
self.createACLItem()
|
||||
# 3) Create ACL Item
|
||||
aclitem = NetworkACL.create(apiclient=self.apiclient, services={},
|
||||
protocol="TCP", number="10", action="Deny", aclid=aclgroup.id, cidrlist=["0.0.0.0/0"])
|
||||
self.assertIsNotNone(aclitem, "Network failed to aclItem")
|
||||
self.debug("Added a network ACL %s to ACL list %s" % (aclitem.id, aclgroup.name))
|
||||
|
||||
# 4) Create network with ACL
|
||||
self.createNetwork()
|
||||
self.services["vpcnetwork"] = {}
|
||||
self.services["vpcnetwork"]["name"] = "vpcntwk"
|
||||
self.services["vpcnetwork"]["displaytext"] = "vpcntwk"
|
||||
ntwk = Network.create(
|
||||
apiclient=self.apiclient,
|
||||
services=self.services["vpcnetwork"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.domain.id,
|
||||
networkofferingid=networkOffering[0].id,
|
||||
zoneid=self.zone.id,
|
||||
vpcid=vpc.id,
|
||||
aclid=aclgroup.id,
|
||||
gateway="10.1.1.1",
|
||||
netmask="255.255.255.192"
|
||||
)
|
||||
self.assertIsNotNone(ntwk, "Network failed to create")
|
||||
self.debug("Network %s created in VPC %s" %(ntwk.id, vpc.id))
|
||||
|
||||
# 5) Deploy a vm
|
||||
self.deployVm()
|
||||
self.services["virtual_machine"]["networkids"] = ntwk.id
|
||||
vm = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"],
|
||||
templateid=self.template.id,
|
||||
zoneid=self.zone.id,
|
||||
accountid=self.account.name,
|
||||
domainid= self.domain.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
)
|
||||
self.assert_(vm is not None, "VM failed to deploy")
|
||||
self.assert_(vm.state == 'Running', "VM is not running")
|
||||
self.debug("VM %s deployed in VPC %s" %(vm.id, vpc.id))
|
||||
|
||||
def createACL(self):
|
||||
createAclCmd = createNetworkACLList.createNetworkACLListCmd()
|
||||
createAclCmd.name = "acl1"
|
||||
createAclCmd.description = "new acl"
|
||||
createAclCmd.vpcId = TestNetworkACL.vpcId
|
||||
createAclResponse = self.apiClient.createNetworkACLList(createAclCmd)
|
||||
TestNetworkACL.aclId = createAclResponse.id
|
||||
|
||||
def createACLItem(self):
|
||||
createAclItemCmd = createNetworkACL.createNetworkACLCmd()
|
||||
createAclItemCmd.cidr = "0.0.0.0/0"
|
||||
createAclItemCmd.protocol = "TCP"
|
||||
createAclItemCmd.number = "10"
|
||||
createAclItemCmd.action = "Deny"
|
||||
createAclItemCmd.aclId = TestNetworkACL.aclId
|
||||
createAclItemResponse = self.apiClient.createNetworkACL(createAclItemCmd)
|
||||
self.assertIsNotNone(createAclItemResponse.id, "Network failed to aclItem")
|
||||
|
||||
def createVPC(self):
|
||||
createVPCCmd = createVPC.createVPCCmd()
|
||||
createVPCCmd.name = "new vpc"
|
||||
createVPCCmd.cidr = "10.1.1.0/24"
|
||||
createVPCCmd.displaytext = "new vpc"
|
||||
createVPCCmd.vpcofferingid = 1
|
||||
createVPCCmd.zoneid = self.zoneId
|
||||
createVPCResponse = self.apiClient.createVPC(createVPCCmd)
|
||||
TestNetworkACL.vpcId = createVPCResponse.id
|
||||
|
||||
|
||||
def createNetwork(self):
|
||||
createNetworkCmd = createNetwork.createNetworkCmd()
|
||||
createNetworkCmd.name = "vpc network"
|
||||
createNetworkCmd.displaytext = "vpc network"
|
||||
createNetworkCmd.netmask = "255.255.255.0"
|
||||
createNetworkCmd.gateway = "10.1.1.1"
|
||||
createNetworkCmd.zoneid = self.zoneId
|
||||
createNetworkCmd.vpcid = TestNetworkACL.vpcId
|
||||
createNetworkCmd.networkofferingid = TestNetworkACL.networkOfferingId
|
||||
createNetworkCmd.aclId = TestNetworkACL.aclId
|
||||
createNetworkResponse = self.apiClient.createNetwork(createNetworkCmd)
|
||||
TestNetworkACL.networkId = createNetworkResponse.id
|
||||
|
||||
self.assertIsNotNone(createNetworkResponse.id, "Network failed to create")
|
||||
|
||||
def deployVm(self):
|
||||
deployVirtualMachineCmd = deployVirtualMachine.deployVirtualMachineCmd()
|
||||
deployVirtualMachineCmd.networkids = TestNetworkACL.networkId
|
||||
deployVirtualMachineCmd.serviceofferingid = TestNetworkACL.serviceOfferingId
|
||||
deployVirtualMachineCmd.zoneid = TestNetworkACL.zoneId
|
||||
deployVirtualMachineCmd.templateid = TestNetworkACL.templateId
|
||||
deployVirtualMachineCmd.hypervisor = "XenServer"
|
||||
deployVMResponse = self.apiClient.deployVirtualMachine(deployVirtualMachineCmd)
|
||||
TestNetworkACL.vmId = deployVMResponse.id
|
||||
|
||||
def tearDown(self):
|
||||
#destroy the vm
|
||||
if TestNetworkACL.vmId is not None:
|
||||
destroyVirtualMachineCmd = destroyVirtualMachine.destroyVirtualMachineCmd()
|
||||
destroyVirtualMachineCmd.id = TestNetworkACL.vmId
|
||||
destroyVirtualMachineResponse = self.apiClient.destroyVirtualMachine(destroyVirtualMachineCmd)
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cleanup_resources(cls.apiclient, cls.cleanup)
|
||||
except Exception, e:
|
||||
raise Exception("Cleanup failed with %s" % e)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,15 @@ class Services:
|
|||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"account": {
|
||||
"email": "test@test.com",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "test",
|
||||
# Random characters are appended in create account to
|
||||
# ensure unique username generated each time
|
||||
"password": "password",
|
||||
},
|
||||
"off":
|
||||
{
|
||||
"name": "Service Offering",
|
||||
|
|
|
|||
|
|
@ -665,7 +665,7 @@ class TestTemplates(cloudstackTestCase):
|
|||
if len(self.zones) <= 1:
|
||||
self.skipTest("Not enough zones available to perform copy template")
|
||||
|
||||
self.services["destzoneid"] = filter(lambda z: z.id != self.services["sourcezoneid"], self.zones)[0]
|
||||
self.services["destzoneid"] = filter(lambda z: z.id != self.services["sourcezoneid"], self.zones)[0].id
|
||||
|
||||
self.debug("Copy template from Zone: %s to %s" % (
|
||||
self.services["sourcezoneid"],
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ fix_nameserver() {
|
|||
# Replace /etc/resolv.conf also
|
||||
cat > /etc/resolv.conf << EOF
|
||||
nameserver 8.8.8.8
|
||||
nameserver 4.4.4.4
|
||||
nameserver 8.8.4.4
|
||||
EOF
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ fix_nameserver() {
|
|||
# Replace /etc/resolv.conf also
|
||||
cat > /etc/resolv.conf << EOF
|
||||
nameserver 8.8.8.8
|
||||
nameserver 4.4.4.4
|
||||
nameserver 8.8.4.4
|
||||
EOF
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"dns2": "4.4.4.4",
|
||||
"dns2": "8.8.4.4",
|
||||
"dns1": "8.8.8.8",
|
||||
"securitygroupenabled": "true",
|
||||
"localstorageenabled": "true",
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"dns2": "4.4.4.4",
|
||||
"dns2": "8.8.4.4",
|
||||
"dns1": "8.8.8.8",
|
||||
"securitygroupenabled": "true",
|
||||
"localstorageenabled": "true",
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"dns2": "4.4.4.4",
|
||||
"dns2": "8.8.4.4",
|
||||
"dns1": "8.8.8.8",
|
||||
"securitygroupenabled": "true",
|
||||
"localstorageenabled": "true",
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"dns2": "4.4.4.4",
|
||||
"dns2": "8.8.4.4",
|
||||
"dns1": "8.8.8.8",
|
||||
"securitygroupenabled": "true",
|
||||
"localstorageenabled": "true",
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ def describe_setup_in_basic_mode():
|
|||
for l in range(1):
|
||||
z = zone()
|
||||
z.dns1 = "8.8.8.8"
|
||||
z.dns2 = "4.4.4.4"
|
||||
z.dns2 = "8.8.4.4"
|
||||
z.internaldns1 = "192.168.110.254"
|
||||
z.internaldns2 = "192.168.110.253"
|
||||
z.name = "test"+str(l)
|
||||
|
|
@ -390,7 +390,7 @@ def describe_setup_in_eip_mode():
|
|||
for l in range(1):
|
||||
z = zone()
|
||||
z.dns1 = "8.8.8.8"
|
||||
z.dns2 = "4.4.4.4"
|
||||
z.dns2 = "8.8.4.4"
|
||||
z.internaldns1 = "192.168.110.254"
|
||||
z.internaldns2 = "192.168.110.253"
|
||||
z.name = "test"+str(l)
|
||||
|
|
@ -519,7 +519,7 @@ def describe_setup_in_advanced_mode():
|
|||
for l in range(1):
|
||||
z = zone()
|
||||
z.dns1 = "8.8.8.8"
|
||||
z.dns2 = "4.4.4.4"
|
||||
z.dns2 = "8.8.4.4"
|
||||
z.internaldns1 = "192.168.110.254"
|
||||
z.internaldns2 = "192.168.110.253"
|
||||
z.name = "test"+str(l)
|
||||
|
|
@ -645,7 +645,7 @@ def describe_setup_in_advancedsg_mode():
|
|||
for l in range(1):
|
||||
z = zone()
|
||||
z.dns1 = "8.8.8.8"
|
||||
z.dns2 = "4.4.4.4"
|
||||
z.dns2 = "8.8.4.4"
|
||||
z.internaldns1 = "192.168.110.254"
|
||||
z.internaldns2 = "192.168.110.253"
|
||||
z.name = "test"+str(l)
|
||||
|
|
|
|||
|
|
@ -1800,7 +1800,7 @@ class Network:
|
|||
def create(cls, apiclient, services, accountid=None, domainid=None,
|
||||
networkofferingid=None, projectid=None,
|
||||
subdomainaccess=None, zoneid=None,
|
||||
gateway=None, netmask=None, vpcid=None, guestcidr=None):
|
||||
gateway=None, netmask=None, vpcid=None, aclid=None, guestcidr=None):
|
||||
"""Create Network for account"""
|
||||
cmd = createNetwork.createNetworkCmd()
|
||||
cmd.name = services["name"]
|
||||
|
|
@ -1846,6 +1846,8 @@ class Network:
|
|||
cmd.guestcidr = guestcidr
|
||||
if vpcid:
|
||||
cmd.vpcid = vpcid
|
||||
if aclid:
|
||||
cmd.aclid = aclid
|
||||
return Network(apiclient.createNetwork(cmd).__dict__)
|
||||
|
||||
def delete(self, apiclient):
|
||||
|
|
@ -1888,25 +1890,55 @@ class NetworkACL:
|
|||
self.__dict__.update(items)
|
||||
|
||||
@classmethod
|
||||
def create(cls, apiclient, networkid, services, traffictype=None):
|
||||
def create(cls, apiclient, services, networkid=None, protocol=None,
|
||||
number=None, aclid=None, action='Allow', traffictype=None, cidrlist=[]):
|
||||
"""Create network ACL rules(Ingress/Egress)"""
|
||||
|
||||
cmd = createNetworkACL.createNetworkACLCmd()
|
||||
cmd.networkid = networkid
|
||||
if "networkid" in services:
|
||||
cmd.networkid = services["networkid"]
|
||||
elif networkid:
|
||||
cmd.networkid = networkid
|
||||
|
||||
if "protocol" in services:
|
||||
cmd.protocol = services["protocol"]
|
||||
if services["protocol"] == 'ICMP':
|
||||
cmd.icmptype = -1
|
||||
cmd.icmpcode = -1
|
||||
elif protocol:
|
||||
cmd.protocol = protocol
|
||||
|
||||
if services["protocol"] == 'ICMP':
|
||||
cmd.icmptype = -1
|
||||
cmd.icmpcode = -1
|
||||
else:
|
||||
if "startport" in services:
|
||||
cmd.startport = services["startport"]
|
||||
if "endport" in services:
|
||||
cmd.endport = services["endport"]
|
||||
|
||||
cmd.cidrlist = services["cidrlist"]
|
||||
if traffictype:
|
||||
if "cidrlist" in services:
|
||||
cmd.cidrlist = services["cidrlist"]
|
||||
elif cidrlist:
|
||||
cmd.cidrlist = cidrlist
|
||||
|
||||
if "traffictype" in services:
|
||||
cmd.traffictype = services["traffictype"]
|
||||
elif traffictype:
|
||||
cmd.traffictype = traffictype
|
||||
# Defaulted to Ingress
|
||||
|
||||
if "action" in services:
|
||||
cmd.action = services["action"]
|
||||
elif action:
|
||||
cmd.action = action
|
||||
|
||||
if "number" in services:
|
||||
cmd.number = services["number"]
|
||||
elif number:
|
||||
cmd.number = number
|
||||
|
||||
if "aclid" in services:
|
||||
cmd.aclid = services["aclid"]
|
||||
elif aclid:
|
||||
cmd.aclid = aclid
|
||||
|
||||
# Defaulted to Ingress
|
||||
return NetworkACL(apiclient.createNetworkACL(cmd).__dict__)
|
||||
|
||||
def delete(self, apiclient):
|
||||
|
|
@ -1925,6 +1957,50 @@ class NetworkACL:
|
|||
return(apiclient.listNetworkACLs(cmd))
|
||||
|
||||
|
||||
class NetworkACLList:
|
||||
"""Manage Network ACL lists lifecycle"""
|
||||
|
||||
def __init__(self, items):
|
||||
self.__dict__.update(items)
|
||||
|
||||
@classmethod
|
||||
def create(cls, apiclient, services, name=None, description=None, vpcid=None):
|
||||
"""Create network ACL container list"""
|
||||
|
||||
cmd = createNetworkACLList.createNetworkACLListCmd()
|
||||
if "name" in services:
|
||||
cmd.name = services["name"]
|
||||
elif name:
|
||||
cmd.name = name
|
||||
|
||||
if "description" in services:
|
||||
cmd.description = services["description"]
|
||||
elif description:
|
||||
cmd.description = description
|
||||
|
||||
if "vpcid" in services:
|
||||
cmd.vpcid = services["vpcid"]
|
||||
elif vpcid:
|
||||
cmd.vpcid = vpcid
|
||||
|
||||
return NetworkACLList(apiclient.createNetworkACLList(cmd).__dict__)
|
||||
|
||||
def delete(self, apiclient):
|
||||
"""Delete network acl list"""
|
||||
|
||||
cmd = deleteNetworkACLList.deleteNetworkACLListCmd()
|
||||
cmd.id = self.id
|
||||
return apiclient.deleteNetworkACLList(cmd)
|
||||
|
||||
@classmethod
|
||||
def list(cls, apiclient, **kwargs):
|
||||
"""List Network ACL lists"""
|
||||
|
||||
cmd = listNetworkACLLists.listNetworkACLListsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listNetworkACLLists(cmd))
|
||||
|
||||
|
||||
class Vpn:
|
||||
"""Manage VPN life cycle"""
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ if __name__ == "__main__":
|
|||
nsp = getResultObj(result)
|
||||
print nsp[0].id
|
||||
|
||||
result = '{ "listzonesresponse" : { "count":1 ,"zone" : [ {"id":1,"name":"test0","dns1":"8.8.8.8","dns2":"4.4.4.4","internaldns1":"192.168.110.254","internaldns2":"192.168.110.253","networktype":"Basic","securitygroupsenabled":true,"allocationstate":"Enabled","zonetoken":"5e818a11-6b00-3429-9a07-e27511d3169a","dhcpprovider":"DhcpServer"} ] } }'
|
||||
result = '{ "listzonesresponse" : { "count":1 ,"zone" : [ {"id":1,"name":"test0","dns1":"8.8.8.8","dns2":"8.8.4.4","internaldns1":"192.168.110.254","internaldns2":"192.168.110.253","networktype":"Basic","securitygroupsenabled":true,"allocationstate":"Enabled","zonetoken":"5e818a11-6b00-3429-9a07-e27511d3169a","dhcpprovider":"DhcpServer"} ] } }'
|
||||
zones = getResultObj(result)
|
||||
print zones[0].id
|
||||
res = authorizeSecurityGroupIngress.authorizeSecurityGroupIngressResponse()
|
||||
|
|
@ -165,7 +165,7 @@ if __name__ == "__main__":
|
|||
asynJob = getResultObj(result)
|
||||
print asynJob
|
||||
|
||||
result = '{ "createzoneresponse" : { "zone" : {"id":1,"name":"test0","dns1":"8.8.8.8","dns2":"4.4.4.4","internaldns1":"192.168.110.254","internaldns2":"192.168.110.253","networktype":"Basic","securitygroupsenabled":true,"allocationstate":"Enabled","zonetoken":"3442f287-e932-3111-960b-514d1f9c4610","dhcpprovider":"DhcpServer"} } }'
|
||||
result = '{ "createzoneresponse" : { "zone" : {"id":1,"name":"test0","dns1":"8.8.8.8","dns2":"8.8.4.4","internaldns1":"192.168.110.254","internaldns2":"192.168.110.253","networktype":"Basic","securitygroupsenabled":true,"allocationstate":"Enabled","zonetoken":"3442f287-e932-3111-960b-514d1f9c4610","dhcpprovider":"DhcpServer"} } }'
|
||||
res = createZone.createZoneResponse()
|
||||
zone = getResultObj(result, res)
|
||||
print zone.id
|
||||
|
|
|
|||
|
|
@ -154,6 +154,15 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.vpc-network-chart .tier-item .content .dashboard-item.disabled {
|
||||
/*+opacity:50%;*/
|
||||
filter: alpha(opacity=50);
|
||||
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
|
||||
-moz-opacity: 0.5;
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.vpc-network-chart .tier-item .content .dashboard-item:hover {
|
||||
background-color: #DBEDFE;
|
||||
/*+box-shadow:inset 0px 1px 2px #000000;*/
|
||||
|
|
@ -271,6 +280,8 @@
|
|||
float: left;
|
||||
/*+placement:shift 10px 176px;*/
|
||||
position: relative;
|
||||
left: 10px;
|
||||
top: 176px;
|
||||
left: 0px;
|
||||
top: 237px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,7 +231,15 @@
|
|||
$dashboardItem.append($total, $name);
|
||||
$dashboardItem.appendTo($dashboard);
|
||||
|
||||
if (dashboardItem._disabled) {
|
||||
$dashboardItem.addClass('disabled');
|
||||
}
|
||||
|
||||
$dashboardItem.click(function() {
|
||||
if ($dashboardItem.is('.disabled')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var section = cloudStack.vpc.sections[id];
|
||||
var $section = $('<div>');
|
||||
var $loading = $('<div>').addClass('loading-overlay');
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
var messages = args.action ? args.action.messages : {};
|
||||
var preAction = args.action ? args.action.preAction : {};
|
||||
var action = args.action ? args.action.action : {};
|
||||
var needsRefresh = args.action.needsRefresh;
|
||||
var section;
|
||||
var data = {
|
||||
id: $instanceRow.data('list-view-item-id'),
|
||||
|
|
@ -142,6 +143,12 @@
|
|||
$item: $instanceRow
|
||||
});
|
||||
} else {
|
||||
if (needsRefresh) {
|
||||
var $loading = $('<div>').addClass('loading-overlay');
|
||||
|
||||
$listView.prepend($loading);
|
||||
}
|
||||
|
||||
var actionArgs = {
|
||||
data: data,
|
||||
ref: options.ref,
|
||||
|
|
@ -206,6 +213,15 @@
|
|||
$instanceRow.data('json-obj'),
|
||||
actionFilter);
|
||||
}
|
||||
|
||||
if (needsRefresh) {
|
||||
if ($listView.closest('.detail-view').size()) {
|
||||
$('.detail-view:last .button.refresh').click();
|
||||
} else {
|
||||
$loading.remove();
|
||||
$listView.listView('refresh');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (additional && additional.complete)
|
||||
|
|
@ -293,7 +309,8 @@
|
|||
if (!args.action.action.externalLink &&
|
||||
!args.action.createForm &&
|
||||
args.action.addRow != 'true' &&
|
||||
!action.custom && !action.uiCustom) {
|
||||
!action.custom && !action.uiCustom &&
|
||||
!args.action.listView) {
|
||||
cloudStack.dialog.confirm({
|
||||
message: messages.confirm(messageArgs),
|
||||
action: function() {
|
||||
|
|
@ -306,6 +323,14 @@
|
|||
});
|
||||
} else if (action.custom || action.uiCustom) {
|
||||
performAction();
|
||||
} else if (args.action.listView) {
|
||||
cloudStack.dialog.listView({
|
||||
context: context,
|
||||
listView: args.action.listView,
|
||||
after: function(args) {
|
||||
performAction(null, { context: args.context });
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var addRow = args.action.addRow == "false" ? false : true;
|
||||
var isHeader = args.action.isHeader;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,13 @@
|
|||
}
|
||||
},
|
||||
fields: {
|
||||
|
||||
'rulenumber':{
|
||||
label:'Rule Number',
|
||||
edit:true
|
||||
|
||||
},
|
||||
|
||||
'cidrlist': { edit: true, label: 'label.cidr' },
|
||||
action: {
|
||||
label: 'Action',
|
||||
|
|
@ -442,8 +449,10 @@
|
|||
},
|
||||
|
||||
detailView: {
|
||||
isMaximized: true,
|
||||
name: 'Internal LB details',
|
||||
actions: {
|
||||
/*
|
||||
assignVm: {
|
||||
label: 'Assign VMs to Internal LB',
|
||||
messages: {
|
||||
|
|
@ -507,7 +516,8 @@
|
|||
notification: {
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
},
|
||||
},
|
||||
*/
|
||||
remove: {
|
||||
label: 'Delete Internal LB',
|
||||
messages: {
|
||||
|
|
@ -604,25 +614,161 @@
|
|||
|
||||
assignedVms: {
|
||||
title: 'Assigned VMs',
|
||||
multiple: true,
|
||||
fields: [
|
||||
{
|
||||
listView: {
|
||||
id: 'assignedVms',
|
||||
fields: {
|
||||
name: { label: 'label.name' },
|
||||
ipaddress: { label: 'label.ip.address' }
|
||||
}
|
||||
],
|
||||
dataProvider: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('listLoadBalancers'),
|
||||
data: {
|
||||
id: args.context.internalLoadBalancers[0].id
|
||||
},
|
||||
success: function(json) {
|
||||
var item = json.listloadbalancerssresponse.loadbalancer[0];
|
||||
args.response.success({ data: item.loadbalancerinstance });
|
||||
},
|
||||
dataProvider: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('listLoadBalancers'),
|
||||
data: {
|
||||
id: args.context.internalLoadBalancers[0].id
|
||||
},
|
||||
success: function(json) {
|
||||
var item = json.listloadbalancerssresponse.loadbalancer[0];
|
||||
args.response.success({ data: item.loadbalancerinstance });
|
||||
}
|
||||
});
|
||||
},
|
||||
actions: {
|
||||
add: {
|
||||
label: 'Assign VMs',
|
||||
messages: {
|
||||
notification: function(args) { return 'Assign VMs'; }
|
||||
},
|
||||
needsRefresh: true,
|
||||
listView: $.extend(true, {}, cloudStack.sections.instances.listView, {
|
||||
type: 'checkbox',
|
||||
filters: false,
|
||||
dataProvider: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('listVirtualMachines'),
|
||||
data: {
|
||||
networkid: args.context.networks[0].id,
|
||||
listAll: true
|
||||
},
|
||||
success: function(json) {
|
||||
var instances = json.listvirtualmachinesresponse.virtualmachine;
|
||||
|
||||
// Pre-select existing instances in LB rule
|
||||
$(instances).map(function(index, instance) {
|
||||
instance._isSelected = $.grep(
|
||||
args.context.internalLoadBalancers[0].loadbalancerinstance,
|
||||
|
||||
function(lbInstance) {
|
||||
return lbInstance.id == instance.id;
|
||||
}
|
||||
).length ? true : false;
|
||||
});
|
||||
|
||||
//remove assigned VMs (i.e. instance._isSelected == true)
|
||||
var items = [];
|
||||
if(instances != null) {
|
||||
for(var i = 0; i < instances.length; i++) {
|
||||
if(instances[i]._isSelected = true)
|
||||
continue;
|
||||
else
|
||||
items.push(instances[i]);
|
||||
}
|
||||
}
|
||||
|
||||
args.response.success({
|
||||
data: items
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}),
|
||||
action: function(args) {
|
||||
var vms = args.context.instances;
|
||||
var array1 = [];
|
||||
for(var i = 0; i < vms.length; i++) {
|
||||
array1.push(vms[i].id);
|
||||
}
|
||||
var virtualmachineids = array1.join(',');
|
||||
|
||||
$.ajax({
|
||||
url: createURL('assignToLoadBalancerRule'),
|
||||
data: {
|
||||
id: args.context.internalLoadBalancers[0].id,
|
||||
virtualmachineids: virtualmachineids
|
||||
},
|
||||
dataType: 'json',
|
||||
async: true,
|
||||
success: function(data) {
|
||||
var jid = data.assigntoloadbalancerruleresponse.jobid;
|
||||
args.response.success({
|
||||
_custom: {
|
||||
jobId: jid,
|
||||
getUpdatedItem: function(json) {
|
||||
$('.list-view').listView('refresh');
|
||||
//return json.queryasyncjobresultresponse.jobresult.volume;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
notification: {
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
detailView: {
|
||||
actions: {
|
||||
remove: {
|
||||
label: 'remove VM from load balancer',
|
||||
addRow: 'false',
|
||||
messages: {
|
||||
confirm: function(args) {
|
||||
return 'Please confirm you want to remove VM from load balancer';
|
||||
},
|
||||
notification: function(args) {
|
||||
return 'remove VM from load balancer';
|
||||
}
|
||||
},
|
||||
action: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('removeFromLoadBalancerRule'),
|
||||
data: {
|
||||
id: args.context.internalLoadBalancers[0].id,
|
||||
virtualmachineids: args.context.assignedVms[0].id
|
||||
},
|
||||
success: function(json) {
|
||||
var jid = json.removefromloadbalancerruleresponse.jobid;
|
||||
args.response.success({
|
||||
_custom: { jobId: jid }
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
notificaton: {
|
||||
poll: pollAsyncJobResult
|
||||
}
|
||||
}
|
||||
},
|
||||
tabs: {
|
||||
details: {
|
||||
title: 'label.details',
|
||||
fields: [
|
||||
{
|
||||
name: { label: 'label.name' }
|
||||
},
|
||||
{
|
||||
ipaddress: { label: 'label.ip.address' }
|
||||
}
|
||||
],
|
||||
dataProvider: function(args) {
|
||||
setTimeout(function() {
|
||||
args.response.success({ data: args.context.assignedVms[0] });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3177,7 +3323,8 @@
|
|||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
action: function(args) {
|
||||
var dataObj = {
|
||||
|
|
@ -3447,17 +3594,41 @@
|
|||
}
|
||||
).length ? tier._highlighted = true : tier._highlighted = false;
|
||||
|
||||
// Get LB capabilities
|
||||
var lbSchemes = $.grep(
|
||||
$.grep(
|
||||
tier.service,
|
||||
function(service) {
|
||||
return service.name == 'Lb';
|
||||
}
|
||||
)[0].capability,
|
||||
function(capability) {
|
||||
return capability.name == 'LbSchemes';
|
||||
}
|
||||
);
|
||||
|
||||
var hasLbScheme = function(schemeVal) {
|
||||
return $.grep(
|
||||
lbSchemes,
|
||||
function(scheme) {
|
||||
return scheme.value == schemeVal;
|
||||
}
|
||||
).length ? true : false;
|
||||
};
|
||||
|
||||
return $.extend(tier, {
|
||||
_dashboardItems: [
|
||||
{
|
||||
id: 'internalLoadBalancers',
|
||||
name: 'Internal LB',
|
||||
total: internalLoadBalancers.count
|
||||
total: internalLoadBalancers.count,
|
||||
_disabled: !hasLbScheme('Internal')
|
||||
},
|
||||
{
|
||||
id: 'publicLbIps',
|
||||
name: 'Public LB IP',
|
||||
total: publicLbIps.count
|
||||
total: publicLbIps.count,
|
||||
_disabled: !hasLbScheme('Public')
|
||||
},
|
||||
{
|
||||
id: 'tierStaticNATs',
|
||||
|
|
|
|||
Loading…
Reference in New Issue