diff --git a/api/src/com/cloud/agent/api/to/VolumeTO.java b/api/src/com/cloud/agent/api/to/VolumeTO.java index 4cbe82b357b..cc0e8182390 100644 --- a/api/src/com/cloud/agent/api/to/VolumeTO.java +++ b/api/src/com/cloud/agent/api/to/VolumeTO.java @@ -37,6 +37,10 @@ public class VolumeTO implements InternalIdentity { private long deviceId; private String chainInfo; private String guestOsType; + private Long bytesReadRate; + private Long bytesWriteRate; + private Long iopsReadRate; + private Long iopsWriteRate; public VolumeTO(long id, Volume.Type type, StoragePoolType poolType, String poolUuid, String name, String mountPoint, String path, long size, String chainInfo) { this.id = id; @@ -133,4 +137,37 @@ public class VolumeTO implements InternalIdentity { public String toString() { return new StringBuilder("Vol[").append(id).append("|").append(type).append("|").append(path).append("|").append(size).append("]").toString(); } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + } diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java index 05307eb47aa..ea39d835eb7 100644 --- a/api/src/com/cloud/network/NetworkModel.java +++ b/api/src/com/cloud/network/NetworkModel.java @@ -274,4 +274,6 @@ public interface NetworkModel { Networks.IsolationType[] listNetworkIsolationMethods(); Nic getNicInNetworkIncludingRemoved(long vmId, long networkId); + + boolean getExecuteInSeqNtwkElmtCmd(); } \ No newline at end of file diff --git a/api/src/com/cloud/offering/DiskOffering.java b/api/src/com/cloud/offering/DiskOffering.java index dd77c70abd9..ae4528cc81a 100644 --- a/api/src/com/cloud/offering/DiskOffering.java +++ b/api/src/com/cloud/offering/DiskOffering.java @@ -52,4 +52,20 @@ public interface DiskOffering extends InfrastructureEntity, Identity, InternalId boolean isCustomized(); void setDiskSize(long diskSize); + + void setBytesReadRate(Long bytesReadRate); + + Long getBytesReadRate(); + + void setBytesWriteRate(Long bytesWriteRate); + + Long getBytesWriteRate(); + + void setIopsReadRate(Long iopsReadRate); + + Long getIopsReadRate(); + + void setIopsWriteRate(Long iopsWriteRate); + + Long getIopsWriteRate(); } diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 72e2a2bbbab..5f522ebff6a 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -16,8 +16,6 @@ // under the License. package com.cloud.offering; -import java.util.Map; - import org.apache.cloudstack.acl.InfrastructureEntity; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -61,6 +59,8 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, public final static String DefaultSharedEIPandELBNetworkOffering = "DefaultSharedNetscalerEIPandELBNetworkOffering"; public final static String DefaultIsolatedNetworkOfferingForVpcNetworks = "DefaultIsolatedNetworkOfferingForVpcNetworks"; public final static String DefaultIsolatedNetworkOfferingForVpcNetworksNoLB = "DefaultIsolatedNetworkOfferingForVpcNetworksNoLB"; + public final static String DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB = "DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB"; + /** * @return name for the network offering. diff --git a/api/src/com/cloud/storage/Storage.java b/api/src/com/cloud/storage/Storage.java index c50bd7e7e87..16ef0192e32 100755 --- a/api/src/com/cloud/storage/Storage.java +++ b/api/src/com/cloud/storage/Storage.java @@ -98,8 +98,8 @@ public class Storage { Iscsi(true), // for e.g., ZFS Comstar ISO(false), // for iso image LVM(false), // XenServer local LVM SR - CLVM(true), - RBD(true), + CLVM(true), + RBD(true), // http://libvirt.org/storage.html#StorageBackendRBD SharedMountPoint(true), VMFS(true), // VMware VMFS storage PreSetup(true), // for XenServer, Storage Pool is set up by customers. diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index df48de2f321..f5ed4e267b6 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -153,7 +153,7 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba Date getCreated(); - long getDiskOfferingId(); + Long getDiskOfferingId(); String getChainInfo(); diff --git a/api/src/com/cloud/vm/DiskProfile.java b/api/src/com/cloud/vm/DiskProfile.java index e3a3386d1e5..3d4c9e730f4 100644 --- a/api/src/com/cloud/vm/DiskProfile.java +++ b/api/src/com/cloud/vm/DiskProfile.java @@ -35,6 +35,10 @@ public class DiskProfile { private Long templateId; private long volumeId; private String path; + private Long bytesReadRate; + private Long bytesWriteRate; + private Long iopsReadRate; + private Long iopsWriteRate; private HypervisorType hyperType; @@ -154,4 +158,36 @@ public class DiskProfile { public void setSize(long size) { this.size = size; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index ab1402ccde9..12e50978475 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -31,6 +31,8 @@ public class ApiConstants { public static final String BOOTABLE = "bootable"; public static final String BIND_DN = "binddn"; public static final String BIND_PASSWORD = "bindpass"; + public static final String BYTES_READ_RATE = "bytesreadrate"; + public static final String BYTES_WRITE_RATE = "byteswriterate"; public static final String CATEGORY = "category"; public static final String CERTIFICATE = "certificate"; public static final String PRIVATE_KEY = "privatekey"; @@ -104,6 +106,8 @@ public class ApiConstants { public static final String INTERNAL_DNS1 = "internaldns1"; public static final String INTERNAL_DNS2 = "internaldns2"; public static final String INTERVAL_TYPE = "intervaltype"; + public static final String IOPS_READ_RATE = "iopsreadrate"; + public static final String IOPS_WRITE_RATE = "iopswriterate"; public static final String IP_ADDRESS = "ipaddress"; public static final String IP6_ADDRESS = "ip6address"; public static final String IP_ADDRESS_ID = "ipaddressid"; @@ -241,8 +245,7 @@ public class ApiConstants { public static final String IS_VOLATILE = "isvolatile"; public static final String VOLUME_ID = "volumeid"; public static final String ZONE_ID = "zoneid"; - public static final String ZONE_NAME = "zonename"; - public static final String ZONE_TYPE = "zonetype"; + public static final String ZONE_NAME = "zonename"; public static final String NETWORK_TYPE = "networktype"; public static final String PAGE = "page"; public static final String PAGE_SIZE = "pagesize"; diff --git a/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java index f2dd3499b84..0417b187e38 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java @@ -70,9 +70,6 @@ public class ListClustersCmd extends BaseListCmd { @Parameter(name=ApiConstants.MANAGED_STATE, type=CommandType.STRING, description="whether this cluster is managed by cloudstack") private String managedState; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - @Parameter(name=ApiConstants.SHOW_CAPACITIES, type=CommandType.BOOLEAN, description="flag to display the capacity of the clusters") private Boolean showCapacities; @@ -117,10 +114,7 @@ public class ListClustersCmd extends BaseListCmd { this.managedState = managedstate; } - public String getZoneType() { - return zoneType; - } - + public Boolean getShowCapacities() { return showCapacities; } diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java index b2d77b85dd2..e902e650332 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/FindHostsForMigrationCmd.java @@ -70,13 +70,12 @@ public class FindHostsForMigrationCmd extends BaseListCmd { public void execute() { ListResponse response = null; Pair,Integer> result; - List hostsWithCapacity = new ArrayList(); Map hostsRequiringStorageMotion; Ternary,Integer>, List, Map> hostsForMigration = _mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal()); result = hostsForMigration.first(); - hostsWithCapacity = hostsForMigration.second(); + List hostsWithCapacity = hostsForMigration.second(); hostsRequiringStorageMotion = hostsForMigration.third(); response = new ListResponse(); diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java index eaaec3091a7..1e378fae464 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java @@ -171,11 +171,10 @@ public class ListHostsCmd extends BaseListCmd { response = _queryService.searchForServers(this); } else { Pair,Integer> result; - List hostsWithCapacity = new ArrayList(); Ternary,Integer>, List, Map> hostsForMigration = _mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal()); result = hostsForMigration.first(); - hostsWithCapacity = hostsForMigration.second(); + List hostsWithCapacity = hostsForMigration.second(); response = new ListResponse(); List hostResponses = new ArrayList(); diff --git a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java index e314b3245c7..68370e8131e 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/internallb/ListInternalLBVMsCmd.java @@ -75,10 +75,7 @@ public class ListInternalLBVMsCmd extends BaseListProjectAndAccountResourcesCmd @Parameter(name=ApiConstants.FOR_VPC, type=CommandType.BOOLEAN, description="if true is passed for this parameter, list only VPC Internal LB VMs") private Boolean forVpc; - - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -123,10 +120,7 @@ public class ListInternalLBVMsCmd extends BaseListProjectAndAccountResourcesCmd public String getRole() { return Role.INTERNAL_LB_VM.toString(); } - - public String getZoneType() { - return zoneType; - } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java b/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java index 2976de4bf28..2726f84163d 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/ldap/LDAPConfigCmd.java @@ -43,10 +43,9 @@ public class LDAPConfigCmd extends BaseCmd { ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - - @Parameter(name=ApiConstants.LIST_ALL, type=CommandType.STRING, description="Hostname or ip address of the ldap server eg: my.ldap.com") - private String listall; - + @Parameter(name=ApiConstants.LIST_ALL, type=CommandType.BOOLEAN, description="If true return current LDAP configuration") + private Boolean listAll; + @Parameter(name=ApiConstants.HOST_NAME, type=CommandType.STRING, description="Hostname or ip address of the ldap server eg: my.ldap.com") private String hostname; @@ -78,10 +77,10 @@ public class LDAPConfigCmd extends BaseCmd { /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - public String getListAll() { - return listall == null ? "false" : listall; + public Boolean getListAll() { + return listAll == null ? Boolean.FALSE : listAll; } - + public String getBindPassword() { return bindPassword; } @@ -156,16 +155,15 @@ public class LDAPConfigCmd extends BaseCmd { InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { try { - if ("true".equalsIgnoreCase(getListAll())){ + if (getListAll()){ // return the existing conf LDAPConfigCmd cmd = _configService.listLDAPConfig(this); - LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(cmd.getHostname(), cmd.getPort(), cmd.getUseSSL(), - cmd.getQueryFilter(), cmd.getSearchBase(), cmd.getBindDN()); + LDAPConfigResponse lr = _responseGenerator.createLDAPConfigResponse(cmd.getHostname(), cmd.getPort(), cmd.getUseSSL(), cmd.getQueryFilter(), cmd.getSearchBase(), cmd.getBindDN()); lr.setResponseName(getCommandName()); this.setResponseObject(lr); } else if (getHostname()==null || getSearchBase() == null || getQueryFilter() == null) { - throw new InvalidParameterValueException("You need to provide hostname, serachbase and queryfilter to configure your LDAP server"); + throw new InvalidParameterValueException("You need to provide hostname, searchbase and queryfilter to configure your LDAP server"); } else { boolean result = _configService.updateLDAP(this); diff --git a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java index 6410715727c..febb0c337eb 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java @@ -95,7 +95,7 @@ public class CreateNetworkOfferingCmd extends BaseCmd { @Parameter(name=ApiConstants.IS_PERSISTENT, type=CommandType.BOOLEAN, description="true if network offering supports persistent networks; defaulted to false if not specified") private Boolean isPersistent; - @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, since="4.2.0", description="Template details in key/value pairs." + + @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, since="4.2.0", description="Network offering details in key/value pairs." + " Supported keys are internallbprovider/publiclbprovider with service provider as a value") protected Map details; diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java index aa11599a69e..a2c5f77f583 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java @@ -62,6 +62,18 @@ public class CreateDiskOfferingCmd extends BaseCmd { @Parameter(name=ApiConstants.STORAGE_TYPE, type=CommandType.STRING, description="the storage type of the disk offering. Values are local and shared.") private String storageType = ServiceOffering.StorageType.shared.toString(); + @Parameter(name=ApiConstants.BYTES_READ_RATE, type=CommandType.LONG, required=false, description="bytes read rate of the disk offering") + private Long bytesReadRate; + + @Parameter(name=ApiConstants.BYTES_WRITE_RATE, type=CommandType.LONG, required=false, description="bytes write rate of the disk offering") + private Long bytesWriteRate; + + @Parameter(name=ApiConstants.IOPS_READ_RATE, type=CommandType.LONG, required=false, description="io requests read rate of the disk offering") + private Long iopsReadRate; + + @Parameter(name=ApiConstants.IOPS_WRITE_RATE, type=CommandType.LONG, required=false, description="io requests write rate of the disk offering") + private Long iopsWriteRate; + @Parameter(name=ApiConstants.DISPLAY_OFFERING, type=CommandType.BOOLEAN, description="an optional field, whether to display the offering to the end user or not.") private Boolean displayOffering; @@ -93,6 +105,22 @@ public class CreateDiskOfferingCmd extends BaseCmd { return domainId; } + public Long getBytesReadRate() { + return bytesReadRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + public String getStorageType() { return storageType; } diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java index 4c54a4e5ec6..decac29ae6b 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java @@ -93,6 +93,18 @@ public class CreateServiceOfferingCmd extends BaseCmd { @Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "details for planner, used to store specific parameters") private Map details; + @Parameter(name=ApiConstants.BYTES_READ_RATE, type=CommandType.LONG, required=false, description="bytes read rate of the disk offering") + private Long bytesReadRate; + + @Parameter(name=ApiConstants.BYTES_WRITE_RATE, type=CommandType.LONG, required=false, description="bytes write rate of the disk offering") + private Long bytesWriteRate; + + @Parameter(name=ApiConstants.IOPS_READ_RATE, type=CommandType.LONG, required=false, description="io requests read rate of the disk offering") + private Long iopsReadRate; + + @Parameter(name=ApiConstants.IOPS_WRITE_RATE, type=CommandType.LONG, required=false, description="io requests write rate of the disk offering") + private Long iopsWriteRate; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -171,6 +183,22 @@ public class CreateServiceOfferingCmd extends BaseCmd { return params; } + public Long getBytesReadRate() { + return bytesReadRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java b/api/src/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java index db233ae441e..3dace4244ae 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/pod/ListPodsByCmd.java @@ -55,9 +55,6 @@ public class ListPodsByCmd extends BaseListCmd { @Parameter(name=ApiConstants.ALLOCATION_STATE, type=CommandType.STRING, description="list pods by allocation state") private String allocationState; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - @Parameter(name=ApiConstants.SHOW_CAPACITIES, type=CommandType.BOOLEAN, description="flag to display the capacity of the pods") private Boolean showCapacities; @@ -81,10 +78,6 @@ public class ListPodsByCmd extends BaseListCmd { return allocationState; } - public String getZoneType() { - return zoneType; - } - public Boolean getShowCapacities() { return showCapacities; } diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java b/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java index 75bcce00acf..1f77c2c5164 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/region/ListPortableIpRangesCmd.java @@ -81,9 +81,8 @@ public class ListPortableIpRangesCmd extends BaseListCmd { public void execute(){ ListResponse response = new ListResponse(); List responses = new ArrayList(); - List portableIpRanges = new ArrayList(); - portableIpRanges = _configService.listPortableIpRanges(this); + List portableIpRanges = _configService.listPortableIpRanges(this); if (portableIpRanges != null && !portableIpRanges.isEmpty()) { for (PortableIpRange range : portableIpRanges) { PortableIpRangeResponse rangeResponse = _responseGenerator.createPortableIPRangeResponse(range); diff --git a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java index 78c3554ae73..a74eb897dba 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/router/ListRoutersCmd.java @@ -65,9 +65,6 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { description="the Zone ID of the router") private Long zoneId; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.UUID, entityType=NetworkResponse.class, description="list by network id") private Long networkId; @@ -107,10 +104,6 @@ public class ListRoutersCmd extends BaseListProjectAndAccountResourcesCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } - public Long getNetworkId() { return networkId; } diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java index 85a3c22a3e2..f33b9877662 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListStoragePoolsCmd.java @@ -64,6 +64,10 @@ public class ListStoragePoolsCmd extends BaseListCmd { description="the ID of the storage pool") private Long id; + @Parameter(name=ApiConstants.SCOPE, type=CommandType.STRING, entityType = StoragePoolResponse.class, + description="the ID of the storage pool") + private String scope; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -115,4 +119,8 @@ public class ListStoragePoolsCmd extends BaseListCmd { response.setResponseName(getCommandName()); this.setResponseObject(response); } + + public String getScope() { + return scope; + } } diff --git a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java index b5a0f3fdd4d..f230a20d513 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/systemvm/ListSystemVMsCmd.java @@ -74,9 +74,6 @@ public class ListSystemVMsCmd extends BaseListCmd { description="the storage ID where vm's volumes belong to", since="3.0.1") private Long storageId; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -113,10 +110,6 @@ public class ListSystemVMsCmd extends BaseListCmd { return storageId; } - public String getZoneType() { - return zoneType; - } - ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java index d27892d8bbe..b490ca9966a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java @@ -78,9 +78,6 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { description="the ID of the zone") private Long zoneId; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -118,10 +115,6 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } - public boolean listInReadyState() { Account account = UserContext.current().getCaller(); // It is account specific if account is admin type and domainId and accountName are not null diff --git a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java index d25e2c05597..afce0926e4d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/network/ListNetworksCmd.java @@ -48,9 +48,6 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd { description="the Zone ID of the network") private Long zoneId; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - @Parameter(name=ApiConstants.TYPE, type=CommandType.STRING, description="the type of the network. Supported values are: Isolated and Shared") private String guestIpType; @@ -99,10 +96,6 @@ public class ListNetworksCmd extends BaseListTaggedResourcesCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } - public String getGuestIpType() { return guestIpType; } diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java index e4ae76908e8..8859ba53c53 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/ListSnapshotsCmd.java @@ -59,13 +59,11 @@ public class ListSnapshotsCmd extends BaseListTaggedResourcesCmd { @Parameter(name=ApiConstants.VOLUME_ID, type=CommandType.UUID, entityType = VolumeResponse.class, description="the ID of the disk volume") private Long volumeId; - - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "list snapshots by zone id") private Long zoneId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -90,14 +88,10 @@ public class ListSnapshotsCmd extends BaseListTaggedResourcesCmd { return volumeId; } - public String getZoneType() { - return zoneType; - } - public Long getZoneId() { return zoneId; - } - + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java index 33591819e3d..0b937be6d59 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java @@ -69,10 +69,6 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType = ZoneResponse.class, description="list templates by zoneId") private Long zoneId; - - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; - ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -97,10 +93,6 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { return zoneId; } - public String getZoneType() { - return zoneType; - } - public boolean listInReadyState() { Account account = UserContext.current().getCaller(); diff --git a/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java b/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java index ed31037407f..4cf3b58a0a8 100644 --- a/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/zone/ListZonesByCmd.java @@ -57,8 +57,8 @@ public class ListZonesByCmd extends BaseListCmd { @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the zone") private String name; - @Parameter(name=ApiConstants.ZONE_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") - private String zoneType; + @Parameter(name=ApiConstants.NETWORK_TYPE, type=CommandType.STRING, description="the network type of the zone that the virtual machine belongs to") + private String networkType; @Parameter(name=ApiConstants.SHOW_CAPACITIES, type=CommandType.BOOLEAN, description="flag to display the capacity of the zones") private Boolean showCapacities; @@ -83,8 +83,8 @@ public class ListZonesByCmd extends BaseListCmd { return name; } - public String getZoneType() { - return zoneType; + public String getNetworkType() { + return networkType; } public Boolean getShowCapacities() { diff --git a/api/src/org/apache/cloudstack/api/response/ClusterResponse.java b/api/src/org/apache/cloudstack/api/response/ClusterResponse.java index ef8cca65040..68aa8928165 100644 --- a/api/src/org/apache/cloudstack/api/response/ClusterResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ClusterResponse.java @@ -45,10 +45,7 @@ public class ClusterResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the cluster") private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - + @SerializedName("hypervisortype") @Param(description="the hypervisor type of the cluster") private String hypervisorType; @@ -118,10 +115,6 @@ public class ClusterResponse extends BaseResponse { this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public String getClusterType() { return clusterType; } diff --git a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java index 377e66ec2b1..35cf21a3b17 100644 --- a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java @@ -58,6 +58,18 @@ public class DiskOfferingResponse extends BaseResponse { @SerializedName("storagetype") @Param(description="the storage type for this disk offering") private String storageType; + @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the disk offering") + private Long bytesReadRate; + + @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the disk offering") + private Long bytesWriteRate; + + @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the disk offering") + private Long iopsReadRate; + + @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the disk offering") + private Long iopsWriteRate; + @SerializedName("displayoffering") @Param(description="whether to display the offering to the end user or not.") private Boolean displayOffering; @@ -149,4 +161,20 @@ public class DiskOfferingResponse extends BaseResponse { public void setStorageType(String storageType) { this.storageType = storageType; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } } diff --git a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java index 852d98815a3..1d31b58a481 100644 --- a/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java +++ b/api/src/org/apache/cloudstack/api/response/DomainRouterResponse.java @@ -42,9 +42,6 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name for the router") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName(ApiConstants.DNS1) @Param(description="the first DNS for the router") private String dns1; @@ -188,14 +185,6 @@ public class DomainRouterResponse extends BaseResponse implements ControlledView this.zoneName = zoneName; } - public String getZoneType() { - return zoneType; - } - - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setDns1(String dns1) { this.dns1 = dns1; } diff --git a/api/src/org/apache/cloudstack/api/response/HostResponse.java b/api/src/org/apache/cloudstack/api/response/HostResponse.java index be1a4b443be..687687d37fc 100644 --- a/api/src/org/apache/cloudstack/api/response/HostResponse.java +++ b/api/src/org/apache/cloudstack/api/response/HostResponse.java @@ -59,10 +59,7 @@ public class HostResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the host") private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - + @SerializedName(ApiConstants.POD_ID) @Param(description="the Pod ID of the host") private String podId; @@ -212,10 +209,6 @@ public class HostResponse extends BaseResponse { this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setPodId(String podId) { this.podId = podId; } diff --git a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java index 70c3d79c4c0..31024330dcd 100644 --- a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java @@ -66,9 +66,6 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the zone the network belongs to") private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description="the networktype of the zone the network belongs to") - private String zoneType; @SerializedName("networkofferingid") @Param(description="network offering id the network is created from") private String networkOfferingId; @@ -309,10 +306,6 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setCidr(String cidr) { this.cidr = cidr; } diff --git a/api/src/org/apache/cloudstack/api/response/PodResponse.java b/api/src/org/apache/cloudstack/api/response/PodResponse.java index 471cac1aa47..f31c289217e 100644 --- a/api/src/org/apache/cloudstack/api/response/PodResponse.java +++ b/api/src/org/apache/cloudstack/api/response/PodResponse.java @@ -36,13 +36,10 @@ public class PodResponse extends BaseResponse { @SerializedName("zoneid") @Param(description="the Zone ID of the Pod") private String zoneId; - + @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the Pod") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName("gateway") @Param(description="the gateway of the Pod") private String gateway; @@ -89,10 +86,6 @@ public class PodResponse extends BaseResponse { return zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setZoneName(String zoneName) { this.zoneName = zoneName; } diff --git a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java index 31533f87728..288f76b4463 100644 --- a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java @@ -87,6 +87,18 @@ public class ServiceOfferingResponse extends BaseResponse { @SerializedName(ApiConstants.NETWORKRATE) @Param(description="data transfer rate in megabits per second allowed.") private Integer networkRate; + @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the service offering") + private Long bytesReadRate; + + @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the service offering") + private Long bytesWriteRate; + + @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the service offering") + private Long iopsReadRate; + + @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the service offering") + private Long iopsWriteRate; + @SerializedName(ApiConstants.DEPLOYMENT_PLANNER) @Param(description="deployment strategy used to deploy VM.") private String deploymentPlanner; @@ -248,4 +260,20 @@ public class ServiceOfferingResponse extends BaseResponse { public void setVolatileVm(boolean isVolatile) { this.isVolatile = isVolatile; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } } diff --git a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java index ca74a18043b..e9cb109bf31 100644 --- a/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SnapshotResponse.java @@ -97,14 +97,6 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe @Param(description = "id of the availability zone") private String zoneId; - @SerializedName(ApiConstants.ZONE_NAME) - @Param(description = "name of the availability zone") - private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) - @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with snapshot", responseObject = ResourceTagResponse.class) private List tags; @@ -188,14 +180,7 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe public void setZoneId(String zoneId) { this.zoneId = zoneId; } - public void setZoneName(String zoneName) { - this.zoneName = zoneName; - } - - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - + public void setTags(List tags) { this.tags = tags; } diff --git a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java index 965407d9952..00500007c18 100644 --- a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java +++ b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java @@ -37,14 +37,12 @@ public class StoragePoolResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the storage pool") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; @SerializedName("podid") @Param(description="the Pod ID of the storage pool") private String podId; @SerializedName("podname") @Param(description="the Pod name of the storage pool") - private String podName; + private String podName; @SerializedName("name") @Param(description="the name of the storage pool") private String name; @@ -143,14 +141,6 @@ public class StoragePoolResponse extends BaseResponse { this.zoneName = zoneName; } - public String getZoneType() { - return zoneType; - } - - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public String getPodId() { return podId; } diff --git a/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java b/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java index 3439dc025e3..8d2798a9d04 100644 --- a/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/SystemVmResponse.java @@ -46,9 +46,6 @@ public class SystemVmResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name for the system VM") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description = "network type of the availability zone") - private String zoneType; - @SerializedName("dns1") @Param(description="the first DNS for the system VM") private String dns1; @@ -153,15 +150,7 @@ public class SystemVmResponse extends BaseResponse { public void setZoneName(String zoneName) { this.zoneName = zoneName; } - - public String getZoneType() { - return zoneType; - } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public String getDns1() { return dns1; } diff --git a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java index 2a8634e43e9..225edd553db 100644 --- a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java +++ b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java @@ -91,9 +91,6 @@ public class TemplateResponse extends BaseResponse implements ControlledViewEnti @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the zone for this template") private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description="the networktype of the zone for this template") - private String zoneType; @SerializedName(ApiConstants.STATUS) @Param(description="the status of the template") private String status; @@ -171,10 +168,6 @@ public class TemplateResponse extends BaseResponse implements ControlledViewEnti this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setAccountId(String accountId) { this.accountId = accountId; } diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java index 1f9eb1ac63f..5b71ba228cc 100644 --- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java @@ -80,9 +80,6 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the availability zone for the virtual machine") private String zoneName; - @SerializedName(ApiConstants.ZONE_TYPE) @Param(description="the network type of the availability zone for the virtual machine") - private String zoneType; - @SerializedName(ApiConstants.HOST_ID) @Param(description="the ID of the host for the virtual machine") private String hostId; @@ -273,10 +270,6 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setHostId(String hostId) { this.hostId = hostId; } diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java index 21d7d1a449f..b643de12585 100644 --- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java @@ -47,10 +47,6 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity @SerializedName(ApiConstants.ZONE_NAME) @Param(description = "name of the availability zone") private String zoneName; - - @SerializedName(ApiConstants.ZONE_TYPE) - @Param(description = "network type of the availability zone") - private String zoneType; @SerializedName(ApiConstants.TYPE) @Param(description = "type of the disk volume (ROOT or DATADISK)") @@ -110,6 +106,18 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity @Param(description = "shared or local storage") private String storageType; + @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the disk volume") + private Long bytesReadRate; + + @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the disk volume") + private Long bytesWriteRate; + + @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the disk volume") + private Long iopsReadRate; + + @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the disk volume") + private Long iopsWriteRate; + @SerializedName(ApiConstants.HYPERVISOR) @Param(description = "Hypervisor the volume belongs to") private String hypervisor; @@ -205,10 +213,6 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity this.zoneName = zoneName; } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public void setVolumeType(String volumeType) { this.volumeType = volumeType; } @@ -258,6 +262,38 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity this.storageType = storageType; } + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + public void setHypervisor(String hypervisor) { this.hypervisor = hypervisor; } diff --git a/awsapi/web/web.xml b/awsapi/web/web.xml index 7efe43d03f3..5ded12b342f 100644 --- a/awsapi/web/web.xml +++ b/awsapi/web/web.xml @@ -22,16 +22,17 @@ - - - org.springframework.web.context.ContextLoaderListener - + CloudBridge + contextConfigLocation classpath:applicationContext.xml - CloudBridge + + org.springframework.web.context.ContextLoaderListener + + EC2MainServlet EC2 Main Servlet diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 2b173596b73..a0a36c8dd65 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -466,6 +466,10 @@ label.disable.vpn=Disable VPN label.disabled=Disabled label.disabling.vpn.access=Disabling VPN Access label.disk.allocated=Disk Allocated +label.disk.bytes.read.rate=Disk Read Rate (BPS) +label.disk.bytes.write.rate=Disk Write Rate (BPS) +label.disk.iops.read.rate=Disk Read Rate (IOPS) +label.disk.iops.write.rate=Disk Write Rate (IOPS) label.disk.offering=Disk Offering label.disk.read.bytes=Disk Read (Bytes) label.disk.read.io=Disk Read (IO) diff --git a/core/src/com/cloud/agent/api/AttachVolumeCommand.java b/core/src/com/cloud/agent/api/AttachVolumeCommand.java index 302b8f80af3..2658262a6cd 100644 --- a/core/src/com/cloud/agent/api/AttachVolumeCommand.java +++ b/core/src/com/cloud/agent/api/AttachVolumeCommand.java @@ -29,6 +29,10 @@ public class AttachVolumeCommand extends Command { String volumeName; Long deviceId; String chainInfo; + Long bytesReadRate; + Long bytesWriteRate; + Long iopsReadRate; + Long iopsWriteRate; protected AttachVolumeCommand() { } @@ -96,4 +100,36 @@ public class AttachVolumeCommand extends Command { public String getChainInfo() { return chainInfo; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } diff --git a/core/src/com/cloud/agent/api/StartCommand.java b/core/src/com/cloud/agent/api/StartCommand.java index ec707d6e851..308730ab5b7 100644 --- a/core/src/com/cloud/agent/api/StartCommand.java +++ b/core/src/com/cloud/agent/api/StartCommand.java @@ -24,6 +24,7 @@ import com.cloud.host.Host; public class StartCommand extends Command { VirtualMachineTO vm; String hostIp; + boolean executeInSequence = false; public VirtualMachineTO getVirtualMachine() { return vm; @@ -31,19 +32,16 @@ public class StartCommand extends Command { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } protected StartCommand() { } - public StartCommand(VirtualMachineTO vm) { - this.vm = vm; - } - - public StartCommand(VirtualMachineTO vm, Host host) { + public StartCommand(VirtualMachineTO vm, Host host, boolean executeInSequence) { this.vm = vm; this.hostIp = host.getPrivateIpAddress(); + this.executeInSequence = executeInSequence; } public String getHostIp() { diff --git a/core/src/com/cloud/agent/api/StopCommand.java b/core/src/com/cloud/agent/api/StopCommand.java index 1c67f3816ca..a3ee3c967d3 100755 --- a/core/src/com/cloud/agent/api/StopCommand.java +++ b/core/src/com/cloud/agent/api/StopCommand.java @@ -23,28 +23,33 @@ public class StopCommand extends RebootCommand { private boolean isProxy=false; private String urlPort=null; private String publicConsoleProxyIpAddress=null; + boolean executeInSequence = false; protected StopCommand() { } - public StopCommand(VirtualMachine vm, boolean isProxy, String urlPort, String publicConsoleProxyIpAddress) { + public StopCommand(VirtualMachine vm, boolean isProxy, String urlPort, String publicConsoleProxyIpAddress, boolean executeInSequence) { super(vm); this.isProxy = isProxy; this.urlPort = urlPort; this.publicConsoleProxyIpAddress = publicConsoleProxyIpAddress; + this.executeInSequence = executeInSequence; } - public StopCommand(VirtualMachine vm, String vnet) { + public StopCommand(VirtualMachine vm, String vnet, boolean executeInSequence) { super(vm); this.vnet = vnet; + this.executeInSequence = executeInSequence; } - public StopCommand(VirtualMachine vm) { + public StopCommand(VirtualMachine vm, boolean executeInSequence) { super(vm); + this.executeInSequence = executeInSequence; } - public StopCommand(String vmName) { + public StopCommand(String vmName, boolean executeInSequence) { super(vmName); + this.executeInSequence = executeInSequence; } public String getVnet() { @@ -53,7 +58,7 @@ public class StopCommand extends RebootCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public boolean isProxy() { diff --git a/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java b/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java index fd8d84c8c3a..d51ea5e70b5 100644 --- a/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java +++ b/core/src/com/cloud/agent/api/routing/DhcpEntryCommand.java @@ -32,6 +32,7 @@ public class DhcpEntryCommand extends NetworkElementCommand { String ip6Gateway; String duid; private boolean isDefault; + boolean executeInSequence = false; protected DhcpEntryCommand() { @@ -39,19 +40,20 @@ public class DhcpEntryCommand extends NetworkElementCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address) { + public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, boolean executeInSequence) { this.vmMac = vmMac; this.vmIpAddress = vmIpAddress; this.vmName = vmName; this.vmIp6Address = vmIp6Address; this.setDefault(true); + this.executeInSequence = executeInSequence; } - public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, String dns, String gateway, String ip6Gateway) { - this(vmMac, vmIpAddress, vmName, vmIp6Address); + public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, String dns, String gateway, String ip6Gateway, boolean executeInSequence) { + this(vmMac, vmIpAddress, vmName, vmIp6Address, executeInSequence); this.dns = dns; this.gateway = gateway; } diff --git a/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java b/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java index 6dac1488e11..c77dbf60987 100644 --- a/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java +++ b/core/src/com/cloud/agent/api/routing/SavePasswordCommand.java @@ -22,19 +22,21 @@ public class SavePasswordCommand extends NetworkElementCommand { String password; String vmIpAddress; String vmName; + boolean executeInSequence = false; protected SavePasswordCommand() { } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public SavePasswordCommand(String password, String vmIpAddress, String vmName) { + public SavePasswordCommand(String password, String vmIpAddress, String vmName, boolean executeInSequence) { this.password = password; this.vmIpAddress = vmIpAddress; this.vmName = vmName; + this.executeInSequence = executeInSequence; } public String getPassword() { diff --git a/core/src/com/cloud/agent/api/routing/UserDataCommand.java b/core/src/com/cloud/agent/api/routing/UserDataCommand.java index f7b38c8c364..cf360023abc 100644 --- a/core/src/com/cloud/agent/api/routing/UserDataCommand.java +++ b/core/src/com/cloud/agent/api/routing/UserDataCommand.java @@ -23,6 +23,7 @@ public class UserDataCommand extends NetworkElementCommand { String vmIpAddress; String routerPrivateIpAddress; String vmName; + boolean executeInSequence = false; protected UserDataCommand() { @@ -30,14 +31,15 @@ public class UserDataCommand extends NetworkElementCommand { @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public UserDataCommand(String userData, String vmIpAddress, String routerPrivateIpAddress, String vmName) { + public UserDataCommand(String userData, String vmIpAddress, String routerPrivateIpAddress, String vmName, boolean executeInSequence) { this.userData = userData; this.vmIpAddress = vmIpAddress; this.routerPrivateIpAddress = routerPrivateIpAddress; this.vmName = vmName; + this.executeInSequence = executeInSequence; } public String getRouterPrivateIpAddress() { diff --git a/core/src/com/cloud/agent/api/routing/VmDataCommand.java b/core/src/com/cloud/agent/api/routing/VmDataCommand.java index df882554479..861f7006432 100644 --- a/core/src/com/cloud/agent/api/routing/VmDataCommand.java +++ b/core/src/com/cloud/agent/api/routing/VmDataCommand.java @@ -28,27 +28,29 @@ public class VmDataCommand extends NetworkElementCommand { String vmName; @LogLevel(Log4jLevel.Trace) List vmData; + boolean executeInSequence = false; protected VmDataCommand() { } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } - public VmDataCommand(String vmIpAddress) { - this(vmIpAddress, null); + public VmDataCommand(String vmIpAddress, boolean executeInSequence) { + this(vmIpAddress, null, executeInSequence); } public String getVmName() { return vmName; } - public VmDataCommand(String vmIpAddress, String vmName) { + public VmDataCommand(String vmIpAddress, String vmName, boolean executeInSequence) { this.vmName = vmName; this.vmIpAddress = vmIpAddress; this.vmData = new ArrayList(); + this.executeInSequence = executeInSequence; } diff --git a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java index 3d05e9ba69c..1acf2cc13f1 100644 --- a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java +++ b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java @@ -28,22 +28,24 @@ public class CopyVolumeCommand extends Command { String secondaryStorageURL; boolean toSecondaryStorage; String vmName; + boolean executeInSequence = false; public CopyVolumeCommand() { } - public CopyVolumeCommand(long volumeId, String volumePath, StoragePool pool, String secondaryStorageURL, boolean toSecondaryStorage, int wait) { + public CopyVolumeCommand(long volumeId, String volumePath, StoragePool pool, String secondaryStorageURL, boolean toSecondaryStorage, int wait, boolean executeInSequence) { this.volumeId = volumeId; this.volumePath = volumePath; this.pool = new StorageFilerTO(pool); this.secondaryStorageURL = secondaryStorageURL; this.toSecondaryStorage = toSecondaryStorage; setWait(wait); + this.executeInSequence = executeInSequence; } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public String getVolumePath() { diff --git a/core/src/com/cloud/agent/api/storage/CreateCommand.java b/core/src/com/cloud/agent/api/storage/CreateCommand.java index fd0375aa6e7..900abfd744e 100644 --- a/core/src/com/cloud/agent/api/storage/CreateCommand.java +++ b/core/src/com/cloud/agent/api/storage/CreateCommand.java @@ -26,6 +26,7 @@ public class CreateCommand extends Command { private StorageFilerTO pool; private DiskProfile diskCharacteristics; private String templateUrl; + boolean executeInSequence = false; protected CreateCommand() { super(); @@ -33,44 +34,47 @@ public class CreateCommand extends Command { /** * Construction for template based volumes. - * - * @param vol - * @param vm * @param diskCharacteristics * @param templateUrl * @param pool + * @param executeInSequence TODO + * @param vol + * @param vm */ - public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StorageFilerTO pool) { - this(diskCharacteristics, pool); + public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StorageFilerTO pool, boolean executeInSequence) { + this(diskCharacteristics, pool, executeInSequence); this.templateUrl = templateUrl; + this.executeInSequence = executeInSequence; } /** * Construction for regular volumes. - * - * @param vol - * @param vm * @param diskCharacteristics * @param pool + * @param executeInSequence TODO + * @param vol + * @param vm */ - public CreateCommand(DiskProfile diskCharacteristics, StorageFilerTO pool) { + public CreateCommand(DiskProfile diskCharacteristics, StorageFilerTO pool, boolean executeInSequence) { this.volId = diskCharacteristics.getVolumeId(); this.diskCharacteristics = diskCharacteristics; this.pool = pool; this.templateUrl = null; + this.executeInSequence = executeInSequence; } - public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StoragePool pool) { - this(diskCharacteristics, templateUrl, new StorageFilerTO(pool)); + public CreateCommand(DiskProfile diskCharacteristics, String templateUrl, StoragePool pool, boolean executeInSequence) { + this(diskCharacteristics, templateUrl, new StorageFilerTO(pool), executeInSequence); } - public CreateCommand(DiskProfile diskCharacteristics, StoragePool pool) { - this(diskCharacteristics, new StorageFilerTO(pool)); + public CreateCommand(DiskProfile diskCharacteristics, StoragePool pool, boolean executeInSequence) { + this(diskCharacteristics, new StorageFilerTO(pool), executeInSequence); + this.executeInSequence = executeInSequence; } @Override public boolean executeInSequence() { - return true; + return executeInSequence; } public String getTemplateUrl() { diff --git a/core/src/com/cloud/network/HAProxyConfigurator.java b/core/src/com/cloud/network/HAProxyConfigurator.java index 29fdf4ae256..162571fa689 100644 --- a/core/src/com/cloud/network/HAProxyConfigurator.java +++ b/core/src/com/cloud/network/HAProxyConfigurator.java @@ -33,7 +33,6 @@ import com.cloud.agent.api.to.LoadBalancerTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.LoadBalancerTO.DestinationTO; import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO; -import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; import com.cloud.utils.net.NetUtils; @@ -41,6 +40,7 @@ import com.cloud.utils.net.NetUtils; public class HAProxyConfigurator implements LoadBalancerConfigurator { private static final Logger s_logger = Logger.getLogger(HAProxyConfigurator.class); + private static final String blankLine = "\t "; private static String[] globalSection = { "global", "\tlog 127.0.0.1:3914 local0 warning", "\tmaxconn 4096", @@ -86,9 +86,9 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { List result = new ArrayList(); result.addAll(Arrays.asList(globalSection)); - result.add(getBlankLine()); + result.add(blankLine); result.addAll(Arrays.asList(defaultsSection)); - result.add(getBlankLine()); + result.add(blankLine); if (pools.isEmpty()) { // haproxy cannot handle empty listen / frontend or backend, so add @@ -96,7 +96,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { // on port 9 result.addAll(Arrays.asList(defaultListen)); } - result.add(getBlankLine()); + result.add(blankLine); for (Map.Entry> e : pools.entrySet()) { List poolRules = getRulesForPool(e.getKey(), e.getValue()); @@ -143,7 +143,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { .append(rule.getDstPortRange()[0]).append(" check"); result.add(sb.toString()); } - result.add(getBlankLine()); + result.add(blankLine); return result; } @@ -507,14 +507,10 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { result.add(sb.toString()); } - result.add(getBlankLine()); + result.add(blankLine); return result; } - private String getBlankLine() { - return new String("\t "); - } - private String generateStatsRule(LoadBalancerConfigCommand lbCmd, String ruleName, String statsIp) { StringBuilder rule = new StringBuilder("\nlisten ").append(ruleName) @@ -534,7 +530,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { List result = new ArrayList(); result.addAll(Arrays.asList(globalSection)); - result.add(getBlankLine()); + result.add(blankLine); result.addAll(Arrays.asList(defaultsSection)); if (!lbCmd.lbStatsVisibility.equals("disabled")) { /* new rule : listen admin_page guestip/link-local:8081 */ @@ -568,7 +564,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { } } - result.add(getBlankLine()); + result.add(blankLine); boolean has_listener = false; for (LoadBalancerTO lbTO : lbCmd.getLoadBalancers()) { if ( lbTO.isRevoked() ) { @@ -578,7 +574,7 @@ public class HAProxyConfigurator implements LoadBalancerConfigurator { result.addAll(poolRules); has_listener = true; } - result.add(getBlankLine()); + result.add(blankLine); if ( !has_listener) { // haproxy cannot handle empty listen / frontend or backend, so add // a dummy listener diff --git a/docs/en-US/CloudStack_GSoC_Guide.xml b/docs/en-US/CloudStack_GSoC_Guide.xml index 1f435931363..cd8205d34ba 100644 --- a/docs/en-US/CloudStack_GSoC_Guide.xml +++ b/docs/en-US/CloudStack_GSoC_Guide.xml @@ -50,5 +50,6 @@ + diff --git a/docs/en-US/Release_Notes.xml b/docs/en-US/Release_Notes.xml index 2ae87320e40..8843f4c2e20 100644 --- a/docs/en-US/Release_Notes.xml +++ b/docs/en-US/Release_Notes.xml @@ -398,7 +398,7 @@ under the License. SSH keypair assigned to a virtual machine. -
+
Issues Fixed in 4.1.0 Apache CloudStack uses Jira to track its issues. All new features and bugs for 4.1.0 have been tracked diff --git a/docs/en-US/add-loadbalancer-rule-vpc.xml b/docs/en-US/add-loadbalancer-rule-vpc.xml index b7b9e3e7613..82e870243d1 100644 --- a/docs/en-US/add-loadbalancer-rule-vpc.xml +++ b/docs/en-US/add-loadbalancer-rule-vpc.xml @@ -25,16 +25,16 @@ External LB is nothing but a LB rule created to redirect the traffic received at a public IP of the VPC virtual router. The traffic is load balanced within a tier based on your configuration. Citrix NetScaler and VPC virtual router are supported for external LB. When you use internal LB - service, traffic received at a tier is load balanced across different tiers within the VPC. For - example, traffic reached at Web tier is redirected to Application tier. External load balancing - devices are not supported for internal LB. The service is provided by a internal LB VM + service, traffic received at a tier is load balanced across different VMs within that tier. For + example, traffic reached at Web tier is redirected to another VM in that tier. External load + balancing devices are not supported for internal LB. The service is provided by a internal LB VM configured on the target tier.
Load Balancing Within a Tier (External LB) A &PRODUCT; user or administrator may create load balancing rules that balance traffic received at a public IP to one or more VMs that belong to a network tier that provides load balancing service in a VPC. A user creates a rule, specifies an algorithm, and assigns the - rule to a set of VMs within a VPC. + rule to a set of VMs within a tier. Log in to the &PRODUCT; UI as an administrator or end user. diff --git a/docs/en-US/building-devcloud.xml b/docs/en-US/building-devcloud.xml index 5f792c375a2..f3c4d19a5d9 100644 --- a/docs/en-US/building-devcloud.xml +++ b/docs/en-US/building-devcloud.xml @@ -27,6 +27,6 @@ The DevCloud appliance can be downloaded from the wiki at . It can also be built from scratch. Code is being developed to provide this alternative build. It is based on veewee, Vagrant and Puppet. The goal is to automate the DevCloud build and make this automation capability available to all within the source release of &PRODUCT; This is under heavy development. The code is located in the source tree under tools/devcloud - A preliminary wiki page describes the build at https://cwiki.pache.org/CLOUDSTACK/building-devcloud.html + A preliminary wiki page describes the build at https://cwiki.apache.org/confluence/display/CLOUDSTACK/Building+DevCloud
diff --git a/docs/en-US/configure-package-repository.xml b/docs/en-US/configure-package-repository.xml index c8ba48f2717..cda46773f53 100644 --- a/docs/en-US/configure-package-repository.xml +++ b/docs/en-US/configure-package-repository.xml @@ -44,7 +44,7 @@ DEB package repository You can add a DEB package repository to your apt sources with the following commands. Please note that only packages for Ubuntu 12.04 LTS (precise) are being built at this time. Use your preferred editor and open (or create) /etc/apt/sources.list.d/cloudstack.list. Add the community provided repository to the file: -deb http://cloudstack.apt-get.eu/ubuntu precise 4.0 +deb http://cloudstack.apt-get.eu/ubuntu precise 4.1 We now have to add the public key to the trusted keys. $ wget -O - http://cloudstack.apt-get.eu/release.asc|apt-key add - Now update your local apt cache. @@ -60,7 +60,7 @@ [cloudstack] name=cloudstack -baseurl=http://cloudstack.apt-get.eu/rhel/4.0/ +baseurl=http://cloudstack.apt-get.eu/rhel/4.1/ enabled=1 gpgcheck=0 diff --git a/docs/en-US/create-vpn-connection-vpc.xml b/docs/en-US/create-vpn-connection-vpc.xml index 1fba09e18fb..88a058c9f89 100644 --- a/docs/en-US/create-vpn-connection-vpc.xml +++ b/docs/en-US/create-vpn-connection-vpc.xml @@ -20,6 +20,7 @@ -->
Creating a VPN Connection + &PRODUCT; supports creating up to 8 VPN connections. Log in to the &PRODUCT; UI as an administrator or end user. @@ -38,19 +39,37 @@ Click the Settings icon. - The following options are displayed. + For each tier, the following options are displayed: - IP Addresses + Internal LB - Gateways + Public LB IP - Site-to-Site VPN + Static NAT - Network ASLs + Virtual Machines + + + CIDR + + + The following router information is displayed: + + + Private Gateways + + + Public IP Addresses + + + Site-to-Site VPNs + + + Network ACL Lists @@ -100,4 +119,4 @@ -
\ No newline at end of file +
diff --git a/docs/en-US/create-vpn-gateway-for-vpc.xml b/docs/en-US/create-vpn-gateway-for-vpc.xml index 396a7d9d174..0f8a0dcc03b 100644 --- a/docs/en-US/create-vpn-gateway-for-vpc.xml +++ b/docs/en-US/create-vpn-gateway-for-vpc.xml @@ -38,19 +38,37 @@ Click the Settings icon. - The following options are displayed. + For each tier, the following options are displayed: - IP Addresses + Internal LB - Gateways + Public LB IP - Site-to-Site VPN + Static NAT - Network ACLs + Virtual Machines + + + CIDR + + + The following router information is displayed: + + + Private Gateways + + + Public IP Addresses + + + Site-to-Site VPNs + + + Network ACL Lists @@ -77,4 +95,4 @@ -
\ No newline at end of file + diff --git a/docs/en-US/delete-reset-vpn.xml b/docs/en-US/delete-reset-vpn.xml index 318e5fe321e..2fe85d279b6 100644 --- a/docs/en-US/delete-reset-vpn.xml +++ b/docs/en-US/delete-reset-vpn.xml @@ -38,19 +38,37 @@ Click the Settings icon. - The following options are displayed. + For each tier, the following options are displayed: - IP Addresses + Internal LB - Gateways + Public LB IP - Site-to-Site VPN + Static NAT - Network ASLs + Virtual Machines + + + CIDR + + + The following router information is displayed: + + + Private Gateways + + + Public IP Addresses + + + Site-to-Site VPNs + + + Network ACL Lists diff --git a/docs/en-US/gsoc-shiva.xml b/docs/en-US/gsoc-shiva.xml new file mode 100644 index 00000000000..400af3c82f6 --- /dev/null +++ b/docs/en-US/gsoc-shiva.xml @@ -0,0 +1,70 @@ + + +%BOOK_ENTITIES; +]> + + + + + Shiva Teja's 2013 GSoC Proposal + This chapter describes Shiva Teja's 2013 Google Summer of Code project within the &PRODUCT; ASF project. It is a copy paste of the submitted proposal. +
+ Abstract + + The aim of this project is to create a new modular UI for Apache CloudStack using Bootstrap by Twitter and Backbone.js. To achieve this easily, I'll be creating a RESTful wrapper API on top of the current CloudStack API. I hope this project will make custom UIs for CloudStack very easy. + + Why does CloudStack need a new UI? + + The current UI cannot be reused easliy to make a custom UI. The UI I will be making using backbone.js can be reused very easily to make custom UIs. The models, views, routers etc can remain the same in all the UIs. The user interface can be changed just by changing the templates. Check the implementation details below for further details. + + Why does it need a RESTful wrapper API ? + + Backbone.js heavily depends on RESTful architecture. Making a new UI with backbone.js using a query based API might not be easy. +
+
+ List of deliverables + + A new UI for CloudStack(with almost all features in the current UI and new ones, if any). + A RESTful wrapper API on top of the CloudStack API + Some documentation about using this UI to make a custom UI. + +
+
+ Approach + Wrapper API: Backbone.js, by default, uses four HTTP methods(GET, PUT, POST, DELETE) for communicating with the server. It uses GET to fetch a resource from the server, POST to create a resource, PUT to update the resource and DELETE to delete the resource. A query based API can probably be used to make the UI by overriding backbone's default sync function. But it makes more sense to have an API which supports the above mentioned method and is resource based. This RESTful API works on top of the CloudStack API. The main task is to map the combinations of these HTTP methods and the resources to appropriate CloudStack API command. The other task is to decide on how the URLs should look like. Say for starting a virtual machine, for it to be RESTful, we have to use POST as we are creating a resource, or a PUT as we are changing the state of a virtual machine. So the possible options on the URL could be to do a POST /runningvirtualmachines and respond with 201 Created code or a PUT on /virtualmachines/id and respond with 200 OK. If these are decided, the wrapper can be generated or be written manually, which can use defined patters to map to appropriate CloudStack API commands(Similar to what cloudmonkey does. See this prototype. I can use cloudmonkey's code to generate the required API entity verb relationships. Each verb will have a set of rules saying what method should be used in the RESTful API and how should it look like in the URL. Another possible way could be to group entities first manually and write the wrapper manually(something like zone/pods/cluster). Some possibilities have been discussed in this thread. + + UI: It will be a single page app. It'll use client side templating for rendering. This makes it very easy to make a custom UI because it can be achieved just by changing the templates. Backbone views will make use of these templates to render the appropriate models/collections. A completely new interface can be written just by changing the templates. Javascript code can completely remain the same. The views will take care of appropriate DOM events. Such event will correspond to appropriate model/collection chages, thus causing appropriate API calls. +
+
+ Approximate Schedle + Till June 17 - Decide on how the RESTful API should look like and design algorithms to generate the wrapper. + July 5(soft deadline), July 10(hard deadline) : Wrapper API will be ready. + July 12(soft) - July 15(hard): Make basic wireframes and designs for the website and get them approved. + July 29(mid term evaluation) : All the basic models, views, routes of the UI should be ready along with a few templates. + August 15(hard deadline, shouldn't take much time actually) - A basic usable UI where users can just list all the entities which are present in the current UI's main navigation( Like Instances, Templates, Accounts etc) + September 1(hard) - From this UI, users should be able to launch instances, edit settings of most of the entities. + September 16(Pencil down!) - Fix some design tweaks and finish a completely usable interface with functions similar to current UI. + September 23 - Finish the documentation on how to use this UI to make custom UIs. +
+
+ About Me + I am a 2nd year computer science undergrad studying at IIT Mandi, India. I've been using Python for an year and a half now. I've used Django, Flask and Tornado for my small projects. Along with Python, I use C++ for competitive programming. Recently, I fell in love with Haskell. I've always been fascinated about web technologies. +
+
diff --git a/docs/en-US/management-server-install-db-local.xml b/docs/en-US/management-server-install-db-local.xml index 918cdc0a265..310327fcc75 100644 --- a/docs/en-US/management-server-install-db-local.xml +++ b/docs/en-US/management-server-install-db-local.xml @@ -143,6 +143,14 @@ binlog-format = 'ROW' -i <management_server_ip> When this script is finished, you should see a message like “Successfully initialized the database.” + + If the script is unable to connect to the MySQL database, check + the "localhost" loopback address in /etc/hosts. It should + be pointing to the IPv4 loopback address "127.0.0.1" and not the IPv6 loopback + address ::1. Alternatively, reconfigure MySQL to bind to the IPv6 loopback + interface. + + If you are running the KVM hypervisor on the same machine with the Management Server, diff --git a/docs/en-US/source-build.xml b/docs/en-US/source-build.xml index 8504385ee29..a56d304245f 100644 --- a/docs/en-US/source-build.xml +++ b/docs/en-US/source-build.xml @@ -28,8 +28,8 @@ Prior to the 4.0.0 incubating release, Ant was used to build &PRODUCT;. A migration to Maven started in the 4.0.0 cycle, and has completed in 4.1.0. The website and the wiki contain up to date information on the build procedure at: - https://cwiki.apache.org/CLOUDSTACK/building-with-maven.html - https://cwiki.apache.org/CLOUDSTACK/setting-up-cloudstack-development-environment.html + https://cwiki.apache.org/confluence/display/CLOUDSTACK/How+to+build+on+master+branch + https://cwiki.apache.org/confluence/display/CLOUDSTACK/Setting+up+CloudStack+Development+Environment The overarching steps to build &PRODUCT; are:. diff --git a/docs/pot/configure-package-repository.pot b/docs/pot/configure-package-repository.pot index e91535826a5..c0ee374254a 100644 --- a/docs/pot/configure-package-repository.pot +++ b/docs/pot/configure-package-repository.pot @@ -60,7 +60,7 @@ msgstr "" #. Tag: programlisting #, no-c-format -msgid "deb http://cloudstack.apt-get.eu/ubuntu precise 4.0" +msgid "deb http://cloudstack.apt-get.eu/ubuntu precise 4.1" msgstr "" #. Tag: para @@ -118,7 +118,7 @@ msgstr "" msgid "\n" "[cloudstack]\n" "name=cloudstack\n" -"baseurl=http://cloudstack.apt-get.eu/rhel/4.0/\n" +"baseurl=http://cloudstack.apt-get.eu/rhel/4.1/\n" "enabled=1\n" "gpgcheck=0\n" " " diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java index 3d7b1aa76cb..3b4aba970ba 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java @@ -40,4 +40,9 @@ public interface VolumeInfo extends DataObject, Volume { void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer); boolean stateTransit(Volume.Event event); + + Long getBytesReadRate(); + Long getBytesWriteRate(); + Long getIopsReadRate(); + Long getIopsWriteRate(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index bc1c061b0ca..ab3d5ea14d3 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -37,6 +37,10 @@ public class VolumeObjectTO implements DataTO { private String chainInfo; private Storage.ImageFormat format; private long id; + private Long bytesReadRate; + private Long bytesWriteRate; + private Long iopsReadRate; + private Long iopsWriteRate; public VolumeObjectTO() { @@ -59,6 +63,10 @@ public class VolumeObjectTO implements DataTO { this.name = volume.getName(); this.setId(volume.getId()); this.format = volume.getFormat(); + this.bytesReadRate = volume.getBytesReadRate(); + this.bytesWriteRate = volume.getBytesWriteRate(); + this.iopsReadRate = volume.getIopsReadRate(); + this.iopsWriteRate = volume.getIopsWriteRate(); } public String getUuid() { @@ -172,4 +180,36 @@ public class VolumeObjectTO implements DataTO { .append("|datastore=").append(dataStore).append("]").toString(); } + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } + } diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java b/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java index e54b9bbbe29..ed6e6965312 100755 --- a/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java +++ b/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java @@ -36,7 +36,7 @@ public interface DataCenterDao extends GenericDao { Pair allocatePrivateIpAddress(long id, long podId, long instanceId, String reservationId); DataCenterIpAddressVO allocatePrivateIpAddress(long id, String reservationId); String allocateLinkLocalIpAddress(long id, long podId, long instanceId, String reservationId); - String allocateVnet(long dcId, long physicalNetworkId, long accountId, String reservationId); + String allocateVnet(long dcId, long physicalNetworkId, long accountId, String reservationId, boolean canUseSystemGuestVlans); void releaseVnet(String vnet, long dcId, long physicalNetworkId, long accountId, String reservationId); void releasePrivateIpAddress(String ipAddress, long dcId, Long instanceId); diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java index 4d9d01065ca..503306f6722 100755 --- a/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java @@ -192,22 +192,27 @@ public class DataCenterDaoImpl extends GenericDaoBase implem } @Override - public String allocateVnet(long dataCenterId, long physicalNetworkId, long accountId, String reservationId) { + public String allocateVnet(long dataCenterId, long physicalNetworkId, long accountId, String reservationId, + boolean canUseSystemGuestVlans) { ArrayList dedicatedVlanDbIds = new ArrayList(); + boolean useDedicatedGuestVlans = false; List maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(accountId); for (AccountGuestVlanMapVO map : maps) { dedicatedVlanDbIds.add(map.getId()); } if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) { + useDedicatedGuestVlans = true; DataCenterVnetVO vo = _vnetAllocDao.take(physicalNetworkId, accountId, reservationId, dedicatedVlanDbIds); if (vo != null) return vo.getVnet(); } - DataCenterVnetVO vo = _vnetAllocDao.take(physicalNetworkId, accountId, reservationId, null); - if (vo == null) { - return null; + if (!useDedicatedGuestVlans || (useDedicatedGuestVlans && canUseSystemGuestVlans)) { + DataCenterVnetVO vo = _vnetAllocDao.take(physicalNetworkId, accountId, reservationId, null); + if (vo != null) { + return vo.getVnet(); + } } - return vo.getVnet(); + return null; } @Override diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java index 3ae0bf38b0b..fae315b01a0 100755 --- a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java @@ -414,4 +414,8 @@ public class NetworkOfferingVO implements NetworkOffering { return publicLb; } + public void setInternalLb(boolean internalLb) { + this.internalLb = internalLb; + } + } diff --git a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java index 23b8d60e31c..b7363e7208a 100755 --- a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java +++ b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java @@ -97,7 +97,19 @@ public class DiskOfferingVO implements DiskOffering { @Column(name = "sort_key") int sortKey; - @Column(name = "display_offering") + @Column(name="bytes_read_rate") + Long bytesReadRate; + + @Column(name="bytes_write_rate") + Long bytesWriteRate; + + @Column(name="iops_read_rate") + Long iopsReadRate; + + @Column(name="iops_write_rate") + Long iopsWriteRate; + + @Column(name="display_offering") boolean displayOffering; public DiskOfferingVO() { @@ -327,4 +339,36 @@ public class DiskOfferingVO implements DiskOffering { public void setDisplayOffering(boolean displayOffering) { this.displayOffering = displayOffering; } + + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } diff --git a/engine/schema/src/com/cloud/storage/VolumeVO.java b/engine/schema/src/com/cloud/storage/VolumeVO.java index 984da21f280..02c09a2f271 100755 --- a/engine/schema/src/com/cloud/storage/VolumeVO.java +++ b/engine/schema/src/com/cloud/storage/VolumeVO.java @@ -351,7 +351,7 @@ public class VolumeVO implements Volume { } @Override - public long getDiskOfferingId() { + public Long getDiskOfferingId() { return diskOfferingId; } diff --git a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index 391fa5895b0..65b9d3b27c7 100755 --- a/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.vm.dao; +import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; @@ -44,6 +45,7 @@ import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.db.UpdateBuilder; @@ -103,6 +105,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im IdNetworkIdStatesSearch.done(); HostUpSearch = createSearchBuilder(); + HostUpSearch.select(null, Func.DISTINCT, HostUpSearch.entity().getId()); HostUpSearch.and("host", HostUpSearch.entity().getHostId(), Op.EQ); HostUpSearch.and("states", HostUpSearch.entity().getState(), Op.NIN); SearchBuilder joinRouterNetwork3 = _routerNetworkDao.createSearchBuilder(); @@ -112,6 +115,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im HostUpSearch.done(); StateNetworkTypeSearch = createSearchBuilder(); + StateNetworkTypeSearch.select(null, Func.DISTINCT, StateNetworkTypeSearch.entity().getId()); StateNetworkTypeSearch.and("state", StateNetworkTypeSearch.entity().getState(), Op.EQ); SearchBuilder joinRouterNetwork4 = _routerNetworkDao.createSearchBuilder(); joinRouterNetwork4.and("networkId", joinRouterNetwork4.entity().getNetworkId(), Op.EQ); @@ -214,7 +218,12 @@ public class DomainRouterDaoImpl extends GenericDaoBase im sc.setParameters("host", hostId); } sc.setJoinParameters("networkRouter", "type", Network.GuestType.Isolated); - return listBy(sc); + List routerIds = listBy(sc); + List routers = new ArrayList(); + for (DomainRouterVO router : routerIds) { + routers.add(findById(router.getId())); + } + return routers; } @Override @@ -253,7 +262,12 @@ public class DomainRouterDaoImpl extends GenericDaoBase im sc.setParameters("state", state); sc.setJoinParameters("networkRouter", "type", type); sc.setJoinParameters("host", "mgmtServerId", mgmtSrvrId); - return listBy(sc); + List routerIds = listBy(sc); + List routers = new ArrayList(); + for (DomainRouterVO router : routerIds) { + routers.add(findById(router.getId())); + } + return routers; } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index d689195957c..071c110da48 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -20,6 +20,8 @@ import java.util.Date; import javax.inject.Inject; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.dao.DiskOfferingDao; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; @@ -63,6 +65,8 @@ public class VolumeObject implements VolumeInfo { ObjectInDataStoreManager objectInStoreMgr; @Inject VMInstanceDao vmInstanceDao; + @Inject + DiskOfferingDao diskOfferingDao; private Object payload; public VolumeObject() { @@ -141,6 +145,50 @@ public class VolumeObject implements VolumeInfo { return result; } + private DiskOfferingVO getDiskOfferingVO() { + if (getDiskOfferingId() != null) { + DiskOfferingVO diskOfferingVO = diskOfferingDao.findById(getDiskOfferingId()); + return diskOfferingVO; + } + return null; + } + + @Override + public Long getBytesReadRate() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getBytesReadRate(); + } + return null; + } + + @Override + public Long getBytesWriteRate() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getBytesWriteRate(); + } + return null; + } + + @Override + public Long getIopsReadRate() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getIopsReadRate(); + } + return null; + } + + @Override + public Long getIopsWriteRate() { + DiskOfferingVO diskOfferingVO = getDiskOfferingVO(); + if (diskOfferingVO != null) { + return diskOfferingVO.getIopsWriteRate(); + } + return null; + } + public void update() { volumeDao.update(volumeVO.getId(), volumeVO); volumeVO = volumeDao.findById(volumeVO.getId()); @@ -313,7 +361,7 @@ public class VolumeObject implements VolumeInfo { } @Override - public long getDiskOfferingId() { + public Long getDiskOfferingId() { return this.volumeVO.getDiskOfferingId(); } diff --git a/patches/systemvm/debian/config/root/edithosts.sh b/patches/systemvm/debian/config/root/edithosts.sh index fb0c34fbd42..eaa82927803 100755 --- a/patches/systemvm/debian/config/root/edithosts.sh +++ b/patches/systemvm/debian/config/root/edithosts.sh @@ -69,7 +69,9 @@ HOSTS=/etc/hosts source /root/func.sh lock="biglock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as DhcpEntryCommand is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/patches/systemvm/debian/config/root/savepassword.sh b/patches/systemvm/debian/config/root/savepassword.sh index a096b862fce..fc736039c2e 100755 --- a/patches/systemvm/debian/config/root/savepassword.sh +++ b/patches/systemvm/debian/config/root/savepassword.sh @@ -25,7 +25,9 @@ source /root/func.sh lock="passwdlock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as password reset command is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/patches/systemvm/debian/config/root/userdata.sh b/patches/systemvm/debian/config/root/userdata.sh index e5d170b5b23..f9ea644c2fd 100644 --- a/patches/systemvm/debian/config/root/userdata.sh +++ b/patches/systemvm/debian/config/root/userdata.sh @@ -21,7 +21,9 @@ source /root/func.sh lock="biglock" -locked=$(getLockFile $lock) +#default timeout value is 30 mins as userdata command is not synchronized on agent side any more, +#and multiple commands can be sent to the same VR at a time +locked=$(getLockFile $lock 1800) if [ "$locked" != "1" ] then exit 1 diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java index f87bf71ca13..c749211e375 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalDhcpManagerImpl.java @@ -53,6 +53,7 @@ import com.cloud.host.Host.Type; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.network.Network; +import com.cloud.network.NetworkModel; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; @@ -100,6 +101,8 @@ public class BaremetalDhcpManagerImpl extends ManagerBase implements BaremetalDh PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; @Inject BaremetalDhcpDao _extDhcpDao; + @Inject + NetworkModel _ntwkModel; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -147,7 +150,7 @@ public class BaremetalDhcpManagerImpl extends ManagerBase implements BaremetalDh dns = nic.getDns2(); } DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), profile.getVirtualMachine().getHostName(), null, dns, - nic.getGateway(), null); + nic.getGateway(), null, _ntwkModel.getExecuteInSeqNtwkElmtCmd()); String errMsg = String.format("Set dhcp entry on external DHCP %1$s failed(ip=%2$s, mac=%3$s, vmname=%4$s)", h.getPrivateIpAddress(), nic.getIp4Address(), nic.getMacAddress(), profile.getVirtualMachine().getHostName()); // prepareBareMetalDhcpEntry(nic, dhcpCommand); diff --git a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java index 59a28117cb5..04f5fbc34a7 100755 --- a/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java +++ b/plugins/hypervisors/baremetal/src/com/cloud/baremetal/networkservice/BaremetalPxeManagerImpl.java @@ -45,6 +45,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.network.NetworkModel; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.resource.ResourceManager; @@ -81,6 +82,7 @@ public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxe @Inject NicDao _nicDao; @Inject ConfigurationDao _configDao; @Inject PhysicalNetworkDao _phynwDao; + @Inject NetworkModel _ntwkModel; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -184,7 +186,7 @@ public class BaremetalPxeManagerImpl extends ManagerBase implements BaremetalPxe String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId()).getDisplayText(); String zoneName = _dcDao.findById(vm.getDataCenterId()).getName(); NicVO nvo = _nicDao.findById(nic.getId()); - VmDataCommand cmd = new VmDataCommand(nvo.getIp4Address(), vm.getInstanceName()); + VmDataCommand cmd = new VmDataCommand(nvo.getIp4Address(), vm.getInstanceName(), _ntwkModel.getExecuteInSeqNtwkElmtCmd()); cmd.addVmData("userdata", "user-data", vm.getUserData()); cmd.addVmData("metadata", "service-offering", StringUtils.unicodeEscape(serviceOffering)); cmd.addVmData("metadata", "availability-zone", StringUtils.unicodeEscape(zoneName)); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 3c7e24d1f6a..46003e9e289 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -58,6 +58,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.cloudstack.utils.qemu.QemuImg; import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; import org.apache.cloudstack.utils.qemu.QemuImgException; @@ -342,6 +343,8 @@ ServerResource { protected HypervisorType _hypervisorType; protected String _hypervisorURI; + protected long _hypervisorLibvirtVersion; + protected long _hypervisorQemuVersion; protected String _hypervisorPath; protected String _networkDirectSourceMode; protected String _networkDirectDevice; @@ -742,6 +745,8 @@ ServerResource { try { _hvVersion = conn.getVersion(); _hvVersion = (_hvVersion % 1000000) / 1000; + _hypervisorLibvirtVersion = conn.getLibVirVersion(); + _hypervisorQemuVersion = conn.getVersion(); } catch (LibvirtException e) { s_logger.trace("Ignoring libvirt error.", e); } @@ -1419,6 +1424,10 @@ ServerResource { VolumeTO volume = new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), pool.getPath(), vol.getName(), vol.getName(), disksize, null); + volume.setBytesReadRate(dskch.getBytesReadRate()); + volume.setBytesWriteRate(dskch.getBytesWriteRate()); + volume.setIopsReadRate(dskch.getIopsReadRate()); + volume.setIopsWriteRate(dskch.getIopsWriteRate()); return new CreateAnswer(cmd, volume); } catch (CloudRuntimeException e) { s_logger.debug("Failed to create volume: " + e.toString()); @@ -2557,7 +2566,7 @@ ServerResource { cmd.getPoolUuid()); KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath()); attachOrDetachDisk(conn, cmd.getAttach(), cmd.getVmName(), disk, - cmd.getDeviceId().intValue()); + cmd.getDeviceId().intValue(), cmd.getBytesReadRate(), cmd.getBytesWriteRate(), cmd.getIopsReadRate(), cmd.getIopsWriteRate()); } catch (LibvirtException e) { return new AttachVolumeAnswer(cmd, e.toString()); } catch (InternalErrorException e) { @@ -3155,6 +3164,8 @@ ServerResource { } else { guest.setGuestType(GuestDef.guestType.KVM); vm.setHvsType(HypervisorType.KVM.toString().toLowerCase()); + vm.setLibvirtVersion(_hypervisorLibvirtVersion); + vm.setQemuVersion(_hypervisorQemuVersion); } guest.setGuestArch(vmTO.getArch()); guest.setMachineType("pc"); @@ -3435,6 +3446,17 @@ ServerResource { } + VolumeObjectTO volumeObjectTO = (VolumeObjectTO)data; + + if ((volumeObjectTO.getBytesReadRate() != null) && (volumeObjectTO.getBytesReadRate() > 0)) + disk.setBytesReadRate(volumeObjectTO.getBytesReadRate()); + if ((volumeObjectTO.getBytesWriteRate() != null) && (volumeObjectTO.getBytesWriteRate() > 0)) + disk.setBytesWriteRate(volumeObjectTO.getBytesWriteRate()); + if ((volumeObjectTO.getIopsReadRate() != null) && (volumeObjectTO.getIopsReadRate() > 0)) + disk.setIopsReadRate(volumeObjectTO.getIopsReadRate()); + if ((volumeObjectTO.getIopsWriteRate() != null) && (volumeObjectTO.getIopsWriteRate() > 0)) + disk.setIopsWriteRate(volumeObjectTO.getIopsWriteRate()); + vm.getDevices().addDevice(disk); } @@ -3560,7 +3582,7 @@ ServerResource { protected synchronized String attachOrDetachDisk(Connect conn, boolean attach, String vmName, KVMPhysicalDisk attachingDisk, - int devId) throws LibvirtException, InternalErrorException { + int devId, Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) throws LibvirtException, InternalErrorException { List disks = null; Domain dm = null; DiskDef diskdef = null; @@ -3600,6 +3622,14 @@ ServerResource { diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, DiskDef.diskBus.VIRTIO); } + if ((bytesReadRate != null) && (bytesReadRate > 0)) + diskdef.setBytesReadRate(bytesReadRate); + if ((bytesWriteRate != null) && (bytesWriteRate > 0)) + diskdef.setBytesWriteRate(bytesWriteRate); + if ((iopsReadRate != null) && (iopsReadRate > 0)) + diskdef.setIopsReadRate(iopsReadRate); + if ((iopsWriteRate != null) && (iopsWriteRate > 0)) + diskdef.setIopsWriteRate(iopsWriteRate); } String xml = diskdef.toString(); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java index b8645e1664a..8514a5bd270 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java @@ -105,6 +105,31 @@ public class LibvirtDomainXMLParser { DiskDef.diskBus.valueOf(bus.toUpperCase())); } } + + NodeList iotune = disk.getElementsByTagName("iotune"); + if ((iotune != null) && (iotune.getLength() !=0)) { + String bytesReadRateStr = getTagValue("read_bytes_sec", (Element)iotune.item(0)); + if (bytesReadRateStr != null) { + Long bytesReadRate = Long.parseLong(bytesReadRateStr); + def.setBytesReadRate(bytesReadRate); + } + String bytesWriteRateStr = getTagValue("write_bytes_sec", (Element)iotune.item(0)); + if (bytesWriteRateStr != null) { + Long bytesWriteRate = Long.parseLong(bytesWriteRateStr); + def.setBytesWriteRate(bytesWriteRate); + } + String iopsReadRateStr = getTagValue("read_iops_sec", (Element)iotune.item(0)); + if (iopsReadRateStr != null) { + Long iopsReadRate = Long.parseLong(iopsReadRateStr); + def.setIopsReadRate(iopsReadRate); + } + String iopsWriteRateStr = getTagValue("write_iops_sec", (Element)iotune.item(0)); + if (iopsWriteRateStr != null) { + Long iopsWriteRate = Long.parseLong(iopsWriteRateStr); + def.setIopsWriteRate(iopsWriteRate); + } + } + diskDefs.add(def); } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index 3ee13480c5d..93b4dfedb62 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -22,8 +22,12 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import com.cloud.utils.script.Script; + public class LibvirtVMDef { private String _hvsType; + private static long _libvirtVersion; + private static long _qemuVersion; private String _domName; private String _domUUID; private String _desc; @@ -439,6 +443,10 @@ public class LibvirtVMDef { private boolean _readonly = false; private boolean _shareable = false; private boolean _deferAttach = false; + private Long _bytesReadRate; + private Long _bytesWriteRate; + private Long _iopsReadRate; + private Long _iopsWriteRate; public void setDeviceType(deviceType deviceType) { _deviceType = deviceType; @@ -584,6 +592,22 @@ public class LibvirtVMDef { return suffix - 'a'; } + public void setBytesReadRate(Long bytesReadRate) { + _bytesReadRate = bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + _bytesWriteRate = bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + _iopsReadRate = iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + _iopsWriteRate = iopsWriteRate; + } + @Override public String toString() { StringBuilder diskBuilder = new StringBuilder(); @@ -627,6 +651,22 @@ public class LibvirtVMDef { diskBuilder.append(" bus='" + _bus + "'"); } diskBuilder.append("/>\n"); + + if ((_deviceType != deviceType.CDROM) && (_libvirtVersion >= 9008) && (_qemuVersion >= 1001000) + && (((_bytesReadRate != null) && (_bytesReadRate > 0)) || ((_bytesWriteRate != null) && (_bytesWriteRate > 0)) + || ((_iopsReadRate != null) && (_iopsReadRate > 0)) || ((_iopsWriteRate != null) && (_iopsWriteRate > 0)) )) { // not CDROM, from libvirt 0.9.8 and QEMU 1.1.0 + diskBuilder.append("\n"); + if ((_bytesReadRate != null) && (_bytesReadRate > 0)) + diskBuilder.append("" + _bytesReadRate + "\n"); + if ((_bytesWriteRate != null) && (_bytesWriteRate > 0)) + diskBuilder.append("" + _bytesWriteRate + "\n"); + if ((_iopsReadRate != null) && (_iopsReadRate > 0)) + diskBuilder.append("" + _iopsReadRate + "\n"); + if ((_iopsWriteRate != null) && (_iopsWriteRate > 0)) + diskBuilder.append("" + _iopsWriteRate + "\n"); + diskBuilder.append("\n"); + } + diskBuilder.append("\n"); return diskBuilder.toString(); } @@ -1012,6 +1052,14 @@ public class LibvirtVMDef { return _hvsType; } + public void setLibvirtVersion(long libvirtVersion) { + _libvirtVersion = libvirtVersion; + } + + public void setQemuVersion(long qemuVersion) { + _qemuVersion = qemuVersion; + } + public void setDomainName(String domainName) { _domName = domainName; } diff --git a/plugins/network-elements/bigswitch-vns/src/com/cloud/network/guru/BigSwitchVnsGuestNetworkGuru.java b/plugins/network-elements/bigswitch-vns/src/com/cloud/network/guru/BigSwitchVnsGuestNetworkGuru.java index e753b131ef7..f660b7c7838 100644 --- a/plugins/network-elements/bigswitch-vns/src/com/cloud/network/guru/BigSwitchVnsGuestNetworkGuru.java +++ b/plugins/network-elements/bigswitch-vns/src/com/cloud/network/guru/BigSwitchVnsGuestNetworkGuru.java @@ -162,7 +162,7 @@ public class BigSwitchVnsGuestNetworkGuru extends GuestNetworkGuru { } String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, - network.getAccountId(), context.getReservationId()); + network.getAccountId(), context.getReservationId(), canUseSystemGuestVlan(network.getAccountId())); if (vnet == null) { throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a " + "part of network " + network + " implement ", DataCenter.class, dcId); diff --git a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java index 781b4b9b2f2..bbdf1108f90 100644 --- a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java +++ b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java @@ -94,7 +94,8 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru { protected void allocateVnet(Network network, NetworkVO implemented, long dcId, long physicalNetworkId, String reservationId) throws InsufficientVirtualNetworkCapcityException { if (network.getBroadcastUri() == null) { - String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId); + String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId, + canUseSystemGuestVlan(network.getAccountId())); if (vnet == null) { throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a part of network " + network + " implement ", DataCenter.class, dcId); } diff --git a/python/lib/cloudutils/networkConfig.py b/python/lib/cloudutils/networkConfig.py index 9e456e970be..405a3be519c 100644 --- a/python/lib/cloudutils/networkConfig.py +++ b/python/lib/cloudutils/networkConfig.py @@ -82,7 +82,7 @@ class networkConfig: if os.path.exists("/proc/sys/net/bridge"): return True - return bash("modprobe bridge").isSucess() + return bash("modprobe -b bridge").isSucess() @staticmethod def isNetworkDev(devName): diff --git a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java index 3ce60b79107..19f0102d173 100755 --- a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java @@ -173,8 +173,8 @@ public class ClusteredAgentManagerImpl extends AgentManagerImpl implements Clust s_logger.trace("Begin scanning directly connected hosts"); } - // for agents that are self-managed, threshold to be considered as disconnected is 3 ping intervals - long cutSeconds = (System.currentTimeMillis() >> 10) - (_pingInterval * 3); + // for agents that are self-managed, threshold to be considered as disconnected after pingtimeout + long cutSeconds = (System.currentTimeMillis() >> 10) - (_pingTimeout); List hosts = _hostDao.findAndUpdateDirectAgentToLoad(cutSeconds, _loadSize, _nodeId); List appliances = _hostDao.findAndUpdateApplianceToLoad(cutSeconds, _nodeId); hosts.addAll(appliances); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 1106422a512..7d91e95bc9a 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -433,13 +433,6 @@ public class ApiResponseHelper implements ResponseGenerator { snapshotResponse.setVolumeId(volume.getUuid()); snapshotResponse.setVolumeName(volume.getName()); snapshotResponse.setVolumeType(volume.getVolumeType().name()); - - DataCenter zone = ApiDBUtils.findZoneById(volume.getDataCenterId()); - if (zone != null) { - snapshotResponse.setZoneName(zone.getName()); - snapshotResponse.setZoneType(zone.getNetworkType().toString()); - snapshotResponse.setZoneId(zone.getUuid()); - } } snapshotResponse.setCreated(snapshot.getCreated()); snapshotResponse.setName(snapshot.getName()); @@ -823,7 +816,6 @@ public class ApiResponseHelper implements ResponseGenerator { if (zone != null) { podResponse.setZoneId(zone.getUuid()); podResponse.setZoneName(zone.getName()); - podResponse.setZoneType(zone.getNetworkType().toString()); } podResponse.setNetmask(NetUtils.getCidrNetmask(pod.getCidrSize())); podResponse.setStartIp(ipRange[0]); @@ -981,7 +973,6 @@ public class ApiResponseHelper implements ResponseGenerator { if (dc != null) { clusterResponse.setZoneId(dc.getUuid()); clusterResponse.setZoneName(dc.getName()); - clusterResponse.setZoneType(dc.getNetworkType().toString()); } clusterResponse.setHypervisorType(cluster.getHypervisorType().toString()); clusterResponse.setClusterType(cluster.getClusterType().toString()); @@ -1182,7 +1173,6 @@ public class ApiResponseHelper implements ResponseGenerator { if (zone != null) { vmResponse.setZoneId(zone.getUuid()); vmResponse.setZoneName(zone.getName()); - vmResponse.setZoneType(zone.getNetworkType().toString()); vmResponse.setDns1(zone.getDns1()); vmResponse.setDns2(zone.getDns2()); } @@ -1539,7 +1529,6 @@ public class ApiResponseHelper implements ResponseGenerator { if (datacenter != null) { isoResponse.setZoneId(datacenter.getUuid()); isoResponse.setZoneName(datacenter.getName()); - isoResponse.setZoneType(datacenter.getNetworkType().toString()); } // If the user is an admin, add the template download status @@ -2208,7 +2197,6 @@ public class ApiResponseHelper implements ResponseGenerator { if (zone != null) { response.setZoneId(zone.getUuid()); response.setZoneName(zone.getName()); - response.setZoneType(zone.getNetworkType().toString()); } if (network.getPhysicalNetworkId() != null) { PhysicalNetworkVO pnet = ApiDBUtils.findPhysicalNetworkById(network.getPhysicalNetworkId()); diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index fca4138b405..9bd8f2a063b 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -27,6 +27,7 @@ import java.util.Set; import javax.ejb.Local; import javax.inject.Inject; +import com.cloud.storage.*; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.affinity.AffinityGroupVMMapVO; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; @@ -54,28 +55,7 @@ import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd; import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd; import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd; import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; -import org.apache.cloudstack.api.response.AccountResponse; -import org.apache.cloudstack.api.response.AsyncJobResponse; -import org.apache.cloudstack.api.response.DiskOfferingResponse; -import org.apache.cloudstack.api.response.DomainRouterResponse; -import org.apache.cloudstack.api.response.EventResponse; -import org.apache.cloudstack.api.response.HostResponse; -import org.apache.cloudstack.api.response.ImageStoreResponse; -import org.apache.cloudstack.api.response.InstanceGroupResponse; -import org.apache.cloudstack.api.response.ListResponse; -import org.apache.cloudstack.api.response.ProjectAccountResponse; -import org.apache.cloudstack.api.response.ProjectInvitationResponse; -import org.apache.cloudstack.api.response.ProjectResponse; -import org.apache.cloudstack.api.response.ResourceDetailResponse; -import org.apache.cloudstack.api.response.ResourceTagResponse; -import org.apache.cloudstack.api.response.SecurityGroupResponse; -import org.apache.cloudstack.api.response.ServiceOfferingResponse; -import org.apache.cloudstack.api.response.StoragePoolResponse; -import org.apache.cloudstack.api.response.TemplateResponse; -import org.apache.cloudstack.api.response.UserResponse; -import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.api.response.VolumeResponse; -import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.cloudstack.api.response.*; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.cloudstack.query.QueryService; import org.apache.log4j.Logger; @@ -151,12 +131,7 @@ import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.server.TaggedResourceService; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Volume; -import com.cloud.storage.VolumeDetailVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDetailsDao; import com.cloud.template.VirtualMachineTemplate.TemplateFilter; @@ -1061,9 +1036,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { @Override public ListResponse searchForRouters(ListRoutersCmd cmd) { - Pair, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), - cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getHostId(), - cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getZoneType()); + Pair, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), + cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), + cmd.getVpcId(), cmd.getForVpc(), cmd.getRole()); ListResponse response = new ListResponse(); List routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first() @@ -1074,9 +1049,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { @Override public ListResponse searchForInternalLbVms(ListInternalLBVMsCmd cmd) { - Pair, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), - cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getHostId(), - cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getZoneType()); + Pair, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), + cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), + cmd.getVpcId(), cmd.getForVpc(), cmd.getRole()); ListResponse response = new ListResponse(); List routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first() @@ -1085,10 +1060,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { return response; } - private Pair, Integer> searchForRoutersInternal(BaseListProjectAndAccountResourcesCmd cmd, - Long id, String name, String state, Long zoneId, Long podId, Long hostId, String keyword, Long networkId, - Long vpcId, Boolean forVpc, String role, String zoneType) { - + private Pair, Integer> searchForRoutersInternal(BaseListProjectAndAccountResourcesCmd cmd, Long id, + String name, String state, Long zoneId, Long podId, Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role) { + Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -1117,7 +1091,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.IN); sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); - sb.and("dataCenterType", sb.entity().getDataCenterType(), SearchCriteria.Op.EQ); sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); sb.and("hostId", sb.entity().getHostId(), SearchCriteria.Op.EQ); sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ); @@ -1168,10 +1141,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.setParameters("podId", podId); } - if (zoneType != null) { - sc.setParameters("dataCenterType", zoneType); - } - if (hostId != null) { sc.setParameters("hostId", hostId); } @@ -1969,6 +1938,14 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } private Pair, Integer> searchForStoragePoolsInternal(ListStoragePoolsCmd cmd) { + ScopeType scopeType = null; + if (cmd.getScope() != null) { + try { + scopeType = Enum.valueOf(ScopeType.class, cmd.getScope().toUpperCase()); + } catch (Exception e) { + throw new InvalidParameterValueException("Invalid scope type: " + cmd.getScope()); + } + } Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId()); Object id = cmd.getId(); @@ -2027,6 +2004,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { if (cluster != null) { sc.setParameters("clusterId", cluster); } + if (scopeType != null) { + sc.setParameters("scope", scopeType.toString()); + } // search Pool details by ids Pair, Integer> uniquePoolPair = _poolJoinDao.searchAndCount(sc, searchFilter); @@ -2401,7 +2381,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { Long id = cmd.getId(); String keyword = cmd.getKeyword(); String name = cmd.getName(); - String networkType = cmd.getZoneType(); + String networkType = cmd.getNetworkType(); Filter searchFilter = new Filter(DataCenterJoinVO.class, null, false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchCriteria sc = _dcJoinDao.createSearchCriteria(); diff --git a/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java index 283181f5245..7022ee60fbb 100644 --- a/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java @@ -75,7 +75,12 @@ public class DiskOfferingJoinDaoImpl extends GenericDaoBase implements hostResponse.setOsCategoryId(host.getOsCategoryUuid()); hostResponse.setOsCategoryName(host.getOsCategoryName()); hostResponse.setZoneName(host.getZoneName()); - hostResponse.setZoneType(host.getZoneType().toString()); hostResponse.setPodName(host.getPodName()); if ( host.getClusterId() > 0) { hostResponse.setClusterName(host.getClusterName()); diff --git a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java index 56e4d0a369e..6f6e27701fa 100644 --- a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java @@ -75,6 +75,10 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase implem } userVmResponse.setZoneId(userVm.getDataCenterUuid()); userVmResponse.setZoneName(userVm.getDataCenterName()); - userVmResponse.setZoneType(userVm.getDataCenterType()); if ((caller == null) || (caller.getType() == Account.ACCOUNT_TYPE_ADMIN)) { userVmResponse.setInstanceName(userVm.getInstanceName()); userVmResponse.setHostId(userVm.getHostUuid()); @@ -141,6 +140,8 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem if (details.contains(VMDetails.all) || details.contains(VMDetails.servoff)) { userVmResponse.setServiceOfferingId(userVm.getServiceOfferingUuid()); userVmResponse.setServiceOfferingName(userVm.getServiceOfferingName()); + } + if (details.contains(VMDetails.all) || details.contains(VMDetails.servoff) || details.contains(VMDetails.stats)) { userVmResponse.setCpuNumber(userVm.getCpu()); userVmResponse.setCpuSpeed(userVm.getSpeed()); userVmResponse.setMemory(userVm.getRamSize()); diff --git a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java index e27e2d93bef..ed2732e184d 100644 --- a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java @@ -86,8 +86,7 @@ public class VolumeJoinDaoImpl extends GenericDaoBase implem volResponse.setZoneId(volume.getDataCenterUuid()); volResponse.setZoneName(volume.getDataCenterName()); - volResponse.setZoneType(volume.getDataCenterType()); - + volResponse.setVolumeType(volume.getVolumeType().toString()); volResponse.setDeviceId(volume.getDeviceId()); @@ -160,6 +159,11 @@ public class VolumeJoinDaoImpl extends GenericDaoBase implem } volResponse.setStorageType(volume.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared .toString()); + volResponse.setBytesReadRate(volume.getBytesReadRate()); + volResponse.setBytesWriteRate(volume.getBytesReadRate()); + volResponse.setIopsReadRate(volume.getIopsWriteRate()); + volResponse.setIopsWriteRate(volume.getIopsWriteRate()); + } Long poolId = volume.getPoolId(); String poolName = (poolId == null) ? "none" : volume.getPoolName(); diff --git a/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java b/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java index 6d3cdcb7fef..2336a48ad14 100644 --- a/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java +++ b/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java @@ -64,6 +64,18 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity, @Column(name="sort_key") int sortKey; + @Column(name="bytes_read_rate") + Long bytesReadRate; + + @Column(name="bytes_write_rate") + Long bytesWriteRate; + + @Column(name="iops_read_rate") + Long iopsReadRate; + + @Column(name="iops_write_rate") + Long iopsWriteRate; + @Column(name="type") Type type; @@ -239,6 +251,36 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity, this.type = type; } + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } diff --git a/server/src/com/cloud/api/query/vo/DomainRouterJoinVO.java b/server/src/com/cloud/api/query/vo/DomainRouterJoinVO.java index 9e9e4a2ba7b..bfe44869b2a 100644 --- a/server/src/com/cloud/api/query/vo/DomainRouterJoinVO.java +++ b/server/src/com/cloud/api/query/vo/DomainRouterJoinVO.java @@ -102,9 +102,6 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti @Column(name="data_center_name") private String dataCenterName = null; - @Column(name="data_center_type") - private String dataCenterType; - @Column(name="dns1") private String dns1 = null; @@ -453,15 +450,6 @@ public class DomainRouterJoinVO extends BaseViewVO implements ControlledViewEnti this.dataCenterName = zoneName; } - - public String getDataCenterType() { - return dataCenterType; - } - - public void setDataCenterType(String dataCenterType) { - this.dataCenterType = dataCenterType; - } - public Long getHostId() { return hostId; diff --git a/server/src/com/cloud/api/query/vo/HostJoinVO.java b/server/src/com/cloud/api/query/vo/HostJoinVO.java index 4b70cfcaa10..cf3cfdc4486 100644 --- a/server/src/com/cloud/api/query/vo/HostJoinVO.java +++ b/server/src/com/cloud/api/query/vo/HostJoinVO.java @@ -130,9 +130,6 @@ public class HostJoinVO extends BaseViewVO implements InternalIdentity, Identity @Column(name="data_center_name") private String zoneName; - @Column(name="data_center_type") - private String zoneType; - @Column(name="pod_id") private long podId; @@ -234,15 +231,7 @@ public class HostJoinVO extends BaseViewVO implements InternalIdentity, Identity public void setZoneName(String zoneName) { this.zoneName = zoneName; } - - public String getZoneType() { - return zoneType; - } - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public String getName() { return name; } diff --git a/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java b/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java index e87a1018bdd..05ff5f3f44a 100644 --- a/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java +++ b/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java @@ -90,6 +90,17 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit @Column(name="sort_key") int sortKey; + @Column(name="bytes_read_rate") + Long bytesReadRate; + + @Column(name="bytes_write_rate") + Long bytesWriteRate; + + @Column(name="iops_read_rate") + Long iopsReadRate; + + @Column(name="iops_write_rate") + Long iopsWriteRate; @Column(name=GenericDao.CREATED_COLUMN) private Date created; @@ -329,5 +340,35 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit this.volatileVm = volatileVm; } + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } } diff --git a/server/src/com/cloud/api/query/vo/StoragePoolJoinVO.java b/server/src/com/cloud/api/query/vo/StoragePoolJoinVO.java index 5ec5447b57a..c0d5ee990a5 100644 --- a/server/src/com/cloud/api/query/vo/StoragePoolJoinVO.java +++ b/server/src/com/cloud/api/query/vo/StoragePoolJoinVO.java @@ -100,9 +100,6 @@ public class StoragePoolJoinVO extends BaseViewVO implements InternalIdentity, I @Column(name="data_center_name") private String zoneName; - @Column(name="data_center_type") - private String zoneType; - @Column(name="pod_id") private long podId; @@ -302,14 +299,6 @@ public class StoragePoolJoinVO extends BaseViewVO implements InternalIdentity, I this.zoneName = zoneName; } - public String getZoneType() { - return zoneType; - } - - public void setZoneType(String zoneType) { - this.zoneType = zoneType; - } - public long getPodId() { return podId; } diff --git a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java index 8ad0fdd6457..c97d71a81ed 100644 --- a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java +++ b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java @@ -156,9 +156,6 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="data_center_name") private String dataCenterName = null; - @Column(name="data_center_type") - private String dataCenterType = null; - @Column(name="security_group_enabled") private boolean securityGroupEnabled; @@ -813,18 +810,8 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { public void setDataCenterName(String zoneName) { this.dataCenterName = zoneName; } - - - public String getDataCenterType() { - return dataCenterType; - } - public void setDataCenterType(String zoneType) { - this.dataCenterType = zoneType; - } - - public boolean isSecurityGroupEnabled() { return securityGroupEnabled; } diff --git a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java index 6ef8c912efe..1f07f52973a 100644 --- a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java +++ b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java @@ -117,9 +117,6 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="data_center_name") private String dataCenterName; - - @Column(name="data_center_type") - private String dataCenterType; @Column(name="vm_id") private long vmId; @@ -184,6 +181,18 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="use_local_storage") private boolean useLocalStorage; + @Column(name="bytes_read_rate") + Long bytesReadRate; + + @Column(name="bytes_write_rate") + Long bytesWriteRate; + + @Column(name="iops_read_rate") + Long iopsReadRate; + + @Column(name="iops_write_rate") + Long iopsWriteRate; + @Column(name="pool_id") private long poolId; @@ -742,6 +751,37 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { } + public void setBytesReadRate(Long bytesReadRate) { + this.bytesReadRate = bytesReadRate; + } + + public Long getBytesReadRate() { + return bytesReadRate; + } + + public void setBytesWriteRate(Long bytesWriteRate) { + this.bytesWriteRate = bytesWriteRate; + } + + public Long getBytesWriteRate() { + return bytesWriteRate; + } + + public void setIopsReadRate(Long iopsReadRate) { + this.iopsReadRate = iopsReadRate; + } + + public Long getIopsReadRate() { + return iopsReadRate; + } + + public void setIopsWriteRate(Long iopsWriteRate) { + this.iopsWriteRate = iopsWriteRate; + } + + public Long getIopsWriteRate() { + return iopsWriteRate; + } public long getPoolId() { return poolId; @@ -1017,20 +1057,8 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity { this.dataCenterName = dataCenterName; } - - - public String getDataCenterType() { - return dataCenterType; - } - - public void setDataCenterType(String dataCenterType) { - this.dataCenterType = dataCenterType; - } - - - public long getPodId() { return podId; } diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 219bed07191..f14a76cb111 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -219,7 +219,14 @@ public enum Config { AlertPurgeInterval("Advanced", ManagementServer.class, Integer.class, "alert.purge.interval", "86400", "The interval (in seconds) to wait before running the alert purge thread", null), AlertPurgeDelay("Advanced", ManagementServer.class, Integer.class, "alert.purge.delay", "0", "Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts", null), HostReservationReleasePeriod("Advanced", ManagementServer.class, Integer.class, "host.reservation.release.period", "300000", "The interval in milliseconds between host reservation release checks", null), - + UseSystemPublicIps("Advanced", ManagementServer.class, Boolean.class, "use.system.public.ips", "true", + "If true, when account has dedicated public ip range(s), once the ips dedicated to the account have been" + + " consumed ips will be acquired from the system pool", + null, ConfigurationParameterScope.account.toString()), + UseSystemGuestVlans("Advanced", ManagementServer.class, Boolean.class, "use.system.guest.vlans", "true", + "If true, when account has dedicated guest vlan range(s), once the vlans dedicated to the account have been" + + " consumed vlans will be allocated from the system pool", + null, ConfigurationParameterScope.account.toString()), // LB HealthCheck Interval. LBHealthCheck("Advanced", ManagementServer.class, String.class, "healthcheck.update.interval", "600", @@ -235,6 +242,10 @@ public enum Config { VmDiskStatsInterval("Advanced", ManagementServer.class, Integer.class, "vm.disk.stats.interval", "0", "Interval (in seconds) to report vm disk statistics.", null), VmTransitionWaitInterval("Advanced", ManagementServer.class, Integer.class, "vm.tranisition.wait.interval", "3600", "Time (in seconds) to wait before taking over a VM in transition state", null), VmDestroyForcestop("Advanced", ManagementServer.class, Boolean.class, "vm.destroy.forcestop", "false", "On destroy, force-stop takes this value ", null), + VmDiskThrottlingIopsReadRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.iops_read_rate", "0", "Default disk I/O read rate in requests per second allowed in User vm's disk.", null), + VmDiskThrottlingIopsWriteRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.iops_write_rate", "0", "Default disk I/O writerate in requests per second allowed in User vm's disk.", null), + VmDiskThrottlingBytesReadRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.bytes_read_rate", "0", "Default disk I/O read rate in bytes per second allowed in User vm's disk.", null), + VmDiskThrottlingBytesWriteRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.bytes_write_rate", "0", "Default disk I/O writerate in bytes per second allowed in User vm's disk.", null), ControlCidr("Advanced", ManagementServer.class, String.class, "control.cidr", "169.254.0.0/16", "Changes the cidr for the control network traffic. Defaults to using link local. Must be unique within pods", null), ControlGateway("Advanced", ManagementServer.class, String.class, "control.gateway", "169.254.0.1", "gateway for the control network traffic", null), @@ -419,11 +430,13 @@ public enum Config { BlacklistedRoutes("Advanced", VpcManager.class, String.class, "blacklisted.routes", null, "Routes that are blacklisted, can not be used for Static Routes creation for the VPC Private Gateway", "routes", ConfigurationParameterScope.zone.toString()), - - InternalLbVmServiceOfferingId("Advanced", ManagementServer.class, Long.class, "internallbvm.service.offering", null, "Uuid of the service offering used by internal lb vm; if NULL - default system internal lb offering will be used", null); - - - + + InternalLbVmServiceOfferingId("Advanced", ManagementServer.class, Long.class, "internallbvm.service.offering", null, "Uuid of the service offering used by internal lb vm; if NULL - default system internal lb offering will be used", null), + ExecuteInSequence("Advanced", ManagementServer.class, Boolean.class, "execute.in.sequence.hypervisor.commands", "false", "If set to true, StartCommand, StopCommand, CopyVolumeCommand, CreateCommand will be synchronized on the agent side." + + " If set to false, these commands become asynchronous. Default value is false.", null), + ExecuteInSequenceNetworkElementCommands("Advanced", NetworkManager.class, Boolean.class, "execute.in.sequence.network.element.commands", "false", "If set to true, DhcpEntryCommand, SavePasswordCommand, UserDataCommand, VmDataCommand will be synchronized on the agent side." + + " If set to false, these commands become asynchronous. Default value is false.", null); + private final String _category; private final Class _componentClass; private final Class _type; diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java b/server/src/com/cloud/configuration/ConfigurationManager.java index 8db037b24ff..93cadfa23a6 100755 --- a/server/src/com/cloud/configuration/ConfigurationManager.java +++ b/server/src/com/cloud/configuration/ConfigurationManager.java @@ -81,10 +81,15 @@ public interface ConfigurationManager extends ConfigurationService, Manager { * @param useVirtualNetwork * @param deploymentPlanner * @param details + * @param bytesReadRate + * @param bytesWriteRate + * @param iopsReadRate + * @param iopsWriteRate * @return ID */ ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, VirtualMachine.Type vm_typeType, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, - boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map details); + boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map details, + Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate); /** * Creates a new disk offering @@ -97,9 +102,14 @@ public interface ConfigurationManager extends ConfigurationService, Manager { * @param isCustomized * @param localStorageRequired * @param isDisplayOfferingEnabled + * @param bytesReadRate + * @param bytesWriteRate + * @param iopsReadRate + * @param iopsWriteRate * @return newly created disk offering */ - DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled); + DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled, + Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate); /** * Creates a new pod diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index ef6968e8db3..8fc0229b67b 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -2148,20 +2148,30 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return createServiceOffering(userId, cmd.getIsSystem(), vmType, cmd.getServiceOfferingName(), cpuNumber.intValue(), memory.intValue(), cpuSpeed.intValue(), cmd.getDisplayText(), localStorageRequired, offerHA, limitCpuUse, volatileVm, cmd.getTags(), cmd.getDomainId(), - cmd.getHostTag(), cmd.getNetworkRate(), cmd.getDeploymentPlanner(), cmd.getDetails()); + cmd.getHostTag(), cmd.getNetworkRate(), cmd.getDeploymentPlanner(), cmd.getDetails(), + cmd.getBytesReadRate(), cmd.getBytesWriteRate(), cmd.getIopsReadRate(), cmd.getIopsWriteRate()); } @Override @ActionEvent(eventType = EventTypes.EVENT_SERVICE_OFFERING_CREATE, eventDescription = "creating service offering") public ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, VirtualMachine.Type vm_type, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, - boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, - Integer networkRate, String deploymentPlanner, Map details) { + boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, + Integer networkRate, String deploymentPlanner, Map details, Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) { tags = cleanupTags(tags); ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, networkRate, null, offerHA, limitResourceUse, volatileVm, displayText, localStorageRequired, false, tags, isSystem, vm_type, domainId, hostTag, deploymentPlanner); + if ((bytesReadRate != null) && (bytesReadRate > 0)) + offering.setBytesReadRate(bytesReadRate); + if ((bytesWriteRate != null) && (bytesWriteRate > 0)) + offering.setBytesWriteRate(bytesWriteRate); + if ((iopsReadRate != null) && (iopsReadRate > 0)) + offering.setIopsReadRate(iopsReadRate); + if ((iopsWriteRate != null) && (iopsWriteRate > 0)) + offering.setIopsWriteRate(iopsWriteRate); + if ((offering = _serviceOfferingDao.persist(offering)) != null) { if (details != null) { _serviceOfferingDetailsDao.persist(offering.getId(), details); @@ -2247,8 +2257,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_CREATE, eventDescription = "creating disk offering") - public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, - String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled) { + public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled, + Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) { long diskSize = 0;// special case for custom disk offerings if (numGibibytes != null && (numGibibytes <= 0)) { throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb."); @@ -2268,6 +2278,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati DiskOfferingVO newDiskOffering = new DiskOfferingVO(domainId, name, description, diskSize, tags, isCustomized); newDiskOffering.setUseLocalStorage(localStorageRequired); newDiskOffering.setDisplayOffering(isDisplayOfferingEnabled); + + if (bytesReadRate != null && (bytesReadRate > 0)) + newDiskOffering.setBytesReadRate(bytesReadRate); + if (bytesWriteRate != null && (bytesWriteRate > 0)) + newDiskOffering.setBytesWriteRate(bytesWriteRate); + if (iopsReadRate != null && (iopsReadRate > 0)) + newDiskOffering.setIopsReadRate(iopsReadRate); + if (iopsWriteRate != null && (iopsWriteRate > 0)) + newDiskOffering.setIopsWriteRate(iopsWriteRate); + UserContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId()); DiskOfferingVO offering = _diskOfferingDao.persist(newDiskOffering); if (offering != null) { @@ -2309,8 +2329,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } - return createDiskOffering(domainId, name, description, numGibibytes, tags, isCustomized, localStorageRequired, - isDisplayOfferingEnabled); + Long bytesReadRate = cmd.getBytesReadRate(); + Long bytesWriteRate = cmd.getBytesWriteRate(); + Long iopsReadRate = cmd.getIopsReadRate(); + Long iopsWriteRate = cmd.getIopsWriteRate(); + return createDiskOffering(domainId, name, description, numGibibytes, tags, isCustomized, localStorageRequired, isDisplayOfferingEnabled, bytesReadRate, bytesWriteRate, iopsReadRate, iopsWriteRate); } @Override @@ -4244,9 +4267,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati Capability.LbSchemes, publicLbStr); internalLb = publicLbStr.contains("internal"); publicLb = publicLbStr.contains("public"); - } else { - // if not specified, default public lb to true - publicLb = true; } } } @@ -4287,6 +4307,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } } + + if (serviceProviderMap != null && serviceProviderMap.containsKey(Service.Lb) && !internalLb && !publicLb) { + //if not specified, default public lb to true + publicLb = true; + } NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, diff --git a/server/src/com/cloud/ha/UserVmDomRInvestigator.java b/server/src/com/cloud/ha/UserVmDomRInvestigator.java index f785d183938..8b48c09dfa1 100644 --- a/server/src/com/cloud/ha/UserVmDomRInvestigator.java +++ b/server/src/com/cloud/ha/UserVmDomRInvestigator.java @@ -182,7 +182,8 @@ public class UserVmDomRInvestigator extends AbstractInvestigatorImpl { Answer pingTestAnswer = _agentMgr.easySend(hostId, new PingTestCommand(routerPrivateIp, privateIp)); if (pingTestAnswer!=null && pingTestAnswer.getResult()) { if (s_logger.isDebugEnabled()) { - s_logger.debug("user vm " + vm.getHostName() + " has been successfully pinged, returning that it is alive"); + s_logger.debug("user vm's " + vm.getHostName() + " ip address "+ privateIp + " has been successfully pinged from the Virtual Router " + + router.getHostName() + ", returning that vm is alive"); } return Boolean.TRUE; } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index bc43daa9975..306169ebcf6 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -386,4 +386,5 @@ public interface NetworkManager { DhcpServiceProvider getDhcpServiceProvider(Network network); PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException; + } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 2fd9bd06c3f..18813d3ddd4 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -444,7 +444,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L // If all the dedicated IPs of the owner are in use fetch an IP from the system pool if (addrs.size() == 0 && fetchFromDedicatedRange) { - if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { + // Verify if account is allowed to acquire IPs from the system + boolean useSystemIps = Boolean.parseBoolean(_configServer.getConfigValue(Config.UseSystemPublicIps.key(), + Config.ConfigurationParameterScope.account.toString(), owner.getId())); + if(useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { fetchFromDedicatedRange = false; sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); @@ -1230,14 +1233,11 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _configs = _configDao.getConfiguration("AgentManager", params); _networkGcWait = NumbersUtil.parseInt(_configs.get(Config.NetworkGcWait.key()), 600); _networkGcInterval = NumbersUtil.parseInt(_configs.get(Config.NetworkGcInterval.key()), 600); - + _configs = _configDao.getConfiguration("Network", params); _networkLockTimeout = NumbersUtil.parseInt(_configs.get(Config.NetworkLockTimeout.key()), 600); - - - // populate providers Map> defaultSharedNetworkOfferingProviders = new HashMap>(); Set defaultProviders = new HashSet(); @@ -1248,6 +1248,15 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L defaultSharedNetworkOfferingProviders.put(Service.UserData, defaultProviders); Map> defaultIsolatedNetworkOfferingProviders = defaultSharedNetworkOfferingProviders; + defaultIsolatedNetworkOfferingProviders.put(Service.Dhcp, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.Dns, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.UserData, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.Firewall, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.Gateway, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.Lb, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.StaticNat, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.PortForwarding, defaultProviders); + defaultIsolatedNetworkOfferingProviders.put(Service.Vpn, defaultProviders); Map> defaultSharedSGEnabledNetworkOfferingProviders = new HashMap>(); defaultSharedSGEnabledNetworkOfferingProviders.put(Service.Dhcp, defaultProviders); @@ -1290,9 +1299,9 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L Transaction txn = Transaction.currentTxn(); txn.start(); - // diff between offering #1 and #2 - securityGroup is enabled for the first, and disabled for the third NetworkOfferingVO offering = null; + //#1 - quick cloud network offering if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices, @@ -1302,6 +1311,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } + + //#2 - SG enabled network offering if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, @@ -1312,36 +1323,26 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _networkOfferingDao.update(offering.getId(), offering); } + //#3 - shared network offering with no SG service if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } + - Map> defaultINetworkOfferingProvidersForVpcNetwork = new HashMap>(); - defaultProviders.clear(); - defaultProviders.add(Network.Provider.VPCVirtualRouter); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Dhcp, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Dns, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.UserData, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Firewall, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Gateway, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Lb, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.SourceNat, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.StaticNat, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.PortForwarding, defaultProviders); - defaultINetworkOfferingProvidersForVpcNetwork.put(Service.Vpn, defaultProviders); - + //#4 - default isolated offering with Source nat service if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, - null, false, Availability.Required, null, defaultINetworkOfferingProvidersForVpcNetwork, + null, false, Availability.Required, null, defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false, false, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } + //#5 - default vpc offering with LB service if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, "Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, @@ -1351,6 +1352,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _networkOfferingDao.update(offering.getId(), offering); } + //#6 - default vpc offering with no LB service if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB) == null) { //remove LB service defaultVPCOffProviders.remove(Service.Lb); @@ -1362,6 +1364,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L _networkOfferingDao.update(offering.getId(), offering); } + //#7 - isolated offering with source nat disabled if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, null, true, @@ -1370,6 +1373,33 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } + + //#8 - network offering with internal lb service + Map> internalLbOffProviders = + new HashMap>(); + Set defaultVpcProvider = new HashSet(); + defaultVpcProvider.add(Network.Provider.VPCVirtualRouter); + + Set defaultInternalLbProvider = new HashSet(); + defaultInternalLbProvider.add(Network.Provider.InternalLbVm); + + internalLbOffProviders.put(Service.Dhcp, defaultVpcProvider); + internalLbOffProviders.put(Service.Dns, defaultVpcProvider); + internalLbOffProviders.put(Service.UserData, defaultVpcProvider); + internalLbOffProviders.put(Service.NetworkACL, defaultVpcProvider); + internalLbOffProviders.put(Service.Gateway, defaultVpcProvider); + internalLbOffProviders.put(Service.Lb, defaultInternalLbProvider); + internalLbOffProviders.put(Service.SourceNat, defaultVpcProvider); + + if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB) == null) { + offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB, + "Offering for Isolated VPC networks with Internal Lb support", TrafficType.Guest, + null, false, Availability.Optional, null, internalLbOffProviders, + true, Network.GuestType.Isolated, false, null, false, null, false, false, null); + offering.setState(NetworkOffering.State.Enabled); + offering.setInternalLb(true); + _networkOfferingDao.update(offering.getId(), offering); + } Map> netscalerServiceProviders = new HashMap>(); Set vrProvider = new HashSet(); @@ -4328,10 +4358,9 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L NicVO nic = new NicVO(null, null, network.getId(), null); nic.setIp4Address(ip4Address); nic.setIp6Address(ip6Address); - nic.setReservationStrategy(ReservationStrategy.PlaceHolder); - nic.setState(Nic.State.Reserved); - nic.setVmType(vmType); - return _nicDao.persist(nic); - } - + nic.setReservationStrategy(ReservationStrategy.PlaceHolder); + nic.setState(Nic.State.Reserved); + nic.setVmType(vmType); + return _nicDao.persist(nic); + } } diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index fa34d65ab1a..4a4da8e3f4f 100755 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -208,11 +208,16 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { private boolean _allowSubdomainNetworkAccess; private Map _configs; + + protected boolean _executeInSequenceNtwkElmtCmd; HashMap _lastNetworkIdsToFree = new HashMap(); static HashMap> s_serviceToImplementedProvidersMap = new HashMap>(); static HashMap s_providerToNetworkElementMap = new HashMap(); + + + /** * */ @@ -1869,6 +1874,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { _configs = _configDao.getConfiguration("Network", params); _networkDomain = _configs.get(Config.GuestDomainSuffix.key()); _allowSubdomainNetworkAccess = Boolean.valueOf(_configs.get(Config.SubDomainNetworkAccess.key())); + _executeInSequenceNtwkElmtCmd = Boolean.valueOf(_configs.get(Config.ExecuteInSequenceNetworkElementCommands.key())); NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPublicNetwork, TrafficType.Public, true); publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering); @@ -2112,4 +2118,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { public Networks.IsolationType[] listNetworkIsolationMethods() { return Networks.IsolationType.values(); } + + @Override + public boolean getExecuteInSeqNtwkElmtCmd() { + return _executeInSequenceNtwkElmtCmd; + } } diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index f026dbc2a32..6796adc3dae 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -27,6 +27,8 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -1355,7 +1357,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { Long id = cmd.getId(); String keyword = cmd.getKeyword(); Long zoneId = cmd.getZoneId(); - String zoneType = cmd.getZoneType(); Account caller = UserContext.current().getCaller(); Long domainId = cmd.getDomainId(); String accountName = cmd.getAccountName(); @@ -1503,40 +1504,40 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { if (!permittedAccounts.isEmpty()) { //get account level networks networksToReturn.addAll(listAccountSpecificNetworks( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, permittedAccounts)); //get domain level networks if (domainId != null) { networksToReturn .addAll(listDomainLevelNetworks( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, true, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, + physicalNetworkId, aclType, true, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, domainId, false)); } } else { //add account specific networks networksToReturn.addAll(listAccountSpecificNetworksByDomainPath( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, path, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, path, isRecursive)); //add domain specific networks of domain + parent domains networksToReturn.addAll(listDomainSpecificNetworksByDomainPath( - buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, path, + buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, path, isRecursive)); //add networks of subdomains if (domainId == null) { networksToReturn .addAll(listDomainLevelNetworks( buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, - physicalNetworkId, aclType, true, restartRequired, specifyIpRanges, vpcId, tags, zoneType), searchFilter, + physicalNetworkId, aclType, true, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, caller.getDomainId(), true)); } } } else { networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, - guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, zoneType), + guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter); } @@ -1581,7 +1582,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, - String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId, Map tags, String zoneType) { + String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId, Map tags) { SearchCriteria sc = sb.create(); @@ -1603,10 +1604,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); } - if(zoneType != null) { - sc.setJoinParameters("zoneSearch", "networkType", zoneType); - } - if (guestIpType != null) { sc.addAnd("guestType", SearchCriteria.Op.EQ, guestIpType); } @@ -2954,6 +2951,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { String updatedVlanRange = null; long guestVlanMapId = 0; long guestVlanMapAccountId = 0; + long vlanOwnerId = 0; // Verify account is valid Account vlanOwner = null; @@ -2974,6 +2972,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Unable to find account by name " + accountName); } } + vlanOwnerId = vlanOwner.getAccountId(); // Verify physical network isolation type is VLAN PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); @@ -3029,40 +3028,59 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } List guestVlanMaps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(physicalNetworkId); + // Verify if vlan range is already dedicated for (AccountGuestVlanMapVO guestVlanMap : guestVlanMaps) { List vlanTokens = getVlanFromRange(guestVlanMap.getGuestVlanRange()); int dedicatedStartVlan = vlanTokens.get(0).intValue(); int dedicatedEndVlan = vlanTokens.get(1).intValue(); - guestVlanMapId = guestVlanMap.getId(); - guestVlanMapAccountId = guestVlanMap.getAccountId(); - - // Verify if range is already dedicated - if (startVlan >= dedicatedStartVlan && endVlan <= dedicatedEndVlan) { - if (guestVlanMap.getAccountId() != vlanOwner.getAccountId()) { - throw new InvalidParameterValueException("Vlan range is already dedicated to another account. Cannot dedicate guest vlan range " + vlan); - } else { - s_logger.debug("Vlan range " + vlan +" is already dedicated to the specified account" + accountName); - return guestVlanMap; - } - } - // Verify if range overlaps with an existing range - if (startVlan < dedicatedStartVlan & endVlan+1 >= dedicatedStartVlan & endVlan <= dedicatedEndVlan) { // extend to the left - updatedVlanRange = startVlan + "-" + dedicatedEndVlan; - break; - } else if (startVlan >= dedicatedStartVlan & startVlan-1 <= dedicatedEndVlan & endVlan > dedicatedEndVlan) { // extend to right - updatedVlanRange = dedicatedStartVlan + "-" + endVlan; - break; - } else if (startVlan < dedicatedStartVlan & endVlan > dedicatedEndVlan){ // extend to the left and right - updatedVlanRange = startVlan + "-" + endVlan; - break; + if ((startVlan < dedicatedStartVlan & endVlan >= dedicatedStartVlan) || + (startVlan >= dedicatedStartVlan & startVlan <= dedicatedEndVlan)) { + throw new InvalidParameterValueException("Vlan range is already dedicated. Cannot" + + " dedicate guest vlan range " + vlan); } } + // Sort the existing dedicated vlan ranges + Collections.sort(guestVlanMaps, new Comparator() { + @Override + public int compare( AccountGuestVlanMapVO obj1 , AccountGuestVlanMapVO obj2) { + List vlanTokens1 = getVlanFromRange(obj1.getGuestVlanRange()); + List vlanTokens2 = getVlanFromRange(obj2.getGuestVlanRange()); + return vlanTokens1.get(0).compareTo(vlanTokens2.get(0)); + } + }); + + // Verify if vlan range extends an already dedicated range + for (int i=0; i < guestVlanMaps.size(); i++) { + guestVlanMapId = guestVlanMaps.get(i).getId(); + guestVlanMapAccountId = guestVlanMaps.get(i).getAccountId(); + List vlanTokens1 = getVlanFromRange(guestVlanMaps.get(i).getGuestVlanRange()); + // Range extends a dedicated vlan range to the left + if (endVlan == (vlanTokens1.get(0).intValue()-1)) { + if(guestVlanMapAccountId == vlanOwnerId) { + updatedVlanRange = startVlan + "-" + vlanTokens1.get(1).intValue(); + } + break; + } + // Range extends a dedicated vlan range to the right + if (startVlan == (vlanTokens1.get(1).intValue()+1) & guestVlanMapAccountId == vlanOwnerId) { + if (i != (guestVlanMaps.size()-1)) { + List vlanTokens2 = getVlanFromRange(guestVlanMaps.get(i+1).getGuestVlanRange()); + // Range extends 2 vlan ranges, both to the right and left + if (endVlan == (vlanTokens2.get(0).intValue()-1) & guestVlanMaps.get(i+1).getAccountId() == vlanOwnerId) { + _datacneter_vnet.releaseDedicatedGuestVlans(guestVlanMaps.get(i+1).getId()); + _accountGuestVlanMapDao.remove(guestVlanMaps.get(i+1).getId()); + updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + vlanTokens2.get(1).intValue(); + break; + } + } + updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + endVlan; + break; + } + } + // Dedicate vlan range AccountGuestVlanMapVO accountGuestVlanMapVO; if (updatedVlanRange != null) { - if (guestVlanMapAccountId != vlanOwner.getAccountId()) { - throw new InvalidParameterValueException("Vlan range is partially dedicated to another account. Cannot dedicate guest vlan range " + vlan); - } accountGuestVlanMapVO = _accountGuestVlanMapDao.findById(guestVlanMapId); accountGuestVlanMapVO.setGuestVlanRange(updatedVlanRange); _accountGuestVlanMapDao.update(guestVlanMapId, accountGuestVlanMapVO); @@ -3075,7 +3093,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { txn.commit(); } // For every guest vlan set the corresponding account guest vlan map id - for (int i = startVlan; i <= endVlan; i++) { + List finaVlanTokens = getVlanFromRange(accountGuestVlanMapVO.getGuestVlanRange()); + for (int i = finaVlanTokens.get(0).intValue(); i <= finaVlanTokens.get(1).intValue(); i++) { List dataCenterVnet = _datacneter_vnet.findVnet(physicalNetwork.getDataCenterId(),((Integer)i).toString()); dataCenterVnet.get(0).setAccountGuestVlanMapId(accountGuestVlanMapVO.getId()); _datacneter_vnet.update(dataCenterVnet.get(0).getId(), dataCenterVnet.get(0)); diff --git a/server/src/com/cloud/network/element/CloudZonesNetworkElement.java b/server/src/com/cloud/network/element/CloudZonesNetworkElement.java index 320258b8d37..bdd8e61bbc2 100644 --- a/server/src/com/cloud/network/element/CloudZonesNetworkElement.java +++ b/server/src/com/cloud/network/element/CloudZonesNetworkElement.java @@ -152,7 +152,7 @@ public class CloudZonesNetworkElement extends AdapterBase implements NetworkElem private VmDataCommand generateVmDataCommand(String vmPrivateIpAddress, String userData, String serviceOffering, String zoneName, String guestIpAddress, String vmName, String vmInstanceName, long vmId, String vmUuid, String publicKey) { - VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName); + VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName, _networkMgr.getExecuteInSeqNtwkElmtCmd()); cmd.addVmData("userdata", "user-data", userData); cmd.addVmData("metadata", "service-offering", serviceOffering); @@ -217,7 +217,7 @@ public class CloudZonesNetworkElement extends AdapterBase implements NetworkElem Commands cmds = new Commands(OnError.Continue); if (password != null && nic.isDefaultNic()) { final String encodedPassword = PasswordGenerator.rot13(password); - SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), uservm.getVirtualMachine().getHostName()); + SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), uservm.getVirtualMachine().getHostName(), _networkMgr.getExecuteInSeqNtwkElmtCmd()); cmds.addCommand("password", cmd); } String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(uservm.getServiceOfferingId()).getDisplayText(); diff --git a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java index eb1b3dc4b24..87098f5049b 100644 --- a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java @@ -130,7 +130,8 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru { // Get a vlan tag int vlanTag; if (config.getBroadcastUri() == null) { - String vnet = _dcDao.allocateVnet(zone.getId(), config.getPhysicalNetworkId(), config.getAccountId(), context.getReservationId()); + String vnet = _dcDao.allocateVnet(zone.getId(), config.getPhysicalNetworkId(), config.getAccountId(), + context.getReservationId(), canUseSystemGuestVlan(config.getAccountId())); try { vlanTag = Integer.parseInt(vnet); diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java index 32ce744979b..89b0694e114 100755 --- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java @@ -26,6 +26,7 @@ import javax.ejb.Local; import javax.inject.Inject; import com.cloud.event.ActionEventUtils; +import com.cloud.server.ConfigurationServer; import com.cloud.utils.Pair; import org.apache.log4j.Logger; @@ -98,6 +99,8 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur IPAddressDao _ipAddressDao; @Inject protected PhysicalNetworkDao _physicalNetworkDao; + @Inject + ConfigurationServer _configServer; Random _rand = new Random(System.currentTimeMillis()); private static final TrafficType[] _trafficTypes = {TrafficType.Guest}; @@ -155,6 +158,11 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur return _isolationMethods; } + public boolean canUseSystemGuestVlan(long accountId) { + return Boolean.parseBoolean(_configServer.getConfigValue(Config.UseSystemGuestVlans.key(), + Config.ConfigurationParameterScope.account.toString(), accountId)); + } + protected abstract boolean canHandle(NetworkOffering offering, final NetworkType networkType, PhysicalNetwork physicalNetwork); @Override @@ -260,7 +268,8 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur protected void allocateVnet(Network network, NetworkVO implemented, long dcId, long physicalNetworkId, String reservationId) throws InsufficientVirtualNetworkCapcityException { if (network.getBroadcastUri() == null) { - String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId); + String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId, + canUseSystemGuestVlan(network.getAccountId())); if (vnet == null) { throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a " + "part of network " + network + " implement ", DataCenter.class, dcId); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index f3719f3334e..f90658747a0 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -167,6 +167,7 @@ import com.cloud.offering.ServiceOffering; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.ResourceManager; import com.cloud.server.ConfigurationServer; +import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.GuestOSVO; @@ -798,7 +799,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress, String userData, String serviceOffering, String zoneName, String guestIpAddress, String vmName, String vmInstanceName, long vmId, String vmUuid, String publicKey, long guestNetworkId) { - VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName); + VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName, _networkModel.getExecuteInSeqNtwkElmtCmd()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId())); @@ -2352,7 +2353,8 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V // Network usage command to create iptables rules boolean forVpc = profile.getVirtualMachine().getVpcId() != null; - cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIp4Address(), router.getHostName(), "create", forVpc)); + if (!forVpc) + cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIp4Address(), router.getHostName(), "create", forVpc)); } protected void finalizeUserDataAndDhcpOnStart(Commands cmds, DomainRouterVO router, Provider provider, Long guestNetworkId) { @@ -3360,7 +3362,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V if (router.getIsRedundantRouter() && router.getRedundantState() != RedundantState.MASTER) { encodedPassword = PasswordGenerator.rot13("saved_password"); } - SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName()); + SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName(), _networkModel.getExecuteInSeqNtwkElmtCmd()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); @@ -3400,7 +3402,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } private void createDhcpEntryCommand(VirtualRouter router, UserVm vm, NicVO nic, Commands cmds) { - DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), vm.getHostName(), nic.getIp6Address()); + DhcpEntryCommand dhcpCommand = new DhcpEntryCommand(nic.getMacAddress(), nic.getIp4Address(), vm.getHostName(), nic.getIp6Address(), _networkModel.getExecuteInSeqNtwkElmtCmd()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); Nic defaultNic = findGatewayIp(vm.getId()); String gatewayIp = defaultNic.getGateway(); diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 45892aafa12..8e952aab4f2 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -1162,8 +1162,33 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } + + //offering #8 - network offering with internal lb service + NetworkOfferingVO internalLbOff = new NetworkOfferingVO( + NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB, + "Offering for Isolated Vpc networks with Internal LB support", + TrafficType.Guest, + false, false, null, null, true, Availability.Optional, + null, Network.GuestType.Isolated, false, false, false, true, false); + internalLbOff.setState(NetworkOffering.State.Enabled); + internalLbOff = _networkOfferingDao.persistDefaultNetworkOffering(internalLbOff); + Map internalLbOffProviders = new HashMap(); + internalLbOffProviders.put(Service.Dhcp, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.Dns, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.UserData, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.NetworkACL, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.Gateway, Provider.VPCVirtualRouter); + internalLbOffProviders.put(Service.Lb, Provider.InternalLbVm); + internalLbOffProviders.put(Service.SourceNat, Provider.VPCVirtualRouter); + + for (Service service : internalLbOffProviders.keySet()) { + NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO + (internalLbOff.getId(), service, internalLbOffProviders.get(service)); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } txn.commit(); } diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index f60ce488e10..aec1be705dc 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -72,4 +72,6 @@ public interface ManagementServer extends ManagementService, PluggableService { String getEncryptionIV(); void resetEncryptionKeyIV(); + boolean getExecuteInSequence(); + } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 5c2917f78f7..424e7bd409e 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -915,7 +915,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe Object hypervisorType = cmd.getHypervisorType(); Object clusterType = cmd.getClusterType(); Object allocationState = cmd.getAllocationState(); - String zoneType = cmd.getZoneType(); String keyword = cmd.getKeyword(); zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), zoneId); @@ -931,13 +930,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sb.and("clusterType", sb.entity().getClusterType(), SearchCriteria.Op.EQ); sb.and("allocationState", sb.entity().getAllocationState(), SearchCriteria.Op.EQ); - if(zoneType != null) { - SearchBuilder zoneSb = _dcDao.createSearchBuilder(); - zoneSb.and("zoneNetworkType", zoneSb.entity().getNetworkType(), SearchCriteria.Op.EQ); - sb.join("zoneSb", zoneSb, sb.entity().getDataCenterId(), zoneSb.entity().getId(), JoinBuilder.JoinType.INNER); - } - - SearchCriteria sc = sb.create(); if (id != null) { sc.setParameters("id", id); @@ -967,10 +959,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sc.setParameters("allocationState", allocationState); } - if(zoneType != null) { - sc.setJoinParameters("zoneSb", "zoneNetworkType", zoneType); - } - if (keyword != null) { SearchCriteria ssc = _clusterDao.createSearchCriteria(); ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); @@ -1386,7 +1374,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe Long zoneId = cmd.getZoneId(); Object keyword = cmd.getKeyword(); Object allocationState = cmd.getAllocationState(); - String zoneType = cmd.getZoneType(); zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), zoneId); @@ -1397,12 +1384,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); sb.and("allocationState", sb.entity().getAllocationState(), SearchCriteria.Op.EQ); - if(zoneType != null) { - SearchBuilder zoneSb = _dcDao.createSearchBuilder(); - zoneSb.and("zoneNetworkType", zoneSb.entity().getNetworkType(), SearchCriteria.Op.EQ); - sb.join("zoneSb", zoneSb, sb.entity().getDataCenterId(), zoneSb.entity().getId(), JoinBuilder.JoinType.INNER); - } - SearchCriteria sc = sb.create(); if (keyword != null) { SearchCriteria ssc = _hostPodDao.createSearchCriteria(); @@ -1428,10 +1409,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sc.setParameters("allocationState", allocationState); } - if(zoneType != null) { - sc.setJoinParameters("zoneSb", "zoneNetworkType", zoneType); - } - Pair, Integer> result = _hostPodDao.searchAndCount(sc, searchFilter); return new Pair, Integer>(result.first(), result.second()); } @@ -2962,7 +2939,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe public Pair, Integer> searchForSystemVm(ListSystemVMsCmd cmd) { String type = cmd.getSystemVmType(); Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId()); - String zoneType = cmd.getZoneType(); Long id = cmd.getId(); String name = cmd.getSystemVmName(); String state = cmd.getState(); @@ -2989,12 +2965,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sb.join("volumeSearch", volumeSearch, sb.entity().getId(), volumeSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER); } - if(zoneType != null) { - SearchBuilder zoneSb = _dcDao.createSearchBuilder(); - zoneSb.and("zoneNetworkType", zoneSb.entity().getNetworkType(), SearchCriteria.Op.EQ); - sb.join("zoneSb", zoneSb, sb.entity().getDataCenterId(), zoneSb.entity().getId(), JoinBuilder.JoinType.INNER); - } - SearchCriteria sc = sb.create(); if (keyword != null) { @@ -3035,10 +3005,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe sc.setJoinParameters("volumeSearch", "poolId", storageId); } - if(zoneType != null) { - sc.setJoinParameters("zoneSb", "zoneNetworkType", zoneType); - } - Pair, Integer> result = _vmInstanceDao.searchAndCount(sc, searchFilter); return new Pair, Integer>(result.first(), result.second()); } @@ -3406,6 +3372,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe _encryptionIV = null; } + @Override + public boolean getExecuteInSequence() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + private static String getBase64EncodedRandomKey(int nBits) { SecureRandom random; try { diff --git a/server/src/com/cloud/storage/StorageManager.java b/server/src/com/cloud/storage/StorageManager.java index d49a7f86e94..29c7ebcef00 100755 --- a/server/src/com/cloud/storage/StorageManager.java +++ b/server/src/com/cloud/storage/StorageManager.java @@ -35,6 +35,8 @@ import com.cloud.exception.ConnectionException; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.utils.Pair; import com.cloud.vm.DiskProfile; @@ -122,4 +124,12 @@ public interface StorageManager extends StorageService { DataStore createLocalStorage(Host host, StoragePoolInfo poolInfo) throws ConnectionException; BigDecimal getStorageOverProvisioningFactor(Long dcId); + + Long getDiskBytesReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering); + + Long getDiskBytesWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering); + + Long getDiskIopsReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering); + + Long getDiskIopsWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 687c4da3331..0df3dbe9116 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -134,6 +134,8 @@ import com.cloud.org.Grouping.AllocationState; import com.cloud.resource.ResourceState; import com.cloud.server.ManagementServer; import com.cloud.server.StatsCollector; +import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume.Type; @@ -144,6 +146,9 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.listener.StoragePoolMonitor; import com.cloud.storage.listener.VolumeStateListener; import com.cloud.template.TemplateManager; @@ -669,6 +674,9 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C HypervisorType hypervisorType = HypervisorType.KVM; if (scopeType == ScopeType.ZONE) { + // ignore passed clusterId and podId + clusterId = null; + podId = null; String hypervisor = cmd.getHypervisor(); if (hypervisor != null) { try { @@ -1864,4 +1872,67 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.ImageCache); } + // get bytesReadRate from service_offering, disk_offering and vm.disk.throttling.bytes_read_rate + @Override + public Long getDiskBytesReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) { + if ((offering != null) && (offering.getBytesReadRate() != null) && (offering.getBytesReadRate() > 0)) { + return offering.getBytesReadRate(); + } else if ((diskOffering != null) && (diskOffering.getBytesReadRate() != null) && (diskOffering.getBytesReadRate() > 0)) { + return diskOffering.getBytesReadRate(); + } else { + Long bytesReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesReadRate.key())); + if ((bytesReadRate > 0) && ((offering == null) || (! offering.getSystemUse()))) { + return bytesReadRate; + } + } + return 0L; + } + + // get bytesWriteRate from service_offering, disk_offering and vm.disk.throttling.bytes_write_rate + @Override + public Long getDiskBytesWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) { + if ((offering != null) && (offering.getBytesWriteRate() != null) && (offering.getBytesWriteRate() > 0)) { + return offering.getBytesWriteRate(); + } else if ((diskOffering != null) && (diskOffering.getBytesWriteRate() != null) && (diskOffering.getBytesWriteRate() > 0)) { + return diskOffering.getBytesWriteRate(); + } else { + Long bytesWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesWriteRate.key())); + if ((bytesWriteRate > 0) && ((offering == null) || (! offering.getSystemUse()))) { + return bytesWriteRate; + } + } + return 0L; + } + + // get iopsReadRate from service_offering, disk_offering and vm.disk.throttling.iops_read_rate + @Override + public Long getDiskIopsReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) { + if ((offering != null) && (offering.getIopsReadRate() != null) && (offering.getIopsReadRate() > 0)) { + return offering.getIopsReadRate(); + } else if ((diskOffering != null) && (diskOffering.getIopsReadRate() != null) && (diskOffering.getIopsReadRate() > 0)) { + return diskOffering.getIopsReadRate(); + } else { + Long iopsReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsReadRate.key())); + if ((iopsReadRate > 0) && ((offering == null) || (! offering.getSystemUse()))) { + return iopsReadRate; + } + } + return 0L; + } + + // get iopsWriteRate from service_offering, disk_offering and vm.disk.throttling.iops_write_rate + @Override + public Long getDiskIopsWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) { + if ((offering != null) && (offering.getIopsWriteRate() != null) && (offering.getIopsWriteRate() > 0)) { + return offering.getIopsWriteRate(); + } else if ((diskOffering != null) && (diskOffering.getIopsWriteRate() != null) && (diskOffering.getIopsWriteRate() > 0)) { + return diskOffering.getIopsWriteRate(); + } else { + Long iopsWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsWriteRate.key())); + if ((iopsWriteRate > 0) && ((offering == null) || (! offering.getSystemUse()))) { + return iopsWriteRate; + } + } + return 0L; + } } diff --git a/server/src/com/cloud/storage/s3/S3ManagerImpl.java b/server/src/com/cloud/storage/s3/S3ManagerImpl.java index 2edf2326b59..f393fff6268 100644 --- a/server/src/com/cloud/storage/s3/S3ManagerImpl.java +++ b/server/src/com/cloud/storage/s3/S3ManagerImpl.java @@ -196,13 +196,12 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { } - @SuppressWarnings("unchecked") - private String determineLockId(final long accountId, final long templateId) { + static String determineLockId(final long accountId, final long templateId) { // TBD The lock scope may be too coarse grained. Deletes need to lock // the template across all zones where upload and download could // probably safely scoped to the zone ... - return join(asList("S3_TEMPLATE", accountId, templateId), "_"); + return join("_", "S3_TEMPLATE", accountId, templateId); } @@ -356,9 +355,7 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { throw new CloudRuntimeException(errMsg); } - final String installPath = join( - asList("template", "tmpl", accountId, - templateId), File.separator); + final String installPath = join(File.separator, "template", "tmpl", accountId, templateId); final VMTemplateHostVO tmpltHost = new VMTemplateHostVO( secondaryStore.getId(), templateId, now(), 100, Status.DOWNLOADED, null, null, diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 7e1e3d424bf..ebe06e707a2 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -535,7 +535,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, String keyword = cmd.getKeyword(); String snapshotTypeStr = cmd.getSnapshotType(); String intervalTypeStr = cmd.getIntervalType(); - String zoneType = cmd.getZoneType(); Map tags = cmd.getTags(); Long zoneId = cmd.getZoneId(); Account caller = UserContext.current().getCaller(); @@ -579,12 +578,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); } - if(zoneType != null) { - SearchBuilder zoneSb = _dcDao.createSearchBuilder(); - zoneSb.and("zoneNetworkType", zoneSb.entity().getNetworkType(), SearchCriteria.Op.EQ); - sb.join("zoneSb", zoneSb, sb.entity().getDataCenterId(), zoneSb.entity().getId(), JoinBuilder.JoinType.INNER); - } - SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -604,10 +597,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } } - if(zoneType != null) { - sc.setJoinParameters("zoneSb", "zoneNetworkType", zoneType); - } - if (zoneId != null) { sc.setParameters("dataCenterId", zoneId); } diff --git a/server/src/com/cloud/test/DatabaseConfig.java b/server/src/com/cloud/test/DatabaseConfig.java index 70c81781959..ef0259d7c60 100755 --- a/server/src/com/cloud/test/DatabaseConfig.java +++ b/server/src/com/cloud/test/DatabaseConfig.java @@ -918,6 +918,20 @@ public class DatabaseConfig { } ServiceOfferingVO serviceOffering = new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText, useLocalStorage, false, null, false, null, false); + + Long bytesReadRate = Long.parseLong(_currentObjectParams.get("bytesReadRate")); + if ((bytesReadRate != null) && (bytesReadRate > 0)) + serviceOffering.setBytesReadRate(bytesReadRate); + Long bytesWriteRate = Long.parseLong(_currentObjectParams.get("bytesWriteRate")); + if ((bytesWriteRate != null) && (bytesWriteRate > 0)) + serviceOffering.setBytesWriteRate(bytesWriteRate); + Long iopsReadRate = Long.parseLong(_currentObjectParams.get("iopsReadRate")); + if ((iopsReadRate != null) && (iopsReadRate > 0)) + serviceOffering.setIopsReadRate(iopsReadRate); + Long iopsWriteRate = Long.parseLong(_currentObjectParams.get("iopsWriteRate")); + if ((iopsWriteRate != null) && (iopsWriteRate > 0)) + serviceOffering.setIopsWriteRate(iopsWriteRate); + ServiceOfferingDaoImpl dao = ComponentContext.inject(ServiceOfferingDaoImpl.class); try { dao.persist(serviceOffering); @@ -967,6 +981,20 @@ public class DatabaseConfig { } DiskOfferingVO diskOffering = new DiskOfferingVO(domainId, name, displayText, diskSpace , tags, false); diskOffering.setUseLocalStorage(local); + + Long bytesReadRate = Long.parseLong(_currentObjectParams.get("bytesReadRate")); + if (bytesReadRate != null && (bytesReadRate > 0)) + diskOffering.setBytesReadRate(bytesReadRate); + Long bytesWriteRate = Long.parseLong(_currentObjectParams.get("bytesWriteRate")); + if (bytesWriteRate != null && (bytesWriteRate > 0)) + diskOffering.setBytesWriteRate(bytesWriteRate); + Long iopsReadRate = Long.parseLong(_currentObjectParams.get("iopsReadRate")); + if (iopsReadRate != null && (iopsReadRate > 0)) + diskOffering.setIopsReadRate(iopsReadRate); + Long iopsWriteRate = Long.parseLong(_currentObjectParams.get("iopsWriteRate")); + if (iopsWriteRate != null && (iopsWriteRate > 0)) + diskOffering.setIopsWriteRate(iopsWriteRate); + DiskOfferingDaoImpl offering = ComponentContext.inject(DiskOfferingDaoImpl.class); try { offering.persist(diskOffering); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index ee3f252f6c3..c45c60e2a23 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -508,18 +508,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use // update the password in vm_details table too // Check if an SSH key pair was selected for the instance and if so // use it to encrypt & save the vm password - String sshPublicKey = userVm.getDetail("SSH.PublicKey"); - if (sshPublicKey != null && !sshPublicKey.equals("") - && password != null && !password.equals("saved_password")) { - String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey( - sshPublicKey, password); - if (encryptedPasswd == null) { - throw new CloudRuntimeException("Error encrypting password"); - } - - userVm.setDetail("Encrypted.Password", encryptedPasswd); - _vmDao.saveDetails(userVm); - } + encryptAndStorePassword(userVm, password); } else { throw new CloudRuntimeException( "Failed to reset password for the virtual machine "); @@ -642,13 +631,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use if (template != null && template.getEnablePassword()) { userVm.setPassword(password); //update the encrypted password in vm_details table too - if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) { - String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password); - if (encryptedPasswd == null) { - throw new CloudRuntimeException("Error encrypting password"); - } - userVm.setDetail("Encrypted.Password", encryptedPasswd); - } + encryptAndStorePassword(userVm, password); } _vmDao.saveDetails(userVm); } else { @@ -3281,18 +3264,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use // Check if an SSH key pair was selected for the instance and if so // use it to encrypt & save the vm password - String sshPublicKey = vm.getDetail("SSH.PublicKey"); - if (sshPublicKey != null && !sshPublicKey.equals("") - && password != null && !password.equals("saved_password")) { - String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey( - sshPublicKey, password); - if (encryptedPasswd == null) { - throw new CloudRuntimeException("Error encrypting password"); - } - - vm.setDetail("Encrypted.Password", encryptedPasswd); - _vmDao.saveDetails(vm); - } + encryptAndStorePassword(vm, password); params = new HashMap(); if (additionalParams != null) { @@ -3809,7 +3781,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use "No permission to migrate VM, Only Root Admin can migrate a VM!"); } - UserVmVO vm = _vmDao.findById(vmId); + VMInstanceVO vm = _vmInstanceDao.findById(vmId); if (vm == null) { throw new InvalidParameterValueException( "Unable to find the VM by id=" + vmId); @@ -3900,7 +3872,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use + " already has max Running VMs(count includes system VMs), cannot migrate to this host"); } - collectVmDiskStatistics(vm); + UserVmVO uservm = _vmDao.findById(vmId); + if (uservm != null) { + collectVmDiskStatistics(uservm); + } VMInstanceVO migratedVm = _itMgr.migrate(vm, srcHostId, dest); return migratedVm; } @@ -4598,15 +4573,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use // update the password in vm_details table too // Check if an SSH key pair was selected for the instance and if so // use it to encrypt & save the vm password - String sshPublicKey = vm.getDetail("SSH.PublicKey"); - if (sshPublicKey != null && !sshPublicKey.equals("") && password != null && !password.equals("saved_password")) { - String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(sshPublicKey, password); - if (encryptedPasswd == null) { - throw new CloudRuntimeException("VM reset is completed but error occurred when encrypting newly created password"); - } - vm.setDetail("Encrypted.Password", encryptedPasswd); - _vmDao.saveDetails(vm); - } + encryptAndStorePassword(vm, password); } else { throw new CloudRuntimeException("VM reset is completed but failed to reset password for the virtual machine "); } @@ -4694,5 +4661,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use if (vm.getState() == State.Running) collectVmDiskStatistics(vm); } + + private void encryptAndStorePassword(UserVmVO vm, String password) { + String sshPublicKey = vm.getDetail("SSH.PublicKey"); + if (sshPublicKey != null && !sshPublicKey.equals("") + && password != null && !password.equals("saved_password")) { + if (!sshPublicKey.startsWith("ssh-rsa")) { + s_logger.warn("Only RSA public keys can be used to encrypt a vm password."); + return; + } + String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey( + sshPublicKey, password); + if (encryptedPasswd == null) { + throw new CloudRuntimeException("Error encrypting password"); + } + + vm.setDetail("Encrypted.Password", encryptedPasswd); + _vmDao.saveDetails(vm); + } + } } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 6af664ab4b0..72d046eba93 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -130,6 +130,7 @@ import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; import com.cloud.resource.ResourceManager; import com.cloud.server.ConfigurationServer; +import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -259,6 +260,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected AffinityGroupVMMapDao _affinityGroupVMMapDao; @Inject protected ConfigurationServer _configServer; + @Inject + protected ManagementServer _mgmtServer; protected List _planners; public List getPlanners() { @@ -857,7 +860,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac VirtualMachineTO vmTO = hvGuru.implement(vmProfile); cmds = new Commands(OnError.Stop); - cmds.addCommand(new StartCommand(vmTO, dest.getHost())); + cmds.addCommand(new StartCommand(vmTO, dest.getHost(), _mgmtServer.getExecuteInSequence())); vmGuru.finalizeDeployment(cmds, vmProfile, dest, ctx); @@ -897,7 +900,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac s_logger.info("The guru did not like the answers so stopping " + vm); } - StopCommand cmd = new StopCommand(vm); + StopCommand cmd = new StopCommand(vm, _mgmtServer.getExecuteInSequence()); StopAnswer answer = (StopAnswer) _agentMgr.easySend(destHostId, cmd); if (answer == null || !answer.getResult()) { s_logger.warn("Unable to stop " + vm + " due to " + (answer != null ? answer.getDetails() : "no answers")); @@ -984,7 +987,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected boolean sendStop(VirtualMachineGuru guru, VirtualMachineProfile profile, boolean force) { VMInstanceVO vm = profile.getVirtualMachine(); - StopCommand stop = new StopCommand(vm); + StopCommand stop = new StopCommand(vm, _mgmtServer.getExecuteInSequence()); try { Answer answer = _agentMgr.send(vm.getHostId(), stop); if (!answer.getResult()) { @@ -1169,8 +1172,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } vmGuru.prepareStop(profile); - - StopCommand stop = new StopCommand(vm); + StopCommand stop = new StopCommand(vm, _mgmtServer.getExecuteInSequence()); boolean stopped = false; StopAnswer answer = null; try { @@ -1923,11 +1925,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } public Command cleanup(VirtualMachine vm) { - return new StopCommand(vm); + return new StopCommand(vm, _mgmtServer.getExecuteInSequence()); } public Command cleanup(String vmName) { - return new StopCommand(vmName); + return new StopCommand(vmName, _mgmtServer.getExecuteInSequence()); } public Commands fullHostSync(final long hostId, StartupRoutingCommand startup) { diff --git a/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java b/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java index e81d7222a60..e5d33296b00 100644 --- a/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java +++ b/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java @@ -291,7 +291,7 @@ public class DedicateGuestVlanRangesTest { try { networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd); } catch (Exception e) { - Assert.assertTrue(e.getMessage().contains("Vlan range is already dedicated to another account")); + Assert.assertTrue(e.getMessage().contains("Vlan range is already dedicated")); } finally { txn.close("runDedicateGuestVlanRangeDedicatedRange"); } @@ -320,7 +320,7 @@ public class DedicateGuestVlanRangesTest { try { networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd); } catch (Exception e) { - Assert.assertTrue(e.getMessage().contains("Vlan range is partially dedicated to another account")); + Assert.assertTrue(e.getMessage().contains("Vlan range is already dedicated")); } finally { txn.close("runDedicateGuestVlanRangePartiallyDedicated"); } diff --git a/server/test/com/cloud/network/MockNetworkModelImpl.java b/server/test/com/cloud/network/MockNetworkModelImpl.java index 3a367480a30..bab9df8dd6d 100644 --- a/server/test/com/cloud/network/MockNetworkModelImpl.java +++ b/server/test/com/cloud/network/MockNetworkModelImpl.java @@ -879,4 +879,10 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) { return null; } + + @Override + public boolean getExecuteInSeqNtwkElmtCmd() { + // TODO Auto-generated method stub + return false; + } } diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java index 21b3590282d..6e3d187d598 100755 --- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java +++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java @@ -489,7 +489,8 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu */ @Override public ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, Type vm_typeType, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA, - boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map details) { + boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map details, + Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) { // TODO Auto-generated method stub return null; } @@ -654,7 +655,8 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu * @see com.cloud.configuration.ConfigurationManager#createDiskOffering(java.lang.Long, java.lang.String, java.lang.String, java.lang.Long, java.lang.String, boolean, boolean, boolean) */ @Override - public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled) { + public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled, + Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) { // TODO Auto-generated method stub return null; } diff --git a/server/test/com/cloud/vpc/MockNetworkModelImpl.java b/server/test/com/cloud/vpc/MockNetworkModelImpl.java index 3e67f5e76e2..a6ab1261c3c 100644 --- a/server/test/com/cloud/vpc/MockNetworkModelImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkModelImpl.java @@ -892,4 +892,10 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { return null; } + @Override + public boolean getExecuteInSeqNtwkElmtCmd() { + // TODO Auto-generated method stub + return false; + } + } diff --git a/services/console-proxy/server/scripts/ssvm-check.sh b/services/console-proxy/server/scripts/ssvm-check.sh deleted file mode 100644 index a4011647f07..00000000000 --- a/services/console-proxy/server/scripts/ssvm-check.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env bash -# 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. - - -# Health check script for the Secondary Storage VM - -# DNS server is specified. - - -CMDLINE=/var/cache/cloud/cmdline -for i in `cat $CMDLINE` -do - key=`echo $i | cut -d= -f1` - value=`echo $i | cut -d= -f2` - case $key in - host) - MGMTSERVER=$value - ;; - esac -done - - -# ping dns server -echo ================================================ -DNSSERVER=`egrep '^nameserver' /etc/resolv.conf | awk '{print $2}'| head -1` -echo "First DNS server is " $DNSSERVER -ping -c 2 $DNSSERVER -if [ $? -eq 0 ] -then - echo "Good: Can ping DNS server" -else - echo "WARNING: cannot ping DNS server" - echo "route follows" - route -n -fi - - -# check dns resolve -echo ================================================ -nslookup download.cloud.com 1> /tmp/dns 2>&1 -grep 'no servers could' /tmp/dns 1> /dev/null 2>&1 -if [ $? -eq 0 ] -then - echo "ERROR: DNS not resolving download.cloud.com" - echo resolv.conf follows - cat /etc/resolv.conf - exit 2 -else - echo "Good: DNS resolves download.cloud.com" -fi - - -# check to see if we have the NFS volume mounted -echo ================================================ -mount|grep -v sunrpc|grep nfs 1> /dev/null 2>&1 -if [ $? -eq 0 ] -then - echo "NFS is currently mounted" - # check for write access - for MOUNTPT in `mount|grep -v sunrpc|grep nfs| awk '{print $3}'` - do - if [ $MOUNTPT != "/proc/xen" ] # mounted by xen - then - echo Mount point is $MOUNTPT - touch $MOUNTPT/foo - if [ $? -eq 0 ] - then - echo "Good: Can write to mount point" - rm $MOUNTPT/foo - else - echo "ERROR: Cannot write to mount point" - echo "You need to export with norootsquash" - fi - fi - done -else - echo "ERROR: NFS is not currently mounted" - echo "Try manually mounting from inside the VM" - NFSSERVER=`awk '{print $17}' $CMDLINE|awk -F= '{print $2}'|awk -F: '{print $1}'` - echo "NFS server is " $NFSSERVER - ping -c 2 $NFSSERVER - if [ $? -eq 0 ] - then - echo "Good: Can ping NFS server" - else - echo "WARNING: cannot ping NFS server" - echo routing table follows - route -n - fi -fi - - -# check for connectivity to the management server -echo ================================================ -echo Management server is $MGMTSERVER. Checking connectivity. -socatout=$(echo | socat - TCP:$MGMTSERVER:8250,connect-timeout=3 2>&1) -if [ $? -eq 0 ] -then - echo "Good: Can connect to management server port 8250" -else - echo "ERROR: Cannot connect to $MGMTSERVER port 8250" - echo $socatout - exit 4 -fi - - -# check for the java process running -echo ================================================ -ps -eaf|grep -v grep|grep java 1> /dev/null 2>&1 -if [ $? -eq 0 ] -then - echo "Good: Java process is running" -else - echo "ERROR: Java process not running. Try restarting the SSVM." - exit 3 -fi - -echo ================================================ -echo Tests Complete. Look for ERROR or WARNING above. - -exit 0 diff --git a/services/console-proxy/server/systemvm-descriptor.xml b/services/console-proxy/server/systemvm-descriptor.xml index e34026bc3a6..6c98d2d3eb0 100644 --- a/services/console-proxy/server/systemvm-descriptor.xml +++ b/services/console-proxy/server/systemvm-descriptor.xml @@ -36,6 +36,15 @@ 555 555 + + ../../secondary-storage/scripts/ + + 555 + 555 + + ssvm-check.sh + + ../../../scripts/storage/secondary/ scripts/storage/secondary diff --git a/setup/bindir/cloud-set-guest-sshkey.in b/setup/bindir/cloud-set-guest-sshkey.in index 15008b8d514..f3f02b15fb0 100755 --- a/setup/bindir/cloud-set-guest-sshkey.in +++ b/setup/bindir/cloud-set-guest-sshkey.in @@ -71,6 +71,7 @@ fi homedir=$(grep ^$user /etc/passwd|awk -F ":" '{print $6}') sshdir=$homedir/.ssh authorized=$sshdir/authorized_keys +restorecon=/sbin/restorecon if [ ! -e $sshdir ] @@ -86,6 +87,10 @@ fi cat $authorized|grep -v "$publickey" > $authorized echo "$publickey" >> $authorized +if [ -e $restorecon ] +then + $restorecon -R -v $sshdir +fi exit 0 diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index a8a133f1263..cc8dfafaf17 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -428,6 +428,14 @@ ALTER TABLE `cloud`.`nics` ADD COLUMN `display_nic` tinyint(1) NOT NULL DEFAULT ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `display_offering` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should disk offering be displayed to the end user'; +ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `bytes_read_rate` bigint(20); + +ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `bytes_write_rate` bigint(20); + +ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `iops_read_rate` bigint(20); + +ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `iops_write_rate` bigint(20); + CREATE TABLE `cloud`.`volume_details` ( `id` bigint unsigned NOT NULL auto_increment, `volume_id` bigint unsigned NOT NULL COMMENT 'volume id', @@ -900,6 +908,10 @@ CREATE VIEW `cloud`.`volume_view` AS disk_offering.display_text disk_offering_display_text, disk_offering.use_local_storage, disk_offering.system_use, + disk_offering.bytes_read_rate, + disk_offering.bytes_write_rate, + disk_offering.iops_read_rate, + disk_offering.iops_write_rate, storage_pool.id pool_id, storage_pool.uuid pool_uuid, storage_pool.name pool_name, @@ -1100,15 +1112,11 @@ CREATE VIEW `cloud`.`domain_router_view` AS left join `cloud`.`disk_offering` ON vm_instance.service_offering_id = disk_offering.id left join - `cloud`.`volumes` ON vm_instance.id = volumes.instance_id - left join - `cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id - left join - `cloud`.`nics` ON vm_instance.id = nics.instance_id + `cloud`.`nics` ON vm_instance.id = nics.instance_id and nics.removed is null left join `cloud`.`networks` ON nics.network_id = networks.id left join - `cloud`.`vpc` ON domain_router.vpc_id = vpc.id + `cloud`.`vpc` ON domain_router.vpc_id = vpc.id and vpc.removed is null left join `cloud`.`async_job` ON async_job.instance_id = vm_instance.id and async_job.instance_type = 'DomainRouter' @@ -1208,6 +1216,10 @@ CREATE VIEW `cloud`.`service_offering_view` AS disk_offering.removed, disk_offering.use_local_storage, disk_offering.system_use, + disk_offering.bytes_read_rate, + disk_offering.bytes_write_rate, + disk_offering.iops_read_rate, + disk_offering.iops_write_rate, service_offering.cpu, service_offering.speed, service_offering.ram_size, @@ -1514,6 +1526,10 @@ CREATE VIEW `cloud`.`disk_offering_view` AS disk_offering.removed, disk_offering.use_local_storage, disk_offering.system_use, + disk_offering.bytes_read_rate, + disk_offering.bytes_write_rate, + disk_offering.iops_read_rate, + disk_offering.iops_write_rate, disk_offering.sort_key, disk_offering.type, disk_offering.display_offering, @@ -1570,7 +1586,7 @@ CREATE VIEW `cloud`.`user_vm_view` AS data_center.uuid data_center_uuid, data_center.name data_center_name, data_center.is_security_group_enabled security_group_enabled, - data_center.networktype data_center_type, + data_center.networktype data_center_type, host.id host_id, host.uuid host_uuid, host.name host_name, @@ -1682,11 +1698,11 @@ CREATE VIEW `cloud`.`user_vm_view` AS left join `cloud`.`security_group` ON security_group_vm_map.security_group_id = security_group.id left join - `cloud`.`nics` ON vm_instance.id = nics.instance_id + `cloud`.`nics` ON vm_instance.id = nics.instance_id and nics.removed is null left join `cloud`.`networks` ON nics.network_id = networks.id left join - `cloud`.`vpc` ON networks.vpc_id = vpc.id + `cloud`.`vpc` ON networks.vpc_id = vpc.id and vpc.removed is null left join `cloud`.`user_ip_address` ON user_ip_address.vm_id = vm_instance.id left join @@ -1754,6 +1770,10 @@ CREATE VIEW `cloud`.`volume_view` AS disk_offering.display_text disk_offering_display_text, disk_offering.use_local_storage, disk_offering.system_use, + disk_offering.bytes_read_rate, + disk_offering.bytes_write_rate, + disk_offering.iops_read_rate, + disk_offering.iops_write_rate, storage_pool.id pool_id, storage_pool.uuid pool_uuid, storage_pool.name pool_name, @@ -2088,7 +2108,10 @@ CREATE TABLE `cloud_usage`.`usage_vm_disk` ( ) ENGINE=InnoDB CHARSET=utf8; INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.stats.interval', 0, 'Interval (in seconds) to report vm disk statistics.'); - +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.iops_read_rate', 0, 'Default disk I/O read rate in requests per second allowed in User vm\'s disk. '); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.iops_write_rate', 0, 'Default disk I/O write rate in requests per second allowed in User vm\'s disk. '); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.bytes_read_rate', 0, 'Default disk I/O read rate in bytes per second allowed in User vm\'s disk. '); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.bytes_write_rate', 0, 'Default disk I/O write rate in bytes per second allowed in User vm\'s disk. '); -- Re-enable foreign key checking, at the end of the upgrade path SET foreign_key_checks = 1; @@ -2096,3 +2119,10 @@ SET foreign_key_checks = 1; UPDATE `cloud`.`snapshot_policy` set uuid=id WHERE uuid is NULL; #update shared sg enabled network with not null name in Advance Security Group enabled network UPDATE `cloud`.`networks` set name='Shared SG enabled network', display_text='Shared SG enabled network' WHERE name IS null AND traffic_type='Guest' AND data_center_id IN (select id from data_center where networktype='Advanced' and is_security_group_enabled=1) AND acl_type='Domain'; + +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'use.system.public.ips', 'true', 'If true, when account has dedicated public ip range(s), once the ips dedicated to the account have been consumed ips will be acquired from the system pool'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'use.system.guest.vlans', 'true', 'If true, when account has dedicated guest vlan range(s), once the vlans dedicated to the account have been consumed vlans will be allocated from the system pool'); + +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'execute.in.sequence.hypervisor.commands', 'false', 'If set to true, StartCommand, StopCommand, CopyVolumeCommand, CreateCommand will be synchronized on the agent side. If set to false, these commands become asynchronous. Default value is false.'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'execute.in.sequence.network.element.commands', 'false', 'If set to true, DhcpEntryCommand, SavePasswordCommand, UserDataCommand, VmDataCommand will be synchronized on the agent side. If set to false, these commands become asynchronous. Default value is false.'); + diff --git a/setup/dev/advanced.cfg b/setup/dev/advanced.cfg index 302016569ab..3d0854d8aa7 100644 --- a/setup/dev/advanced.cfg +++ b/setup/dev/advanced.cfg @@ -218,7 +218,8 @@ "mgtSvrIp": "localhost", "passwd": "password", "user": "root", - "port": 8096 + "port": 8096, + "hypervisor" : "simulator" } ] } diff --git a/test/integration/component/maint/__init__.py b/test/integration/component/maint/__init__.py new file mode 100644 index 00000000000..f044f8bcd9a --- /dev/null +++ b/test/integration/component/maint/__init__.py @@ -0,0 +1,21 @@ +# 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. + +""" +Tests that put hosts, zones, resources in to maintenance mode are here. +These will have to be run sequentiall when resources are available so as not disrupt other tests +""" \ No newline at end of file diff --git a/test/integration/component/test_high_availability.py b/test/integration/component/maint/test_high_availability.py similarity index 100% rename from test/integration/component/test_high_availability.py rename to test/integration/component/maint/test_high_availability.py diff --git a/test/integration/component/test_host_high_availability.py b/test/integration/component/maint/test_host_high_availability.py similarity index 99% rename from test/integration/component/test_host_high_availability.py rename to test/integration/component/maint/test_host_high_availability.py index 57eb5edede9..5fb047ba6cb 100644 --- a/test/integration/component/test_host_high_availability.py +++ b/test/integration/component/maint/test_host_high_availability.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -""" P1 tests for dedicated Host high availability +""" P1 tests for dedicated Host high availability """ #Import Local Modules from nose.plugins.attrib import attr @@ -142,7 +142,6 @@ class TestHostHighAvailability(cloudstackTestCase): try: #Clean up, terminate the created accounts, domains etc cleanup_resources(self.apiclient, self.cleanup) - self.testClient.close() except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @@ -158,7 +157,7 @@ class TestHostHighAvailability(cloudstackTestCase): # Validations, #1. Ensure that the offering is created and that in the UI the 'Offer HA' field is enabled (Yes) #The listServiceOffering API should list 'offerha' as true. - #2. Select the newly created VM and ensure that the Compute offering field value lists the compute service offering that was selected. + #2. Select the newly created VM and ensure that the Compute offering field value lists the compute service offering that was selected. # Also, check that the HA Enabled field is enabled 'Yes'. #list and validate above created service offering with Ha enabled @@ -258,7 +257,7 @@ class TestHostHighAvailability(cloudstackTestCase): self.debug("Deployed VM on host: %s" % vm.hostid) - #validate the virtual machine created is host Ha enabled + #validate the virtual machine created is host Ha enabled list_hosts_response = list_hosts( self.apiclient, id=vm.hostid @@ -594,7 +593,7 @@ class TestHostHighAvailability(cloudstackTestCase): vm_with_ha_enabled = vms[0] - #Verify the virtual machine got created on non HA host + #Verify the virtual machine got created on non HA host list_hosts_response = list_hosts( self.apiclient, id=vm_with_ha_enabled.hostid @@ -726,7 +725,7 @@ class TestHostHighAvailability(cloudstackTestCase): vm_with_ha_disabled = vms[0] - #Verify the virtual machine got created on non HA host + #Verify the virtual machine got created on non HA host list_hosts_response = list_hosts( self.apiclient, id=vm_with_ha_disabled.hostid diff --git a/test/integration/component/test_vpc_host_maintenance.py b/test/integration/component/maint/test_vpc_host_maintenance.py similarity index 63% rename from test/integration/component/test_vpc_host_maintenance.py rename to test/integration/component/maint/test_vpc_host_maintenance.py index d28b7985b9b..8fc427abd36 100644 --- a/test/integration/component/test_vpc_host_maintenance.py +++ b/test/integration/component/maint/test_vpc_host_maintenance.py @@ -558,332 +558,4 @@ class TestVMLifeCycleHostmaintenance(cloudstackTestCase): "Router state should be running" ) # TODO: Check for the network connectivity - return - - -class TestVPCNetworkRules(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestVPCNetworkRules, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering_1 = ServiceOffering.create( - cls.api_client, - cls.services["service_offering_1"] - ) - cls.service_offering_2 = ServiceOffering.create( - cls.api_client, - cls.services["service_offering_2"] - ) - cls.vpc_off = VpcOffering.create( - cls.api_client, - cls.services["vpc_offering"] - ) - cls.vpc_off.update(cls.api_client, state='Enabled') - - cls.account = Account.create( - cls.api_client, - cls.services["account"], - admin=True, - domainid=cls.domain.id - ) - - cls.vpc_off = VpcOffering.create( - cls.api_client, - cls.services["vpc_offering"] - ) - - cls.vpc_off.update(cls.api_client, state='Enabled') - - cls.services["vpc"]["cidr"] = '10.1.1.1/16' - cls.vpc = VPC.create( - cls.api_client, - cls.services["vpc"], - vpcofferingid=cls.vpc_off.id, - zoneid=cls.zone.id, - account=cls.account.name, - domainid=cls.account.domainid - ) - - cls.nw_off = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=False - ) - # Enable Network offering - cls.nw_off.update(cls.api_client, state='Enabled') - - # Creating network using the network offering created - cls.network_1 = Network.create( - cls.api_client, - cls.services["network"], - accountid=cls.account.name, - domainid=cls.account.domainid, - networkofferingid=cls.nw_off.id, - zoneid=cls.zone.id, - gateway='10.1.1.1', - vpcid=cls.vpc.id - ) - cls.nw_off_no_lb = NetworkOffering.create( - cls.api_client, - cls.services["network_offering_no_lb"], - conservemode=False - ) - # Enable Network offering - cls.nw_off_no_lb.update(cls.api_client, state='Enabled') - - # Creating network using the network offering created - cls.network_2 = Network.create( - cls.api_client, - cls.services["network"], - accountid=cls.account.name, - domainid=cls.account.domainid, - networkofferingid=cls.nw_off_no_lb.id, - zoneid=cls.zone.id, - gateway='10.1.2.1', - vpcid=cls.vpc.id - ) - # Spawn an instance in that network - cls.vm_1 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_1.id, - networkids=[str(cls.network_1.id)] - ) - # Spawn an instance in that network - cls.vm_2 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_2.id, - networkids=[str(cls.network_1.id)] - ) - cls.vm_3 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_1.id, - networkids=[str(cls.network_2.id)] - ) - cls.vm_4 = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering_2.id, - networkids=[str(cls.network_2.id)] - ) - - cls._cleanup = [ - cls.service_offering_1, - cls.service_offering_2, - cls.nw_off, - cls.nw_off_no_lb, - ] - return - - @classmethod - def tearDownClass(cls): - try: - cls.account.delete(cls.api_client) - wait_for_cleanup(cls.api_client, ["account.cleanup.interval"]) - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - - # Waiting for network cleanup to delete vpc offering - wait_for_cleanup(cls.api_client, ["network.gc.wait", - "network.gc.interval"]) - cls.vpc_off.delete(cls.api_client) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def validate_vm_deployment(self): - """Validates VM deployment on different hosts""" - - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - networkid=self.network_1.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs shall return a valid response" - ) - host_1 = vms[0].hostid - self.debug("Host for network 1: %s" % vms[0].hostid) - - vms = VirtualMachine.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - networkid=self.network_2.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List VMs shall return a valid response" - ) - host_2 = vms[0].hostid - self.debug("Host for network 2: %s" % vms[0].hostid) - - self.assertNotEqual( - host_1, - host_2, - "Both the virtual machines should be deployed on diff hosts " - ) - return - - @attr(tags=["advanced", "intervlan"]) - def test_list_pf_rules_for_vpc(self): - """ Test List Port Forwarding Rules & vms belonging to a VPC - """ - - # Validate the following - # 1. Create a VPC with cidr - 10.1.1.1/16 - # 2. Add network1(10.1.1.1/24) and network2(10.1.2.1/24) to this VPC. - # 3. Deploy vm1 and vm2 in network1 and vm3 and vm4 in network2. - # Make sure vm1 and vm3 are deployed on one host in the cluster - # while vm2 and vm4 are deployed on the other host in the cluster. - # This can be done using host's tags and service offerings with - # host tags. - # 4. Create a PF rule for vms in network1. - # 5. Create a PF rule for vms in network2. - # Steps: - # 1. List all the Port Forwarding Rules belonging to a VPC - # 2. Successfully List the Port Forwarding Rules belonging to the VPC - # 3. List the VMs on network1 for selection for the PF Rule - # 4. Successfully list the VMs for Port Forwarding Rule creation - - self.debug("Associating public IP for network: %s" % - self.network_1.name) - public_ip_1 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=self.network_1.id, - vpcid=self.vpc.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_1.ipaddress.ipaddress, - self.network_1.id - )) - - nat_rule_1 = NATRule.create( - self.apiclient, - self.vm_1, - self.services["natrule"], - ipaddressid=public_ip_1.ipaddress.id, - openfirewall=False, - networkid=self.network_1.id, - vpcid=self.vpc.id - ) - - self.debug("Associating public IP for network: %s" % - self.network_2.name) - public_ip_2 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=self.network_2.id, - vpcid=self.vpc.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_2.ipaddress.ipaddress, - self.network_2.id - )) - - nat_rule_2 = NATRule.create( - self.apiclient, - self.vm_3, - self.services["natrule"], - ipaddressid=public_ip_2.ipaddress.id, - openfirewall=False, - networkid=self.network_2.id, - vpcid=self.vpc.id - ) - - self.debug("Listing all the PF rules belonging to VPC") - nat_rules = NATRule.list( - self.apiclient, - vpcid=self.vpc.id, - listall=True - ) - self.assertEqual( - isinstance(nat_rules, list), - True, - "List NAT rules should return the valid list" - ) - self.assertEqual( - len(nat_rules), - 2, - "List NAT for VPC shall return all NAT rules belonging to VPC" - ) - for nat_rule in nat_rules: - self.assertEqual( - nat_rule.vpcid, - self.vpc.id, - "NAT rules should belong to VPC" - ) - - self.debug( - "Listing all the VMs belonging to VPC for network: %s" % - self.network_1.name) - vms = VirtualMachine.list( - self.apiclient, - networkid=self.network_1.id, - vpcid=self.vpc.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List virtual machines should return the valid list" - ) - for vm in vms: - self.assertEqual( - vm.networkid, - self.network_1.id, - "List VMs should return vms belonging to network_1" - ) - return - + return \ No newline at end of file diff --git a/test/integration/component/maint/test_vpc_on_host_maintenance.py b/test/integration/component/maint/test_vpc_on_host_maintenance.py new file mode 100644 index 00000000000..6630ee61e0a --- /dev/null +++ b/test/integration/component/maint/test_vpc_on_host_maintenance.py @@ -0,0 +1,323 @@ +# 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. + +from nose.plugins.attrib import attr +from marvin.cloudstackTestCase import * +from marvin.cloudstackAPI import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.base import * +from marvin.integration.lib.common import * + + +class Services: + """Test VPC services + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + "vpc_offering": { + "name": 'VPC off', + "displaytext": 'VPC off', + "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,NetworkACL', + }, + "vpc": { + "name": "TestVPC", + "displaytext": "TestVPC", + "cidr": '10.0.0.1/24' + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + # Hypervisor type should be same as + # hypervisor type of cluster + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + # Cent OS 5.3 (64 bit) + "sleep": 60, + "timeout": 10 + } + +class TestVPCHostMaintenance(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestVPCHostMaintenance, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + cls.services["mode"] = cls.zone.networktype + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.vpc_off = VpcOffering.create( + cls.api_client, + cls.services["vpc_offering"] + ) + cls.vpc_off.update(cls.api_client, state='Enabled') + hosts = Host.list( + cls.api_client, + zoneid=cls.zone.id, + listall=True, + type='Routing' + ) + + if isinstance(hosts, list): + for host in hosts: + Host.enableMaintenance( + cls.api_client, + id=host.id + ) + + timeout = cls.services["timeout"] + while True: + time.sleep(cls.services["sleep"]) + hosts_states = Host.list( + cls.api_client, + id=host.id, + listall=True + ) + if hosts_states[0].resourcestate == 'PrepareForMaintenance': + # Wait for sometimetill host goes in maintenance state + time.sleep(cls.services["sleep"]) + elif hosts_states[0].resourcestate == 'Maintenance': + time.sleep(cls.services["sleep"]) + break + elif timeout == 0: + raise unittest.SkipTest( + "Failed to enable maintenance mode on %s" % host.name) + timeout = timeout - 1 + + cls._cleanup = [ + cls.service_offering, + cls.vpc_off + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + hosts = Host.list( + cls.api_client, + zoneid=cls.zone.id, + listall=True, + type='Routing' + ) + if isinstance(hosts, list): + for host in hosts: + Host.cancelMaintenance( + cls.api_client, + id=host.id + ) + hosts_states = Host.list( + cls.api_client, + id=host.id, + listall=True + ) + if hosts_states[0].resourcestate != 'Enabled': + raise Exception( + "Failed to cancel maintenance mode on %s" % (host.name)) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + def tearDown(self): + try: + #Clean up, terminate the created network offerings + cleanup_resources(self.apiclient, self.cleanup) + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def validate_vpc_offering(self, vpc_offering): + """Validates the VPC offering""" + + self.debug("Check if the VPC offering is created successfully?") + vpc_offs = VpcOffering.list( + self.apiclient, + id=vpc_offering.id + ) + self.assertEqual( + isinstance(vpc_offs, list), + True, + "List VPC offerings should return a valid list" + ) + self.assertEqual( + vpc_offering.name, + vpc_offs[0].name, + "Name of the VPC offering should match with listVPCOff data" + ) + self.debug( + "VPC offering is created successfully - %s" % + vpc_offering.name) + return + + def validate_vpc_network(self, network, state=None): + """Validates the VPC network""" + + self.debug("Check if the VPC network is created successfully?") + vpc_networks = VPC.list( + self.apiclient, + id=network.id + ) + self.assertEqual( + isinstance(vpc_networks, list), + True, + "List VPC network should return a valid list" + ) + self.assertEqual( + network.name, + vpc_networks[0].name, + "Name of the VPC network should match with listVPC data" + ) + if state: + self.assertEqual( + vpc_networks[0].state, + state, + "VPC state should be '%s'" % state + ) + self.debug("VPC network validated - %s" % network.name) + return + + @attr(tags=["advanced", "intervlan"]) + def test_01_create_vpc_host_maintenance(self): + """ Test VPC when host is in maintenance mode + """ + + # Validate the following + # 1. Put the host in maintenance mode. + # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 + # 3. VPC will be created but will be in "Disabled" state + + self.debug("creating a VPC network in the account: %s" % + self.account.name) + self.services["vpc"]["cidr"] = '10.1.1.1/16' + vpc = VPC.create( + self.apiclient, + self.services["vpc"], + vpcofferingid=self.vpc_off.id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.validate_vpc_network(vpc, state='Disabled') + return + + @attr(tags=["advanced", "intervlan"]) + def test_02_create_vpc_wait_gc(self): + """ Test VPC when host is in maintenance mode and wait till nw gc + """ + + # Validate the following + # 1. Put the host in maintenance mode. + # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 + # 3. Wait for the VPC GC thread to run. + # 3. VPC will be created but will be in "Disabled" state and should + # get deleted + + self.debug("creating a VPC network in the account: %s" % + self.account.name) + self.services["vpc"]["cidr"] = '10.1.1.1/16' + vpc = VPC.create( + self.apiclient, + self.services["vpc"], + vpcofferingid=self.vpc_off.id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.validate_vpc_network(vpc, state='Disabled') + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + wait = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + self.debug("Sleep till network gc thread runs..") + # Sleep to ensure that all resources are deleted + time.sleep(int(interval[0].value) + int(wait[0].value)) + vpcs = VPC.list( + self.apiclient, + id=vpc.id, + listall=True + ) + self.assertEqual( + vpcs, + None, + "List VPC should not return anything after network gc" + ) + return diff --git a/test/integration/component/test_accounts.py b/test/integration/component/test_accounts.py index 3f106c3b048..39ff3eaaf11 100644 --- a/test/integration/component/test_accounts.py +++ b/test/integration/component/test_accounts.py @@ -84,6 +84,7 @@ class Services: "isfeatured": True, "ispublic": True, "isextractable": True, + "ostype": 'CentOS 5.3 (64-bit)', }, "natrule": { "publicport": 22, @@ -752,13 +753,14 @@ class TestServiceOfferingHierarchy(cloudstackTestCase): domainid=cls.domain_2.id ) - cls._cleanup = [ - cls.account_1, - cls.account_2, - cls.service_offering, - cls.domain_1, - cls.domain_2, - ] + cls._cleanup = [ + cls.account_2, + cls.domain_2, + cls.service_offering, + cls.account_1, + cls.domain_1, + ] + return @classmethod diff --git a/test/integration/component/test_advancedsg_networks.py b/test/integration/component/test_advancedsg_networks.py index e1694f12668..f8774be9e48 100644 --- a/test/integration/component/test_advancedsg_networks.py +++ b/test/integration/component/test_advancedsg_networks.py @@ -246,6 +246,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase): raise Exception("Warning: Exception during network cleanup : %s" % e) return + @attr(tags = ["advancedsg"]) def test_createIsolatedNetwork(self): """ Test Isolated Network """ @@ -423,8 +424,9 @@ class TestNetworksInAdvancedSG(cloudstackTestCase): except Exception as e: self.debug("Network creation failed because create isolated network is invalid in advanced zone with security groups.") + @attr(tags = ["advancedsg"]) def test_createSharedNetwork_withoutSG(self): - """ Test Shared Network with used vlan 01 """ + """ Test Shared Network with without SecurityProvider """ # Steps, # 1. create an Admin account @@ -574,6 +576,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase): except Exception as e: self.debug("Network creation failed because there is no SecurityProvider in the network offering.") + @attr(tags = ["advancedsg"]) def test_deployVM_SharedwithSG(self): """ Test VM deployment in shared networks with SecurityProvider """ diff --git a/test/integration/component/test_blocker_bugs.py b/test/integration/component/test_blocker_bugs.py index d099bf1a448..1f7ac97afb3 100644 --- a/test/integration/component/test_blocker_bugs.py +++ b/test/integration/component/test_blocker_bugs.py @@ -68,11 +68,6 @@ class Services: "publicport": 22, "protocol": 'TCP', }, - "volume": { - "diskname": "APP Data Volume", - "size": 1, # in GBs - "diskdevice": "/dev/xvdb", # Data Disk - }, "templates": { "displaytext": 'Template from snapshot', "name": 'Template from snapshot', @@ -86,13 +81,6 @@ class Services: "isextractable": True, "passwordenabled": True, }, - "paths": { - "mount_dir": "/mnt/tmp", - "sub_dir": "test", - "sub_lvl_dir1": "test1", - "sub_lvl_dir2": "test2", - "random_data": "random.data", - }, "static_nat": { "startport": 22, "endport": 22, @@ -104,297 +92,6 @@ class Services: } -class TestSnapshots(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super(TestSnapshots, cls).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.services['mode'] = cls.zone.networktype - cls.disk_offering = DiskOffering.create( - cls.api_client, - cls.services["disk_offering"] - ) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["volume"]["zoneid"] = cls.zone.id - - cls.services["template"] = cls.template.id - cls.services["zoneid"] = cls.zone.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( - cls.api_client, - cls.services["virtual_machine"], - templateid=cls.template.id, - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering.id, - mode=cls.services["mode"] - ) - - cls._cleanup = [ - cls.service_offering, - cls.disk_offering, - cls.account, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.cleanup = [] - return - - def tearDown(self): - try: - #Clean up, terminate the created instance, volumes and snapshots - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags = ["advanced", "advancedns"]) - def test_01_volume_from_snapshot(self): - """TS_BUG_001-Test Creating snapshot from volume having spaces in name(KVM) - """ - - - # Validate the following - #1. Create a virtual machine and data volume - #2. Attach data volume to VM - #3. Login to machine; create temp/test directories on data volume - #4. Snapshot the Volume - #5. Create another Volume from snapshot - #6. Mount/Attach volume to another server - #7. Compare data - - random_data_0 = random_gen(100) - random_data_1 = random_gen(100) - - volume = Volume.create( - self.apiclient, - self.services["volume"], - zoneid=self.zone.id, - account=self.account.name, - domainid=self.account.domainid, - diskofferingid=self.disk_offering.id - ) - self.debug("Created volume with ID: %s" % volume.id) - self.virtual_machine.attach_volume( - self.apiclient, - volume - ) - self.debug("Attach volume: %s to VM: %s" % - (volume.id, self.virtual_machine.id)) - try: - ssh_client = self.virtual_machine.get_ssh_client() - except Exception as e: - self.fail("SSH failed for VM: %s" % - self.virtual_machine.ipaddress) - - self.debug("Formatting volume: %s to ext3" % volume.id) - #Format partition using ext3 - format_volume_to_ext3( - ssh_client, - self.services["volume"]["diskdevice"] - ) - cmds = [ - "mkdir -p %s" % self.services["paths"]["mount_dir"], - "mount %s1 %s" % ( - self.services["volume"]["diskdevice"], - self.services["paths"]["mount_dir"] - ), - "mkdir -p %s/%s/{%s,%s} " % ( - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir1"], - self.services["paths"]["sub_lvl_dir2"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_0, - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir1"], - self.services["paths"]["random_data"] - ), - "echo %s > %s/%s/%s/%s" % ( - random_data_1, - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir2"], - self.services["paths"]["random_data"] - ), - ] - for c in cmds: - self.debug("Command: %s" % c) - ssh_client.execute(c) - - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["paths"]["mount_dir"]), - ] - for c in cmds: - self.debug("Command: %s" % c) - ssh_client.execute(c) - - list_volume_response = Volume.list( - self.apiclient, - virtualmachineid=self.virtual_machine.id, - type='DATADISK', - listall=True - ) - - self.assertEqual( - isinstance(list_volume_response, list), - True, - "Check list volume response for valid data" - ) - volume_response = list_volume_response[0] - #Create snapshot from attached volume - snapshot = Snapshot.create( - self.apiclient, - volume_response.id, - account=self.account.name, - domainid=self.account.domainid - ) - self.debug("Created snapshot: %s" % snapshot.id) - #Create volume from snapshot - volume_from_snapshot = Volume.create_from_snapshot( - self.apiclient, - snapshot.id, - self.services["volume"], - account=self.account.name, - domainid=self.account.domainid - ) - self.debug("Created Volume: %s from Snapshot: %s" % ( - volume_from_snapshot.id, - snapshot.id)) - volumes = Volume.list( - self.apiclient, - id=volume_from_snapshot.id - ) - self.assertEqual( - isinstance(volumes, list), - True, - "Check list response returns a valid list" - ) - - self.assertNotEqual( - len(volumes), - None, - "Check Volume list Length" - ) - self.assertEqual( - volumes[0].id, - volume_from_snapshot.id, - "Check Volume in the List Volumes" - ) - #Attaching volume to new VM - new_virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - templateid=self.template.id, - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - mode=self.services["mode"] - ) - self.debug("Deployed new VM for account: %s" % self.account.name) - self.cleanup.append(new_virtual_machine) - - self.debug("Attaching volume: %s to VM: %s" % ( - volume_from_snapshot.id, - new_virtual_machine.id - )) - - cmd = attachVolume.attachVolumeCmd() - cmd.id = volume_from_snapshot.id - cmd.virtualmachineid = new_virtual_machine.id - self.apiclient.attachVolume(cmd) - - try: - #Login to VM to verify test directories and files - ssh = new_virtual_machine.get_ssh_client() - - cmds = [ - "mkdir -p %s" % self.services["paths"]["mount_dir"], - "mount %s1 %s" % ( - self.services["volume"]["diskdevice"], - self.services["paths"]["mount_dir"] - ), - ] - - for c in cmds: - self.debug("Command: %s" % c) - ssh.execute(c) - - returned_data_0 = ssh.execute( - "cat %s/%s/%s/%s" % ( - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir1"], - self.services["paths"]["random_data"] - )) - returned_data_1 = ssh.execute( - "cat %s/%s/%s/%s" % ( - self.services["paths"]["mount_dir"], - self.services["paths"]["sub_dir"], - self.services["paths"]["sub_lvl_dir2"], - self.services["paths"]["random_data"] - )) - except Exception as e: - self.fail("SSH access failed for VM: %s" % - new_virtual_machine.ipaddress) - #Verify returned data - self.assertEqual( - random_data_0, - returned_data_0[0], - "Verify newly attached volume contents with existing one" - ) - self.assertEqual( - random_data_1, - returned_data_1[0], - "Verify newly attached volume contents with existing one" - ) - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["paths"]["mount_dir"]), - ] - for c in cmds: - self.debug("Command: %s" % c) - ssh_client.execute(c) - return - - class TestTemplate(cloudstackTestCase): def setUp(self): diff --git a/test/integration/component/test_custom_hostname.py b/test/integration/component/test_custom_hostname.py index c9db2154a94..e569215980c 100644 --- a/test/integration/component/test_custom_hostname.py +++ b/test/integration/component/test_custom_hostname.py @@ -300,7 +300,7 @@ class TestInstanceNameFlagTrue(cloudstackTestCase): "Running", "Vm state should be running after deployment" ) - self.assertEqual( + self.assertNotEqual( vm.displayname, vm.id, "Vm display name should not match the given name" diff --git a/test/integration/component/test_explicit_dedication.py b/test/integration/component/test_explicit_dedication.py index 21a4904e71b..e1991ac5219 100644 --- a/test/integration/component/test_explicit_dedication.py +++ b/test/integration/component/test_explicit_dedication.py @@ -87,9 +87,6 @@ class Services: "name": "Cent OS Template", "passwordenabled": True, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, "ostype": 'CentOS 5.3 (64-bit)' diff --git a/test/integration/component/test_implicit_planner.py b/test/integration/component/test_implicit_planner.py index ffcd248b462..854b48148c6 100644 --- a/test/integration/component/test_implicit_planner.py +++ b/test/integration/component/test_implicit_planner.py @@ -80,9 +80,6 @@ class Services: "name": "Cent OS Template", "passwordenabled": True, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, #Migrate VM to hostid diff --git a/test/integration/component/test_netscaler_configs.py b/test/integration/component/test_netscaler_configs.py index 3c18c0050fd..5de0843b49b 100644 --- a/test/integration/component/test_netscaler_configs.py +++ b/test/integration/component/test_netscaler_configs.py @@ -104,7 +104,7 @@ class Services: "UserData": 'VirtualRouter', "StaticNat": 'VirtualRouter', }, - "servicecapabilitylist": { + "serviceCapabilityList": { "SourceNat": { "SupportedSourceNatTypes": "peraccount" }, diff --git a/test/integration/component/test_netscaler_lb.py b/test/integration/component/test_netscaler_lb.py index b4e6c30497f..534ffb1cfab 100644 --- a/test/integration/component/test_netscaler_lb.py +++ b/test/integration/component/test_netscaler_lb.py @@ -93,7 +93,7 @@ class Services: "UserData": 'VirtualRouter', "StaticNat": 'VirtualRouter', }, - "servicecapabilitylist": { + "serviceCapabilityList": { "SourceNat": { "SupportedSourceNatTypes": "peraccount" }, @@ -1085,7 +1085,7 @@ class TestAddMultipleVmsLb(cloudstackTestCase): # 3. Acquire Ip address and create LB rule on it. Add multiple VMs to # this rule. LB rule should be # In Netscaler: For every Vm added to the LB rule: - # 1. A server and service instance is created using guest VM’s IP and + # 1. A server and service instance is created using guest VMs IP and # port number on the Netscaler LB device, # 2. This service is bound to lb virtual server corresponding to lb # rule. diff --git a/test/integration/component/test_netscaler_nw_off.py b/test/integration/component/test_netscaler_nw_off.py index cd3b48e5930..256d1be0308 100644 --- a/test/integration/component/test_netscaler_nw_off.py +++ b/test/integration/component/test_netscaler_nw_off.py @@ -117,7 +117,7 @@ class Services: "UserData": 'VirtualRouter', "StaticNat": 'VirtualRouter', }, - "servicecapabilitylist": { + "serviceCapabilityList": { "SourceNat": { "SupportedSourceNatTypes": "peraccount" }, @@ -157,11 +157,10 @@ class Services: "publicport": 22, "openfirewall": False, }, - "ostypeid": '01853327-513e-4508-9628-f1f55db1946f', + "ostype": 'Cent OS 5.3 (64 bit)', # Cent OS 5.3 (64 bit) "sleep": 60, "timeout": 10, - "mode": 'advanced' } diff --git a/test/integration/component/test_redundant_router.py b/test/integration/component/test_redundant_router.py index a87818a4ccb..5f7b1caf32c 100644 --- a/test/integration/component/test_redundant_router.py +++ b/test/integration/component/test_redundant_router.py @@ -15,18 +15,14 @@ # specific language governing permissions and limitations # under the License. -from random import random -import marvin from nose.plugins.attrib import attr from marvin.integration.lib.base import * from marvin.integration.lib.utils import * from marvin.integration.lib.common import * #Import Local Modules -from marvin.cloudstackTestCase import * +from marvin.cloudstackTestCase import cloudstackTestCase from marvin.cloudstackAPI import * -from marvin import remoteSSHClient - class Services: """Test Services for customer defects @@ -65,13 +61,6 @@ class Services: "publicport": 22, "protocol": 'TCP', }, - "volume": { - "diskname": "APP Data Volume", - "size": 1, - # in GBs - "diskdevice": "/dev/xvdb", - # Data Disk - }, "static_nat": { "startport": 22, "endport": 22, @@ -95,10 +84,10 @@ class Services: "UserData": 'VirtualRouter', "StaticNat": 'VirtualRouter', }, - "servicecapabilitylist": { + "serviceCapabilityList": { "SourceNat": { "SupportedSourceNatTypes": "peraccount", - "RedundantRouter": 'true', + "RedundantRouter": "true", }, "lb": { "SupportedLbIsolation": "dedicated" @@ -141,8 +130,6 @@ class Services: }, "ostype": 'CentOS 5.3 (64-bit)', "sleep": 60, - "mode": 'advanced', - # Networking mode, Advanced, Basic } @@ -197,6 +184,7 @@ class TestCreateRvRNetworkOffering(cloudstackTestCase): # Validate the following # 1. Redundant Router offering should be created successfully and # listed in listNetworkOfferings response + # assert if RvR capability is enabled self.debug("Creating network offering with redundant VR capability") try: @@ -229,6 +217,14 @@ class TestCreateRvRNetworkOffering(cloudstackTestCase): 1, "List network off should have newly created network off" ) + for service in network_offs[0].service: + if service.name == 'SourceNat': + self.debug("Verifying SourceNat capabilites") + for capability in service.capability: + if capability.name == 'RedundantRouter': + self.assertTrue(capability.value=='true') + self.debug("RedundantRouter is enabled") + return @@ -288,22 +284,7 @@ class TestCreateRvRNetwork(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -494,27 +475,12 @@ class TestCreateRvRNetworkNonDefaultGuestCidr(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) def test_createRvRNetwork(self): - """Test create network with redundant routers + """Test create network with non-default guest cidr with redundant routers """ # Validate the following: @@ -708,22 +674,7 @@ class TestRVRInternals(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -956,12 +907,12 @@ class TestRVRInternals(cloudstackTestCase): return -class TestRedundancy(cloudstackTestCase): +class TestRvRRedundancy(cloudstackTestCase): @classmethod def setUpClass(cls): cls.api_client = super( - TestRedundancy, + TestRvRRedundancy, cls ).getClsTestClient().getApiClient() cls.services = Services().services @@ -1036,22 +987,7 @@ class TestRedundancy(cloudstackTestCase): networkids=[str(self.network.id)] ) self.debug("Deployed VM in network: %s" % self.network.id) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return @attr(tags=["advanced", "advancedns", "ssh"]) @@ -1107,9 +1043,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Stopping the MASTER router") try: - cmd = stopRouter.stopRouterCmd() - cmd.id = master_router.id - self.apiclient.stopRouter(cmd) + Router.stop(self.apiclient, id=master_router.id) except Exception as e: self.fail("Failed to stop master router: %s" % e) @@ -1151,9 +1085,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Starting the old MASTER router") try: - cmd = startRouter.startRouter(cmd) - cmd.id = master_router.id - self.apiclient.startRouter(cmd) + Router.start(self.apiclient, id=master_router.id) self.debug("old MASTER router started") except Exception as e: self.fail("Failed to stop master router: %s" % e) @@ -1234,9 +1166,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Stopping the BACKUP router") try: - cmd = stopRouter.stopRouterCmd() - cmd.id = backup_router.id - self.apiclient.stopRouter(cmd) + Router.stop(self.apiclient, id=backup_router.id) except Exception as e: self.fail("Failed to stop backup router: %s" % e) @@ -1278,9 +1208,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Starting the old BACKUP router") try: - cmd = startRouter.startRouter(cmd) - cmd.id = backup_router.id - self.apiclient.startRouter(cmd) + Router.start(self.apiclient, id=backup_router.id) self.debug("old BACKUP router started") except Exception as e: self.fail("Failed to stop master router: %s" % e) @@ -1355,9 +1283,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Rebooting the master router") try: - cmd = rebootRouter.rebootRouterCmd() - cmd.id = master_router.id - self.apiclient.rebootRouter(cmd) + Router.reboot(self.apiclient, id=master_router.id) except Exception as e: self.fail("Failed to reboot MASTER router: %s" % e) @@ -1449,9 +1375,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Rebooting the backuo router") try: - cmd = rebootRouter.rebootRouterCmd() - cmd.id = backup_router.id - self.apiclient.rebootRouter(cmd) + Router.reboot(self.apiclient, id=backup_router.id) except Exception as e: self.fail("Failed to reboot BACKUP router: %s" % e) @@ -1543,9 +1467,7 @@ class TestRedundancy(cloudstackTestCase): self.debug("Stopping the backup router") try: - cmd = stopRouter.stopRouterCmd() - cmd.id = backup_router.id - self.apiclient.stopRouter(cmd) + Router.stop(self.apiclient, id=backup_router.id) except Exception as e: self.fail("Failed to stop BACKUP router: %s" % e) @@ -1613,3969 +1535,3 @@ class TestRedundancy(cloudstackTestCase): "Redundant state of the router should be BACKUP" ) return - - -class TestApplyAndDeleteNetworkRulesOnRvR(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestApplyAndDeleteNetworkRulesOnRvR, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_apply_and__delete_NetworkRulesOnRvR(self): - """Test apply and delete network rules on redundant router - """ - - # Steps to validate - # 1. listNetworks should show the created network in allocated state - # 2. listRouters returns no running routers - # 3. VMs should be deployed and in Running state - # 4. should list MASTER and BACKUP routers - # 5. listPublicIpAddresses for networkid should show acquired IP - # 6. listRemoteAccessVpns for the network associated should show the - # VPN created - # 7. listRemoteAccessVpns for the network associated should return - # empty response - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - self.debug("Enabling static NAT for IP: %s" % - public_ip.ipaddress.ipaddress) - try: - static_nat = StaticNATRule.create( - self.apiclient, - self.services["fw_rule"], - ipaddressid=public_ip.ipaddress.id - ) - self.debug("Static NAT enabled for IP: %s" % - public_ip.ipaddress.ipaddress) - static_nat.enable( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - virtualmachineid=virtual_machine.id - ) - except Exception as e: - self.fail("Failed to enable static NAT on IP: %s - %s" % ( - public_ip.ipaddress.ipaddress, e)) - - public_ips = PublicIPAddress.list( - self.apiclient, - networkid=network.id, - listall=True, - isstaticnat=True - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "List public Ip for network should list the Ip addr" - ) - self.assertEqual( - public_ips[0].ipaddress, - public_ip.ipaddress.ipaddress, - "List public Ip for network should list the Ip addr" - ) - - self.debug("creating a FW rule on IP: %s" % - public_ip.ipaddress.ipaddress) - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created a firewall rule on 22 port of IP: %s" % - public_ip.ipaddress.ipaddress) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_2 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_2.ipaddress.ipaddress, - network.id - )) - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_221"], - ipaddressid=public_ip_2.ipaddress.id, - openfirewall=True - ) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_2.ipaddress.ipaddress, - reconnect=True, - port=self.services["natrule_221"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_3 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_3.ipaddress.ipaddress, - network.id - )) - - self.debug("Creating LB rule for IP address: %s" % - public_ip_3.ipaddress.ipaddress) - - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=public_ip_3.ipaddress.id, - accountid=self.account.name, - networkid=network.id - ) - - self.debug("Adding %s to the LB rule %s" % ( - virtual_machine.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine]) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_3.ipaddress.ipaddress, - reconnect=True, - port=self.services["lbrule"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - return - - -class TestEnableVPNOverRvR(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestEnableVPNOverRvR, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_enableVPNOverRvR(self): - """Test redundant router internals - """ - - # Steps to validate - # 1. listNetworks should show the created network in allocated state - # 2. listRouters returns no running routers - # 3. VMs should be deployed and in Running state - # 4. should list MASTER and BACKUP routers - # 5. listPublicIpAddresses for networkid should show acquired IP addr - # 6. listRemoteAccessVpns for the network associated should show VPN - # created - # 7. listRemoteAccessVpns for the network associated should return - # empty response - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - - self.debug("Creating a remote access VPN for account: %s" % - self.account.name) - - try: - vpn = Vpn.create( - self.apiclient, - publicipid=public_ip.ipaddress.id, - account=self.account.name, - domainid=self.account.domainid - ) - except Exception as e: - self.fail("Failed to create VPN for account: %s - %s" % ( - self.account.name, e)) - - try: - vpnuser = VpnUser.create( - self.apiclient, - username="root", - password="password", - account=self.account.name, - domainid=self.account.domainid - ) - except Exception as e: - self.fail("Failed to create VPN user: %s" % e) - - self.debug("Checking if the remote access VPN is created or not?") - remote_vpns = Vpn.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - publicipid=public_ip.ipaddress.id, - listall=True - ) - self.assertEqual( - isinstance(remote_vpns, list), - True, - "List remote VPNs should not return empty response" - ) - self.debug("Deleting the remote access VPN for account: %s" % - self.account.name) - - try: - vpn.delete(self.apiclient) - except Exception as e: - self.fail("Failed to delete VPN : %s" % e) - - self.debug("Checking if the remote access VPN is created or not?") - remote_vpns = Vpn.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - publicipid=public_ip.ipaddress.id, - listall=True - ) - self.assertEqual( - remote_vpns, - None, - "List remote VPNs should not return empty response" - ) - return - - -class TestNetworkRulesMasterDownDeleteNetworkRules(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestNetworkRulesMasterDownDeleteNetworkRules, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_applyNetworkRules_MasterDown_deleteNetworkRules(self): - """Test apply network rules when master down and delete network rules - """ - - # Steps to validate - # 1. listNetworks should show the created network in allocated state - # 2. listRouters returns no running routers - # 3. VMs should be deployed and in Running state - # 4. should list MASTER and BACKUP routers - # 5. listPublicIpAddresses for networkid should show acquired IP addr - # 6. listStaticNats for the network associated - # 7. listFirewallRules should show allowed ports open - # 8. ssh to succeed to the guestVM - # 9. listPublicIpAddresses for networkid should show acquired IP addr - # 10. listPortForwardRules to show open ports 221, 222 - # 11. ssh should succeed for both ports - # 12. listPublicIpAddresses for networkid should show acquired IP addr - # 13 and 14. listLoadBalancerRules should show associated VMs for - # public IP - # 15. ssh should succeed to the user VMs - # 16. listRouters should show one Router in MASTER state and Running - # 17. ssh should work for PF, FW, and LB ips - # 18. listRouters should show both routers MASTER and BACKUP in - # Running state - # 19. listPortForwardingRules, listFirewallRules, listLoadBalancerRule - # should return empty response - # 20. listPublicIpAddresses should show now more addresses - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - - self.debug("Stopping router ID: %s" % master_router.id) - - try: - #Stop the router - cmd = stopRouter.stopRouterCmd() - cmd.id = master_router.id - self.apiclient.stopRouter(cmd) - except Exception as e: - self.fail("Failed to stop master router..") - - self.debug("Associating public IP for network: %s" % network.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - self.debug("Enabling static NAT for IP: %s" % - public_ip.ipaddress.ipaddress) - try: - static_nat = StaticNATRule.create( - self.apiclient, - self.services["fw_rule"], - ipaddressid=public_ip.ipaddress.id - ) - static_nat.enable( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - virtualmachineid=virtual_machine.id - ) - self.debug("Static NAT enabled for IP: %s" % - public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("Failed to enable static NAT on IP: %s - %s" % ( - public_ip.ipaddress.ipaddress, e)) - - public_ips = PublicIPAddress.list( - self.apiclient, - networkid=network.id, - listall=True, - isstaticnat=True - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "List public Ip for network should list the Ip addr" - ) - self.assertEqual( - public_ips[0].ipaddress, - public_ip.ipaddress.ipaddress, - "List public Ip for network should list the Ip addr" - ) - - self.debug("creating a FW rule on IP: %s" % - public_ip.ipaddress.ipaddress) - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created a firewall rule on 22 port of IP: %s" % - public_ip.ipaddress.ipaddress) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_2 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_2.ipaddress.ipaddress, - network.id - )) - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_221"], - ipaddressid=public_ip_2.ipaddress.id, - openfirewall=True - ) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_2.ipaddress.ipaddress, - reconnect=True, - port=self.services["natrule_221"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_3 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_3.ipaddress.ipaddress, - network.id - )) - - self.debug("Creating LB rule for IP address: %s" % - public_ip_3.ipaddress.ipaddress) - - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=public_ip_3.ipaddress.id, - accountid=self.account.name, - networkid=network.id - ) - - self.debug("Adding %s to the LB rule %s" % ( - virtual_machine.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine]) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_3.ipaddress.ipaddress, - reconnect=True, - port=self.services["lbrule"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Starting router ID: %s" % master_router.id) - - try: - #Stop the router - cmd = startRouter.startRouterCmd() - cmd.id = master_router.id - self.apiclient.startRouter(cmd) - except Exception as e: - self.fail("Failed to start master router..") - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - return - - -class TestApplyDeleteNetworkRulesRebootRouter(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestApplyDeleteNetworkRulesRebootRouter, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_applyNetworkRules_MasterDown_deleteNetworkRules(self): - """Test apply network rules when master & backup routers rebooted - """ - - # Steps to validate - # 1. listNetworks should show the created network in allocated state - # 2. listRouters returns no running routers - # 3. VMs should be deployed and in Running state - # 4. should list MASTER and BACKUP routers - # 5. listPublicIpAddresses for networkid should show acquired IP addr - # 6. listStaticNats for the network associated - # 7. listFirewallRules should show allowed ports open - # 8. ssh to succeed to the guestVM - # 9. listPublicIpAddresses for networkid should show acquired IP addr - # 10. listPortForwardRules to show open ports 221, 222 - # 11. ssh should succeed for both ports - # 12. listPublicIpAddresses for networkid should show acquired IP addr - # 13 and 14. listLoadBalancerRules should show associated VMs for - # public IP - # 15. ssh should succeed to the user VMs - # 16. listRouters should show one Router in MASTER state and Running - # 17. ssh should work for PF, FW, and LB ips - # 18. listRouters should show both routers MASTER and BACKUP in - # Running state - # 19. listPortForwardingRules, listFirewallRules, listLoadBalancerRule - # should return empty response - # 20. listPublicIpAddresses should show now more addresses - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - - self.debug("Associating public IP for network: %s" % network.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - self.debug("Enabling static NAT for IP: %s" % - public_ip.ipaddress.ipaddress) - try: - static_nat = StaticNATRule.create( - self.apiclient, - self.services["fw_rule"], - ipaddressid=public_ip.ipaddress.id - ) - static_nat.enable( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - virtualmachineid=virtual_machine.id - ) - self.debug("Static NAT enabled for IP: %s" % - public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("Failed to enable static NAT on IP: %s - %s" % ( - public_ip.ipaddress.ipaddress, e)) - - public_ips = PublicIPAddress.list( - self.apiclient, - networkid=network.id, - listall=True, - isstaticnat=True - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "List public Ip for network should list the Ip addr" - ) - self.assertEqual( - public_ips[0].ipaddress, - public_ip.ipaddress.ipaddress, - "List public Ip for network should list the Ip addr" - ) - - self.debug("creating a FW rule on IP: %s" % - public_ip.ipaddress.ipaddress) - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created a firewall rule on 22 port of IP: %s" % - public_ip.ipaddress.ipaddress) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_2 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_2.ipaddress.ipaddress, - network.id - )) - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_221"], - ipaddressid=public_ip_2.ipaddress.id, - openfirewall=True - ) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_3 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_3.ipaddress.ipaddress, - network.id - )) - - self.debug("Creating LB rule for IP address: %s" % - public_ip_3.ipaddress.ipaddress) - - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=public_ip_3.ipaddress.id, - accountid=self.account.name, - networkid=network.id - ) - - self.debug("Adding %s to the LB rule %s" % ( - virtual_machine.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine]) - - self.debug("Starting router ID: %s" % master_router.id) - - for router in routers: - try: - self.debug("Rebooting router ID: %s" % master_router.id) - #Stop the router - cmd = rebootRouter.rebootRouterCmd() - cmd.id = router.id - self.apiclient.rebootRouter(cmd) - except Exception as e: - self.fail("Failed to reboot router..") - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_2.ipaddress.ipaddress, - reconnect=True, - port=self.services["natrule_221"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_3.ipaddress.ipaddress, - reconnect=True, - port=self.services["lbrule"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - return - - -class TestRestartRvRNetworkWithoutCleanup(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestRestartRvRNetworkWithoutCleanup, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_restartRvRNetwork_withoutCleanup(self): - """Test apply rules after network restart - """ - - # Steps to validate - # 1. createNetwork using network offering for redundant virtual router - # 2. listRouters in above network - # 3. deployVM in above user account in the created network - # 4. restartNetwork cleanup=false - # 5. listRouters in the account - # 6. delete the account - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - - self.debug("restarting network with cleanup=False") - try: - network.restart(self.apiclient, cleanup=False) - except Exception as e: - self.fail("Failed to cleanup network - %s" % e) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - self.assertIn( - router.linklocalip, - [master_router.linklocalip, backup_router.linklocalip], - "Routers should have same linklocal IP after nw restart" - ) - return - - -class TestRestartRvRNetworkWithCleanup(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestRestartRvRNetworkWithCleanup, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_restartRvRNetwork_withCleanup(self): - """Test Restart network with cleanup - """ - - # Steps to validate - # 1. createNetwork using network offering for redundant virtual router - # 2. listRouters in above network - # 3. deployVM in above user account in the created network - # 4. restartNetwork cleanup=false - # 5. listRouters in the account - # 6. delete the account - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - - self.debug("restarting network with cleanup=True") - try: - network.restart(self.apiclient, cleanup=True) - except Exception as e: - self.fail("Failed to cleanup network - %s" % e) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - self.assertIn( - router.linklocalip, - [master_router.linklocalip, backup_router.linklocalip], - "Routers should have same linklocal IP after nw restart" - ) - return - - -class TestDeleteRvRNetwork(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestDeleteRvRNetwork, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_restartRvRNetwork_withCleanup(self): - """Test Restart network with cleanup - """ - - # Steps to validate - # 1. createNetwork using network offering for redundant virtual router - # 2. listRouters in above network - # 3. deployVM in above user account in the created network - # 4. restartNetwork cleanup=false - # 5. listRouters in the account - # 6. delete the account - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - self.debug("Trying to delete the network with running Vms") - with self.assertRaises(Exception): - network.delete(self.apiclient, cleanup=True) - - self.debug("Network delete failed!") - self.debug("Destroying the user VMs for account: %s" % - self.account.name) - - try: - virtual_machine.delete(self.apiclient) - except Exception as e: - self.fail("Failed to delete guest Vm from account: %s - %s" % - (self.account.name, e)) - - interval = list_configurations( - self.apiclient, - name='expunge.delay' - ) - delay = int(interval[0].value) - interval = list_configurations( - self.apiclient, - name='expunge.interval' - ) - exp = int(interval[0].value) - - self.debug("Sleeping for exp delay + interval time") - # Sleep to ensure that all resources are deleted - time.sleep((delay + exp) * 2) - - self.debug("Trying to delete guest network for account: %s" % - self.account.name) - try: - network.delete(self.apiclient) - except Exception as e: - self.fail("Failed to delete network: %s" % e) - return - - -class TestNetworkGCRvR(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestNetworkGCRvR, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_networkGC_RvR(self): - """Test network garbage collection with RVR - """ - - # Steps to validate - # 1. createNetwork using network offering for redundant virtual router - # 2. listRouters in above network - # 3. deployVM in above user account in the created network - # 4. stop the running user VM - # 5. wait for network.gc time - # 6. listRouters - # 7. start the routers MASTER and BACK - # 8. wait for network.gc time and listRouters - # 9. delete the account - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - self.debug("Stopping the user VM: %s" % virtual_machine.name) - - try: - virtual_machine.stop(self.apiclient) - except Exception as e: - self.fail("Failed to stop guest Vm: %s - %s" % - (virtual_machine.name, e)) - - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - delay = int(interval[0].value) - interval = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - exp = int(interval[0].value) - - self.debug("Sleeping for network gc wait + interval time") - # Sleep to ensure that all resources are deleted - time.sleep((delay + exp) * 2) - - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - for router in routers: - self.assertEqual( - router.state, - "Stopped", - "Router should be in stopped state" - ) - self.debug("Starting the stopped router again") - cmd = startRouter.startRouterCmd() - cmd.id = router.id - self.apiclient.startRouter(cmd) - - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router should be in running state" - ) - - self.debug("Sleeping for network gc wait + interval time") - # Sleep to ensure that all resources are deleted - time.sleep((delay + exp) * 2) - - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - for router in routers: - self.assertEqual( - router.state, - "Stopped", - "Router should be in stopped state" - ) - return - - -class TestApplyRulesRestartRvRNetwork(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestApplyRulesRestartRvRNetwork, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_applyRules_restartRvRNetwork(self): - """Test apply rules after network restart - """ - - # Steps to validate - # 1. listNetworks should show the created network in allocated state - # 2. listRouters returns no running routers - # 3. VMs should be deployed and in Running state - # 4. should list MASTER and BACKUP routers - # 5. listPublicIpAddresses for networkid should show acquired IP addr - # 6. listStaticNats for the network associated - # 7. listFirewallRules should show allowed ports open - # 8. ssh to succeed to the guestVM - # 9. listPublicIpAddresses for networkid should show acquired IP addr - # 10. listPortForwardRules to show open ports 221, 222 - # 11. ssh should succeed for both ports - # 12. listPublicIpAddresses for networkid should show acquired IP addr - # 13 and 14. listLoadBalancerRules should show associated VMs for - # public IP - # 15. ssh should succeed to the user VMs - # 16. listRouters should show one Router in MASTER state and Running & - # one in BACKUP and Running - # 17. ssh should work for PF, FW, and LB ips - # 18. listRouters should show one Router in MASTER state and Running & - # one in BACKUP and Running - # 19. ssh should work for PF, FW, and LB ips - # 20. listPortForwardingRules, listFirewallRules, listLoadBalancerRule - # should return empty response - # 21. listPublicIpAddresses should show now more addresses - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - if routers[0].redundantstate == 'MASTER': - master_router = routers[0] - backup_router = routers[1] - else: - master_router = routers[1] - backup_router = routers[0] - - self.debug("Associating public IP for network: %s" % network.name) - public_ip = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip.ipaddress.ipaddress, - network.id - )) - self.debug("Enabling static NAT for IP: %s" % - public_ip.ipaddress.ipaddress) - try: - static_nat = StaticNATRule.create( - self.apiclient, - self.services["fw_rule"], - ipaddressid=public_ip.ipaddress.id - ) - static_nat.enable( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - virtualmachineid=virtual_machine.id - ) - self.debug("Static NAT enabled for IP: %s" % - public_ip.ipaddress.ipaddress) - except Exception as e: - self.fail("Failed to enable static NAT on IP: %s - %s" % ( - public_ip.ipaddress.ipaddress, e)) - - public_ips = PublicIPAddress.list( - self.apiclient, - networkid=network.id, - listall=True, - isstaticnat=True - ) - self.assertEqual( - isinstance(public_ips, list), - True, - "List public Ip for network should list the Ip addr" - ) - self.assertEqual( - public_ips[0].ipaddress, - public_ip.ipaddress.ipaddress, - "List public Ip for network should list the Ip addr" - ) - - self.debug("creating a FW rule on IP: %s" % - public_ip.ipaddress.ipaddress) - fw_rule = FireWallRule.create( - self.apiclient, - ipaddressid=public_ip.ipaddress.id, - protocol='TCP', - cidrlist=[self.services["fw_rule"]["cidr"]], - startport=self.services["fw_rule"]["startport"], - endport=self.services["fw_rule"]["endport"] - ) - self.debug("Created a firewall rule on 22 port of IP: %s" % - public_ip.ipaddress.ipaddress) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_2 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_2.ipaddress.ipaddress, - network.id - )) - - nat_rule = NATRule.create( - self.apiclient, - virtual_machine, - self.services["natrule_221"], - ipaddressid=public_ip_2.ipaddress.id, - openfirewall=True - ) - - self.debug("Associating public IP for network: %s" % network.name) - public_ip_3 = PublicIPAddress.create( - self.apiclient, - accountid=self.account.name, - zoneid=self.zone.id, - domainid=self.account.domainid, - networkid=network.id - ) - self.debug("Associated %s with network %s" % ( - public_ip_3.ipaddress.ipaddress, - network.id - )) - - self.debug("Creating LB rule for IP address: %s" % - public_ip_3.ipaddress.ipaddress) - - lb_rule = LoadBalancerRule.create( - self.apiclient, - self.services["lbrule"], - ipaddressid=public_ip_3.ipaddress.id, - accountid=self.account.name, - networkid=network.id - ) - - self.debug("Adding %s to the LB rule %s" % ( - virtual_machine.name, - lb_rule.name - )) - lb_rule.assign(self.apiclient, [virtual_machine]) - - self.debug("Restarting network ID: %s with cleanup true" % - network.id) - - try: - network.restart(self.apiclient, cleanup=True) - except Exception as e: - self.fail("Failed to cleanup network") - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_2.ipaddress.ipaddress, - reconnect=True, - port=self.services["natrule_221"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_3.ipaddress.ipaddress, - reconnect=True, - port=self.services["lbrule"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Restarting network ID: %s with cleanup false" % - network.id) - - try: - network.restart(self.apiclient, cleanup=False) - except Exception as e: - self.fail("Failed to cleanup network") - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - for router in routers: - self.assertEqual( - router.state, - "Running", - "Router state should be running" - ) - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip.ipaddress.ipaddress) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_2.ipaddress.ipaddress, - reconnect=True, - port=self.services["natrule_221"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - - self.debug("Trying to SSH into the virtual machine") - try: - virtual_machine.get_ssh_client( - ipaddress=public_ip_3.ipaddress.ipaddress, - reconnect=True, - port=self.services["lbrule"]["publicport"] - ) - self.debug("SSH to guest VM succeeded") - except Exception as e: - self.fail("SSH to guest VM failed: %s" % e) - return - - -class TestUpgradeDowngradeRVR(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestUpgradeDowngradeRVR, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_upgradeVR_to_redundantVR(self): - """Test upgrade virtual router to redundant virtual router - """ - - # Steps to validate - # 1. create a network with DefaultNetworkOfferingWithSourceNATservice - # (all VR based services) - # 2. deploy a VM in the above network and listRouters - # 3. create a network Offering that has redundant router enabled and - # all VR based services - # 4. updateNetwork created above to the offfering in 3. - # 5. listRouters in the network - # 6. delete account in which resources are created - # Validate the following - # 1. listNetworks should show the created network in allocated state - # 2. VM should be deployed and in Running state and there should be - # one Router running for this network - # 3. listNetworkOfferings should show craeted offering for RvR - # 4. listNetworks shows the network still successfully implemented - # 5. listRouters shows two routers Up and Running (MASTER and BACKUP) - - network_offerings = NetworkOffering.list( - self.apiclient, - name='DefaultIsolatedNetworkOfferingWithSourceNatService', - listall=True - ) - self.assertEqual( - isinstance(network_offerings, list), - True, - "List network offering should not return empty response" - ) - - network_off_vr = network_offerings[0] - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - network_off_vr.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=network_off_vr.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in the account: %s" % - self.account.name) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for account: %s" % - self.account.name) - routers = Router.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return only one router" - ) - self.assertEqual( - len(routers), - 1, - "Length of the list router should be 1" - ) - - self.debug("Upgrading the network to RVR network offering..") - try: - network.update( - self.apiclient, - networkofferingid=self.network_offering.id - ) - except Exception as e: - self.fail("Failed to upgrade the network from VR to RVR: %s" % e) - - self.debug("Listing routers for account: %s" % - self.account.name) - routers = Router.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return two routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (MASTER & BACKUP)" - ) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_downgradeRvR_to_VR(self): - """Test downgrade redundant virtual router to virtual router - """ - - # Steps to validate - # 1. create a network Offering that has redundant router enabled and - # all VR based services - # 2. create a network with above offering - # 3. deploy a VM in the above network and listRouters - # 4. create a network Offering that has redundant router disabled and - # all VR based services - # 5. updateNetwork - downgrade - created above to the offfering in 4. - # 6. listRouters in the network - # 7. delete account in which resources are created - # Validate the following - # 1. listNetworkOfferings should show craeted offering for RvR - # 2. listNetworks should show the created network in allocated state - # 3. VM should be deployed and in Running state and there should be - # two routers (MASTER and BACKUP) for this network - # 4. listNetworkOfferings should show craeted offering for VR - # 5. listNetworks shows the network still successfully implemented - # 6. listRouters shows only one router for this network in Running - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in the account: %s" % - self.account.name) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for account: %s" % - self.account.name) - routers = Router.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return two routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (MASTER & BACKUP)" - ) - - network_offerings = NetworkOffering.list( - self.apiclient, - name='DefaultIsolatedNetworkOfferingWithSourceNatService', - listall=True - ) - self.assertEqual( - isinstance(network_offerings, list), - True, - "List network offering should not return empty response" - ) - - network_off_vr = network_offerings[0] - - self.debug("Upgrading the network to RVR network offering..") - try: - network.update( - self.apiclient, - networkofferingid=network_off_vr.id - ) - except Exception as e: - self.fail("Failed to upgrade the network from VR to RVR: %s" % e) - - self.debug("Listing routers for account: %s" % - self.account.name) - routers = Router.list( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return only one router" - ) - self.assertEqual( - len(routers), - 1, - "Length of the list router should be 1" - ) - return - - -class TestRVRWithDiffEnvs(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestRVRWithDiffEnvs, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - # Enable Network offering - cls.network_offering.update(cls.api_client, state='Enabled') - - cls._cleanup = [ - cls.service_offering, - cls.network_offering, - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [] - return - - def tearDown(self): - try: - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='account.cleanup.interval' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) * 2) - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_RvR_multipods(self): - """Test RvR with muti pods - """ - - # Steps to validate - # 0. listPods should have at least 2 pods - # 1. create a network offering for redundant router - # 2. create a network out of this offering - # 3. deploy a VM in this network - # 4. listRouters - # 5. delete the account - # Validate the following - # 1. listNetworkOfferings should show created offering for RvR - # 2. listNetworks should show the created network in allocated state - # 3. VM should be deployed and in Running state - # 4. There should be two routers (MASTER and BACKUP) for this network - # ensure both routers should be on different pods - - self.debug("Checking if the current zone has 2 active pods in it..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Enabled" - ) - self.assertEqual( - isinstance(pods, list), - True, - "List pods should not return an empty response" - ) - - if len(pods) < 2: - raise unittest.SkipTest("The env don't have 2 pods req for test") - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - self.assertNotEqual( - routers[0].podid, - routers[1].podid, - "Both the routers should be in different pods" - ) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_RvR_multicluster(self): - """Test RvR with muti clusters - """ - - # Steps to validate - # 0. listClusters should have at least two clusters (if there are - # multiple pods, disable all except one with two clusters) - # 1. create a network offering for redundant router - # 2. create a network out of this offering - # 3. deploy a VM in this network on a host in either of clusters - # found in 0. (specify hostid for deployment) - # 4. listRouters - # 5. delete the account - # 6. enable all disabled pods - # Validate the following - # 1. listNetworkOfferings should show created offering for RvR - # 2. listNetworks should show the created network in allocated state - # 3. VM should be deployed and in Running state - # 4. There should be two routers (MASTER and BACKUP) for this network - # ensure both routers should be on different pods - - self.debug("Checking if the current zone has 2 active pods in it..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Enabled" - ) - self.assertEqual( - isinstance(pods, list), - True, - "List pods should not return an empty response" - ) - enabled_pod = pods[0] - - self.debug("Cheking if pod has atleast 2 clusters") - clusters = Cluster.list( - self.apiclient, - podid=enabled_pod.id, - listall=True - ) - self.assertEqual( - isinstance(clusters, list), - True, - "List clusters should not return empty response" - ) - if len(clusters) < 2: - raise unittest.SkipTest( - "The env don't have 2 clusters req for test") - - self.debug("disable all pods except one!") - if len(pods) > 1: - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Disabled' - self.apiclient.updatePod(cmd) - - self.debug("Warning: Disabled all pods in zone") - - cmd = updatePod.updatePodCmd() - cmd.id = pods[0].id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - self.debug("Enabled first pod for testing..") - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - - hosts = Host.list( - self.apiclient, - id=routers[0].hostid, - listall=True - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List host should return a valid data" - ) - first_host = hosts[0] - - hosts = Host.list( - self.apiclient, - id=routers[1].hostid, - listall=True - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List host should return a valid data" - ) - second_host = hosts[0] - - # Checking if the cluster IDs of both routers are different? - self.assertNotEqual( - first_host.clusterid, - second_host.clusterid, - "Both the routers should be in different clusters" - ) - self.debug("Enabling remaining pods if any..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Disabled" - ) - - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_RvR_multiprimarystorage(self): - """Test RvR with muti primary storage - """ - - # Steps to validate - # 0. listStoragePools should have atleast two pools in a single - # cluster (disable pods/clusters as necessary) - # 1. create a network offering for redundant router - # 2. create a network out of this offering - # 3. deploy a VM in this network on a host in the cluster from 0 - # (specify hostid for deployment) - # 4. listRouters - # 5. delete the account - # 6. enable the clusters and pods - # Validate the following - # 1. listNetworkOfferings should show created offering for RvR - # 2. listNetworks should show the created network in allocated state - # 3. VM should be deployed and in Running state and on the specified - # host - # 4. There should be two routers (MASTER and BACKUP) for this network - # ensure both routers should be on different storage pools - - self.debug( - "Checking if the current zone has multiple active pods in it..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Enabled" - ) - self.assertEqual( - isinstance(pods, list), - True, - "List pods should not return an empty response" - ) - - enabled_pod = pods[0] - self.debug("Cheking if pod has multiple clusters") - clusters = Cluster.list( - self.apiclient, - podid=enabled_pod.id, - listall=True - ) - self.assertEqual( - isinstance(clusters, list), - True, - "List clusters should not return empty response" - ) - - enabled_cluster = clusters[0] - - self.debug("Cheking if cluster has multiple storage pools") - storage_pools = StoragePool.list( - self.apiclient, - clusterid=enabled_cluster.id, - listall=True - ) - self.assertEqual( - isinstance(storage_pools, list), - True, - "List storage pools should not return empty response" - ) - - if len(storage_pools) < 2: - raise unittest.SkipTest( - "The env don't have 2 storage pools req for test") - - self.debug("disable all pods except one!") - if len(pods) > 1: - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Disabled' - self.apiclient.updatePod(cmd) - - self.debug("Warning: Disabled all pods in zone") - - cmd = updatePod.updatePodCmd() - cmd.id = pods[0].id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - self.debug("Enabled first pod for testing..") - - self.debug("disable all clusters except one!") - if len(pods) > 1: - for cluster in clusters: - cmd = updateCluster.updateClusterCmd() - cmd.id = cluster.id - cmd.allocationstate = 'Disabled' - self.apiclient.updateCluster(cmd) - - self.debug("Warning: Disabled all pods in zone") - - cmd = updateCluster.updateClusterCmd() - cmd.id = clusters[0].id - cmd.allocationstate = 'Enabled' - self.apiclient.updateCluster(cmd) - self.debug("Enabled first cluster for testing..") - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Retrieving the list of hosts in the cluster") - hosts = Host.list( - self.apiclient, - clusterid=enabled_cluster.id, - listall=True - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List hosts should not return an empty response" - ) - host = hosts[0] - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)], - hostid=host.id - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - self.assertNotEqual( - routers[0].hostid, - routers[1].hostid, - "Both the routers should be in different storage pools" - ) - self.debug("Enabling remaining pods if any..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Disabled" - ) - self.assertEqual( - isinstance(pods, list), - True, - "List pods should not return an empty response" - ) - - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - - clusters = Cluster.list( - self.apiclient, - allocationstate="Disabled", - podid=enabled_pod.id, - listall=True - ) - - for cluster in clusters: - cmd = updateCluster.updateClusterCmd() - cmd.id = cluster.id - cmd.allocationstate = 'Enabled' - self.apiclient.updateCluster(cmd) - return - - @attr(tags=["advanced", "advancedns", "ssh"]) - def test_RvR_multihosts(self): - """Test RvR with muti hosts - """ - - # Steps to validate - # 0. listHosts should have atleast two hosts in a single cluster - # (disable pods/clusters as necessary) - # 1. create a network offering for redundant router - # 2. create a network out of this offering - # 3. deploy a VM in this network on a host in the cluster from 0 - # (specify hostid for deployment) - # 4. listRouters - # 5. delete the account - # 6. enable the clusters and pods - # Validate the following - # 1. listNetworkOfferings should show created offering for RvR - # 2. listNetworks should show the created network in allocated state - # 3. VM should be deployed and in Running state and on specified host - # 4. There should be two routers (MASTER and BACKUP) for this network - # ensure both routers should be on different hosts - - self.debug( - "Checking if the current zone has multiple active pods in it..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Enabled" - ) - self.assertEqual( - isinstance(pods, list), - True, - "List pods should not return an empty response" - ) - - enabled_pod = pods[0] - self.debug("Cheking if pod has multiple clusters") - clusters = Cluster.list( - self.apiclient, - podid=enabled_pod.id, - listall=True - ) - self.assertEqual( - isinstance(clusters, list), - True, - "List clusters should not return empty response" - ) - - enabled_cluster = clusters[0] - - self.debug("Cheking if cluster has multiple hosts") - hosts = Host.list( - self.apiclient, - clusterid=enabled_cluster.id, - listall=True - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List hosts should not return empty response" - ) - - if len(hosts) < 2: - raise unittest.SkipTest( - "The env don't have 2 hosts req for test") - - self.debug("disable all pods except one!") - if len(pods) > 1: - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Disabled' - self.apiclient.updatePod(cmd) - - self.debug("Warning: Disabled all pods in zone") - - cmd = updatePod.updatePodCmd() - cmd.id = pods[0].id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - self.debug("Enabled first pod for testing..") - - self.debug("disable all clusters except one!") - if len(pods) > 1: - for cluster in clusters: - cmd = updateCluster.updateClusterCmd() - cmd.id = cluster.id - cmd.allocationstate = 'Disabled' - self.apiclient.updateCluster(cmd) - - self.debug("Warning: Disabled all pods in zone") - - cmd = updateCluster.updateClusterCmd() - cmd.id = clusters[0].id - cmd.allocationstate = 'Enabled' - self.apiclient.updateCluster(cmd) - self.debug("Enabled first cluster for testing..") - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id - ) - self.debug("Created network with ID: %s" % network.id) - - networks = Network.list( - self.apiclient, - id=network.id, - listall=True - ) - self.assertEqual( - isinstance(networks, list), - True, - "List networks should return a valid response for created network" - ) - nw_response = networks[0] - - self.debug("Network state: %s" % nw_response.state) - self.assertEqual( - nw_response.state, - "Allocated", - "The network should be in allocated state after creation" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - routers, - None, - "Routers should not be spawned when network is in allocated state" - ) - - self.debug("Retrieving the list of hosts in the cluster") - hosts = Host.list( - self.apiclient, - clusterid=enabled_cluster.id, - listall=True - ) - self.assertEqual( - isinstance(hosts, list), - True, - "List hosts should not return an empty response" - ) - host = hosts[0] - - self.debug("Deploying VM in account: %s" % self.account.name) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)], - hostid=host.id - ) - self.debug("Deployed VM in network: %s" % network.id) - - vms = VirtualMachine.list( - self.apiclient, - id=virtual_machine.id, - listall=True - ) - self.assertEqual( - isinstance(vms, list), - True, - "List Vms should return a valid list" - ) - vm = vms[0] - self.assertEqual( - vm.state, - "Running", - "Vm should be in running state after deployment" - ) - - self.debug("Listing routers for network: %s" % network.name) - routers = Router.list( - self.apiclient, - networkid=network.id, - listall=True - ) - self.assertEqual( - isinstance(routers, list), - True, - "list router should return Master and backup routers" - ) - self.assertEqual( - len(routers), - 2, - "Length of the list router should be 2 (Backup & master)" - ) - self.assertNotEqual( - routers[0].hostid, - routers[1].hostid, - "Both the routers should be in different hosts" - ) - self.debug("Enabling remaining pods if any..") - pods = Pod.list( - self.apiclient, - zoneid=self.zone.id, - listall=True, - allocationstate="Disabled" - ) - - if pods is not None: - for pod in pods: - cmd = updatePod.updatePodCmd() - cmd.id = pod.id - cmd.allocationstate = 'Enabled' - self.apiclient.updatePod(cmd) - - clusters = Cluster.list( - self.apiclient, - allocationstate="Disabled", - podid=enabled_pod.id, - listall=True - ) - if clusters is not None: - for cluster in clusters: - cmd = updateCluster.updateClusterCmd() - cmd.id = cluster.id - cmd.allocationstate = 'Enabled' - self.apiclient.updateCluster(cmd) - return diff --git a/test/integration/component/test_redundant_router_cleanups.py b/test/integration/component/test_redundant_router_cleanups.py new file mode 100644 index 00000000000..694db862876 --- /dev/null +++ b/test/integration/component/test_redundant_router_cleanups.py @@ -0,0 +1,675 @@ +# 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. + +from nose.plugins.attrib import attr +from marvin.integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.common import * + +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * + +class Services: + """Test Services for customer defects + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "static_nat": { + "startport": 22, + "endport": 22, + "protocol": "TCP" + }, + "network_offering": { + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true", + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "host": { + "username": "root", + "password": "password", + "publicport": 22, + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 22, + "openfirewall": True, + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + }, + "natrule_221": { + "privateport": 22, + "publicport": 221, + "protocol": "TCP" + }, + "fw_rule": { + "startport": 1, + "endport": 6000, + "cidr": '55.55.0.0/11', + # Any network (For creating FW rule) + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + } + + +class TestRedundantRouterNetworkCleanups(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestRedundantRouterNetworkCleanups, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self._cleanup.insert(0, self.account) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_restart_ntwk_no_cleanup(self): + """Test restarting RvR network without cleanup + """ + + # Steps to validate + # 1. createNetwork using network offering for redundant virtual router + # 2. listRouters in above network + # 3. deployVM in above user account in the created network + # 4. restartNetwork cleanup=false + # 5. listRouters in the account + # 6. delete the account + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + if routers[0].redundantstate == 'MASTER': + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("restarting network with cleanup=False") + try: + network.restart(self.apiclient, cleanup=False) + except Exception as e: + self.fail("Failed to cleanup network - %s" % e) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + self.assertIn( + router.linklocalip, + [master_router.linklocalip, backup_router.linklocalip], + "Routers should have same linklocal IP after nw restart" + ) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_restart_ntwk_with_cleanup(self): + """Test restart RvR network with cleanup + """ + + # Steps to validate + # 1. createNetwork using network offering for redundant virtual router + # 2. listRouters in above network + # 3. deployVM in above user account in the created network + # 4. restartNetwork cleanup=false + # 5. listRouters in the account + # 6. delete the account + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + if routers[0].redundantstate == 'MASTER': + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("restarting network with cleanup=True") + try: + network.restart(self.apiclient, cleanup=True) + except Exception as e: + self.fail("Failed to cleanup network - %s" % e) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + self.assertIn( + router.linklocalip, + [master_router.linklocalip, backup_router.linklocalip], + "Routers should have same linklocal IP after nw restart" + ) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_network_gc(self): + """Test network garbage collection with RVR + """ + + # Steps to validate + # 1. createNetwork using network offering for redundant virtual router + # 2. listRouters in above network + # 3. deployVM in above user account in the created network + # 4. stop the running user VM + # 5. wait for network.gc time + # 6. listRouters + # 7. start the routers MASTER and BACK + # 8. wait for network.gc time and listRouters + # 9. delete the account + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + self.debug("Stopping the user VM: %s" % virtual_machine.name) + + try: + virtual_machine.stop(self.apiclient) + except Exception as e: + self.fail("Failed to stop guest Vm: %s - %s" % + (virtual_machine.name, e)) + + interval = list_configurations( + self.apiclient, + name='network.gc.interval' + ) + delay = int(interval[0].value) + interval = list_configurations( + self.apiclient, + name='network.gc.wait' + ) + exp = int(interval[0].value) + + self.debug("Sleeping for network gc wait + interval time") + # Sleep to ensure that all resources are deleted + time.sleep((delay + exp) * 2) + + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + for router in routers: + self.assertEqual( + router.state, + "Stopped", + "Router should be in stopped state" + ) + self.debug("Starting the stopped router again") + cmd = startRouter.startRouterCmd() + cmd.id = router.id + self.apiclient.startRouter(cmd) + + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router should be in running state" + ) + + self.debug("Sleeping for network gc wait + interval time") + # Sleep to ensure that all resources are deleted + time.sleep((delay + exp) * 2) + + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + for router in routers: + self.assertEqual( + router.state, + "Stopped", + "Router should be in stopped state" + ) + return \ No newline at end of file diff --git a/test/integration/component/test_redundant_router_deployment_planning.py b/test/integration/component/test_redundant_router_deployment_planning.py new file mode 100644 index 00000000000..5f0679420ff --- /dev/null +++ b/test/integration/component/test_redundant_router_deployment_planning.py @@ -0,0 +1,1006 @@ +# 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. + +from nose.plugins.attrib import attr +from marvin.integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.common import * + +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * + +class Services: + """Test Services for customer defects + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "static_nat": { + "startport": 22, + "endport": 22, + "protocol": "TCP" + }, + "network_offering": { + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true", + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "host": { + "username": "root", + "password": "password", + "publicport": 22, + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 22, + "openfirewall": True, + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + }, + "natrule_221": { + "privateport": 22, + "publicport": 221, + "protocol": "TCP" + }, + "fw_rule": { + "startport": 1, + "endport": 6000, + "cidr": '55.55.0.0/11', + # Any network (For creating FW rule) + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + } + +class TestRvRDeploymentPlanning(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestRvRDeploymentPlanning, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self._cleanup.insert(0, self.account) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_RvR_multipods(self): + """Test RvR with muti pods + """ + + # Steps to validate + # 0. listPods should have at least 2 pods + # 1. create a network offering for redundant router + # 2. create a network out of this offering + # 3. deploy a VM in this network + # 4. listRouters + # 5. delete the account + # Validate the following + # 1. listNetworkOfferings should show created offering for RvR + # 2. listNetworks should show the created network in allocated state + # 3. VM should be deployed and in Running state + # 4. There should be two routers (MASTER and BACKUP) for this network + # ensure both routers should be on different pods + + self.debug("Checking if the current zone has 2 active pods in it..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Enabled" + ) + self.assertEqual( + isinstance(pods, list), + True, + "List pods should not return an empty response" + ) + + if len(pods) < 2: + raise unittest.SkipTest("The env don't have 2 pods req for test") + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + self.assertNotEqual( + routers[0].podid, + routers[1].podid, + "Both the routers should be in different pods" + ) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_RvR_multicluster(self): + """Test RvR with muti clusters + """ + + # Steps to validate + # 0. listClusters should have at least two clusters (if there are + # multiple pods, disable all except one with two clusters) + # 1. create a network offering for redundant router + # 2. create a network out of this offering + # 3. deploy a VM in this network on a host in either of clusters + # found in 0. (specify hostid for deployment) + # 4. listRouters + # 5. delete the account + # 6. enable all disabled pods + # Validate the following + # 1. listNetworkOfferings should show created offering for RvR + # 2. listNetworks should show the created network in allocated state + # 3. VM should be deployed and in Running state + # 4. There should be two routers (MASTER and BACKUP) for this network + # ensure both routers should be on different pods + + self.debug("Checking if the current zone has 2 active pods in it..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Enabled" + ) + self.assertEqual( + isinstance(pods, list), + True, + "List pods should not return an empty response" + ) + enabled_pod = pods[0] + + self.debug("Cheking if pod has atleast 2 clusters") + clusters = Cluster.list( + self.apiclient, + podid=enabled_pod.id, + listall=True + ) + self.assertEqual( + isinstance(clusters, list), + True, + "List clusters should not return empty response" + ) + if len(clusters) < 2: + raise unittest.SkipTest( + "The env don't have 2 clusters req for test") + + self.debug("disable all pods except one!") + if len(pods) > 1: + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Disabled' + self.apiclient.updatePod(cmd) + + self.debug("Warning: Disabled all pods in zone") + + cmd = updatePod.updatePodCmd() + cmd.id = pods[0].id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + self.debug("Enabled first pod for testing..") + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + hosts = Host.list( + self.apiclient, + id=routers[0].hostid, + listall=True + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List host should return a valid data" + ) + first_host = hosts[0] + + hosts = Host.list( + self.apiclient, + id=routers[1].hostid, + listall=True + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List host should return a valid data" + ) + second_host = hosts[0] + + # Checking if the cluster IDs of both routers are different? + self.assertNotEqual( + first_host.clusterid, + second_host.clusterid, + "Both the routers should be in different clusters" + ) + self.debug("Enabling remaining pods if any..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Disabled" + ) + + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_RvR_multiprimarystorage(self): + """Test RvR with muti primary storage + """ + + # Steps to validate + # 0. listStoragePools should have atleast two pools in a single + # cluster (disable pods/clusters as necessary) + # 1. create a network offering for redundant router + # 2. create a network out of this offering + # 3. deploy a VM in this network on a host in the cluster from 0 + # (specify hostid for deployment) + # 4. listRouters + # 5. delete the account + # 6. enable the clusters and pods + # Validate the following + # 1. listNetworkOfferings should show created offering for RvR + # 2. listNetworks should show the created network in allocated state + # 3. VM should be deployed and in Running state and on the specified + # host + # 4. There should be two routers (MASTER and BACKUP) for this network + # ensure both routers should be on different storage pools + + self.debug( + "Checking if the current zone has multiple active pods in it..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Enabled" + ) + self.assertEqual( + isinstance(pods, list), + True, + "List pods should not return an empty response" + ) + + enabled_pod = pods[0] + self.debug("Cheking if pod has multiple clusters") + clusters = Cluster.list( + self.apiclient, + podid=enabled_pod.id, + listall=True + ) + self.assertEqual( + isinstance(clusters, list), + True, + "List clusters should not return empty response" + ) + + enabled_cluster = clusters[0] + + self.debug("Cheking if cluster has multiple storage pools") + storage_pools = StoragePool.list( + self.apiclient, + clusterid=enabled_cluster.id, + listall=True + ) + self.assertEqual( + isinstance(storage_pools, list), + True, + "List storage pools should not return empty response" + ) + + if len(storage_pools) < 2: + raise unittest.SkipTest( + "The env don't have 2 storage pools req for test") + + self.debug("disable all pods except one!") + if len(pods) > 1: + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Disabled' + self.apiclient.updatePod(cmd) + + self.debug("Warning: Disabled all pods in zone") + + cmd = updatePod.updatePodCmd() + cmd.id = pods[0].id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + self.debug("Enabled first pod for testing..") + + self.debug("disable all clusters except one!") + if len(pods) > 1: + for cluster in clusters: + cmd = updateCluster.updateClusterCmd() + cmd.id = cluster.id + cmd.allocationstate = 'Disabled' + self.apiclient.updateCluster(cmd) + + self.debug("Warning: Disabled all pods in zone") + + cmd = updateCluster.updateClusterCmd() + cmd.id = clusters[0].id + cmd.allocationstate = 'Enabled' + self.apiclient.updateCluster(cmd) + self.debug("Enabled first cluster for testing..") + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Retrieving the list of hosts in the cluster") + hosts = Host.list( + self.apiclient, + clusterid=enabled_cluster.id, + listall=True + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List hosts should not return an empty response" + ) + host = hosts[0] + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)], + hostid=host.id + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + self.assertNotEqual( + routers[0].hostid, + routers[1].hostid, + "Both the routers should be in different storage pools" + ) + self.debug("Enabling remaining pods if any..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Disabled" + ) + self.assertEqual( + isinstance(pods, list), + True, + "List pods should not return an empty response" + ) + + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + + clusters = Cluster.list( + self.apiclient, + allocationstate="Disabled", + podid=enabled_pod.id, + listall=True + ) + + for cluster in clusters: + cmd = updateCluster.updateClusterCmd() + cmd.id = cluster.id + cmd.allocationstate = 'Enabled' + self.apiclient.updateCluster(cmd) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_RvR_multihosts(self): + """Test RvR with muti hosts + """ + + # Steps to validate + # 0. listHosts should have atleast two hosts in a single cluster + # (disable pods/clusters as necessary) + # 1. create a network offering for redundant router + # 2. create a network out of this offering + # 3. deploy a VM in this network on a host in the cluster from 0 + # (specify hostid for deployment) + # 4. listRouters + # 5. delete the account + # 6. enable the clusters and pods + # Validate the following + # 1. listNetworkOfferings should show created offering for RvR + # 2. listNetworks should show the created network in allocated state + # 3. VM should be deployed and in Running state and on specified host + # 4. There should be two routers (MASTER and BACKUP) for this network + # ensure both routers should be on different hosts + + self.debug( + "Checking if the current zone has multiple active pods in it..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Enabled" + ) + self.assertEqual( + isinstance(pods, list), + True, + "List pods should not return an empty response" + ) + + enabled_pod = pods[0] + self.debug("Cheking if pod has multiple clusters") + clusters = Cluster.list( + self.apiclient, + podid=enabled_pod.id, + listall=True + ) + self.assertEqual( + isinstance(clusters, list), + True, + "List clusters should not return empty response" + ) + + enabled_cluster = clusters[0] + + self.debug("Cheking if cluster has multiple hosts") + hosts = Host.list( + self.apiclient, + clusterid=enabled_cluster.id, + listall=True + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List hosts should not return empty response" + ) + + if len(hosts) < 2: + raise unittest.SkipTest( + "The env don't have 2 hosts req for test") + + self.debug("disable all pods except one!") + if len(pods) > 1: + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Disabled' + self.apiclient.updatePod(cmd) + + self.debug("Warning: Disabled all pods in zone") + + cmd = updatePod.updatePodCmd() + cmd.id = pods[0].id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + self.debug("Enabled first pod for testing..") + + self.debug("disable all clusters except one!") + if len(pods) > 1: + for cluster in clusters: + cmd = updateCluster.updateClusterCmd() + cmd.id = cluster.id + cmd.allocationstate = 'Disabled' + self.apiclient.updateCluster(cmd) + + self.debug("Warning: Disabled all pods in zone") + + cmd = updateCluster.updateClusterCmd() + cmd.id = clusters[0].id + cmd.allocationstate = 'Enabled' + self.apiclient.updateCluster(cmd) + self.debug("Enabled first cluster for testing..") + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Retrieving the list of hosts in the cluster") + hosts = Host.list( + self.apiclient, + clusterid=enabled_cluster.id, + listall=True + ) + self.assertEqual( + isinstance(hosts, list), + True, + "List hosts should not return an empty response" + ) + host = hosts[0] + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)], + hostid=host.id + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + self.assertNotEqual( + routers[0].hostid, + routers[1].hostid, + "Both the routers should be in different hosts" + ) + self.debug("Enabling remaining pods if any..") + pods = Pod.list( + self.apiclient, + zoneid=self.zone.id, + listall=True, + allocationstate="Disabled" + ) + + if pods is not None: + for pod in pods: + cmd = updatePod.updatePodCmd() + cmd.id = pod.id + cmd.allocationstate = 'Enabled' + self.apiclient.updatePod(cmd) + + clusters = Cluster.list( + self.apiclient, + allocationstate="Disabled", + podid=enabled_pod.id, + listall=True + ) + if clusters is not None: + for cluster in clusters: + cmd = updateCluster.updateClusterCmd() + cmd.id = cluster.id + cmd.allocationstate = 'Enabled' + self.apiclient.updateCluster(cmd) + return \ No newline at end of file diff --git a/test/integration/component/test_redundant_router_network_rules.py b/test/integration/component/test_redundant_router_network_rules.py new file mode 100644 index 00000000000..d2d63b48873 --- /dev/null +++ b/test/integration/component/test_redundant_router_network_rules.py @@ -0,0 +1,1416 @@ +# 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. + +from nose.plugins.attrib import attr +from marvin.integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.common import * + +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * + +class Services: + """Test Services for customer defects + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "static_nat": { + "startport": 22, + "endport": 22, + "protocol": "TCP" + }, + "network_offering": { + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true", + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "host": { + "username": "root", + "password": "password", + "publicport": 22, + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 22, + "openfirewall": True, + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + }, + "natrule_221": { + "privateport": 22, + "publicport": 221, + "protocol": "TCP" + }, + "fw_rule": { + "startport": 1, + "endport": 6000, + "cidr": '55.55.0.0/11', + # Any network (For creating FW rule) + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + } + +class TestRedundantRouterRulesLifeCycle(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestRedundantRouterRulesLifeCycle, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self._clean.insert(0, self.account) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_applyNetworkRules_MasterDown_deleteNetworkRules(self): + """Test apply network rules when master & backup routers rebooted + """ + + # Steps to validate + # 1. listNetworks should show the created network in allocated state + # 2. listRouters returns no running routers + # 3. VMs should be deployed and in Running state + # 4. should list MASTER and BACKUP routers + # 5. listPublicIpAddresses for networkid should show acquired IP addr + # 6. listStaticNats for the network associated + # 7. listFirewallRules should show allowed ports open + # 8. ssh to succeed to the guestVM + # 9. listPublicIpAddresses for networkid should show acquired IP addr + # 10. listPortForwardRules to show open ports 221, 222 + # 11. ssh should succeed for both ports + # 12. listPublicIpAddresses for networkid should show acquired IP addr + # 13 and 14. listLoadBalancerRules should show associated VMs for + # public IP + # 15. ssh should succeed to the user VMs + # 16. listRouters should show one Router in MASTER state and Running + # 17. ssh should work for PF, FW, and LB ips + # 18. listRouters should show both routers MASTER and BACKUP in + # Running state + # 19. listPortForwardingRules, listFirewallRules, listLoadBalancerRule + # should return empty response + # 20. listPublicIpAddresses should show now more addresses + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + if routers[0].redundantstate == 'MASTER': + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + self.debug("Enabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + try: + static_nat = StaticNATRule.create( + self.apiclient, + self.services["fw_rule"], + ipaddressid=public_ip.ipaddress.id + ) + static_nat.enable( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=virtual_machine.id + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip.ipaddress.ipaddress) + except Exception as e: + self.fail("Failed to enable static NAT on IP: %s - %s" % ( + public_ip.ipaddress.ipaddress, e)) + + public_ips = PublicIPAddress.list( + self.apiclient, + networkid=network.id, + listall=True, + isstaticnat=True + ) + self.assertEqual( + isinstance(public_ips, list), + True, + "List public Ip for network should list the Ip addr" + ) + self.assertEqual( + public_ips[0].ipaddress, + public_ip.ipaddress.ipaddress, + "List public Ip for network should list the Ip addr" + ) + + self.debug("creating a FW rule on IP: %s" % + public_ip.ipaddress.ipaddress) + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + protocol='TCP', + cidrlist=[self.services["fw_rule"]["cidr"]], + startport=self.services["fw_rule"]["startport"], + endport=self.services["fw_rule"]["endport"] + ) + self.debug("Created a firewall rule on 22 port of IP: %s" % + public_ip.ipaddress.ipaddress) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_2 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_2.ipaddress.ipaddress, + network.id + )) + + nat_rule = NATRule.create( + self.apiclient, + virtual_machine, + self.services["natrule_221"], + ipaddressid=public_ip_2.ipaddress.id, + openfirewall=True + ) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_3 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_3.ipaddress.ipaddress, + network.id + )) + + self.debug("Creating LB rule for IP address: %s" % + public_ip_3.ipaddress.ipaddress) + + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip_3.ipaddress.id, + accountid=self.account.name, + networkid=network.id + ) + + self.debug("Adding %s to the LB rule %s" % ( + virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [virtual_machine]) + + self.debug("Starting router ID: %s" % master_router.id) + + for router in routers: + try: + self.debug("Rebooting router ID: %s" % master_router.id) + #Stop the router + cmd = rebootRouter.rebootRouterCmd() + cmd.id = router.id + self.apiclient.rebootRouter(cmd) + except Exception as e: + self.fail("Failed to reboot router..") + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip.ipaddress.ipaddress) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_2.ipaddress.ipaddress, + reconnect=True, + port=self.services["natrule_221"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_3.ipaddress.ipaddress, + reconnect=True, + port=self.services["lbrule"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_applyRules_restartRvRNetwork(self): + """Test apply rules after network restart + """ + + # Steps to validate + # 1. listNetworks should show the created network in allocated state + # 2. listRouters returns no running routers + # 3. VMs should be deployed and in Running state + # 4. should list MASTER and BACKUP routers + # 5. listPublicIpAddresses for networkid should show acquired IP addr + # 6. listStaticNats for the network associated + # 7. listFirewallRules should show allowed ports open + # 8. ssh to succeed to the guestVM + # 9. listPublicIpAddresses for networkid should show acquired IP addr + # 10. listPortForwardRules to show open ports 221, 222 + # 11. ssh should succeed for both ports + # 12. listPublicIpAddresses for networkid should show acquired IP addr + # 13 and 14. listLoadBalancerRules should show associated VMs for + # public IP + # 15. ssh should succeed to the user VMs + # 16. listRouters should show one Router in MASTER state and Running & + # one in BACKUP and Running + # 17. ssh should work for PF, FW, and LB ips + # 18. listRouters should show one Router in MASTER state and Running & + # one in BACKUP and Running + # 19. ssh should work for PF, FW, and LB ips + # 20. listPortForwardingRules, listFirewallRules, listLoadBalancerRule + # should return empty response + # 21. listPublicIpAddresses should show now more addresses + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + if routers[0].redundantstate == 'MASTER': + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + self.debug("Enabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + try: + static_nat = StaticNATRule.create( + self.apiclient, + self.services["fw_rule"], + ipaddressid=public_ip.ipaddress.id + ) + static_nat.enable( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=virtual_machine.id + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip.ipaddress.ipaddress) + except Exception as e: + self.fail("Failed to enable static NAT on IP: %s - %s" % ( + public_ip.ipaddress.ipaddress, e)) + + public_ips = PublicIPAddress.list( + self.apiclient, + networkid=network.id, + listall=True, + isstaticnat=True + ) + self.assertEqual( + isinstance(public_ips, list), + True, + "List public Ip for network should list the Ip addr" + ) + self.assertEqual( + public_ips[0].ipaddress, + public_ip.ipaddress.ipaddress, + "List public Ip for network should list the Ip addr" + ) + + self.debug("creating a FW rule on IP: %s" % + public_ip.ipaddress.ipaddress) + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + protocol='TCP', + cidrlist=[self.services["fw_rule"]["cidr"]], + startport=self.services["fw_rule"]["startport"], + endport=self.services["fw_rule"]["endport"] + ) + self.debug("Created a firewall rule on 22 port of IP: %s" % + public_ip.ipaddress.ipaddress) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_2 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_2.ipaddress.ipaddress, + network.id + )) + + nat_rule = NATRule.create( + self.apiclient, + virtual_machine, + self.services["natrule_221"], + ipaddressid=public_ip_2.ipaddress.id, + openfirewall=True + ) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_3 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_3.ipaddress.ipaddress, + network.id + )) + + self.debug("Creating LB rule for IP address: %s" % + public_ip_3.ipaddress.ipaddress) + + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip_3.ipaddress.id, + accountid=self.account.name, + networkid=network.id + ) + + self.debug("Adding %s to the LB rule %s" % ( + virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [virtual_machine]) + + self.debug("Restarting network ID: %s with cleanup true" % + network.id) + + try: + network.restart(self.apiclient, cleanup=True) + except Exception as e: + self.fail("Failed to cleanup network") + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip.ipaddress.ipaddress) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_2.ipaddress.ipaddress, + reconnect=True, + port=self.services["natrule_221"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_3.ipaddress.ipaddress, + reconnect=True, + port=self.services["lbrule"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Restarting network ID: %s with cleanup false" % + network.id) + + try: + network.restart(self.apiclient, cleanup=False) + except Exception as e: + self.fail("Failed to cleanup network") + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip.ipaddress.ipaddress) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_2.ipaddress.ipaddress, + reconnect=True, + port=self.services["natrule_221"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_3.ipaddress.ipaddress, + reconnect=True, + port=self.services["lbrule"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_apply_and__delete_NetworkRulesOnRvR(self): + """Test apply and delete network rules on redundant router + """ + + # Steps to validate + # 1. listNetworks should show the created network in allocated state + # 2. listRouters returns no running routers + # 3. VMs should be deployed and in Running state + # 4. should list MASTER and BACKUP routers + # 5. listPublicIpAddresses for networkid should show acquired IP + # 6. listRemoteAccessVpns for the network associated should show the + # VPN created + # 7. listRemoteAccessVpns for the network associated should return + # empty response + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + self.debug("Enabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + try: + static_nat = StaticNATRule.create( + self.apiclient, + self.services["fw_rule"], + ipaddressid=public_ip.ipaddress.id + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip.ipaddress.ipaddress) + static_nat.enable( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=virtual_machine.id + ) + except Exception as e: + self.fail("Failed to enable static NAT on IP: %s - %s" % ( + public_ip.ipaddress.ipaddress, e)) + + public_ips = PublicIPAddress.list( + self.apiclient, + networkid=network.id, + listall=True, + isstaticnat=True + ) + self.assertEqual( + isinstance(public_ips, list), + True, + "List public Ip for network should list the Ip addr" + ) + self.assertEqual( + public_ips[0].ipaddress, + public_ip.ipaddress.ipaddress, + "List public Ip for network should list the Ip addr" + ) + + self.debug("creating a FW rule on IP: %s" % + public_ip.ipaddress.ipaddress) + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + protocol='TCP', + cidrlist=[self.services["fw_rule"]["cidr"]], + startport=self.services["fw_rule"]["startport"], + endport=self.services["fw_rule"]["endport"] + ) + self.debug("Created a firewall rule on 22 port of IP: %s" % + public_ip.ipaddress.ipaddress) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip.ipaddress.ipaddress) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_2 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_2.ipaddress.ipaddress, + network.id + )) + + nat_rule = NATRule.create( + self.apiclient, + virtual_machine, + self.services["natrule_221"], + ipaddressid=public_ip_2.ipaddress.id, + openfirewall=True + ) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_2.ipaddress.ipaddress, + reconnect=True, + port=self.services["natrule_221"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_3 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_3.ipaddress.ipaddress, + network.id + )) + + self.debug("Creating LB rule for IP address: %s" % + public_ip_3.ipaddress.ipaddress) + + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip_3.ipaddress.id, + accountid=self.account.name, + networkid=network.id + ) + + self.debug("Adding %s to the LB rule %s" % ( + virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [virtual_machine]) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_3.ipaddress.ipaddress, + reconnect=True, + port=self.services["lbrule"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_applyNetworkRules_MasterDown_deleteNetworkRules(self): + """Test apply network rules when master down and delete network rules + """ + + # Steps to validate + # 1. listNetworks should show the created network in allocated state + # 2. listRouters returns no running routers + # 3. VMs should be deployed and in Running state + # 4. should list MASTER and BACKUP routers + # 5. listPublicIpAddresses for networkid should show acquired IP addr + # 6. listStaticNats for the network associated + # 7. listFirewallRules should show allowed ports open + # 8. ssh to succeed to the guestVM + # 9. listPublicIpAddresses for networkid should show acquired IP addr + # 10. listPortForwardRules to show open ports 221, 222 + # 11. ssh should succeed for both ports + # 12. listPublicIpAddresses for networkid should show acquired IP addr + # 13 and 14. listLoadBalancerRules should show associated VMs for + # public IP + # 15. ssh should succeed to the user VMs + # 16. listRouters should show one Router in MASTER state and Running + # 17. ssh should work for PF, FW, and LB ips + # 18. listRouters should show both routers MASTER and BACKUP in + # Running state + # 19. listPortForwardingRules, listFirewallRules, listLoadBalancerRule + # should return empty response + # 20. listPublicIpAddresses should show now more addresses + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + if routers[0].redundantstate == 'MASTER': + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("Stopping router ID: %s" % master_router.id) + + try: + Router.stop(self.apiclient, id=master_router.id) + except Exception as e: + self.fail("Failed to stop master router..") + + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + self.debug("Enabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + try: + static_nat = StaticNATRule.create( + self.apiclient, + self.services["fw_rule"], + ipaddressid=public_ip.ipaddress.id + ) + static_nat.enable( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=virtual_machine.id + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip.ipaddress.ipaddress) + except Exception as e: + self.fail("Failed to enable static NAT on IP: %s - %s" % ( + public_ip.ipaddress.ipaddress, e)) + + public_ips = PublicIPAddress.list( + self.apiclient, + networkid=network.id, + listall=True, + isstaticnat=True + ) + self.assertEqual( + isinstance(public_ips, list), + True, + "List public Ip for network should list the Ip addr" + ) + self.assertEqual( + public_ips[0].ipaddress, + public_ip.ipaddress.ipaddress, + "List public Ip for network should list the Ip addr" + ) + + self.debug("creating a FW rule on IP: %s" % + public_ip.ipaddress.ipaddress) + fw_rule = FireWallRule.create( + self.apiclient, + ipaddressid=public_ip.ipaddress.id, + protocol='TCP', + cidrlist=[self.services["fw_rule"]["cidr"]], + startport=self.services["fw_rule"]["startport"], + endport=self.services["fw_rule"]["endport"] + ) + self.debug("Created a firewall rule on 22 port of IP: %s" % + public_ip.ipaddress.ipaddress) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip.ipaddress.ipaddress) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_2 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_2.ipaddress.ipaddress, + network.id + )) + + nat_rule = NATRule.create( + self.apiclient, + virtual_machine, + self.services["natrule_221"], + ipaddressid=public_ip_2.ipaddress.id, + openfirewall=True + ) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_2.ipaddress.ipaddress, + reconnect=True, + port=self.services["natrule_221"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip_3 = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip_3.ipaddress.ipaddress, + network.id + )) + + self.debug("Creating LB rule for IP address: %s" % + public_ip_3.ipaddress.ipaddress) + + lb_rule = LoadBalancerRule.create( + self.apiclient, + self.services["lbrule"], + ipaddressid=public_ip_3.ipaddress.id, + accountid=self.account.name, + networkid=network.id + ) + + self.debug("Adding %s to the LB rule %s" % ( + virtual_machine.name, + lb_rule.name + )) + lb_rule.assign(self.apiclient, [virtual_machine]) + + self.debug("Trying to SSH into the virtual machine") + try: + virtual_machine.get_ssh_client( + ipaddress=public_ip_3.ipaddress.ipaddress, + reconnect=True, + port=self.services["lbrule"]["publicport"] + ) + self.debug("SSH to guest VM succeeded") + except Exception as e: + self.fail("SSH to guest VM failed: %s" % e) + + self.debug("Starting router ID: %s" % master_router.id) + + try: + Router.start(self.apiclient, id=master_router.id) + except Exception as e: + self.fail("Failed to start master router..") + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + for router in routers: + self.assertEqual( + router.state, + "Running", + "Router state should be running" + ) + return \ No newline at end of file diff --git a/test/integration/component/test_redundant_router_services.py b/test/integration/component/test_redundant_router_services.py new file mode 100644 index 00000000000..cc4d367e016 --- /dev/null +++ b/test/integration/component/test_redundant_router_services.py @@ -0,0 +1,376 @@ +# 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. + + +from nose.plugins.attrib import attr +from marvin.integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.common import * + +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * + +class Services: + """Test Services for customer defects + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "static_nat": { + "startport": 22, + "endport": 22, + "protocol": "TCP" + }, + "network_offering": { + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true", + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "host": { + "username": "root", + "password": "password", + "publicport": 22, + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 22, + "openfirewall": True, + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + }, + "natrule_221": { + "privateport": 22, + "publicport": 221, + "protocol": "TCP" + }, + "fw_rule": { + "startport": 1, + "endport": 6000, + "cidr": '55.55.0.0/11', + # Any network (For creating FW rule) + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + } + + +class TestEnableVPNOverRvR(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestEnableVPNOverRvR, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self._cleanup.insert(0, self.account) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_enableVPNOverRvR(self): + """Test redundant router internals + """ + + # Steps to validate + # 1. listNetworks should show the created network in allocated state + # 2. listRouters returns no running routers + # 3. VMs should be deployed and in Running state + # 4. should list MASTER and BACKUP routers + # 5. listPublicIpAddresses for networkid should show acquired IP addr + # 6. listRemoteAccessVpns for the network associated should show VPN + # created + # 7. listRemoteAccessVpns for the network associated should return + # empty response + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + routers, + None, + "Routers should not be spawned when network is in allocated state" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in network: %s" % network.id) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for network: %s" % network.name) + routers = Router.list( + self.apiclient, + networkid=network.id, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return Master and backup routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (Backup & master)" + ) + + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create( + self.apiclient, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id + ) + self.debug("Associated %s with network %s" % ( + public_ip.ipaddress.ipaddress, + network.id + )) + + self.debug("Creating a remote access VPN for account: %s" % + self.account.name) + + try: + vpn = Vpn.create( + self.apiclient, + publicipid=public_ip.ipaddress.id, + account=self.account.name, + domainid=self.account.domainid + ) + except Exception as e: + self.fail("Failed to create VPN for account: %s - %s" % ( + self.account.name, e)) + + try: + vpnuser = VpnUser.create( + self.apiclient, + username="root", + password="password", + account=self.account.name, + domainid=self.account.domainid + ) + except Exception as e: + self.fail("Failed to create VPN user: %s" % e) + + self.debug("Checking if the remote access VPN is created or not?") + remote_vpns = Vpn.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + publicipid=public_ip.ipaddress.id, + listall=True + ) + self.assertEqual( + isinstance(remote_vpns, list), + True, + "List remote VPNs should not return empty response" + ) + self.debug("Deleting the remote access VPN for account: %s" % + self.account.name) + + try: + vpn.delete(self.apiclient) + except Exception as e: + self.fail("Failed to delete VPN : %s" % e) + + self.debug("Checking if the remote access VPN is created or not?") + remote_vpns = Vpn.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + publicipid=public_ip.ipaddress.id, + listall=True + ) + self.assertEqual( + remote_vpns, + None, + "List remote VPNs should not return empty response" + ) + return + diff --git a/test/integration/component/test_redundant_router_upgrades.py b/test/integration/component/test_redundant_router_upgrades.py new file mode 100644 index 00000000000..654faeb03be --- /dev/null +++ b/test/integration/component/test_redundant_router_upgrades.py @@ -0,0 +1,486 @@ +# 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. + + +from nose.plugins.attrib import attr +from marvin.integration.lib.base import * +from marvin.integration.lib.utils import * +from marvin.integration.lib.common import * + +#Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.cloudstackAPI import * + +class Services: + """Test Services for customer defects + """ + + def __init__(self): + self.services = { + "account": { + "email": "test@test.com", + "firstname": "Test", + "lastname": "User", + "username": "test", + # Random characters are appended for unique + # username + "password": "password", + }, + "service_offering": { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + }, + "disk_offering": { + "displaytext": "Small", + "name": "Small", + "disksize": 1 + }, + "virtual_machine": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'XenServer', + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + }, + "static_nat": { + "startport": 22, + "endport": 22, + "protocol": "TCP" + }, + "network_offering": { + "name": 'Network offering-RVR services', + "displaytext": 'Network off-RVR services', + "guestiptype": 'Isolated', + "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Vpn": 'VirtualRouter', + "Dhcp": 'VirtualRouter', + "Dns": 'VirtualRouter', + "SourceNat": 'VirtualRouter', + "PortForwarding": 'VirtualRouter', + "Firewall": 'VirtualRouter', + "Lb": 'VirtualRouter', + "UserData": 'VirtualRouter', + "StaticNat": 'VirtualRouter', + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true", + }, + "lb": { + "SupportedLbIsolation": "dedicated" + }, + }, + }, + "host": { + "username": "root", + "password": "password", + "publicport": 22, + }, + "network": { + "name": "Test Network", + "displaytext": "Test Network", + }, + "lbrule": { + "name": "SSH", + "alg": "roundrobin", + # Algorithm used for load balancing + "privateport": 22, + "publicport": 22, + "openfirewall": True, + }, + "natrule": { + "privateport": 22, + "publicport": 22, + "protocol": "TCP" + }, + "natrule_221": { + "privateport": 22, + "publicport": 221, + "protocol": "TCP" + }, + "fw_rule": { + "startport": 1, + "endport": 6000, + "cidr": '55.55.0.0/11', + # Any network (For creating FW rule) + "protocol": 'TCP', + }, + "ostype": 'CentOS 5.3 (64-bit)', + "sleep": 60, + } + +class TestRvRUpgradeDowngrade(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.api_client = super( + TestRvRUpgradeDowngrade, + cls + ).getClsTestClient().getApiClient() + cls.services = Services().services + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.services) + cls.zone = get_zone(cls.api_client, cls.services) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.services["ostype"] + ) + cls.services["virtual_machine"]["zoneid"] = cls.zone.id + cls.services["virtual_machine"]["template"] = cls.template.id + + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.services["network_offering"], + conservemode=True + ) + # Enable Network offering + cls.network_offering.update(cls.api_client, state='Enabled') + + cls._cleanup = [ + cls.service_offering, + cls.network_offering, + ] + return + + @classmethod + def tearDownClass(cls): + try: + #Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.account = Account.create( + self.apiclient, + self.services["account"], + admin=True, + domainid=self.domain.id + ) + self._cleanup.insert(0, self.account) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_upgradeVR_to_redundantVR(self): + """Test upgrade virtual router to redundant virtual router + """ + + # Steps to validate + # 1. create a network with DefaultNetworkOfferingWithSourceNATservice + # (all VR based services) + # 2. deploy a VM in the above network and listRouters + # 3. create a network Offering that has redundant router enabled and + # all VR based services + # 4. updateNetwork created above to the offfering in 3. + # 5. listRouters in the network + # 6. delete account in which resources are created + # Validate the following + # 1. listNetworks should show the created network in allocated state + # 2. VM should be deployed and in Running state and there should be + # one Router running for this network + # 3. listNetworkOfferings should show craeted offering for RvR + # 4. listNetworks shows the network still successfully implemented + # 5. listRouters shows two routers Up and Running (MASTER and BACKUP) + + network_offerings = NetworkOffering.list( + self.apiclient, + name='DefaultIsolatedNetworkOfferingWithSourceNatService', + listall=True + ) + self.assertEqual( + isinstance(network_offerings, list), + True, + "List network offering should not return empty response" + ) + + network_off_vr = network_offerings[0] + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + network_off_vr.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=network_off_vr.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in the account: %s" % + self.account.name) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for account: %s" % + self.account.name) + routers = Router.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return only one router" + ) + self.assertEqual( + len(routers), + 1, + "Length of the list router should be 1" + ) + + self.debug("Upgrading the network to RVR network offering..") + try: + network.update( + self.apiclient, + networkofferingid=self.network_offering.id + ) + except Exception as e: + self.fail("Failed to upgrade the network from VR to RVR: %s" % e) + + self.debug("Listing routers for account: %s" % + self.account.name) + routers = Router.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return two routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (MASTER & BACKUP)" + ) + return + + @attr(tags=["advanced", "advancedns", "ssh"]) + def test_downgradeRvR_to_VR(self): + """Test downgrade redundant virtual router to virtual router + """ + + # Steps to validate + # 1. create a network Offering that has redundant router enabled and + # all VR based services + # 2. create a network with above offering + # 3. deploy a VM in the above network and listRouters + # 4. create a network Offering that has redundant router disabled and + # all VR based services + # 5. updateNetwork - downgrade - created above to the offfering in 4. + # 6. listRouters in the network + # 7. delete account in which resources are created + # Validate the following + # 1. listNetworkOfferings should show craeted offering for RvR + # 2. listNetworks should show the created network in allocated state + # 3. VM should be deployed and in Running state and there should be + # two routers (MASTER and BACKUP) for this network + # 4. listNetworkOfferings should show craeted offering for VR + # 5. listNetworks shows the network still successfully implemented + # 6. listRouters shows only one router for this network in Running + + # Creating network using the network offering created + self.debug("Creating network with network offering: %s" % + self.network_offering.id) + network = Network.create( + self.apiclient, + self.services["network"], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=self.network_offering.id, + zoneid=self.zone.id + ) + self.debug("Created network with ID: %s" % network.id) + + networks = Network.list( + self.apiclient, + id=network.id, + listall=True + ) + self.assertEqual( + isinstance(networks, list), + True, + "List networks should return a valid response for created network" + ) + nw_response = networks[0] + + self.debug("Network state: %s" % nw_response.state) + self.assertEqual( + nw_response.state, + "Allocated", + "The network should be in allocated state after creation" + ) + + self.debug("Deploying VM in account: %s" % self.account.name) + + # Spawn an instance in that network + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)] + ) + self.debug("Deployed VM in the account: %s" % + self.account.name) + + vms = VirtualMachine.list( + self.apiclient, + id=virtual_machine.id, + listall=True + ) + self.assertEqual( + isinstance(vms, list), + True, + "List Vms should return a valid list" + ) + vm = vms[0] + self.assertEqual( + vm.state, + "Running", + "Vm should be in running state after deployment" + ) + + self.debug("Listing routers for account: %s" % + self.account.name) + routers = Router.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return two routers" + ) + self.assertEqual( + len(routers), + 2, + "Length of the list router should be 2 (MASTER & BACKUP)" + ) + + network_offerings = NetworkOffering.list( + self.apiclient, + name='DefaultIsolatedNetworkOfferingWithSourceNatService', + listall=True + ) + self.assertEqual( + isinstance(network_offerings, list), + True, + "List network offering should not return empty response" + ) + + network_off_vr = network_offerings[0] + + self.debug("Upgrading the network to RVR network offering..") + try: + network.update( + self.apiclient, + networkofferingid=network_off_vr.id + ) + except Exception as e: + self.fail("Failed to upgrade the network from VR to RVR: %s" % e) + + self.debug("Listing routers for account: %s" % + self.account.name) + routers = Router.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + listall=True + ) + self.assertEqual( + isinstance(routers, list), + True, + "list router should return only one router" + ) + self.assertEqual( + len(routers), + 1, + "Length of the list router should be 1" + ) + return diff --git a/test/integration/component/test_shared_networks.py b/test/integration/component/test_shared_networks.py index cb2b55f705a..6bcfbfdfb39 100644 --- a/test/integration/component/test_shared_networks.py +++ b/test/integration/component/test_shared_networks.py @@ -19,6 +19,7 @@ """ #Import Local Modules import marvin +from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * from marvin.cloudstackAPI import * from marvin.integration.lib.utils import * diff --git a/test/integration/component/test_snapshots.py b/test/integration/component/test_snapshots.py index 014b55afcc1..708a8b29996 100644 --- a/test/integration/component/test_snapshots.py +++ b/test/integration/component/test_snapshots.py @@ -108,6 +108,18 @@ class Services: "ostype": "CentOS 5.3 (64-bit)", "templatefilter": 'self', }, + "volume": { + "diskname": "APP Data Volume", + "size": 1, # in GBs + "diskdevice": "/dev/xvdb", # Data Disk + }, + "paths": { + "mount_dir": "/mnt/tmp", + "sub_dir": "test", + "sub_lvl_dir1": "test1", + "sub_lvl_dir2": "test2", + "random_data": "random.data", + }, "diskdevice": "/dev/xvda", "diskname": "TestDiskServ", "size": 1, # GBs @@ -377,6 +389,11 @@ class TestSnapshots(cloudstackTestCase): cls.services["zoneid"] = cls.zone.id cls.services["diskoffering"] = cls.disk_offering.id + #determine device type from hypervisor + hosts = Host.list(cls.api_client, id=cls.virtual_machine.hostid) + if len(hosts) > 0 and hosts[0].hypervisor.lower() == "kvm": + cls.service["volume"]["diskdevice"] = "/dev/vdb" + # Create VMs, NAT Rules etc cls.account = Account.create( cls.api_client, @@ -583,81 +600,102 @@ class TestSnapshots(cloudstackTestCase): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "smoke", "xen"]) - def test_03_volume_from_snapshot(self): - """Create volumes from snapshots + @attr(tags = ["advanced", "advancedns", "basic", "sg"]) + def test_01_volume_from_snapshot(self): + """Test Creating snapshot from volume having spaces in name(KVM) """ - #1. Login to machine; create temp/test directories on data volume - #2. Snapshot the Volume - #3. Create another Volume from snapshot - #4. Mount/Attach volume to another server - #5. Compare data + # Validate the following + #1. Create a virtual machine and data volume + #2. Attach data volume to VM + #3. Login to machine; create temp/test directories on data volume + #4. Snapshot the Volume + #5. Create another Volume from snapshot + #6. Mount/Attach volume to another server + #7. Compare data + random_data_0 = random_gen(100) random_data_1 = random_gen(100) + volume = Volume.create( + self.apiclient, + self.services["volume"], + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid, + diskofferingid=self.disk_offering.id + ) + self.debug("Created volume with ID: %s" % volume.id) + self.virtual_machine.attach_volume( + self.apiclient, + volume + ) + self.debug("Attach volume: %s to VM: %s" % + (volume.id, self.virtual_machine.id)) + + try: ssh_client = self.virtual_machine.get_ssh_client() + except Exception as e: + self.fail("SSH failed for VM: %s" % + self.virtual_machine.ipaddress) - #Format partition using ext3 - format_volume_to_ext3( + self.debug("Formatting volume: %s to ext3" % volume.id) + #Format partition using ext3 + format_volume_to_ext3( ssh_client, - self.services["diskdevice"] + self.services["volume"]["diskdevice"] ) - cmds = [ - "mkdir -p %s" % self.services["mount_dir"], + cmds = [ + "mkdir -p %s" % self.services["paths"]["mount_dir"], "mount %s1 %s" % ( - self.services["diskdevice"], - self.services["mount_dir"] + self.services["volume"]["diskdevice"], + self.services["paths"]["mount_dir"] ), "mkdir -p %s/%s/{%s,%s} " % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["sub_lvl_dir2"] - ), + self.services["paths"]["mount_dir"], + self.services["paths"]["sub_dir"], + self.services["paths"]["sub_lvl_dir1"], + self.services["paths"]["sub_lvl_dir2"] + ), "echo %s > %s/%s/%s/%s" % ( - random_data_0, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - ), + random_data_0, + self.services["paths"]["mount_dir"], + self.services["paths"]["sub_dir"], + self.services["paths"]["sub_lvl_dir1"], + self.services["paths"]["random_data"] + ), "echo %s > %s/%s/%s/%s" % ( - random_data_1, - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - ), + random_data_1, + self.services["paths"]["mount_dir"], + self.services["paths"]["sub_dir"], + self.services["paths"]["sub_lvl_dir2"], + self.services["paths"]["random_data"] + ), ] - for c in cmds: - self.debug(c) - ssh_client.execute(c) + for c in cmds: + self.debug("Command: %s" % c) + ssh_client.execute(c) - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine.ipaddress) # Unmount the Sec Storage cmds = [ - "umount %s" % (self.services["mount_dir"]), + "umount %s" % (self.services["paths"]["mount_dir"]), ] + for c in cmds: + self.debug("Command: %s" % c) + ssh_client.execute(c) - try: - for c in cmds: - self.debug(c) - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.virtual_machine.ipaddress) - - list_volume_response = list_volumes( + list_volume_response = Volume.list( self.apiclient, virtualmachineid=self.virtual_machine.id, type='DATADISK', listall=True ) + self.assertEqual( + isinstance(list_volume_response, list), + True, + "Check list volume response for valid data" + ) volume_response = list_volume_response[0] #Create snapshot from attached volume snapshot = Snapshot.create( @@ -666,81 +704,94 @@ class TestSnapshots(cloudstackTestCase): account=self.account.name, domainid=self.account.domainid ) - self.debug("Created Snapshot from volume: %s" % volume_response.id) - + self.debug("Created snapshot: %s" % snapshot.id) #Create volume from snapshot - self.debug("Creating volume from snapshot: %s" % snapshot.id) - volume = Volume.create_from_snapshot( + volume_from_snapshot = Volume.create_from_snapshot( self.apiclient, snapshot.id, - self.services, + self.services["volume"], account=self.account.name, domainid=self.account.domainid ) - - volumes = list_volumes( + self.debug("Created Volume: %s from Snapshot: %s" % ( + volume_from_snapshot.id, + snapshot.id)) + volumes = Volume.list( self.apiclient, - id=volume.id + id=volume_from_snapshot.id ) self.assertEqual( isinstance(volumes, list), True, "Check list response returns a valid list" ) + self.assertNotEqual( len(volumes), None, "Check Volume list Length" ) - self.assertEqual( volumes[0].id, - volume.id, + volume_from_snapshot.id, "Check Volume in the List Volumes" ) #Attaching volume to new VM - new_virtual_machine = self.virtual_machine_without_disk + new_virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["server_without_disk"], + templateid=self.template.id, + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + mode=self.services["mode"] + ) + self.debug("Deployed new VM for account: %s" % self.account.name) self.cleanup.append(new_virtual_machine) - cmd = attachVolume.attachVolumeCmd() - cmd.id = volume.id - cmd.virtualmachineid = new_virtual_machine.id - self.apiclient.attachVolume(cmd) + self.debug("Attaching volume: %s to VM: %s" % ( + volume_from_snapshot.id, + new_virtual_machine.id + )) + + self.new_virtual_machine.attach_volume( + self.apiclient, + volume_from_snapshot + ) try: #Login to VM to verify test directories and files ssh = new_virtual_machine.get_ssh_client() cmds = [ - "mkdir -p %s" % self.services["mount_dir"], + "mkdir -p %s" % self.services["paths"]["mount_dir"], "mount %s1 %s" % ( - self.services["diskdevice"], - self.services["mount_dir"] + self.services["volume"]["diskdevice"], + self.services["paths"]["mount_dir"] ), ] for c in cmds: - self.debug(c) - result = ssh.execute(c) - self.debug(result) - - returned_data_0 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir1"], - self.services["random_data"] - )) - returned_data_1 = ssh.execute("cat %s/%s/%s/%s" % ( - self.services["mount_dir"], - self.services["sub_dir"], - self.services["sub_lvl_dir2"], - self.services["random_data"] - )) + self.debug("Command: %s" % c) + ssh.execute(c) + returned_data_0 = ssh.execute( + "cat %s/%s/%s/%s" % ( + self.services["paths"]["mount_dir"], + self.services["paths"]["sub_dir"], + self.services["paths"]["sub_lvl_dir1"], + self.services["paths"]["random_data"] + )) + returned_data_1 = ssh.execute( + "cat %s/%s/%s/%s" % ( + self.services["paths"]["mount_dir"], + self.services["paths"]["sub_dir"], + self.services["paths"]["sub_lvl_dir2"], + self.services["paths"]["random_data"] + )) except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.new_virtual_machine.ipaddress) - + self.fail("SSH access failed for VM: %s" % + new_virtual_machine.ipaddress) #Verify returned data self.assertEqual( random_data_0, @@ -754,15 +805,11 @@ class TestSnapshots(cloudstackTestCase): ) # Unmount the Sec Storage cmds = [ - "umount %s" % (self.services["mount_dir"]), + "umount %s" % (self.services["paths"]["mount_dir"]), ] - try: - for c in cmds: - ssh_client.execute(c) - - except Exception as e: - self.fail("SSH failed for VM with IP: %s" % - self.new_virtual_machine.ipaddress) + for c in cmds: + self.debug("Command: %s" % c) + ssh_client.execute(c) return @attr(speed = "slow") @@ -1182,6 +1229,7 @@ class TestSnapshots(cloudstackTestCase): new_virtual_machine.ipaddress) return + class TestCreateVMsnapshotTemplate(cloudstackTestCase): @classmethod @@ -1560,7 +1608,7 @@ class TestAccountSnapshotClean(cloudstackTestCase): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns"]) + @attr(tags = ["advanced", "advancedns", "basic", "sg"]) def test_02_accountSnapshotClean(self): """Test snapshot cleanup after account deletion """ @@ -1852,6 +1900,11 @@ class TestSnapshotDetachedDisk(cloudstackTestCase): cls.services["template"] = template.id + #determine device type from hypervisor + hosts = Host.list(cls.api_client, id=cls.virtual_machine.hostid) + if len(hosts) > 0 and hosts[0].hypervisor.lower() == "kvm": + cls.service["volume"]["diskdevice"] = "/dev/vdb" + # Create VMs, NAT Rules etc cls.account = Account.create( cls.api_client, @@ -1905,7 +1958,7 @@ class TestSnapshotDetachedDisk(cloudstackTestCase): return @attr(speed = "slow") - @attr(tags = ["advanced", "advancedns", "xen"]) + @attr(tags = ["advanced", "advancedns", "basic", "sg"]) def test_03_snapshot_detachedDisk(self): """Test snapshot from detached disk """ @@ -1941,7 +1994,7 @@ class TestSnapshotDetachedDisk(cloudstackTestCase): #Format partition using ext3 format_volume_to_ext3( ssh_client, - self.services["diskdevice"] + self.services["volume"]["diskdevice"] ) cmds = [ "mkdir -p %s" % self.services["mount_dir"], diff --git a/test/integration/component/test_storage_motion.py b/test/integration/component/test_storage_motion.py index 0dcc7f8e8d1..eda77d1a629 100644 --- a/test/integration/component/test_storage_motion.py +++ b/test/integration/component/test_storage_motion.py @@ -79,9 +79,6 @@ class Services: "name": "Cent OS Template", "passwordenabled": True, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, #Migrate VM to hostid diff --git a/test/integration/component/test_volumes.py b/test/integration/component/test_volumes.py index 34a067930de..369cefcaf34 100644 --- a/test/integration/component/test_volumes.py +++ b/test/integration/component/test_volumes.py @@ -26,10 +26,7 @@ from marvin.integration.lib.base import * from marvin.integration.lib.common import * from marvin.remoteSSHClient import remoteSSHClient #Import System modules -import os -import urllib import time -import tempfile class Services: diff --git a/test/integration/component/test_vpc.py b/test/integration/component/test_vpc.py index 3fc0cc5a7e2..63c10aacdb2 100644 --- a/test/integration/component/test_vpc.py +++ b/test/integration/component/test_vpc.py @@ -18,16 +18,13 @@ """ Component tests for VPC functionality """ #Import Local Modules -import marvin -import unittest from nose.plugins.attrib import attr from marvin.cloudstackTestCase import * +from marvin.cloudstackException import cloudstackAPIException from marvin.cloudstackAPI import * from marvin.integration.lib.utils import * from marvin.integration.lib.base import * from marvin.integration.lib.common import * -from marvin.remoteSSHClient import remoteSSHClient -import datetime class Services: @@ -205,7 +202,6 @@ class TestVPC(cloudstackTestCase): cls.vpc_off.update(cls.api_client, state='Enabled') cls._cleanup = [ cls.service_offering, - cls.vpc_off ] return @@ -227,25 +223,7 @@ class TestVPC(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [self.account] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return def validate_vpc_offering(self, vpc_offering): @@ -331,7 +309,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_02_restart_vpc_with_networks(self): - """ Test restart VPC having with networks + """ Test restart VPC having networks """ # Validate the following @@ -456,7 +434,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_04_delete_vpc_with_networks(self): - """ Test delete VPC having with networks + """ Test delete VPC having networks """ # Validate the following @@ -778,7 +756,7 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["account"], ) - self.cleanup.append(self.user) + self._cleanup.append(self.user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % @@ -799,16 +777,16 @@ class TestVPC(cloudstackTestCase): self.services["vpc"], vpcofferingid=self.vpc_off.id, zoneid=self.zone.id, - account=self.user.account.name, - domainid=self.user.account.domainid + account=self.user.name, + domainid=self.user.domainid ) self.validate_vpc_network(vpc_2) self.debug("Validating list VPCs call by passing account and domain") vpcs = VPC.list( self.apiclient, - account=self.user.account.name, - domainid=self.user.account.domainid, + account=self.user.name, + domainid=self.user.domainid, listall=True ) self.assertEqual( @@ -824,7 +802,7 @@ class TestVPC(cloudstackTestCase): ) return - @attr(tags=["advanced", "intervlan"]) + @attr(tags=["advanced", "intervlan", "multiple"]) def test_07_restart_network_vm_running(self): """ Test Restart VPC when there are multiple networks associated """ @@ -1654,7 +1632,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_11_deploy_vm_wo_network_netdomain(self): - """ Test deployment of vm in a VPC without network netdomain + """ Test deployment of vm in a VPC without network domain """ # 1. Create VPC without providing networkDomain. @@ -1862,7 +1840,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_13_deploy_vm_with_vpc_netdomain(self): - """ Test deployment of vm in a VPC with netdomain + """ Test deployment of vm in a VPC with network domain """ # 1. Create VPC with providing networkDomain. @@ -1927,8 +1905,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_14_deploy_vm_1(self): - """ Test deployment of vm in a network from user account. But the VPC is created - without account/domain ID + """ Test vm deploy in network by a user where VPC was created without account/domain ID """ # 1. Create VPC without providing account/domain ID. @@ -1939,18 +1916,19 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["account"] ) - self.debug("Created account: %s" % user.account.name) - self.cleanup.append(user) + self.debug("Created account: %s" % user.name) + self._cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % - user.account.name) + user.name) - userapiclient = self.testClient.createNewApiClient( - UserName=user.account.name, - DomainName=user.account.domain, + userapiclient = self.testClient.createUserApiClient( + UserName=user.name, + DomainName=user.domain, acctType=0) + vpc = VPC.create( userapiclient, self.services["vpc"], @@ -2003,8 +1981,7 @@ class TestVPC(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_15_deploy_vm_2(self): - """ Test deployment of vm in a network from domain admin account. But the VPC is created - without account/domain ID + """ Test deployment of vm in a network in a domain admin account where VPC is created without account/domain ID """ # 1. Create VPC without providing account/domain ID. @@ -2020,18 +1997,18 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["account"] ) - self.debug("Created account: %s" % user.account.name) - self.cleanup.append(user) + self.debug("Created account: %s" % user.name) + self._cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % - user.account.name) + user.name) #0 - User, 1 - Root Admin, 2 - Domain Admin - userapiclient = self.testClient.createNewApiClient( - UserName=user.account.name, - DomainName=self.services["domain"]["name"], - acctType=2) + userapiclient = self.testClient.getUserApiClient( + account=user.name, + domain=self.services["domain"]["name"], + type=2) vpc = VPC.create( userapiclient, @@ -2096,23 +2073,23 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["account"] ) - self.debug("Created account: %s" % user.account.name) - self.cleanup.append(user) + self.debug("Created account: %s" % user.name) + self._cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % - user.account.name) + user.name) - userapiclient = self.testClient.createNewApiClient( - UserName=user.account.name, - DomainName=user.account.domain, - acctType=0) + userapiclient = self.testClient.getUserApiClient( + account=user.name, + domain=user.domain, + type=0) vpc = VPC.create( self.apiclient, self.services["vpc"], - account=user.account.name, - domainid=user.account.domainid, + account=user.name, + domainid=user.domainid, vpcofferingid=self.vpc_off.id, zoneid=self.zone.id, ) @@ -2180,87 +2157,43 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["domain_admin"] ) - self.debug("Created account: %s" % domain_admin.account.name) - self.cleanup.append(domain_admin) - da_apiclient = self.testClient.createNewApiClient( - UserName=domain_admin.account.name, - #DomainName=self.services["domain"]["name"], - DomainName=domain_admin.account.domain, - acctType=2) + self.debug("Created account: %s" % domain_admin.name) + self._cleanup.append(domain_admin) + da_apiclient = self.testClient.getUserApiClient( + account=domain_admin.name, + domain=domain_admin.domain, + type=2) user = Account.create( self.apiclient, self.services["account"] ) - self.debug("Created account: %s" % user.account.name) - self.cleanup.append(user) + self.debug("Created account: %s" % user.name) + self._cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % - user.account.name) + user.name) #0 - User, 1 - Root Admin, 2 - Domain Admin - userapiclient = self.testClient.createNewApiClient( - UserName=user.account.name, - DomainName=user.account.domain, - acctType=0) + userapiclient = self.testClient.getUserApiClient( + account=user.name, + domain=user.domain, + type=0) - vpc = VPC.create( - da_apiclient, - self.services["vpc"], - account=user.account.name, - domainid=user.account.domainid, - vpcofferingid=self.vpc_off.id, - zoneid=self.zone.id, - ) - self.validate_vpc_network(vpc) - - self.network_offering = NetworkOffering.create( - self.apiclient, - self.services["network_offering"], - conservemode=False - ) - # Enable Network offering - self.network_offering.update(self.apiclient, state='Enabled') - self._cleanup.append(self.network_offering) - - gateway = vpc.cidr.split('/')[0] - # Split the cidr to retrieve gateway - # for eg. cidr = 10.0.0.1/24 - # Gateway = 10.0.0.1 - - # Creating network using the network offering created - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - network = Network.create( - userapiclient, - self.services["network"], - networkofferingid=self.network_offering.id, - zoneid=self.zone.id, - gateway=gateway, - vpcid=vpc.id - ) - self.debug("Created network with ID: %s" % network.id) - - # Spawn an instance in that network - virtual_machine = VirtualMachine.create( - userapiclient, - self.services["virtual_machine"], - serviceofferingid=self.service_offering.id, - networkids=[str(network.id)] - ) - self.debug("Deployed VM in network: %s" % network.id) - - self.assertNotEqual(virtual_machine, - None, - "VM creation in the network failed") - - return + with self.assertRaises(cloudstackAPIException): + vpc = VPC.create( + da_apiclient, + self.services["vpc"], + account=user.name, + domainid=user.domainid, + vpcofferingid=self.vpc_off.id, + zoneid=self.zone.id, + ) @attr(tags=["advanced", "intervlan"]) def test_18_create_net_for_user_diff_domain_by_doadmin(self): - """ Test creation of network by domain admin for user from different - domain. + """ Test creation of network by domain admin for user from different domain """ #1. As domain admin account , Create VPC(name,zoneId,cidr,vpcOfferingId,networkDomain) without passing Account/domain ID. @@ -2275,29 +2208,29 @@ class TestVPC(cloudstackTestCase): self.apiclient, self.services["domain_admin"] ) - self.debug("Created account: %s" % domain_admin.account.name) - self.cleanup.append(domain_admin) - da_apiclient = self.testClient.createNewApiClient( - UserName=domain_admin.account.name, - DomainName=self.services["domain"]["name"], - acctType=2) + self.debug("Created account: %s" % domain_admin.name) + self._cleanup.append(domain_admin) + da_apiclient = self.testClient.getUserApiClient( + account=domain_admin.name, + domain=self.services["domain"]["name"], + type=2) user = Account.create( self.apiclient, self.services["account"] ) - self.debug("Created account: %s" % user.account.name) - self.cleanup.append(user) + self.debug("Created account: %s" % user.name) + self._cleanup.append(user) self.services["vpc"]["cidr"] = "10.1.1.1/16" self.debug("creating a VPC network in the account: %s" % - user.account.name) + user.name) #0 - User, 1 - Root Admin, 2 - Domain Admin - userapiclient = self.testClient.createNewApiClient( - UserName=user.account.name, - DomainName=user.account.domain, - acctType=0) + userapiclient = self.testClient.getUserApiClient( + account=user.name, + domain=user.domain, + type=0) vpc = VPC.create( da_apiclient, @@ -2457,7 +2390,7 @@ class TestVPC(cloudstackTestCase): vpc_networks = VPC.list( self.apiclient, - id=network.id + id=vpc.id ) self.assertEqual( @@ -2471,253 +2404,4 @@ class TestVPC(cloudstackTestCase): self.assertEqual(vpc_networks[0].displaytext, new_display_text, - "Updation of VPC display text failed.") - - -class TestVPCHostMaintenance(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls.api_client = super( - TestVPCHostMaintenance, - cls - ).getClsTestClient().getApiClient() - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.vpc_off = VpcOffering.create( - cls.api_client, - cls.services["vpc_offering"] - ) - cls.vpc_off.update(cls.api_client, state='Enabled') - hosts = Host.list( - cls.api_client, - zoneid=cls.zone.id, - listall=True, - type='Routing' - ) - - if isinstance(hosts, list): - for host in hosts: - Host.enableMaintenance( - cls.api_client, - id=host.id - ) - - timeout = cls.services["timeout"] - while True: - time.sleep(cls.services["sleep"]) - hosts_states = Host.list( - cls.api_client, - id=host.id, - listall=True - ) - if hosts_states[0].resourcestate == 'PrepareForMaintenance': - # Wait for sometimetill host goes in maintenance state - time.sleep(cls.services["sleep"]) - elif hosts_states[0].resourcestate == 'Maintenance': - time.sleep(cls.services["sleep"]) - break - elif timeout == 0: - raise unittest.SkipTest( - "Failed to enable maintenance mode on %s" % host.name) - timeout = timeout - 1 - - cls._cleanup = [ - cls.service_offering, - cls.vpc_off - ] - return - - @classmethod - def tearDownClass(cls): - try: - #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) - hosts = Host.list( - cls.api_client, - zoneid=cls.zone.id, - listall=True, - type='Routing' - ) - if isinstance(hosts, list): - for host in hosts: - Host.cancelMaintenance( - cls.api_client, - id=host.id - ) - hosts_states = Host.list( - cls.api_client, - id=host.id, - listall=True - ) - if hosts_states[0].resourcestate != 'Enabled': - raise Exception( - "Failed to cancel maintenance mode on %s" % (host.name)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [self.account] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - def validate_vpc_offering(self, vpc_offering): - """Validates the VPC offering""" - - self.debug("Check if the VPC offering is created successfully?") - vpc_offs = VpcOffering.list( - self.apiclient, - id=vpc_offering.id - ) - self.assertEqual( - isinstance(vpc_offs, list), - True, - "List VPC offerings should return a valid list" - ) - self.assertEqual( - vpc_offering.name, - vpc_offs[0].name, - "Name of the VPC offering should match with listVPCOff data" - ) - self.debug( - "VPC offering is created successfully - %s" % - vpc_offering.name) - return - - def validate_vpc_network(self, network, state=None): - """Validates the VPC network""" - - self.debug("Check if the VPC network is created successfully?") - vpc_networks = VPC.list( - self.apiclient, - id=network.id - ) - self.assertEqual( - isinstance(vpc_networks, list), - True, - "List VPC network should return a valid list" - ) - self.assertEqual( - network.name, - vpc_networks[0].name, - "Name of the VPC network should match with listVPC data" - ) - if state: - self.assertEqual( - vpc_networks[0].state, - state, - "VPC state should be '%s'" % state - ) - self.debug("VPC network validated - %s" % network.name) - return - - @attr(tags=["advanced", "intervlan"]) - def test_01_create_vpc_host_maintenance(self): - """ Test VPC when host is in maintenance mode - """ - - # Validate the following - # 1. Put the host in maintenance mode. - # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 - # 3. VPC will be created but will be in "Disabled" state - - self.debug("creating a VPC network in the account: %s" % - self.account.name) - self.services["vpc"]["cidr"] = '10.1.1.1/16' - vpc = VPC.create( - self.apiclient, - self.services["vpc"], - vpcofferingid=self.vpc_off.id, - zoneid=self.zone.id, - account=self.account.name, - domainid=self.account.domainid - ) - self.validate_vpc_network(vpc, state='Disabled') - return - - @attr(tags=["advanced", "intervlan"]) - def test_02_create_vpc_wait_gc(self): - """ Test VPC when host is in maintenance mode and wait till nw gc - """ - - # Validate the following - # 1. Put the host in maintenance mode. - # 2. Attempt to Create a VPC with cidr - 10.1.1.1/16 - # 3. Wait for the VPC GC thread to run. - # 3. VPC will be created but will be in "Disabled" state and should - # get deleted - - self.debug("creating a VPC network in the account: %s" % - self.account.name) - self.services["vpc"]["cidr"] = '10.1.1.1/16' - vpc = VPC.create( - self.apiclient, - self.services["vpc"], - vpcofferingid=self.vpc_off.id, - zoneid=self.zone.id, - account=self.account.name, - domainid=self.account.domainid - ) - self.validate_vpc_network(vpc, state='Disabled') - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - self.debug("Sleep till network gc thread runs..") - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - vpcs = VPC.list( - self.apiclient, - id=vpc.id, - listall=True - ) - self.assertEqual( - vpcs, - None, - "List VPC should not return anything after network gc" - ) - return + "Updation of VPC display text failed.") \ No newline at end of file diff --git a/test/integration/component/test_vpc_network.py b/test/integration/component/test_vpc_network.py index a997f43a612..d76996ae85b 100644 --- a/test/integration/component/test_vpc_network.py +++ b/test/integration/component/test_vpc_network.py @@ -72,7 +72,6 @@ class Services: }, "serviceCapabilityList": { "SourceNat": {"SupportedSourceNatTypes": "peraccount"}, - "Lb": {"lbSchemes": "public", "SupportedLbIsolation": "dedicated"} }, }, "network_off_netscaler": { @@ -95,7 +94,6 @@ class Services: }, "serviceCapabilityList": { "SourceNat": {"SupportedSourceNatTypes": "peraccount"}, - "Lb": {"lbSchemes": "public", "SupportedLbIsolation": "dedicated"} }, }, "network_off_shared": { @@ -229,25 +227,7 @@ class TestVPCNetwork(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [self.account] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return def validate_vpc_offering(self, vpc_offering): @@ -394,7 +374,7 @@ class TestVPCNetwork(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_02_create_network_fail(self): - """ Test create network in VPC + """ Test create network in VPC mismatched services (Should fail) """ # Validate the following @@ -712,7 +692,7 @@ class TestVPCNetwork(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_06_create_network_with_rvr(self): - """ Test create network with eredundant router capability + """ Test create network with redundant router capability """ # Validate the following @@ -752,7 +732,7 @@ class TestVPCNetwork(cloudstackTestCase): self.validate_vpc_network(vpc) # Enable redundant router capability for the network offering - self.services["network"]["servicecapabilitylist"] = { + self.services["network"]["serviceCapabilityList"] = { "SourceNat": { "RedundantRouter": "true", }, @@ -1094,25 +1074,7 @@ class TestVPCNetworkRanges(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [self.account] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return def validate_vpc_offering(self, vpc_offering): @@ -1365,6 +1327,7 @@ class TestVPCNetworkRanges(cloudstackTestCase): # 3. Add network2 with cidr - 10.1.1.1/24 to this VPC # 4. Add network3 with cidr - 10.1.1.1/26 to this VPC # 5. Network creation in step 3 & 4 should fail. + self.services = Services().services self.debug("Creating a VPC offering") vpc_off = VpcOffering.create( @@ -1606,19 +1569,7 @@ class TestVPCNetworkUpgrade(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [self.account] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - wait_for_cleanup(self.apiclient, [ - "network.gc.interval", - "network.gc.wait"]) - - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return def validate_vpc_offering(self, vpc_offering): @@ -1673,8 +1624,7 @@ class TestVPCNetworkUpgrade(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_01_network_services_upgrade(self): - """ Test update Network that is part of a VPC to a network offering - that has more services. + """ Test update Network that is part of a VPC to a network offering that has more services """ # Validate the following @@ -2027,8 +1977,7 @@ class TestVPCNetworkUpgrade(cloudstackTestCase): @attr(tags=["advanced", "intervlan"]) def test_02_network_vpcvr2vr_upgrade(self): - """ Test update Network that is NOT part of a VPC to a nw offering - that has services that are provided by VPCVR and vice versa. + """ Test update Network that is NOT part of a VPC to a nw offering that has services that are provided by VPCVR and vice versa """ # Validate the following @@ -2298,7 +2247,6 @@ class TestVPCNetworkGc(cloudstackTestCase): cmd = stopVirtualMachine.stopVirtualMachineCmd() cmd.id = vm.id self.apiclient.stopVirtualMachine(cmd) - self.cleanup = [] return def tearDown(self): @@ -2311,15 +2259,7 @@ class TestVPCNetworkGc(cloudstackTestCase): ) for vm in vms: if vm.state == "Stopped": - cmd = startVirtualMachine.startVirtualMachineCmd() - cmd.id = vm.id - self.apiclient.startVirtualMachine(cmd) - - try: - #Clean up, terminate the created network offerings - cleanup_resources(self.apiclient, self.cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + vm.start(self.apiclient) return def validate_vpc_offering(self, vpc_offering): diff --git a/test/integration/component/test_vpc_network_lbrules.py b/test/integration/component/test_vpc_network_lbrules.py index 66d6c4d4018..b0357fa8de1 100644 --- a/test/integration/component/test_vpc_network_lbrules.py +++ b/test/integration/component/test_vpc_network_lbrules.py @@ -87,8 +87,6 @@ class Services: "StaticNat": 'VpcVirtualRouter', "NetworkACL": 'VpcVirtualRouter' }, - "servicecapabilitylist": { - }, }, "network_offering_no_lb": { "name": 'VPC Network offering', @@ -176,7 +174,6 @@ class Services: "ostype": 'CentOS 5.3 (64-bit)', "sleep": 60, "timeout": 10, - "mode": 'advanced' } class TestVPCNetworkLBRules(cloudstackTestCase): @@ -408,7 +405,7 @@ class TestVPCNetworkLBRules(cloudstackTestCase): self.services["vpc_offering"] ) - self._cleanup.append(self.vpc_off) + self._cleanup.append(vpc_off) self.debug("Enabling the VPC offering created") vpc_off.update(self.apiclient, state='Enabled') diff --git a/test/integration/component/test_vpc_network_pfrules.py b/test/integration/component/test_vpc_network_pfrules.py index 92b04ad3f21..b478b6a1780 100644 --- a/test/integration/component/test_vpc_network_pfrules.py +++ b/test/integration/component/test_vpc_network_pfrules.py @@ -84,8 +84,6 @@ class Services: "StaticNat": 'VpcVirtualRouter', "NetworkACL": 'VpcVirtualRouter' }, - "servicecapabilitylist": { - }, }, "network_offering_no_lb": { "name": 'VPC Network offering', @@ -175,7 +173,6 @@ class Services: "ostype": 'CentOS 5.3 (64-bit)', "sleep": 60, "timeout": 10, - "mode": 'advanced' } @@ -406,7 +403,7 @@ class TestVPCNetworkPFRules(cloudstackTestCase): self.services["vpc_offering"] ) - self._cleanup.append(self.vpc_off) + self._cleanup.append(vpc_off) self.debug("Enabling the VPC offering created") vpc_off.update(self.apiclient, state='Enabled') diff --git a/test/integration/component/test_vpc_network_staticnatrule.py b/test/integration/component/test_vpc_network_staticnatrule.py index bed1b5298b3..c5d9e57434d 100644 --- a/test/integration/component/test_vpc_network_staticnatrule.py +++ b/test/integration/component/test_vpc_network_staticnatrule.py @@ -83,8 +83,6 @@ class Services: "StaticNat": 'VpcVirtualRouter', "NetworkACL": 'VpcVirtualRouter' }, - "servicecapabilitylist": { - }, }, "network_offering_no_lb": { "name": 'VPC Network offering', @@ -174,7 +172,6 @@ class Services: "ostype": 'CentOS 5.3 (64-bit)', "sleep": 60, "timeout": 10, - "mode": 'advanced' } diff --git a/test/integration/component/test_vpc_offerings.py b/test/integration/component/test_vpc_offerings.py index a111d7d9059..cf37d907d5e 100644 --- a/test/integration/component/test_vpc_offerings.py +++ b/test/integration/component/test_vpc_offerings.py @@ -130,7 +130,6 @@ class Services: # Cent OS 5.3 (64 bit) "sleep": 60, "timeout": 10, - "mode": 'advanced' } @@ -181,36 +180,7 @@ class TestVPCOffering(cloudstackTestCase): admin=True, domainid=self.domain.id ) - self.cleanup = [] - return - - def tearDown(self): - try: - #Clean up, terminate the created network offering - self.account.delete(self.apiclient) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - cleanup_resources(self.apiclient, self.cleanup) - interval = list_configurations( - self.apiclient, - name='network.gc.interval' - ) - wait = list_configurations( - self.apiclient, - name='network.gc.wait' - ) - # Sleep to ensure that all resources are deleted - time.sleep(int(interval[0].value) + int(wait[0].value)) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) + self._cleanup.insert(0, self.account) return def validate_vpc_offering(self, vpc_offering): @@ -273,7 +243,7 @@ class TestVPCOffering(cloudstackTestCase): ) self.debug("Check if the VPC offering is created successfully?") - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) self.validate_vpc_offering(vpc_off) return @@ -581,7 +551,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) self.validate_vpc_offering(vpc_off) self.debug("Enabling the VPC offering created") @@ -700,7 +670,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) self.validate_vpc_offering(vpc_off) self.debug("Enabling the VPC offering created") @@ -821,7 +791,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) self.validate_vpc_offering(vpc_off) self.debug("Enabling the VPC offering created") @@ -934,7 +904,7 @@ class TestVPCOffering(cloudstackTestCase): ) self.validate_vpc_offering(vpc_off) # Appending to cleanup to delete after test - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) except Exception as e: self.fail("Failed to create the VPC offering - %s" % e) return @@ -958,7 +928,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off) + self._cleanup.append(vpc_off) self.validate_vpc_offering(vpc_off) self.debug("Enabling the VPC offering created") @@ -1054,7 +1024,7 @@ class TestVPCOffering(cloudstackTestCase): self.apiclient, self.services["vpc_offering"] ) - self.cleanup.append(vpc_off_1) + self._cleanup.append(vpc_off_1) self.validate_vpc_offering(vpc_off_1) self.debug("Disabling the VPC offering created") vpc_off_1.update(self.apiclient, state='Disabled') @@ -1064,7 +1034,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off_2) + self._cleanup.append(vpc_off_2) self.validate_vpc_offering(vpc_off_2) self.debug("Enabling the VPC offering created") vpc_off_2.update(self.apiclient, state='Enabled') @@ -1074,7 +1044,7 @@ class TestVPCOffering(cloudstackTestCase): self.services["vpc_offering"] ) - self.cleanup.append(vpc_off_3) + self._cleanup.append(vpc_off_3) self.validate_vpc_offering(vpc_off_3) self.debug("Enabling the VPC offering created") vpc_off_3.update(self.apiclient, state='Enabled') @@ -1083,7 +1053,7 @@ class TestVPCOffering(cloudstackTestCase): self.apiclient, self.services["vpc_offering"] ) - self.validate_vpc_offering(vpc_off_4) + self._cleanup.append(vpc_off_4) self.debug("Enabling the VPC offering created") vpc_off_4.update(self.apiclient, state='Enabled') diff --git a/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py b/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py index af832995245..fc8e71648af 100644 --- a/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py +++ b/test/integration/smoke/test_deploy_vms_with_varied_deploymentplanners.py @@ -16,7 +16,7 @@ # under the License. from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.integration.lib.base import Account, VirtualMachine, ServiceOffering, Host +from marvin.integration.lib.base import Account, VirtualMachine, ServiceOffering, Host, Cluster from marvin.integration.lib.common import get_zone, get_domain, get_template, cleanup_resources from nose.plugins.attrib import attr @@ -77,6 +77,7 @@ class TestDeployVmWithVariedPlanners(cloudstackTestCase): ) cls.services["account"] = cls.account.name cls.hosts = Host.list(cls.apiclient, type='Routing') + cls.clusters = Cluster.list(cls.apiclient) cls.cleanup = [ cls.account ] @@ -241,10 +242,13 @@ class TestDeployVmWithVariedPlanners(cloudstackTestCase): ) vm1clusterid = filter(lambda c: c.id == vm1.hostid, self.hosts)[0].clusterid vm2clusterid = filter(lambda c: c.id == vm2.hostid, self.hosts)[0].clusterid + + vm1podid = filter(lambda p: p.id == vm1clusterid, self.clusters)[0].podid + vm2podid = filter(lambda p: p.id == vm2clusterid, self.clusters)[0].podid self.assertEqual( - vm1clusterid, - vm2clusterid, - msg="VMs (%s, %s) meant to be concentrated are deployed on different clusters (%s, %s)" % (vm1.id, vm2.id, vm1clusterid, vm2clusterid) + vm1podid, + vm2podid, + msg="VMs (%s, %s) meant to be pod concentrated are deployed on different pods (%s, %s)" % (vm1.id, vm2.id, vm1clusterid, vm2clusterid) ) @classmethod diff --git a/test/integration/smoke/test_network.py b/test/integration/smoke/test_network.py index a75ffeb8953..121bda03506 100644 --- a/test/integration/smoke/test_network.py +++ b/test/integration/smoke/test_network.py @@ -1163,7 +1163,7 @@ class TestRebootRouter(cloudstackTestCase): self.debug("SSH into VM (ID : %s ) after reboot" % self.vm_1.id) remoteSSHClient( - self.nat_rule.ipaddress.ipaddress, + self.nat_rule.ipaddress, self.services["natrule"]["publicport"], self.vm_1.username, self.vm_1.password diff --git a/test/integration/smoke/test_nic.py b/test/integration/smoke/test_nic.py index 8e8d3407dfb..0d43a920e97 100644 --- a/test/integration/smoke/test_nic.py +++ b/test/integration/smoke/test_nic.py @@ -122,9 +122,6 @@ class Services: "name": "Cent OS Template", "passwordenabled": True, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, #Migrate VM to hostid diff --git a/test/integration/smoke/test_portable_publicip.py b/test/integration/smoke/test_portable_publicip.py index 5b2fbc7e307..9a3a398c17a 100644 --- a/test/integration/smoke/test_portable_publicip.py +++ b/test/integration/smoke/test_portable_publicip.py @@ -21,7 +21,6 @@ from marvin.cloudstackAPI import * from marvin.integration.lib.utils import * from marvin.integration.lib.base import * from marvin.integration.lib.common import * -from marvin import remoteSSHClient from nose.plugins.attrib import attr class Services: diff --git a/test/integration/smoke/test_resource_detail.py b/test/integration/smoke/test_resource_detail.py index 1d5db3ae4e6..93bc2ffc1f1 100644 --- a/test/integration/smoke/test_resource_detail.py +++ b/test/integration/smoke/test_resource_detail.py @@ -91,9 +91,6 @@ class Services: "name": "xs", "passwordenabled": False, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, #Migrate VM to hostid diff --git a/test/integration/smoke/test_scale_vm.py b/test/integration/smoke/test_scale_vm.py index fa2418b7cd8..b23ddd1b2cd 100644 --- a/test/integration/smoke/test_scale_vm.py +++ b/test/integration/smoke/test_scale_vm.py @@ -85,9 +85,6 @@ class Services: "name": "xs", "passwordenabled": False, }, - "diskdevice": '/dev/xvdd', - # Disk device where ISO is attached to instance - "mount_dir": "/mnt/tmp", "sleep": 60, "timeout": 10, #Migrate VM to hostid diff --git a/test/integration/smoke/test_ssvm.py b/test/integration/smoke/test_ssvm.py index d637f966a0b..6893472ebe1 100644 --- a/test/integration/smoke/test_ssvm.py +++ b/test/integration/smoke/test_ssvm.py @@ -334,7 +334,19 @@ class TestSSVMs(cloudstackTestCase): self.debug("Running SSVM check script") - result = get_process_status( + if self.apiclient.hypervisor.lower() == 'vmware': + #SSH into SSVMs is done via management server for Vmware + result = get_process_status( + self.apiclient.connection.mgtSvr, + 22, + self.apiclient.connection.user, + self.apiclient.connection.passwd, + ssvm.privateip, + "/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL", + hypervisor=self.apiclient.hypervisor + ) + else: + result = get_process_status( host.ipaddress, self.services['host']["publicport"], self.services['host']["username"], @@ -358,7 +370,19 @@ class TestSSVMs(cloudstackTestCase): ) #Check status of cloud service - result = get_process_status( + if self.apiclient.hypervisor.lower() == 'vmware': + #SSH into SSVMs is done via management server for Vmware + result = get_process_status( + self.apiclient.connection.mgtSvr, + 22, + self.apiclient.connection.user, + self.apiclient.connection.passwd, + ssvm.privateip, + "service cloud status", + hypervisor=self.apiclient.hypervisor + ) + else: + result = get_process_status( host.ipaddress, self.services['host']["publicport"], self.services['host']["username"], @@ -426,7 +450,19 @@ class TestSSVMs(cloudstackTestCase): self.debug("Checking cloud process status") - result = get_process_status( + if self.apiclient.hypervisor.lower() == 'vmware': + #SSH into SSVMs is done via management server for vmware + result = get_process_status( + self.apiclient.connection.mgtSvr, + 22, + self.apiclient.connection.user, + self.apiclient.connection.passwd, + cpvm.privateip, + "service cloud status", + hypervisor=self.apiclient.hypervisor + ) + else: + result = get_process_status( host.ipaddress, self.services['host']["publicport"], self.services['host']["username"], diff --git a/test/integration/smoke/test_vm_life_cycle.py b/test/integration/smoke/test_vm_life_cycle.py index 9aaa13fcb57..a7283478879 100644 --- a/test/integration/smoke/test_vm_life_cycle.py +++ b/test/integration/smoke/test_vm_life_cycle.py @@ -739,7 +739,7 @@ class TestVMLifeCycle(cloudstackTestCase): self.debug("Found %s host" % hosts[0].hypervisor) if hosts[0].hypervisor.lower() == "kvm": - self.services["diskdevice"] = "/dev/vda" + self.services["diskdevice"] = "/dev/vdb" try: ssh_client = self.virtual_machine.get_ssh_client() diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py index 1bb9e5dd011..dd3d8a41b0b 100644 --- a/test/integration/smoke/test_volumes.py +++ b/test/integration/smoke/test_volumes.py @@ -81,7 +81,6 @@ class Services: "privateport": 22, "publicport": 22, "protocol": 'TCP', - "diskdevice": "/dev/xvdb", "ostype": 'CentOS 5.5 (64-bit)', "sleep": 10, "timeout": 600, diff --git a/tools/cli/cloudmonkey/config.py b/tools/cli/cloudmonkey/config.py index aaf97ebd25d..36f7e77ed82 100644 --- a/tools/cli/cloudmonkey/config.py +++ b/tools/cli/cloudmonkey/config.py @@ -18,7 +18,7 @@ # Use following rules for versioning: # - -__version__ = "4.1.0-0" +__version__ = "4.2.0-0" __description__ = "Command Line Interface for Apache CloudStack" __maintainer__ = "Rohit Yadav" __maintaineremail__ = "bhaisaab@apache.org" diff --git a/tools/cli/cloudmonkey/requester.py b/tools/cli/cloudmonkey/requester.py index d2dae6dfc3f..b06e1fc99e3 100644 --- a/tools/cli/cloudmonkey/requester.py +++ b/tools/cli/cloudmonkey/requester.py @@ -125,61 +125,36 @@ def monkeyrequest(command, args, isasync, asyncblock, logger, host, port, command = "queryAsyncJobResult" request = {'jobid': jobid} timeout = int(timeout) - pollperiod = 3 + pollperiod = 2 progress = 1 while timeout > 0: print '\r' + '.' * progress, sys.stdout.flush() - progress += 1 + time.sleep(pollperiod) timeout = timeout - pollperiod + progress += 1 logger_debug(logger, "Job %s to timeout in %ds" % (jobid, timeout)) - sys.stdout.flush() - if re.match("queryAsyncJobResult", command): - time.sleep(pollperiod) - else: - response, error = monkeyrequest(command, request, isasync, - asyncblock, logger, - host, port, apikey, secretkey, - timeout, protocol, path) + response, error = make_request(command, request, logger, + host, port, apikey, secretkey, + protocol, path) + if error is not None: + return response, error + response = process_json(response) responsekeys = filter(lambda x: 'response' in x, response.keys()) if len(responsekeys) < 1: - time.sleep(pollperiod) continue result = response[responsekeys[0]] jobstatus = result['jobstatus'] - jobresultcode = result['jobresultcode'] - try: - jobresult = result["jobresult"] - logger_debug(logger, "jobresult %s" % (jobresult)) - sys.stdout.flush() - return response, None - except KeyError: - logger_debug(logger, "No jobresult yet %s" % (result)) - sys.stdout.flush() - - if jobresultcode != 0: - error = "Error: resultcode %d for jobid %s" % (jobresultcode, - jobid) - logger_debug(logger, "%s" % (error)) - return response, error - else: - # if we get a valid respons resultcode give back results - response, error = monkeyrequest(command, request, isasync, - asyncblock, logger, - host, port, apikey, secretkey, - timeout, protocol, path) - logger_debug(logger, "Ok: %s" % (jobid)) - return response, error - if jobstatus == 2: + jobresult = result["jobresult"] error = "\rAsync job %s failed\nError %s, %s" % (jobid, jobresult["errorcode"], jobresult["errortext"]) return response, error elif jobstatus == 1: - print '\r', + print "\r" + " " * progress, return response, error else: logger_debug(logger, "We should not arrive here!") diff --git a/tools/marvin/marvin/cloudstackTestClient.py b/tools/marvin/marvin/cloudstackTestClient.py index d85a61c4872..37380d62f73 100644 --- a/tools/marvin/marvin/cloudstackTestClient.py +++ b/tools/marvin/marvin/cloudstackTestClient.py @@ -121,6 +121,7 @@ class cloudstackTestClient(object): apiKey, securityKey, self.connection.asyncTimeout, self.connection.logging) self.userApiClient = cloudstackAPIClient.CloudStackAPIClient(newUserConnection) self.userApiClient.connection = newUserConnection + self.userApiClient.hypervisor = self.apiClient.hypervisor return self.userApiClient def close(self): diff --git a/tools/marvin/marvin/integration/lib/utils.py b/tools/marvin/marvin/integration/lib/utils.py index 6892c41d1ec..839ec89f4fd 100644 --- a/tools/marvin/marvin/integration/lib/utils.py +++ b/tools/marvin/marvin/integration/lib/utils.py @@ -160,7 +160,7 @@ def get_process_status(hostip, port, username, password, linklocalip, process, h #SSH to the machine ssh = remoteSSHClient(hostip, port, username, password) if str(hypervisor).lower() == 'vmware': - ssh_command = "ssh -i /var/lib/cloud/management/.ssh/id_rsa -ostricthostkeychecking=no " + ssh_command = "ssh -i /var/cloudstack/management/.ssh/id_rsa -ostricthostkeychecking=no " else: ssh_command = "ssh -i ~/.ssh/id_rsa.cloud -ostricthostkeychecking=no " diff --git a/tools/marvin/marvin/marvinPlugin.py b/tools/marvin/marvin/marvinPlugin.py index 46a8a4f3445..846f73577c1 100644 --- a/tools/marvin/marvin/marvinPlugin.py +++ b/tools/marvin/marvin/marvinPlugin.py @@ -34,9 +34,15 @@ class MarvinPlugin(Plugin): """ name = "marvin" + def configure(self, options, config): - self.enabled = 1 - self.enableOpt = "--with-marvin" + if hasattr(options,self.enableOpt): + if not getattr(options, self.enableOpt): + self.enabled = False + return + else: + self.enabled = True + self.logformat = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s") if options.debug_log: diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index a86b2a25ca5..7113dbcb557 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -140,6 +140,17 @@ table tbody td.loading { border-top: 1px solid #FBFBFB; } +table tbody td.truncated { + overflow: visible; + max-width: 88px; +} + +table tbody td.truncated > span { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + /** Actions table cell*/ table tbody td.actions { width: 130px; @@ -441,7 +452,7 @@ body.login { div.list-view table tbody td span { display: block; float: left; - max-width: 100%; + max-width: 89%; word-wrap: break-word; text-indent: 0; margin-left: 12px; @@ -3457,6 +3468,12 @@ div.view table td.editable div.edit { top: 0px; } +div.view table td.truncated.editable div.edit { + top: 1px; + width: 285px; + left: 1px; +} + div.view table td.editable div.edit input { float: left; width: 66%; @@ -9087,29 +9104,63 @@ div.ui-dialog div.multi-edit-add-list div.view div.data-table table.body tbody t /*** View switcher (drop-down)*/ .project-switcher { float: left; - width: 141px; + width: 223px; padding: 9px 17px 0 0; -} - -.project-switcher label { - position: absolute; - top: -2px; - color: #FFFFFF; - font-size: 11px; -} - -.project-switcher select { - width: 100%; - font-size: 12px; - border: 1px solid #000000; - border-bottom: #FFFFFF; /*+border-radius:4px;*/ -moz-border-radius: 4px; -webkit-border-radius: 4px; -khtml-border-radius: 4px; border-radius: 4px; - background: #ECECEC; - margin-top: 2px; +} + +.project-switcher label { + position: absolute; + top: 15px; + color: #FFFFFF; + font-size: 12px; + font-weight: bold; +} + +.project-switcher select { + width: 79%; + font-weight: bold; + font-size: 12px; + /*+text-shadow:0px -1px 1px #000000;*/ + -moz-text-shadow: 0px -1px 1px #000000; + -webkit-text-shadow: 0px -1px 1px #000000; + -o-text-shadow: 0px -1px 1px #000000; + text-shadow: 0px -1px 1px #000000; + border: 1px solid #9A9A9A; + border-bottom: #FFFFFF; + /*+box-shadow:inset 0px -1px #A2A2A2;*/ + -moz-box-shadow: inset 0px -1px #A2A2A2; + -webkit-box-shadow: inset 0px -1px #A2A2A2; + -o-box-shadow: inset 0px -1px #A2A2A2; + box-shadow: inset 0px -1px #A2A2A2; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + color: #FFFFFF; + margin-top: -2px; + margin-left: 53px; + background: url(../images/bg-gradients.png) 0px -867px; + padding: 5px; +} + +.project-switcher select:hover { + /*+box-shadow:inset 0px 2px 6px #3B3B3B;*/ + -moz-box-shadow: inset 0px 2px 6px #3B3B3B; + -webkit-box-shadow: inset 0px 2px 6px #3B3B3B; + -o-box-shadow: inset 0px 2px 6px #3B3B3B; + box-shadow: inset 0px 2px 6px #3B3B3B; + cursor: pointer; + border-bottom: 1px solid #828282; +} + +.project-switcher select option { + background: #7F8487; } /*** Select project*/ diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index a5f0662e0bf..7809cdb6c9d 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -472,6 +472,10 @@ dictionary = { 'label.disable.vpn': '', 'label.disabling.vpn.access': '', 'label.disk.allocated': '', +'label.disk.bytes.read.rate': '', +'label.disk.bytes.write.rate': '', +'label.disk.iops.write.rate': '', +'label.disk.iops.read.rate': '', 'label.disk.read.bytes': '', 'label.disk.read.io': '', 'label.disk.offering': '', diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index cadde8c91a7..b1a68512382 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -109,6 +109,34 @@ number: true } }, + diskBytesReadRate: { + label: 'label.disk.bytes.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskBytesWriteRate: { + label: 'label.disk.bytes.write.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsReadRate: { + label: 'label.disk.iops.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsWriteRate: { + label: 'label.disk.iops.write.rate', + validation: { + required: false, //optional + number: true + } + }, offerHA: { label: 'label.offer.ha', docID: 'helpComputeOfferingHA', @@ -227,7 +255,26 @@ networkrate: args.data.networkRate }); } - + if(args.data.diskBytesReadRate != null && args.data.diskBytesReadRate.length > 0) { + $.extend(data, { + bytesreadrate: args.data.diskBytesReadRate + }); + } + if(args.data.diskBytesWriteRate != null && args.data.diskBytesWriteRate.length > 0) { + $.extend(data, { + byteswriterate: args.data.diskBytesWriteRate + }); + } + if(args.data.diskIopsReadRate != null && args.data.diskIopsReadRate.length > 0) { + $.extend(data, { + iopsreadrate: args.data.diskIopsReadRate + }); + } + if(args.data.diskIopsWriteRate != null && args.data.diskIopsWriteRate.length > 0) { + $.extend(data, { + iopswriterate: args.data.diskIopsWriteRate + }); + } $.extend(data, { offerha: (args.data.offerHA == "on") }); @@ -396,6 +443,10 @@ } }, networkrate: { label: 'label.network.rate' }, + diskBytesReadRate: { label: 'label.disk.bytes.read.rate' }, + diskBytesWriteRate: { label: 'label.disk.bytes.write.rate' }, + diskIopsReadRate: { label: 'label.disk.iops.read.rate' }, + diskIopsWriteRate: { label: 'label.disk.iops.write.rate' }, offerha: { label: 'label.offer.ha', converter: cloudStack.converters.toBooleanText @@ -534,6 +585,34 @@ number: true } }, + diskBytesReadRate: { + label: 'label.disk.bytes.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskBytesWriteRate: { + label: 'label.disk.bytes.write.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsReadRate: { + label: 'label.disk.iops.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsWriteRate: { + label: 'label.disk.iops.write.rate', + validation: { + required: false, //optional + number: true + } + }, offerHA: { label: 'label.offer.ha', docID: 'helpSystemOfferingHA', @@ -602,6 +681,26 @@ networkrate: args.data.networkRate }); } + if(args.data.diskBytesReadRate != null && args.data.diskBytesReadRate.length > 0) { + $.extend(data, { + bytesreadrate: args.data.diskBytesReadRate + }); + } + if(args.data.diskBytesWriteRate != null && args.data.diskBytesWriteRate.length > 0) { + $.extend(data, { + byteswriterate: args.data.diskBytesWriteRate + }); + } + if(args.data.diskIopsReadRate != null && args.data.diskIopsReadRate.length > 0) { + $.extend(data, { + iopsreadrate: args.data.diskIopsReadRate + }); + } + if(args.data.diskIopsWriteRate != null && args.data.diskIopsWriteRate.length > 0) { + $.extend(data, { + iopswriterate: args.data.diskIopsWriteRate + }); + } $.extend(data, { offerha: (args.data.offerHA == "on") @@ -781,6 +880,10 @@ } }, networkrate: { label: 'label.network.rate' }, + diskBytesReadRate: { label: 'label.disk.bytes.write.rate' }, + diskBytesWriteRate: { label: 'label.disk.bytes.write.rate' }, + diskIopsReadRate: { label: 'label.disk.iops.write.rate' }, + diskIopsWriteRate: { label: 'label.disk.iops.write.rate' }, offerha: { label: 'label.offer.ha', converter: cloudStack.converters.toBooleanText @@ -911,6 +1014,34 @@ dependsOn: 'isCustomized', validation: { required: true, number: true } }, + diskBytesReadRate: { + label: 'label.disk.bytes.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskBytesWriteRate: { + label: 'label.disk.bytes.write.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsReadRate: { + label: 'label.disk.iops.read.rate', + validation: { + required: false, //optional + number: true + } + }, + diskIopsWriteRate: { + label: 'label.disk.iops.write.rate', + validation: { + required: false, //optional + number: true + } + }, tags: { label: 'label.storage.tags', docID: 'helpDiskOfferingStorageTags' @@ -972,6 +1103,26 @@ domainid: args.data.domainId }); } + if(args.data.diskBytesReadRate != null && args.data.diskBytesReadRate.length > 0) { + $.extend(data, { + bytesreadrate: args.data.diskBytesReadRate + }); + } + if(args.data.diskBytesWriteRate != null && args.data.diskBytesWriteRate.length > 0) { + $.extend(data, { + byteswriterate: args.data.diskBytesWriteRate + }); + } + if(args.data.diskIopsReadRate != null && args.data.diskIopsReadRate.length > 0) { + $.extend(data, { + iopsreadrate: args.data.diskIopsReadRate + }); + } + if(args.data.diskIopsWriteRate != null && args.data.diskIopsWriteRate.length > 0) { + $.extend(data, { + iopswriterate: args.data.diskIopsWriteRate + }); + } $.ajax({ url: createURL('createDiskOffering'), @@ -1084,6 +1235,10 @@ return "N/A"; } }, + diskBytesReadRate: { label: 'label.disk.bytes.write.rate' }, + diskBytesWriteRate: { label: 'label.disk.bytes.write.rate' }, + diskIopsReadRate: { label: 'label.disk.iops.write.rate' }, + diskIopsWriteRate: { label: 'label.disk.iops.write.rate' }, tags: { label: 'label.storage.tags' }, domain: { label: 'label.domain' }, storagetype: { label: 'label.storage.type' } diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js index 48db443f7a8..5aa352afdbf 100755 --- a/ui/scripts/docs.js +++ b/ui/scripts/docs.js @@ -231,7 +231,7 @@ cloudStack.docs = { externalLink: '' }, helpComputeOfferingNetworkRate: { - desc: 'Allowed data transfer rate in MB per second', + desc: 'Allowed data transfer rate in megabits(Mb) per second', externalLink: '' }, helpComputeOfferingHA: { @@ -482,7 +482,7 @@ cloudStack.docs = { externalLink: '' }, helpNetworkOfferingNetworkRate: { - desc: 'Allowed data transfer rate in MB per second', + desc: 'Allowed data transfer rate in megabits(Mb) per second', externalLink: '' }, helpNetworkOfferingTrafficType: { @@ -699,7 +699,7 @@ cloudStack.docs = { externalLink: '' }, helpSystemOfferingNetworkRate: { - desc: 'Allowed data transfer rate in MB per second', + desc: 'Allowed data transfer rate in megabits(Mb) per second', externalLink: '' }, helpSystemOfferingHA: { diff --git a/ui/scripts/globalSettings.js b/ui/scripts/globalSettings.js index 2687fcaac03..1ae73b70604 100644 --- a/ui/scripts/globalSettings.js +++ b/ui/scripts/globalSettings.js @@ -57,7 +57,7 @@ fields: { name: { label: 'label.name', id: true }, description: { label: 'label.description' }, - value: { label: 'label.value', editable: true } + value: { label: 'label.value', editable: true, truncate: true } }, dataProvider: function(args) { var data = { diff --git a/ui/scripts/network.js b/ui/scripts/network.js index fb63e4b4f19..d18e796b9a6 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -274,40 +274,46 @@ } }; - var networkOfferingObjs = []; - var checkVpc=0; + var networkOfferingObjs = []; + var advZoneObjs; + cloudStack.sections.network = { title: 'label.network', id: 'network', sectionSelect: { preFilter: function(args) { - var havingSecurityGroupNetwork = false; - + var sectionsToShow = ['networks']; + + $.ajax({ + url: createURL('listZones'), + data: { + networktype: 'Advanced' + }, + async: false, + success: function(json) { + advZoneObjs = json.listzonesresponse.zone; + if(advZoneObjs != null && advZoneObjs.length > 0) { + sectionsToShow.push('vpc'); + sectionsToShow.push('vpnCustomerGateway'); + } + } + }); + $.ajax({ url: createURL('listNetworks', { ignoreProject: true }), data: { supportedServices: 'SecurityGroup', listAll: true, - details: 'min' + details: 'min' }, async: false, - success: function(data) { - if (data.listnetworksresponse.network != null && data.listnetworksresponse.network.length > 0) { - havingSecurityGroupNetwork = true; + success: function(json) { + if(json.listnetworksresponse.network != null && json.listnetworksresponse.network.length > 0) { + sectionsToShow.push('securityGroups'); } } }); - - var sectionsToShow = ['networks']; - - if(args.context.zoneType != 'Basic') { //Advanced type or all types - sectionsToShow.push('vpc'); - sectionsToShow.push('vpnCustomerGateway'); - } - - if(havingSecurityGroupNetwork == true) - sectionsToShow.push('securityGroups'); - + return sectionsToShow; }, @@ -323,11 +329,18 @@ add: { label: 'Add Isolated Guest Network with SourceNat', - preFilter: function(args) { //Isolated networks is only supported in Advanced (SG-disabled) zone - if(args.context.zoneType != 'Basic') - return true; - else - return false; + preFilter: function(args) { + if(advZoneObjs != null && advZoneObjs.length > 0) { + for(var i = 0; i < advZoneObjs.length; i++) { + if(advZoneObjs[i].securitygroupsenabled != true) { //'Add Isolated Guest Network with SourceNat' is only supported in Advanced SG-disabled zone + return true; + } + } + return false; + } + else{ + return false; + } }, createForm: { @@ -4532,78 +4545,67 @@ docID: 'helpVPCDomain', label: 'label.DNS.domain.for.guest.networks' }, - - loadbalancer:{ //Support for Netscaler as an external device for load balancing - label:'Load Balancer', + publicLoadBalancerProvider:{ + label:'Public Load Balancer Provider', select:function(args){ - $.ajax({ - url:createURL('listVPCOfferings&listall=true'), - dataType:'json', - success:function(json){ - var items=[]; - var vpcObj = json.listvpcofferingsresponse.vpcoffering; - $(vpcObj).each(function(){ - items.push({id:this.id , description:this.name}); - }); - args.response.success({data:items}); - - } - - }); - - } - - } - + var items = []; + items.push({id: 'VpcVirtualRouter', description: 'VpcVirtualRouter'}); + items.push({id: 'Netscaler', description: 'Netscaler'}); + args.response.success({data: items}); + } + } } }, - action: function(args) { - /* var defaultvpcofferingid; - $.ajax({ - url: createURL("listVPCOfferings"), - dataType: "json", - data: { - isdefault: true - }, - async: false, - success: function(json) { - defaultvpcofferingid = json.listvpcofferingsresponse.vpcoffering[0].id; - } - });*/ - - var dataObj = { - name: args.data.name, - displaytext: args.data.displaytext, - zoneid: args.data.zoneid, - cidr: args.data.cidr, - vpcofferingid: args.data.loadbalancer // Support for external load balancer - }; - - if(args.data.networkdomain != null && args.data.networkdomain.length > 0) - $.extend(dataObj, { networkdomain: args.data.networkdomain }); - - $.ajax({ - url: createURL("createVPC"), - dataType: "json", - data: dataObj, - async: true, - success: function(json) { - var jid = json.createvpcresponse.jobid; - args.response.success( - {_custom: - {jobId: jid, - getUpdatedItem: function(json) { - return json.queryasyncjobresultresponse.jobresult.vpc; - } + action: function(args) { + var vpcOfferingName; + if (args.data.publicLoadBalancerProvider == 'VpcVirtualRouter') + vpcOfferingName = 'Default VPC offering'; + else if (args.data.publicLoadBalancerProvider == 'Netscaler') + vpcOfferingName = 'Default VPC offering with Netscaler'; + + $.ajax({ + url:createURL('listVPCOfferings'), + data: { + name: vpcOfferingName + }, + success:function(json){ + var vpcofferingid = json.listvpcofferingsresponse.vpcoffering[0].id; + + var dataObj = { + name: args.data.name, + displaytext: args.data.displaytext, + zoneid: args.data.zoneid, + cidr: args.data.cidr, + vpcofferingid: vpcofferingid + }; + + if(args.data.networkdomain != null && args.data.networkdomain.length > 0) + $.extend(dataObj, { networkdomain: args.data.networkdomain }); + + $.ajax({ + url: createURL("createVPC"), + dataType: "json", + data: dataObj, + async: true, + success: function(json) { + var jid = json.createvpcresponse.jobid; + args.response.success( + {_custom: + {jobId: jid, + getUpdatedItem: function(json) { + return json.queryasyncjobresultresponse.jobresult.vpc; + } + } + }); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); } - }); - }, - error: function(data) { - args.response.error(parseXMLHttpResponse(data)); - } - }); - }, - + }); + } + }); + + }, notification: { poll: pollAsyncJobResult } diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index d87f0dcb0ae..86dc68eaf4b 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -114,11 +114,7 @@ function createURL(apiName, options) { if (cloudStack.context && cloudStack.context.projects && !options.ignoreProject) { urlString = urlString + '&projectid=' + cloudStack.context.projects[0].id; } - - if(cloudStack.context != null && cloudStack.context.zoneType != null && cloudStack.context.zoneType.length > 0) { //Basic type or Advanced type - urlString = urlString + '&zonetype=' + cloudStack.context.zoneType; - } - + return urlString; } diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 0d5e212b061..b0da21cfdfb 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -1321,6 +1321,13 @@ } }, + preFilter: function(args) { //Shared networks is only supported in Basic zone and Advanced zone with SG + if(selectedZoneObj.networktype == "Advanced" && selectedZoneObj.securitygroupsenabled != true) + return false; + else + return true; + }, + createForm: { title: 'label.add.guest.network', //Add guest network in advanced zone @@ -4019,6 +4026,332 @@ } }, + //Baremetal DHCP provider detail view + BaremetalDhcpProvider: { + type: 'detailView', + id: 'BaremetalDhcpProvider', + label: 'Baremetal DHCP Provider', + viewAll: { label: 'label.devices', path: '_zone.BaremetalDhcpDevices' }, + tabs: { + details: { + title: 'label.details', + fields: [ + { + name: { label: 'label.name' } + }, + { + state: { label: 'label.state' } + } + ], + dataProvider: function(args) { + refreshNspData("BaremetalDhcpProvider"); + var providerObj; + $(nspHardcodingArray).each(function(){ + if(this.id == "BaremetalDhcpProvider") { + providerObj = this; + return false; //break each loop + } + }); + args.response.success({ + data: providerObj, + actionFilter: networkProviderActionFilter('BaremetalDhcpProvider') + }); + } + } + }, + actions: { + add: { + label: 'Add Baremetal DHCP Device', + createForm: { + title: 'Add Baremetal DHCP Device', + fields: { + url: { + label: 'label.url', + validation: { required: true } + }, + username: { + label: 'label.username', + validation: { required: true } + }, + password: { + label: 'label.password', + isPassword: true, + validation: { required: true } + } + } + }, + action: function(args) { + addBaremetalDhcpDeviceFn(args); + }, + messages: { + notification: function(args) { + return 'Add Baremetal DHCP Device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + enable: { + label: 'label.enable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["BaremetalDhcpProvider"].id + "&state=Enabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.enable.provider'; + }, + notification: function() { + return 'label.enable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + disable: { + label: 'label.disable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["BaremetalDhcpProvider"].id + "&state=Disabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.disable.provider'; + }, + notification: function() { + return 'label.disable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + destroy: { + label: 'label.shutdown.provider', + action: function(args) { + $.ajax({ + url: createURL("deleteNetworkServiceProvider&id=" + nspMap["BaremetalDhcpProvider"].id), + dataType: "json", + success: function(json) { + var jid = json.deletenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid + } + } + ); + + $(window).trigger('cloudStack.fullRefresh'); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.shutdown.provider'; + }, + notification: function(args) { + return 'label.shutdown.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + } + } + }, + + //Baremetal PXE provider detail view + BaremetalPxeProvider: { + type: 'detailView', + id: 'BaremetalPxeProvider', + label: 'Baremetal PXE Provider', + viewAll: { label: 'label.devices', path: '_zone.BaremetalPxeDevices' }, + tabs: { + details: { + title: 'label.details', + fields: [ + { + name: { label: 'label.name' } + }, + { + state: { label: 'label.state' } + } + ], + dataProvider: function(args) { + refreshNspData("BaremetalPxeProvider"); + var providerObj; + $(nspHardcodingArray).each(function(){ + if(this.id == "BaremetalPxeProvider") { + providerObj = this; + return false; //break each loop + } + }); + args.response.success({ + data: providerObj, + actionFilter: networkProviderActionFilter('BaremetalPxeProvider') + }); + } + } + }, + actions: { + add: { + label: 'Add Baremetal PXE Device', + createForm: { + title: 'Add Baremetal PXE Device', + fields: { + url: { + label: 'label.url', + validation: { required: true } + }, + username: { + label: 'label.username', + validation: { required: true } + }, + password: { + label: 'label.password', + isPassword: true, + validation: { required: true } + }, + tftpdir: { + label: 'Tftp root directory', + validation: { required: true } + } + } + }, + action: function(args) { + addBaremetalPxeDeviceFn(args); + }, + messages: { + notification: function(args) { + return 'Add Baremetal PXE Device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + enable: { + label: 'label.enable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["BaremetalPxeProvider"].id + "&state=Enabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.enable.provider'; + }, + notification: function() { + return 'label.enable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + disable: { + label: 'label.disable.provider', + action: function(args) { + $.ajax({ + url: createURL("updateNetworkServiceProvider&id=" + nspMap["BaremetalPxeProvider"].id + "&state=Disabled"), + dataType: "json", + success: function(json) { + var jid = json.updatenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + $(window).trigger('cloudStack.fullRefresh'); + } + } + } + ); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.disable.provider'; + }, + notification: function() { + return 'label.disable.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + }, + destroy: { + label: 'label.shutdown.provider', + action: function(args) { + $.ajax({ + url: createURL("deleteNetworkServiceProvider&id=" + nspMap["BaremetalPxeProvider"].id), + dataType: "json", + success: function(json) { + var jid = json.deletenetworkserviceproviderresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid + } + } + ); + + $(window).trigger('cloudStack.fullRefresh'); + } + }); + }, + messages: { + confirm: function(args) { + return 'message.confirm.shutdown.provider'; + }, + notification: function(args) { + return 'label.shutdown.provider'; + } + }, + notification: { poll: pollAsyncJobResult } + } + } + }, + //f5 provider detail view f5: { type: 'detailView', @@ -7929,6 +8262,134 @@ } }, + // Baremetal DHCP devices listView + BaremetalDhcpDevices: { + id: 'BaremetalDhcpDevices', + title: 'Baremetal DHCP Devices', + listView: { + id: 'BaremetalDhcpDevices', + fields: { + url: { label: 'label.url' } + }, + actions: { + add: { + label: 'Add Baremetal DHCP Device', + createForm: { + title: 'Add Baremetal DHCP Device', + fields: { + url: { + label: 'label.url', + validation: { required: true } + }, + username: { + label: 'label.username', + validation: { required: true } + }, + password: { + label: 'label.password', + isPassword: true, + validation: { required: true } + } + } + }, + action: function(args) { + addBaremetalDhcpDeviceFn(args); + }, + messages: { + notification: function(args) { + return 'Add Baremetal DHCP Device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + }, + dataProvider: function(args) { + $.ajax({ + url: createURL('listBaremetalDhcp'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + page: args.page, + pageSize: pageSize + }, + dataType: "json", + async: false, + success: function(json) { + var items = json.listexternaldhcpresponse.baremetaldhcp; + args.response.success({data: items}); + } + }); + } + } + }, + + // Baremetal PXE devices listView + BaremetalPxeDevices: { + id: 'BaremetalPxeDevices', + title: 'Baremetal PXE Devices', + listView: { + id: 'BaremetalPxeDevices', + fields: { + url: { label: 'label.url' } + }, + actions: { + add: { + label: 'Add Baremetal PXE Device', + createForm: { + title: 'Add Baremetal PXE Device', + fields: { + url: { + label: 'label.url', + validation: { required: true } + }, + username: { + label: 'label.username', + validation: { required: true } + }, + password: { + label: 'label.password', + isPassword: true, + validation: { required: true } + }, + tftpdir: { + label: 'Tftp root directory', + validation: { required: true } + } + } + }, + action: function(args) { + addBaremetalPxeDeviceFn(args); + }, + messages: { + notification: function(args) { + return 'Add Baremetal PXE Device'; + } + }, + notification: { + poll: pollAsyncJobResult + } + }, + }, + dataProvider: function(args) { + $.ajax({ + url: createURL('listBaremetalPxePingServer'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + page: args.page, + pageSize: pageSize + }, + dataType: "json", + async: false, + success: function(json) { + var items = json.listpingpxeserverresponse.pingpxeserver; + args.response.success({data: items}); + } + }); + } + } + }, + // F5 devices listView f5Devices: { id: 'f5Devices', @@ -13573,6 +14034,184 @@ } }; + function addBaremetalDhcpDeviceFn(args) { + if(nspMap["BaremetalDhcpProvider"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=BaremetalDhcpProvider&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addBaremetalDhcpProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId="+jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(addBaremetalDhcpProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["BaremetalDhcpProvider"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + + $.ajax({ + url: createURL('addBaremetalDhcp'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + dhcpservertype: 'DHCPD', + url: args.data.url, + username: args.data.username, + password: args.data.password + }, + success: function(json) { + var jid = json.addexternaldhcpresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult.baremetaldhcp; + return item; + } + } + } + ); + } + }); + } + else if (result.jobstatus == 2) { + alert(_s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + alert(parseXMLHttpResponse(XMLHttpResponse)); + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } + else { + $.ajax({ + url: createURL('addBaremetalDhcp'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + dhcpservertype: 'DHCPD', + url: args.data.url, + username: args.data.username, + password: args.data.password + }, + success: function(json) { + var jid = json.addexternaldhcpresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult.baremetaldhcp; + return item; + } + } + } + ); + } + }); + } + } + + function addBaremetalPxeDeviceFn(args) { + if(nspMap["BaremetalPxeProvider"] == null) { + $.ajax({ + url: createURL("addNetworkServiceProvider&name=BaremetalPxeProvider&physicalnetworkid=" + selectedPhysicalNetworkObj.id), + dataType: "json", + async: true, + success: function(json) { + var jobId = json.addnetworkserviceproviderresponse.jobid; + var addBaremetalPxeProviderIntervalID = setInterval(function() { + $.ajax({ + url: createURL("queryAsyncJobResult&jobId="+jobId), + dataType: "json", + success: function(json) { + var result = json.queryasyncjobresultresponse; + if (result.jobstatus == 0) { + return; //Job has not completed + } + else { + clearInterval(addBaremetalPxeProviderIntervalID); + if (result.jobstatus == 1) { + nspMap["BaremetalPxeProvider"] = json.queryasyncjobresultresponse.jobresult.networkserviceprovider; + + $.ajax({ + url: createURL('addBaremetalPxeKickStartServer'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + pxeservertype: 'KICK_START', + url: args.data.url, + username: args.data.username, + password: args.data.password, + tftpdir: args.data.tftpdir + }, + success: function(json) { + var jid = json.addexternalpxeresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult.externalpxe; + return item; + } + } + } + ); + } + }); + } + else if (result.jobstatus == 2) { + alert(_s(result.jobresult.errortext)); + } + } + }, + error: function(XMLHttpResponse) { + alert(parseXMLHttpResponse(XMLHttpResponse)); + } + }); + }, g_queryAsyncJobResultInterval); + } + }); + } + else { + $.ajax({ + url: createURL('addBaremetalPxeKickStartServer'), + data: { + physicalnetworkid: selectedPhysicalNetworkObj.id, + pxeservertype: 'KICK_START', + url: args.data.url, + username: args.data.username, + password: args.data.password, + tftpdir: args.data.tftpdir + }, + success: function(json) { + var jid = json.addexternalpxeresponse.jobid; + args.response.success( + {_custom: + { + jobId: jid, + getUpdatedItem: function(json) { + var item = json.queryasyncjobresultresponse.jobresult.externalpxe; + return item; + } + } + } + ); + } + }); + } + } + function addExternalLoadBalancer(args, physicalNetworkObj, apiCmd, apiCmdRes, apiCmdObj) { var array1 = []; array1.push("&physicalnetworkid=" + physicalNetworkObj.id); @@ -14524,6 +15163,12 @@ case "MidoNet": nspMap["midoNet"] = items[i]; break; + case "BaremetalDhcpProvider": + nspMap["BaremetalDhcpProvider"] = items[i]; + break; + case "BaremetalPxeProvider": + nspMap["BaremetalPxeProvider"] = items[i]; + break; case "F5BigIp": nspMap["f5"] = items[i]; break; @@ -14565,7 +15210,17 @@ id: 'bigswitchVns', name: 'BigSwitch Vns', state: nspMap.bigswitchVns ? nspMap.bigswitchVns.state : 'Disabled' - } + }, + { + id: 'BaremetalDhcpProvider', + name: 'Baremetal DHCP', + state: nspMap.BaremetalDhcpProvider ? nspMap.BaremetalDhcpProvider.state : 'Disabled' + }, + { + id: 'BaremetalPxeProvider', + name: 'Baremetal PXE', + state: nspMap.BaremetalPxeProvider ? nspMap.BaremetalPxeProvider.state : 'Disabled' + } ]; $(window).trigger('cloudStack.system.serviceProviders.makeHarcodedArray', { diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index ba4d2881580..bc68a7241ce 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -949,6 +949,10 @@ .appendTo($tr); var content = dataItem[key]; + if (field.truncate) { + $td.addClass('truncated'); + } + if (field.indicator) { $td.addClass('state').addClass(field.indicator[content]); @@ -1327,6 +1331,12 @@ }); $table.dataTable(null, { noSelect: uiCustom }); + if(args.data && + args.data.length < pageSize && + options.setEndTable) { + options.setEndTable(); + } + setTimeout(function() { $table.dataTable('refresh'); }); @@ -1467,6 +1477,12 @@ var page = 1; var actions = listViewData.actions; var reorder = listViewData.reorder; + var tableHeight = $table.height(); + var endTable = false; + var setEndTable = function() { + endTable = true; + } + var $switcher; if (args.sections) { @@ -1572,7 +1588,8 @@ { context: args.context, reorder: reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable } ); @@ -1625,7 +1642,8 @@ { context: $listView.data('view-args').context, reorder: listViewData.reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable } ); }; @@ -1675,7 +1693,8 @@ { context: $listView.data('view-args').context, reorder: listViewData.reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable } ); }; @@ -1728,8 +1747,6 @@ return false; }); - var tableHeight = $table.height(); - var endTable = false; // Infinite scrolling event $listView.bind('scroll', function(event) { @@ -1767,7 +1784,8 @@ filterBy: filterBy }, actions, { reorder: listViewData.reorder, - detailView: listViewData.detailView + detailView: listViewData.detailView, + setEndTable: setEndTable }); $table.height() == tableHeight ? endTable = true : tableHeight = $table.height(); } diff --git a/ui/scripts/ui/widgets/multiEdit.js b/ui/scripts/ui/widgets/multiEdit.js index 936c20c48a0..ea177c57848 100755 --- a/ui/scripts/ui/widgets/multiEdit.js +++ b/ui/scripts/ui/widgets/multiEdit.js @@ -354,7 +354,7 @@ error: function(message) { cloudStack.dialog.notice({ message: message }); $item.show(); - $loading.remove(); + $dataItem.find('.loading-overlay').remove(); } } }); diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index 67aba437099..ef8ddbb6b8c 100755 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -3556,7 +3556,13 @@ } }); } - } + }, + + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + error('addCluster', errorMsg, { fn: 'addCluster', args: args }); + } + }); } else{ diff --git a/utils/src/com/cloud/utils/S3Utils.java b/utils/src/com/cloud/utils/S3Utils.java index 0a4a4430cd5..5ee578304d5 100644 --- a/utils/src/com/cloud/utils/S3Utils.java +++ b/utils/src/com/cloud/utils/S3Utils.java @@ -226,8 +226,8 @@ public final class S3Utils { try { tempFile = createTempFile( - join(asList(targetDirectory.getName(), currentTimeMillis(), - "part"), "-"), "tmp", targetDirectory); + join("-", targetDirectory.getName(), currentTimeMillis(), + "part"), "tmp", targetDirectory); tempFile.deleteOnExit(); if (LOGGER.isDebugEnabled()) { diff --git a/utils/src/com/cloud/utils/StringUtils.java b/utils/src/com/cloud/utils/StringUtils.java index 14ff4b1ae94..359b169e1b2 100644 --- a/utils/src/com/cloud/utils/StringUtils.java +++ b/utils/src/com/cloud/utils/StringUtils.java @@ -16,8 +16,6 @@ // under the License. package com.cloud.utils; -import static java.util.Arrays.asList; - import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -25,8 +23,6 @@ import java.util.regex.Pattern; import org.owasp.esapi.StringUtilities; -// StringUtils exists in Apache Commons Lang, but rather than import the entire JAR to our system, for now -// just implement the method needed public class StringUtils { private static final char[] hexChar = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' @@ -50,7 +46,7 @@ public class StringUtils { public static String join(final String delimiter, final Object... components) { - return join(asList(components), delimiter); + return org.apache.commons.lang.StringUtils.join(components, delimiter); } /** diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index 5c13454da79..60993799b41 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -257,7 +257,7 @@ public class NetUtils { return ipFromInetAddress(addr); } - return new String("127.0.0.1"); + return "127.0.0.1"; } public static String ipFromInetAddress(InetAddress addr) { diff --git a/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java b/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java index 2755c548048..a14e5a4a9d7 100644 --- a/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java +++ b/utils/src/com/cloud/utils/ssh/SSHKeysHelper.java @@ -82,7 +82,7 @@ public class SSHKeysHelper { if (!keyMaterial.contains(" ")) keyMaterial = new String(Base64.decodeBase64(keyMaterial.getBytes())); - if (!keyMaterial.startsWith("ssh-rsa") || !keyMaterial.contains(" ")) + if ((!keyMaterial.startsWith("ssh-rsa") && !keyMaterial.startsWith("ssh-dss")) || !keyMaterial.contains(" ")) return null; String[] key = keyMaterial.split(" "); diff --git a/utils/test/com/cloud/utils/StringUtilsTest.java b/utils/test/com/cloud/utils/StringUtilsTest.java index 3c162c75c02..796efbaacd7 100644 --- a/utils/test/com/cloud/utils/StringUtilsTest.java +++ b/utils/test/com/cloud/utils/StringUtilsTest.java @@ -103,4 +103,9 @@ public class StringUtilsTest { assertEquals(result, expected); } + @Test + public void testJoin() { + assertEquals("a-b-c", StringUtils.join("-", "a", "b", "c")); + assertEquals("", StringUtils.join("-")); + } } diff --git a/utils/test/com/cloud/utils/crypto/RSAHelperTest.java b/utils/test/com/cloud/utils/crypto/RSAHelperTest.java new file mode 100644 index 00000000000..d1f496e1ab1 --- /dev/null +++ b/utils/test/com/cloud/utils/crypto/RSAHelperTest.java @@ -0,0 +1,50 @@ +// 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. +package com.cloud.utils.crypto; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import com.cloud.utils.crypt.RSAHelper; + +public class RSAHelperTest { + @Test + public void testEncryptWithRSA() { + String rsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" + + "hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" + + "ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" + + "2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" + + "ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX"; + String encryptedString = RSAHelper.encryptWithSSHPublicKey(rsaKey, "content"); + assertNotNull(encryptedString); + } + + @Test + public void testEncryptWithDSA() { + String dssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+ + "tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" + + "i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" + + "tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" + + "4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" + + "+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" + + "os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" + + "UebZcBgNRyeky7VZSbbF2jQSQ=="; + String encryptedString = RSAHelper.encryptWithSSHPublicKey(dssKey, "content"); + assertNull(encryptedString); + } +} diff --git a/utils/test/com/cloud/utils/net/NetUtilsTest.java b/utils/test/com/cloud/utils/net/NetUtilsTest.java index 38fe21d5324..3cfc98fb3b6 100644 --- a/utils/test/com/cloud/utils/net/NetUtilsTest.java +++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java @@ -168,4 +168,9 @@ public class NetUtilsTest extends TestCase { newMac = NetUtils.generateMacOnIncrease(mac, 16); assertTrue(newMac.equals("06:00:0f:00:45:67")); } + + @Test + public void testGetLocalIPString() { + assertNotNull(NetUtils.getLocalIPString()); + } } diff --git a/utils/test/com/cloud/utils/ssh/SSHKeysHelperTest.java b/utils/test/com/cloud/utils/ssh/SSHKeysHelperTest.java new file mode 100644 index 00000000000..6402e3ef347 --- /dev/null +++ b/utils/test/com/cloud/utils/ssh/SSHKeysHelperTest.java @@ -0,0 +1,69 @@ +// 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. +package com.cloud.utils.ssh; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class SSHKeysHelperTest { + @Test + public void rsaKeyTest() { + String rsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" + + "hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" + + "ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" + + "2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" + + "ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX test@testkey"; + String storedRsaKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2D2Cs0XAEqm+ajJpumIPrMpKp0CWtIW+8ZY2/MJCW" + + "hge1eY18u9I3PPnkMVJsTOaN0wQojjw4AkKgKjNZXA9wyUq56UyN/stmipu8zifWPgxQGDRkuzzZ6buk" + + "ef8q2Awjpo8hv5/0SRPJxQLEafESnUP+Uu/LUwk5VVC7PHzywJRUGFuzDl/uT72+6hqpL2YpC6aTl4/P" + + "2eDvUQhCdL9dBmUSFX8ftT53W1jhsaQl7mPElVgSCtWz3IyRkogobMPrpJW/IPKEiojKIuvNoNv4CDR6" + + "ybeVjHOJMb9wi62rXo+CzUsW0Y4jPOX/OykAm5vrNOhQhw0aaBcv5XVv8BRX"; + String parsedKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(rsaKey); + String fingerprint = SSHKeysHelper.getPublicKeyFingerprint(parsedKey); + + assertTrue(storedRsaKey.equals(parsedKey)); + assertTrue("f6:96:3f:f4:78:f7:80:11:6c:f8:e3:2b:40:20:f1:14".equals(fingerprint)); + + } + + @Test + public void dsaKeyTest() { + String dssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+ + "tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" + + "i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" + + "tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" + + "4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" + + "+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" + + "os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" + + "UebZcBgNRyeky7VZSbbF2jQSQ== test key"; + String storedDssKey = "ssh-dss AAAAB3NzaC1kc3MAAACBALbaewDnzZ5AcGbZno7VW1m7Si3Q+yEANXZioVupfSwOP0q9aP2iV"+ + "tyqq575JnUVZXMDR2Gr254F/qCJ0TKAvucN0gcd2XslX4jBcu1Z7s7YZf6d7fC58k0NE6/keokJNKhQO" + + "i56iirRzSA/YFrD64mzfq6rEmai0q7GjGGP0RT1AAAAFQDO5++6JonyqnoRkV9Yl1OaEOPjVwAAAIAYA" + + "tqtKtU/INlTIuL3wt3nyKzwPUnz3fqxP5Ger3OlRZsOahalTFt2OF5jGGmCunyBTRteOetZObr0QhUIF" + + "4bSDr6UiYYYbH1ES0ws/t1mDIeTh3UUHV1QYACN6c07FKyKLMtB9AthiG2FMLKCEedG3NeXItuNzsuQD" + + "+n/K1rzMAAAAIBi5SM4pFPiB7BvTZvARV56vrG5QNgWVazSwbwgl/EACiWYbRauHDUQA9f+Rq+ayWcsR" + + "os1CD+Q81y9SmlQaZVKkSPZLxXfu5bi3s4o431xjilhZdt4vKbj2pK364IjghJPNBBfmRXzlj9awKxr/" + + "UebZcBgNRyeky7VZSbbF2jQSQ=="; + String parsedKey = SSHKeysHelper.getPublicKeyFromKeyMaterial(dssKey); + String fingerprint = SSHKeysHelper.getPublicKeyFingerprint(parsedKey); + + assertTrue(storedDssKey.equals(parsedKey)); + assertTrue("fc:6e:ef:31:93:f8:92:2b:a9:03:c7:06:90:f5:ec:bb".equals(fingerprint)); + + } +} diff --git a/utils/test/com/cloud/utils/testcase/NioTest.java b/utils/test/com/cloud/utils/testcase/NioTest.java index e20532c8204..3b8fe692683 100644 --- a/utils/test/com/cloud/utils/testcase/NioTest.java +++ b/utils/test/com/cloud/utils/testcase/NioTest.java @@ -16,20 +16,18 @@ // under the License. package com.cloud.utils.testcase; -import java.nio.channels.ClosedChannelException; -import java.util.Random; - -import org.apache.log4j.Logger; - import com.cloud.utils.nio.HandlerFactory; import com.cloud.utils.nio.Link; import com.cloud.utils.nio.NioClient; import com.cloud.utils.nio.NioServer; import com.cloud.utils.nio.Task; import com.cloud.utils.nio.Task.Type; - -import org.junit.Assert; import junit.framework.TestCase; +import org.apache.log4j.Logger; +import org.junit.Assert; + +import java.nio.channels.ClosedChannelException; +import java.util.Random; /** * @@ -83,6 +81,7 @@ public class NioTest extends TestCase { while (_clientLink == null) { try { + s_logger.debug("Link is not up! Waiting ..."); Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block @@ -94,6 +93,7 @@ public class NioTest extends TestCase { public void tearDown() { while (!isTestsDone()) { try { + s_logger.debug(this._completedCount + "/" + this._testCount + " tests done. Waiting for completion"); Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block