diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 1e9435f6a8e..a0cd0f5a600 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -206,6 +206,7 @@ public class ApiConstants { public static final String STATE = "state"; public static final String STATUS = "status"; public static final String STORAGE_TYPE = "storagetype"; + public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled"; public static final String SYSTEM_VM_TYPE = "systemvmtype"; public static final String TAGS = "tags"; public static final String TARGET_IQN = "targetiqn"; @@ -304,6 +305,8 @@ public class ApiConstants { public static final String TEMPLATE_TAG = "templatetag"; public static final String HYPERVISOR_VERSION = "hypervisorversion"; public static final String MAX_GUESTS_LIMIT = "maxguestslimit"; + public static final String MAX_DATA_VOLUMES_LIMIT = "maxdatavolumeslimit"; + public static final String MAX_HOSTS_PER_CLUSTER = "maxhostspercluster"; public static final String PROJECT_ID = "projectid"; public static final String PROJECT_IDS = "projectids"; public static final String PROJECT = "project"; diff --git a/api/src/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java b/api/src/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java index 36021876184..2d37add5eb4 100644 --- a/api/src/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java +++ b/api/src/org/apache/cloudstack/api/response/HypervisorCapabilitiesResponse.java @@ -42,6 +42,14 @@ public class HypervisorCapabilitiesResponse extends BaseResponse { @SerializedName(ApiConstants.SECURITY_GROUP_EANBLED) @Param(description="true if security group is supported") private boolean isSecurityGroupEnabled; + @SerializedName(ApiConstants.MAX_DATA_VOLUMES_LIMIT) @Param(description="the maximum number of Data Volumes that can be attached for this hypervisor") + private Integer maxDataVolumesLimit; + + @SerializedName(ApiConstants.MAX_HOSTS_PER_CLUSTER) @Param(description="the maximum number of Hosts per cluster for this hypervisor") + private Integer maxHostsPerCluster; + + @SerializedName(ApiConstants.STORAGE_MOTION_ENABLED) @Param(description="true if storage motion is supported") + private boolean isStorageMotionSupported; public String getId() { return id; @@ -83,4 +91,28 @@ public class HypervisorCapabilitiesResponse extends BaseResponse { public void setIsSecurityGroupEnabled(Boolean sgEnabled) { this.isSecurityGroupEnabled = sgEnabled; } + + public Boolean getIsStorageMotionSupported() { + return this.isStorageMotionSupported; + } + + public void setIsStorageMotionSupported(Boolean smSupported) { + this.isStorageMotionSupported = smSupported; + } + + public Integer getMaxDataVolumesLimit() { + return maxDataVolumesLimit; + } + + public void setMaxDataVolumesLimit(Integer maxDataVolumesLimit) { + this.maxDataVolumesLimit = maxDataVolumesLimit; + } + + public Integer getMaxHostsPerCluster() { + return maxHostsPerCluster; + } + + public void setMaxHostsPerCluster(Integer maxHostsPerCluster) { + this.maxHostsPerCluster = maxHostsPerCluster; + } } diff --git a/client/tomcatconf/classpath.conf.in b/client/tomcatconf/classpath.conf.in index f2aeebac2a4..3ae0fb4d778 100644 --- a/client/tomcatconf/classpath.conf.in +++ b/client/tomcatconf/classpath.conf.in @@ -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 diff --git a/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java b/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java index 01a560a129a..18115a5e499 100755 --- a/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java +++ b/engine/schema/src/com/cloud/alert/dao/AlertDaoImpl.java @@ -156,7 +156,7 @@ public class AlertDaoImpl extends GenericDaoBase implements Alert public List listOlderAlerts(Date oldTime) { if (oldTime == null) return null; SearchCriteria sc = createSearchCriteria(); - sc.addAnd("createDate", SearchCriteria.Op.LT, oldTime); + sc.addAnd("createdDate", SearchCriteria.Op.LT, oldTime); sc.addAnd("archived", SearchCriteria.Op.EQ, false); return listIncludingRemovedBy(sc, null); } diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java index 15849732c0b..955ea566f40 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java @@ -112,16 +112,215 @@ public class Upgrade410to420 implements DbUpgrade { } private void updateSystemVmTemplates(Connection conn) { - PreparedStatement sql = null; + + PreparedStatement pstmt = null; + ResultSet rs = null; + boolean xenserver = false; + boolean kvm = false; + boolean VMware = false; + boolean Hyperv = false; + boolean LXC = false; + s_logger.debug("Updating System Vm template IDs"); + try{ + //Get all hypervisors in use + try { + pstmt = conn.prepareStatement("select distinct(hypervisor_type) from `cloud`.`cluster` where removed is null"); + rs = pstmt.executeQuery(); + while(rs.next()){ + if("XenServer".equals(rs.getString(1))){ + xenserver = true; + } else if("KVM".equals(rs.getString(1))){ + kvm = true; + } else if("VMware".equals(rs.getString(1))){ + VMware = true; + } else if("Hyperv".equals(rs.getString(1))) { + Hyperv = true; + } else if("LXC".equals(rs.getString(1))) { + LXC = true; + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while listing hypervisors in use", e); + } + + s_logger.debug("Updating XenSever System Vms"); + //XenServer + try { + //Get 4.2.0 xenserer system Vm template Id + pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name like 'systemvm-xenserver-4.2' and removed is null order by id desc limit 1"); + rs = pstmt.executeQuery(); + if(rs.next()){ + long templateId = rs.getLong(1); + rs.close(); + pstmt.close(); + // change template type to SYSTEM + pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + // update templete ID of system Vms + pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'XenServer'"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + } else { + if (xenserver){ + throw new CloudRuntimeException("4.2.0 XenServer SystemVm template not found. Cannot upgrade system Vms"); + } else { + s_logger.warn("4.2.0 XenServer SystemVm template not found. XenServer hypervisor is not used, so not failing upgrade"); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while updating XenServer systemVm template", e); + } + + //KVM + s_logger.debug("Updating KVM System Vms"); + try { + //Get 4.2.0 KVM system Vm template Id + pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-kvm-4.2' and removed is null order by id desc limit 1"); + rs = pstmt.executeQuery(); + if(rs.next()){ + long templateId = rs.getLong(1); + rs.close(); + pstmt.close(); + // change template type to SYSTEM + pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + // update templete ID of system Vms + pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'KVM'"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + } else { + if (kvm){ + throw new CloudRuntimeException("4.2.0 KVM SystemVm template not found. Cannot upgrade system Vms"); + } else { + s_logger.warn("4.2.0 KVM SystemVm template not found. KVM hypervisor is not used, so not failing upgrade"); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while updating KVM systemVm template", e); + } + + //VMware + s_logger.debug("Updating VMware System Vms"); + try { + //Get 4.2.0 VMware system Vm template Id + pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-vmware-4.2' and removed is null order by id desc limit 1"); + rs = pstmt.executeQuery(); + if(rs.next()){ + long templateId = rs.getLong(1); + rs.close(); + pstmt.close(); + // change template type to SYSTEM + pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + // update templete ID of system Vms + pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'VMware'"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + } else { + if (VMware){ + throw new CloudRuntimeException("4.2.0 VMware SystemVm template not found. Cannot upgrade system Vms"); + } else { + s_logger.warn("4.2.0 VMware SystemVm template not found. VMware hypervisor is not used, so not failing upgrade"); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while updating VMware systemVm template", e); + } + + //Hyperv + s_logger.debug("Updating Hyperv System Vms"); + try { + //Get 4.2.0 Hyperv system Vm template Id + pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-hyperv-4.2' and removed is null order by id desc limit 1"); + rs = pstmt.executeQuery(); + if(rs.next()){ + long templateId = rs.getLong(1); + rs.close(); + pstmt.close(); + // change template type to SYSTEM + pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + // update templete ID of system Vms + pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'Hyperv'"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + } else { + if (Hyperv){ + throw new CloudRuntimeException("4.2.0 HyperV SystemVm template not found. Cannot upgrade system Vms"); + } else { + s_logger.warn("4.2.0 Hyperv SystemVm template not found. Hyperv hypervisor is not used, so not failing upgrade"); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while updating Hyperv systemVm template", e); + } + + //LXC + s_logger.debug("Updating LXC System Vms"); + try { + //Get 4.2.0 LXC system Vm template Id + pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-lxc-4.2' and removed is null order by id desc limit 1"); + rs = pstmt.executeQuery(); + if(rs.next()){ + long templateId = rs.getLong(1); + rs.close(); + pstmt.close(); + // change template type to SYSTEM + pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + // update templete ID of system Vms + pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'LXC'"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + } else { + if (LXC){ + throw new CloudRuntimeException("4.2.0 LXC SystemVm template not found. Cannot upgrade system Vms"); + } else { + s_logger.warn("4.2.0 LXC SystemVm template not found. LXC hypervisor is not used, so not failing upgrade"); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while updating LXC systemVm template", e); + } + s_logger.debug("Updating System Vm Template IDs Complete"); + } + finally { + try { + if (rs != null) { + rs.close(); + } + + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + pstmt = null; try { - sql = conn.prepareStatement("update vm_template set image_data_store_id = 1 where type = 'SYSTEM' or type = 'BUILTIN'"); - sql.executeUpdate(); + pstmt = conn.prepareStatement("update vm_template set image_data_store_id = 1 where type = 'SYSTEM' or type = 'BUILTIN'"); + pstmt.executeUpdate(); } catch (SQLException e) { throw new CloudRuntimeException("Failed to upgrade vm template data store uuid: " + e.toString()); } finally { - if (sql != null) { + if (pstmt != null) { try { - sql.close(); + pstmt.close(); } catch (SQLException e) { } } diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index 83ccae8c582..1f112ddd686 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -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 diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java index 72ecc67cad6..823be86b45f 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/cisco/CiscoVnmcConnectionImpl.java @@ -1070,7 +1070,7 @@ public class CiscoVnmcConnectionImpl implements CiscoVnmcConnection { } private String getNameForDNatIpPool(String tenantName, String identifier) { - return "IpPool-" + tenantName + "-" + identifier; + return "IpPool-" + tenantName + "-" + identifier + "n"; } private String getDnForDNatIpPool(String tenantName, String identifier) { diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java index 9118bad6afe..553325ccaa9 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/element/CiscoVnmcElement.java @@ -807,7 +807,7 @@ public class CiscoVnmcElement extends AdapterBase implements SourceNatServicePro List rulesTO = new ArrayList(); for (StaticNat rule : rules) { IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId()); - StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, + StaticNatRuleTO ruleTO = new StaticNatRuleTO(rule.getSourceIpAddressId(), sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); rulesTO.add(ruleTO); } diff --git a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java index fc0c33483ac..9524bf99cec 100644 --- a/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java +++ b/plugins/network-elements/cisco-vnmc/src/com/cloud/network/resource/CiscoVnmcResource.java @@ -501,7 +501,7 @@ public class CiscoVnmcResource implements ServerResource { } /* - * Destination NAT + * PF */ private synchronized Answer execute(SetPortForwardingRulesCommand cmd) { refreshVnmcConnection(); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 55929cf5ecb..bcc1605d8b9 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -2485,6 +2485,9 @@ public class ApiResponseHelper implements ResponseGenerator { hpvCapabilitiesResponse.setHypervisorVersion(hpvCapabilities.getHypervisorVersion()); hpvCapabilitiesResponse.setIsSecurityGroupEnabled(hpvCapabilities.isSecurityGroupEnabled()); hpvCapabilitiesResponse.setMaxGuestsLimit(hpvCapabilities.getMaxGuestsLimit()); + hpvCapabilitiesResponse.setMaxDataVolumesLimit(hpvCapabilities.getMaxDataVolumesLimit()); + hpvCapabilitiesResponse.setMaxHostsPerCluster(hpvCapabilities.getMaxHostsPerCluster()); + hpvCapabilitiesResponse.setIsStorageMotionSupported(hpvCapabilities.isStorageMotionSupported()); return hpvCapabilitiesResponse; } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index cf50e61d6ac..96c72e4a4e2 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -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 iterator = allHosts.iterator(); iterator.hasNext();) { + Host host = iterator.next(); Map> volumePools = findSuitablePoolsForVolumes(vmProfile, host); if (volumePools.isEmpty()) { - allHosts.remove(host); + iterator.remove(); } else { if (!host.getClusterId().equals(srcHost.getClusterId()) || usesLocal) { requiresStorageMotion.put(host, true); diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java index 7c46d4abb08..483c19af431 100644 --- a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java @@ -528,6 +528,10 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR @Override public List listGlobalLoadBalancerRule(ListGlobalLoadBalancerRuleCmd listGslbCmd) { + + UserContext ctx = UserContext.current(); + Account caller = ctx.getCaller(); + Integer regionId = listGslbCmd.getRegionId(); Long ruleId = listGslbCmd.getId(); List response = new ArrayList(); @@ -546,12 +550,14 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR if (gslbRule == null) { throw new InvalidParameterValueException("Invalid gslb rule id specified"); } + _accountMgr.checkAccess(caller, org.apache.cloudstack.acl.SecurityChecker.AccessType.ListEntry, false, gslbRule); + response.add(gslbRule); return response; } if (regionId != null) { - List gslbRules = _gslbRuleDao.listByRegionId(regionId); + List gslbRules = _gslbRuleDao.listByAccount(caller.getAccountId()); if (gslbRules != null) { response.addAll(gslbRules); } diff --git a/test/integration/smoke/test_internal_lb.py b/test/integration/smoke/test_internal_lb.py index 07a539592ca..0de2d4cf338 100644 --- a/test/integration/smoke/test_internal_lb.py +++ b/test/integration/smoke/test_internal_lb.py @@ -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) diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py index 6b3be75e896..5daacbb7cea 100755 --- a/tools/marvin/marvin/integration/lib/base.py +++ b/tools/marvin/marvin/integration/lib/base.py @@ -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 @@ -2798,7 +2798,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 +2806,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 +3218,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)) \ No newline at end of file diff --git a/ui/scripts/projects.js b/ui/scripts/projects.js index 4004709a75d..ea1e6dbdd02 100644 --- a/ui/scripts/projects.js +++ b/ui/scripts/projects.js @@ -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 []; diff --git a/ui/scripts/ui-custom/projects.js b/ui/scripts/ui-custom/projects.js index 82abadd7fe8..7824b3de11c 100644 --- a/ui/scripts/ui-custom/projects.js +++ b/ui/scripts/ui-custom/projects.js @@ -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( + $('