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
81d2a70bf3
|
|
@ -36,11 +36,3 @@ done
|
|||
export CLASSPATH
|
||||
PATH=/sbin:/usr/sbin:$PATH
|
||||
export PATH
|
||||
|
||||
#catalina.out owned by `cloud` not `root`
|
||||
if [ ! -f $TOMCAT_LOG ]; then
|
||||
touch $TOMCAT_LOG
|
||||
chown $TOMCAT_USER:$TOMCAT_USER $TOMCAT_LOG
|
||||
else
|
||||
chown $TOMCAT_USER:$TOMCAT_USER $TOMCAT_LOG
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -216,6 +216,8 @@ ln -sf /var/log/%{name}/management ${RPM_BUILD_ROOT}%{_datadir}/%{name}-manageme
|
|||
ln -sf /var/cache/%{name}/management/temp ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/temp
|
||||
ln -sf /var/cache/%{name}/management/work ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/work
|
||||
|
||||
/bin/touch ${RPM_BUILD_ROOT}%{_localstatedir}/log/%{name}/management/catalina.out
|
||||
|
||||
install -D client/target/utilities/bin/cloud-migrate-databases ${RPM_BUILD_ROOT}%{_bindir}/%{name}-migrate-databases
|
||||
install -D client/target/utilities/bin/cloud-set-guest-password ${RPM_BUILD_ROOT}%{_bindir}/%{name}-set-guest-password
|
||||
install -D client/target/utilities/bin/cloud-set-guest-sshkey ${RPM_BUILD_ROOT}%{_bindir}/%{name}-set-guest-sshkey
|
||||
|
|
@ -519,6 +521,7 @@ fi
|
|||
%dir %attr(0770,root,root) %{_localstatedir}/log/%{name}-management
|
||||
%{_defaultdocdir}/%{name}-management-%{version}/LICENSE
|
||||
%{_defaultdocdir}/%{name}-management-%{version}/NOTICE
|
||||
%attr(0644,cloud,cloud) %{_localstatedir}/log/%{name}/management/catalina.out
|
||||
|
||||
%files agent
|
||||
%attr(0755,root,root) %{_bindir}/%{name}-setup-agent
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import java.util.Comparator;
|
|||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
|
@ -373,15 +374,6 @@ import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd;
|
|||
import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.*;
|
||||
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.DeleteVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.CreateStaticRouteCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.CreateVPCCmd;
|
||||
import org.apache.cloudstack.api.command.user.vpc.DeleteStaticRouteCmd;
|
||||
|
|
@ -1184,10 +1176,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
allHosts.remove(srcHost);
|
||||
|
||||
// Check if the host has storage pools for all the volumes of the vm to be migrated.
|
||||
for (Host host : allHosts) {
|
||||
for (Iterator<HostVO> iterator = allHosts.iterator(); iterator.hasNext();) {
|
||||
Host host = iterator.next();
|
||||
Map<Volume, List<StoragePool>> volumePools = findSuitablePoolsForVolumes(vmProfile, host);
|
||||
if (volumePools.isEmpty()) {
|
||||
allHosts.remove(host);
|
||||
iterator.remove();
|
||||
} else {
|
||||
if (!host.getClusterId().equals(srcHost.getClusterId()) || usesLocal) {
|
||||
requiresStorageMotion.put(host, true);
|
||||
|
|
|
|||
|
|
@ -755,6 +755,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
}
|
||||
|
||||
if (vm.getState() == State.Running && vm.getHostId() != null) {
|
||||
collectVmDiskStatistics(vm);
|
||||
return _itMgr.reboot(vm, null, caller, owner);
|
||||
} else {
|
||||
s_logger.error("Vm id=" + vmId
|
||||
|
|
@ -3379,9 +3380,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
boolean status;
|
||||
State vmState = vm.getState();
|
||||
|
||||
// Collect vm disk statistics from host before stopping Vm
|
||||
collectVmDiskStatistics(vm);
|
||||
|
||||
try {
|
||||
VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid());
|
||||
status = vmEntity.destroy(new Long(userId).toString());
|
||||
|
|
@ -3830,7 +3828,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
"No permission to migrate VM, Only Root Admin can migrate a VM!");
|
||||
}
|
||||
|
||||
VMInstanceVO vm = _vmInstanceDao.findById(vmId);
|
||||
UserVmVO vm = _vmDao.findById(vmId);
|
||||
if (vm == null) {
|
||||
throw new InvalidParameterValueException(
|
||||
"Unable to find the VM by id=" + vmId);
|
||||
|
|
@ -3921,6 +3919,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
+ " already has max Running VMs(count includes system VMs), cannot migrate to this host");
|
||||
}
|
||||
|
||||
collectVmDiskStatistics(vm);
|
||||
VMInstanceVO migratedVm = _itMgr.migrate(vm, srcHostId, dest);
|
||||
return migratedVm;
|
||||
}
|
||||
|
|
@ -4710,6 +4709,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
|||
|
||||
@Override
|
||||
public void prepareStop(VirtualMachineProfile<UserVmVO> profile) {
|
||||
UserVmVO vm = profile.getVirtualMachine();
|
||||
if (vm.getState() == State.Running)
|
||||
collectVmDiskStatistics(vm);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,228 +25,163 @@ 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 TestInternalLb(cloudstackTestCase):
|
||||
networkOfferingId = None
|
||||
networkId = None
|
||||
vmId = None
|
||||
lbId = None
|
||||
"""Test Internal LB
|
||||
"""
|
||||
|
||||
zoneId = 1
|
||||
serviceOfferingId = 1
|
||||
templateId = 5
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.apiclient = super(TestInternalLb, 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]
|
||||
|
||||
|
||||
serviceProviderList = [
|
||||
{
|
||||
"provider": "VpcVirtualRouter",
|
||||
"service": "Vpn"
|
||||
},
|
||||
{
|
||||
"provider": "VpcVirtualRouter",
|
||||
"service": "UserData"
|
||||
},
|
||||
{
|
||||
"provider": "VpcVirtualRouter",
|
||||
"service": "Dhcp"
|
||||
},
|
||||
{
|
||||
"provider": "VpcVirtualRouter",
|
||||
"service": "Dns"
|
||||
},
|
||||
{
|
||||
"provider": "InternalLbVM",
|
||||
"service": "Lb"
|
||||
},
|
||||
{
|
||||
"provider": "VpcVirtualRouter",
|
||||
"service": "SourceNat"
|
||||
},
|
||||
{
|
||||
"provider": "VpcVirtualRouter",
|
||||
"service": "StaticNat"
|
||||
},
|
||||
{
|
||||
"provider": "VpcVirtualRouter",
|
||||
"service": "PortForwarding"
|
||||
},
|
||||
{
|
||||
"provider": "VpcVirtualRouter",
|
||||
"service": "NetworkACL"
|
||||
}
|
||||
]
|
||||
|
||||
serviceCapsList = [
|
||||
{
|
||||
"service": "SourceNat",
|
||||
"capabilitytype": "SupportedSourceNatTypes",
|
||||
"capabilityvalue": "peraccount"
|
||||
},
|
||||
{
|
||||
"service": "Lb",
|
||||
"capabilitytype": "SupportedLbIsolation",
|
||||
"capabilityvalue": "dedicated"
|
||||
},
|
||||
{
|
||||
"service": "Lb",
|
||||
"capabilitytype": "lbSchemes",
|
||||
"capabilityvalue": "internal"
|
||||
}
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.apiClient = self.testClient.getApiClient()
|
||||
|
||||
|
||||
|
||||
@attr(tags=["advanced"])
|
||||
@attr(tags=["smoke", "advanced"])
|
||||
def test_internallb(self):
|
||||
"""Test create, delete, assign, remove of internal loadbalancer
|
||||
"""
|
||||
|
||||
#1) Create and enable network offering with Internal Lb vm service
|
||||
self.createNetworkOffering()
|
||||
|
||||
self.networkOffering = NetworkOffering.create(self.apiclient, self.services["network_offering"], conservemode=False)
|
||||
self.networkOffering.update(self.apiclient, state="Enabled")
|
||||
|
||||
#2) Create VPC and network in it
|
||||
self.createNetwork()
|
||||
|
||||
#3) Deploy a vm
|
||||
self.deployVm()
|
||||
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-internallb"
|
||||
self.services["vpc"]["displaytext"] = "vpc-internallb"
|
||||
self.services["vpc"]["cidr"] = "10.1.1.0/24"
|
||||
vpc = VPC.create(
|
||||
apiclient=self.apiclient,
|
||||
services=self.services["vpc"],
|
||||
networkDomain="vpc.internallb",
|
||||
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")
|
||||
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=self.networkOffering.id,
|
||||
zoneid=self.zone.id,
|
||||
vpcid=vpc.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))
|
||||
|
||||
#3) Deploy a vm
|
||||
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))
|
||||
|
||||
#4) Create an Internal Load Balancer
|
||||
self.createInternalLoadBalancer()
|
||||
applb = ApplicationLoadBalancer.create(self.apiclient, services=self.services,
|
||||
name="lbrule",
|
||||
sourceport=22,
|
||||
instanceport=22,
|
||||
algorithm="roundrobin",
|
||||
scheme="internal",
|
||||
sourcenetworkid=ntwk.id,
|
||||
networkid=ntwk.id)
|
||||
|
||||
#5) Assign the VM to the Internal Load Balancer
|
||||
self.assignToLoadBalancerRule()
|
||||
applb.assign(self.apiclient, vms=[vm.id])
|
||||
|
||||
#6) Remove the vm from the Interanl Load Balancer
|
||||
self.removeFromLoadBalancerRule()
|
||||
applb.remove(self.apiclient, vms=[vm.id])
|
||||
|
||||
#7) Delete the Load Balancer
|
||||
self.deleteLoadBalancer()
|
||||
applb.delete(self.apiclient)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cleanup_resources(cls.apiclient, cls.cleanup)
|
||||
except Exception, e:
|
||||
raise Exception("Cleanup failed with %s" % e)
|
||||
|
||||
def deployVm(self):
|
||||
deployVirtualMachineCmd = deployVirtualMachine.deployVirtualMachineCmd()
|
||||
deployVirtualMachineCmd.networkids = TestInternalLb.networkId
|
||||
deployVirtualMachineCmd.serviceofferingid = TestInternalLb.serviceOfferingId
|
||||
deployVirtualMachineCmd.zoneid = TestInternalLb.zoneId
|
||||
deployVirtualMachineCmd.templateid = TestInternalLb.templateId
|
||||
deployVirtualMachineCmd.hypervisor = "XenServer"
|
||||
deployVMResponse = self.apiClient.deployVirtualMachine(deployVirtualMachineCmd)
|
||||
TestInternalLb.vmId = deployVMResponse.id
|
||||
|
||||
|
||||
def createInternalLoadBalancer(self):
|
||||
createLoadBalancerCmd = createLoadBalancer.createLoadBalancerCmd()
|
||||
createLoadBalancerCmd.name = "lb rule"
|
||||
createLoadBalancerCmd.sourceport = 22
|
||||
createLoadBalancerCmd.instanceport = 22
|
||||
createLoadBalancerCmd.algorithm = "roundrobin"
|
||||
createLoadBalancerCmd.scheme = "internal"
|
||||
createLoadBalancerCmd.sourceipaddressnetworkid = TestInternalLb.networkId
|
||||
createLoadBalancerCmd.networkid = TestInternalLb.networkId
|
||||
createLoadBalancerResponse = self.apiClient.createLoadBalancer(createLoadBalancerCmd)
|
||||
TestInternalLb.lbId = createLoadBalancerResponse.id
|
||||
self.assertIsNotNone(createLoadBalancerResponse.id, "Failed to create a load balancer")
|
||||
|
||||
|
||||
def assignToLoadBalancerRule(self):
|
||||
assignToLoadBalancerRuleCmd = assignToLoadBalancerRule.assignToLoadBalancerRuleCmd()
|
||||
assignToLoadBalancerRuleCmd.id = TestInternalLb.lbId
|
||||
assignToLoadBalancerRuleCmd.virtualMachineIds = TestInternalLb.vmId
|
||||
assignToLoadBalancerRuleResponse = self.apiClient.assignToLoadBalancerRule(assignToLoadBalancerRuleCmd)
|
||||
self.assertTrue(assignToLoadBalancerRuleResponse.success, "Failed to assign the vm to the load balancer")
|
||||
|
||||
|
||||
|
||||
def removeFromLoadBalancerRule(self):
|
||||
removeFromLoadBalancerRuleCmd = removeFromLoadBalancerRule.removeFromLoadBalancerRuleCmd()
|
||||
removeFromLoadBalancerRuleCmd.id = TestInternalLb.lbId
|
||||
removeFromLoadBalancerRuleCmd.virtualMachineIds = TestInternalLb.vmId
|
||||
removeFromLoadBalancerRuleResponse = self.apiClient.removeFromLoadBalancerRule(removeFromLoadBalancerRuleCmd)
|
||||
self.assertTrue(removeFromLoadBalancerRuleResponse.success, "Failed to remove the vm from the load balancer")
|
||||
|
||||
|
||||
|
||||
#def removeInternalLoadBalancer(self):
|
||||
def deleteLoadBalancer(self):
|
||||
deleteLoadBalancerCmd = deleteLoadBalancer.deleteLoadBalancerCmd()
|
||||
deleteLoadBalancerCmd.id = TestInternalLb.lbId
|
||||
deleteLoadBalancerResponse = self.apiClient.deleteLoadBalancer(deleteLoadBalancerCmd)
|
||||
self.assertTrue(deleteLoadBalancerResponse.success, "Failed to remove the load balancer")
|
||||
|
||||
|
||||
|
||||
def createNetwork(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)
|
||||
|
||||
|
||||
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 = createVPCResponse.id
|
||||
createNetworkCmd.networkofferingid = TestInternalLb.networkOfferingId
|
||||
createNetworkResponse = self.apiClient.createNetwork(createNetworkCmd)
|
||||
TestInternalLb.networkId = createNetworkResponse.id
|
||||
|
||||
self.assertIsNotNone(createNetworkResponse.id, "Network failed to create")
|
||||
|
||||
|
||||
def createNetworkOffering(self):
|
||||
createNetworkOfferingCmd = createNetworkOffering.createNetworkOfferingCmd()
|
||||
createNetworkOfferingCmd.name = "Network offering for internal lb service - " + str(random.randrange(1,100+1))
|
||||
createNetworkOfferingCmd.displaytext = "Network offering for internal lb service"
|
||||
createNetworkOfferingCmd.guestiptype = "isolated"
|
||||
createNetworkOfferingCmd.traffictype = "Guest"
|
||||
createNetworkOfferingCmd.conservemode = "false"
|
||||
createNetworkOfferingCmd.supportedservices = "Vpn,Dhcp,Dns,Lb,UserData,SourceNat,StaticNat,PortForwarding,NetworkACL"
|
||||
|
||||
|
||||
createNetworkOfferingCmd.serviceproviderlist = []
|
||||
for item in self.serviceProviderList:
|
||||
createNetworkOfferingCmd.serviceproviderlist.append({
|
||||
'service': item['service'],
|
||||
'provider': item['provider']
|
||||
})
|
||||
|
||||
createNetworkOfferingCmd.servicecapabilitylist = []
|
||||
for item in self.serviceCapsList:
|
||||
createNetworkOfferingCmd.servicecapabilitylist.append({
|
||||
'service': item['service'],
|
||||
'capabilitytype': item['capabilitytype'],
|
||||
'capabilityvalue': item['capabilityvalue']
|
||||
})
|
||||
|
||||
|
||||
createNetworkOfferingResponse = self.apiClient.createNetworkOffering(createNetworkOfferingCmd)
|
||||
TestInternalLb.networkOfferingId = createNetworkOfferingResponse.id
|
||||
|
||||
#enable network offering
|
||||
updateNetworkOfferingCmd = updateNetworkOffering.updateNetworkOfferingCmd()
|
||||
updateNetworkOfferingCmd.id = TestInternalLb.networkOfferingId
|
||||
updateNetworkOfferingCmd.state = "Enabled"
|
||||
updateNetworkOfferingResponse = self.apiClient.updateNetworkOffering(updateNetworkOfferingCmd)
|
||||
|
||||
|
||||
#list network offering to see if its enabled
|
||||
listNetworkOfferingsCmd = listNetworkOfferings.listNetworkOfferingsCmd()
|
||||
listNetworkOfferingsCmd.id = TestInternalLb.networkOfferingId
|
||||
listOffResponse = self.apiClient.listNetworkOfferings(listNetworkOfferingsCmd)
|
||||
|
||||
self.assertNotEqual(len(listOffResponse), 0, "Check if the list network offerings API \
|
||||
returns a non-empty response")
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
#destroy the vm
|
||||
if TestInternalLb.vmId is not None:
|
||||
destroyVirtualMachineCmd = destroyVirtualMachine.destroyVirtualMachineCmd()
|
||||
destroyVirtualMachineCmd.id = TestInternalLb.vmId
|
||||
destroyVirtualMachineResponse = self.apiClient.destroyVirtualMachine(destroyVirtualMachineCmd)
|
||||
|
|
|
|||
|
|
@ -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"],
|
||||
|
|
|
|||
|
|
@ -1371,18 +1371,18 @@ class NetworkOffering:
|
|||
|
||||
if "useVpc" in services:
|
||||
cmd.useVpc = services["useVpc"]
|
||||
cmd.serviceProviderList = []
|
||||
cmd.serviceproviderlist = []
|
||||
if "serviceProviderList" in services:
|
||||
for service, provider in services["serviceProviderList"].items():
|
||||
cmd.serviceProviderList.append({
|
||||
cmd.serviceproviderlist.append({
|
||||
'service': service,
|
||||
'provider': provider
|
||||
})
|
||||
if "servicecapabilitylist" in services:
|
||||
cmd.serviceCapabilityList = []
|
||||
for service, capability in services["servicecapabilitylist"].items():
|
||||
if "serviceCapabilityList" in services:
|
||||
cmd.servicecapabilitylist = []
|
||||
for service, capability in services["serviceCapabilityList"].items():
|
||||
for ctype, value in capability.items():
|
||||
cmd.serviceCapabilityList.append({
|
||||
cmd.servicecapabilitylist.append({
|
||||
'service': service,
|
||||
'capabilitytype': ctype,
|
||||
'capabilityvalue': value
|
||||
|
|
@ -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"""
|
||||
|
||||
|
|
@ -2798,7 +2874,7 @@ class VPC:
|
|||
|
||||
@classmethod
|
||||
def create(cls, apiclient, services, vpcofferingid,
|
||||
zoneid, networkDomain=None, account=None, domainid=None):
|
||||
zoneid, networkDomain=None, account=None, domainid=None, **kwargs):
|
||||
"""Creates the virtual private connection (VPC)"""
|
||||
|
||||
cmd = createVPC.createVPCCmd()
|
||||
|
|
@ -2806,13 +2882,15 @@ class VPC:
|
|||
cmd.displaytext = "-".join([services["displaytext"], random_gen()])
|
||||
cmd.vpcofferingid = vpcofferingid
|
||||
cmd.zoneid = zoneid
|
||||
cmd.cidr = services["cidr"]
|
||||
if "cidr" in services:
|
||||
cmd.cidr = services["cidr"]
|
||||
if account:
|
||||
cmd.account = account
|
||||
if domainid:
|
||||
cmd.domainid = domainid
|
||||
if networkDomain:
|
||||
cmd.networkDomain = networkDomain
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return VPC(apiclient.createVPC(cmd).__dict__)
|
||||
|
||||
def update(self, apiclient, name=None, displaytext=None):
|
||||
|
|
@ -3216,3 +3294,83 @@ class Region:
|
|||
cmd.id = self.id
|
||||
region = apiclient.removeRegion(cmd)
|
||||
return region
|
||||
|
||||
|
||||
class ApplicationLoadBalancer:
|
||||
"""Manage Application Load Balancers in VPC"""
|
||||
|
||||
def __init__(self, items):
|
||||
self.__dict__.update(items)
|
||||
|
||||
@classmethod
|
||||
def create(cls, apiclient, services, name=None, sourceport=None, instanceport=22,
|
||||
algorithm="roundrobin", scheme="internal", sourcenetworkid=None, networkid=None):
|
||||
"""Create Application Load Balancer"""
|
||||
cmd = createLoadBalancer.createLoadBalancerCmd()
|
||||
|
||||
if "name" in services:
|
||||
cmd.name = services["name"]
|
||||
elif name:
|
||||
cmd.name = name
|
||||
|
||||
if "sourceport" in services:
|
||||
cmd.sourceport = services["sourceport"]
|
||||
elif sourceport:
|
||||
cmd.sourceport = sourceport
|
||||
|
||||
if "instanceport" in services:
|
||||
cmd.instanceport = services["instanceport"]
|
||||
elif instanceport:
|
||||
cmd.instanceport = instanceport
|
||||
|
||||
if "algorithm" in services:
|
||||
cmd.algorithm = services["algorithm"]
|
||||
elif algorithm:
|
||||
cmd.algorithm = algorithm
|
||||
|
||||
if "scheme" in services:
|
||||
cmd.scheme = services["scheme"]
|
||||
elif scheme:
|
||||
cmd.scheme = scheme
|
||||
|
||||
if "sourceipaddressnetworkid" in services:
|
||||
cmd.sourceipaddressnetworkid = services["sourceipaddressnetworkid"]
|
||||
elif sourcenetworkid:
|
||||
cmd.sourceipaddressnetworkid = sourcenetworkid
|
||||
|
||||
if "networkid" in services:
|
||||
cmd.networkid = services["networkid"]
|
||||
elif networkid:
|
||||
cmd.networkid = networkid
|
||||
|
||||
return LoadBalancerRule(apiclient.createLoadBalancer(cmd).__dict__)
|
||||
|
||||
def delete(self, apiclient):
|
||||
"""Delete application load balancer"""
|
||||
cmd = deleteLoadBalancer.deleteLoadBalancerCmd()
|
||||
cmd.id = self.id
|
||||
apiclient.deleteLoadBalancerRule(cmd)
|
||||
return
|
||||
|
||||
def assign(self, apiclient, vms):
|
||||
"""Assign virtual machines to load balancing rule"""
|
||||
cmd = assignToLoadBalancerRule.assignToLoadBalancerRuleCmd()
|
||||
cmd.id = self.id
|
||||
cmd.virtualmachineids = [str(vm.id) for vm in vms]
|
||||
apiclient.assignToLoadBalancerRule(cmd)
|
||||
return
|
||||
|
||||
def remove(self, apiclient, vms):
|
||||
"""Remove virtual machines from load balancing rule"""
|
||||
cmd = removeFromLoadBalancerRule.removeFromLoadBalancerRuleCmd()
|
||||
cmd.id = self.id
|
||||
cmd.virtualmachineids = [str(vm.id) for vm in vms]
|
||||
apiclient.removeFromLoadBalancerRule(cmd)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def list(cls, apiclient, **kwargs):
|
||||
"""List all appln load balancers"""
|
||||
cmd = listLoadBalancers.listLoadBalancersCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listLoadBalancerRules(cmd))
|
||||
|
|
@ -849,6 +849,9 @@
|
|||
getUpdatedItem: function(data) {
|
||||
return $.extend(data, { state: 'Destroyed' });
|
||||
},
|
||||
onComplete: function(data) {
|
||||
$(window).trigger('cloudStack.deleteProject', args);
|
||||
},
|
||||
getActionFilter: function(args) {
|
||||
return function() {
|
||||
return [];
|
||||
|
|
|
|||
|
|
@ -333,9 +333,15 @@
|
|||
response: {
|
||||
success: function(args) {
|
||||
var project = args.data;
|
||||
var $projectSwitcher = $('div.project-switcher');
|
||||
|
||||
$(window).trigger('cloudStack.fullRefresh');
|
||||
|
||||
// dynamically add newly created project into project switcher
|
||||
$projectSwitcher.find('select').append(
|
||||
$('<option>').val(project.id).html(project.name)
|
||||
);
|
||||
|
||||
$loading.remove();
|
||||
|
||||
// Confirmation
|
||||
|
|
@ -681,6 +687,20 @@
|
|||
}).closest('.ui-dialog').overlay();
|
||||
};
|
||||
|
||||
var deleteProject = function(args) {
|
||||
var projectId = args.id;
|
||||
var $projectSwitcher = $('div.project-switcher');
|
||||
var contextProjectId = cloudStack.context.projects ? cloudStack.context.projects[0].id : -1;
|
||||
|
||||
$projectSwitcher.find('option[value="'+projectId+'"]').remove();
|
||||
|
||||
//return to default view if current project is deleted
|
||||
if(contextProjectId == projectId) {
|
||||
$projectSwitcher.find('select').trigger('change');
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the dashboard, in panel
|
||||
*/
|
||||
|
|
@ -741,4 +761,9 @@
|
|||
$(window).bind('cloudStack.newProject', function() {
|
||||
addProject();
|
||||
});
|
||||
|
||||
|
||||
$(window).bind('cloudStack.deleteProject', function(event, args) {
|
||||
deleteProject({id: args.data.id});
|
||||
});
|
||||
})(cloudStack, jQuery);
|
||||
|
|
|
|||
Loading…
Reference in New Issue