diff --git a/agent/pom.xml b/agent/pom.xml index 1a6840c1c512..9ff0c5e23cfc 100644 --- a/agent/pom.xml +++ b/agent/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT diff --git a/api/pom.xml b/api/pom.xml index 8d813960fa2a..6b9c98f9c191 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT diff --git a/api/src/com/cloud/network/guru/NetworkGuruAdditionalFunctions.java b/api/src/com/cloud/network/guru/NetworkGuruAdditionalFunctions.java new file mode 100644 index 000000000000..b31822195b9a --- /dev/null +++ b/api/src/com/cloud/network/guru/NetworkGuruAdditionalFunctions.java @@ -0,0 +1,28 @@ +// 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.network.guru; + +import java.util.Map; + +public interface NetworkGuruAdditionalFunctions { + + public static final String NSX_LSWITCH_UUID = "logicalswitch"; + public static final String NSX_LSWITCHPORT_UUID = "logicalswitchport"; + + void finalizeNetworkDesign(long networkId, String vlanIdAsUUID); + Map listAdditionalNicParams(String nicUuid); +} diff --git a/api/src/com/cloud/vm/VmDetailConstants.java b/api/src/com/cloud/vm/VmDetailConstants.java index d06ad67197eb..d34afc13a169 100644 --- a/api/src/com/cloud/vm/VmDetailConstants.java +++ b/api/src/com/cloud/vm/VmDetailConstants.java @@ -19,7 +19,7 @@ public interface VmDetailConstants { public static final String KEYBOARD = "keyboard"; public static final String NIC_ADAPTER = "nicAdapter"; - public static final String ROOK_DISK_CONTROLLER = "rootDiskController"; + public static final String ROOT_DISK_CONTROLLER = "rootDiskController"; public static final String NESTED_VIRTUALIZATION_FLAG = "nestedVirtualizationFlag"; public static final String HYPERVISOR_TOOLS_VERSION = "hypervisortoolsversion"; public static final String DATA_DISK_CONTROLLER = "dataDiskController"; diff --git a/api/src/com/cloud/vm/VmStats.java b/api/src/com/cloud/vm/VmStats.java index 2b7943883e19..1c23c01ed8be 100644 --- a/api/src/com/cloud/vm/VmStats.java +++ b/api/src/com/cloud/vm/VmStats.java @@ -32,4 +32,10 @@ public interface VmStats { public double getDiskWriteKBs(); + public double getMemoryKBs(); + + public double getIntFreeMemoryKBs(); + + public double getTargetMemoryKBs(); + } diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 934972cf3192..ef4ff9a0fe9f 100644 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -499,6 +499,7 @@ public class ApiConstants { public static final String NICIRA_NVP_TRANSPORT_ZONE_UUID = "transportzoneuuid"; public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename"; public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid"; + public static final String NICIRA_NVP_L2_GATEWAYSERVICE_UUID = "l2gatewayserviceuuid"; public static final String S3_ACCESS_KEY = "accesskey"; public static final String S3_SECRET_KEY = "secretkey"; public static final String S3_END_POINT = "endpoint"; diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java index b8fbb02ad221..4708aff6ff40 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/RevertSnapshotCmd.java @@ -36,7 +36,7 @@ import com.cloud.storage.Snapshot; import com.cloud.user.Account; -@APICommand(name = "revertSnapshot", description = "revert a volume snapshot.", responseObject = SnapshotResponse.class, entityType = {Snapshot.class}, +@APICommand(name = "revertSnapshot", description = "This is supposed to revert a volume snapshot. This command is only supported with KVM so far", responseObject = SnapshotResponse.class, entityType = {Snapshot.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class RevertSnapshotCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RevertSnapshotCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java index 82c281dad467..7769ff8573b1 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/DeployVMCmd.java @@ -474,7 +474,7 @@ public void execute() { response.setResponseName(getCommandName()); setResponseObject(response); } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to deploy vm"); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to deploy vm uuid:"+getEntityUuid()); } } @@ -556,7 +556,7 @@ public void create() throws ResourceAllocationException { VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId); // Make sure a valid template ID was specified if (template == null) { - throw new InvalidParameterValueException("Unable to use template " + templateId); + throw new InvalidParameterValueException("Unable to find the template " + templateId); } DiskOffering diskOffering = null; diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java index 0fb496cc0433..e1131092f02b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java @@ -51,7 +51,7 @@ public class CreateVpnCustomerGatewayCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.STRING, required = true, description = "guest cidr list of the customer gateway") private String peerCidrList; - @Parameter(name = ApiConstants.IPSEC_PSK, type = CommandType.STRING, required = true, description = "IPsec Preshared-Key of the customer gateway") + @Parameter(name = ApiConstants.IPSEC_PSK, type = CommandType.STRING, required = true, description = "IPsec Preshared-Key of the customer gateway. Cannot contain newline or double quotes.") private String ipsecPsk; @Parameter(name = ApiConstants.IKE_POLICY, type = CommandType.STRING, required = true, description = "IKE policy of the customer gateway") diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java index 3b188b85ca99..bb5914111b4d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java @@ -57,7 +57,7 @@ public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.STRING, required = true, description = "guest cidr of the customer gateway") private String guestCidrList; - @Parameter(name = ApiConstants.IPSEC_PSK, type = CommandType.STRING, required = true, description = "IPsec Preshared-Key of the customer gateway") + @Parameter(name = ApiConstants.IPSEC_PSK, type = CommandType.STRING, required = true, description = "IPsec Preshared-Key of the customer gateway. Cannot contain newline or double quotes.") private String ipsecPsk; @Parameter(name = ApiConstants.IKE_POLICY, type = CommandType.STRING, required = true, description = "IKE policy of the customer gateway") diff --git a/api/src/org/apache/cloudstack/api/response/NicResponse.java b/api/src/org/apache/cloudstack/api/response/NicResponse.java index 2f79d7ff4778..73358360a058 100644 --- a/api/src/org/apache/cloudstack/api/response/NicResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NicResponse.java @@ -102,6 +102,14 @@ public class NicResponse extends BaseResponse { @Param(description = "Id of the vm to which the nic belongs") private String vmId; + @SerializedName("nsxlogicalswitch") + @Param(description = "Id of the NSX Logical Switch (if NSX based), null otherwise", since="4.6.0") + private String nsxLogicalSwitch; + + @SerializedName("nsxlogicalswitchport") + @Param(description = "Id of the NSX Logical Switch Port (if NSX based), null otherwise", since="4.6.0") + private String nsxLogicalSwitchPort; + public void setVmId(String vmId) { this.vmId = vmId; } @@ -205,4 +213,12 @@ public void setSecondaryIps(List ipList) { this.secondaryIps = ipList; } + public void setNsxLogicalSwitch(String nsxLogicalSwitch) { + this.nsxLogicalSwitch = nsxLogicalSwitch; + } + + public void setNsxLogicalSwitchPort(String nsxLogicalSwitchPort) { + this.nsxLogicalSwitchPort = nsxLogicalSwitchPort; + } + } diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java index e8d1a9ed890c..f1119ddbfbf8 100644 --- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java @@ -196,6 +196,18 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp @Param(description = "the write (bytes) of disk on the vm") private Long diskKbsWrite; + @SerializedName("memorykbs") + @Param(description = "the memory used by the vm") + private Long memoryKBs; + + @SerializedName("memoryintfreekbs") + @Param(description = "the internal memory thats free in vm") + private Long memoryIntFreeKBs; + + @SerializedName("memorytargetkbs") + @Param(description = "the target memory in vm") + private Long memoryTargetKBs; + @SerializedName("diskioread") @Param(description = "the read (io) of disk on the vm") private Long diskIORead; @@ -466,6 +478,18 @@ public Long getDiskKbsWrite() { return diskKbsWrite; } + public Long getMemoryKBs() { + return memoryKBs; + } + + public Long getMemoryIntFreeKBs() { + return memoryIntFreeKBs; + } + + public Long getMemoryTargetKBs() { + return memoryTargetKBs; + } + public Long getDiskIORead() { return diskIORead; } @@ -645,6 +669,18 @@ public void setDiskIORead(Long diskIORead) { this.diskIORead = diskIORead; } + public void setMemoryKBs(Long memoryKBs) { + this.memoryKBs = memoryKBs; + } + + public void setMemoryIntFreeKBs(Long memoryIntFreeKBs) { + this.memoryIntFreeKBs = memoryIntFreeKBs; + } + + public void setMemoryTargetKBs(Long memoryTargetKBs) { + this.memoryTargetKBs = memoryTargetKBs; + } + public void setDiskIOWrite(Long diskIOWrite) { this.diskIOWrite = diskIOWrite; } diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 3219b2666c26..fbdedda5c2db 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -942,6 +942,7 @@ label.nfs.storage=NFS Storage label.nfs=NFS label.nic.adapter.type=NIC adapter type label.nicira.controller.address=Controller Address +label.nicira.l2gatewayserviceuuid=L2 Gateway Service Uuid label.nicira.l3gatewayserviceuuid=L3 Gateway Service Uuid label.nicira.transportzoneuuid=Transport Zone Uuid label.brocade.vcs.address=Vcs Switch Address diff --git a/client/pom.xml b/client/pom.xml index 163282c4f692..5cafd832d208 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index c54900872415..60dc02ff576e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT diff --git a/core/src/com/cloud/agent/api/BackupSnapshotCommand.java b/core/src/com/cloud/agent/api/BackupSnapshotCommand.java index 2a46610117f8..d93c32f99086 100644 --- a/core/src/com/cloud/agent/api/BackupSnapshotCommand.java +++ b/core/src/com/cloud/agent/api/BackupSnapshotCommand.java @@ -39,6 +39,7 @@ public class BackupSnapshotCommand extends SnapshotCommand { private S3TO s3; StorageFilerTO pool; private Long secHostId; + private String nfsVersion; protected BackupSnapshotCommand() { @@ -107,4 +108,12 @@ public Long getSnapshotId() { public Long getSecHostId() { return secHostId; } + + public String getNfsVersion() { + return nfsVersion; + } + + public void setNfsVersion(String nfsVersion) { + this.nfsVersion = nfsVersion; + } } diff --git a/core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java b/core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java index 7ac2ddedd2e3..5a09994ab728 100644 --- a/core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java +++ b/core/src/com/cloud/agent/api/CreatePrivateTemplateFromSnapshotCommand.java @@ -28,6 +28,7 @@ public class CreatePrivateTemplateFromSnapshotCommand extends SnapshotCommand { private String origTemplateInstallPath; private Long newTemplateId; private String templateName; + private String nfsVersion; protected CreatePrivateTemplateFromSnapshotCommand() { @@ -72,4 +73,12 @@ public Long getNewTemplateId() { public String getTemplateName() { return templateName; } + + public String getNfsVersion() { + return nfsVersion; + } + + public void setNfsVersion(String nfsVersion) { + this.nfsVersion = nfsVersion; + } } diff --git a/core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java b/core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java index 3025147a3044..b6cc6ac4475a 100644 --- a/core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java +++ b/core/src/com/cloud/agent/api/CreatePrivateTemplateFromVolumeCommand.java @@ -32,6 +32,7 @@ public class CreatePrivateTemplateFromVolumeCommand extends SnapshotCommand { StorageFilerTO _primaryPool; // For XenServer private String _secondaryStorageUrl; + private String nfsVersion; public CreatePrivateTemplateFromVolumeCommand() { } @@ -99,4 +100,12 @@ public Long getAccountId() { public void setTemplateId(long templateId) { _templateId = templateId; } + + public String getNfsVersion() { + return nfsVersion; + } + + public void setNfsVersion(String nfsVersion) { + this.nfsVersion = nfsVersion; + } } diff --git a/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java b/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java index fa9a4d584613..933be0360686 100644 --- a/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java +++ b/core/src/com/cloud/agent/api/CreateVolumeFromSnapshotCommand.java @@ -26,6 +26,8 @@ */ public class CreateVolumeFromSnapshotCommand extends SnapshotCommand { + private String nfsVersion; + protected CreateVolumeFromSnapshotCommand() { } @@ -50,4 +52,12 @@ public CreateVolumeFromSnapshotCommand(StoragePool pool, String secondaryStorage super(pool, secondaryStoragePoolURL, backedUpSnapshotUuid, backedUpSnapshotName, dcId, accountId, volumeId); setWait(wait); } + + public String getNfsVersion() { + return nfsVersion; + } + + public void setNfsVersion(String nfsVersion) { + this.nfsVersion = nfsVersion; + } } diff --git a/core/src/com/cloud/agent/api/GetStorageStatsCommand.java b/core/src/com/cloud/agent/api/GetStorageStatsCommand.java index 23e8f9e3e55d..84b54264511c 100644 --- a/core/src/com/cloud/agent/api/GetStorageStatsCommand.java +++ b/core/src/com/cloud/agent/api/GetStorageStatsCommand.java @@ -30,6 +30,7 @@ public class GetStorageStatsCommand extends Command { private StoragePoolType pooltype; private String secUrl; private DataStoreTO store; + private String nfsVersion; public String getSecUrl() { return secUrl; @@ -54,6 +55,11 @@ public GetStorageStatsCommand(DataStoreTO store) { this.store = store; } + public GetStorageStatsCommand(DataStoreTO store, String nfsVersion) { + this.store = store; + this.nfsVersion = nfsVersion; + } + public GetStorageStatsCommand(String secUrl) { this.secUrl = secUrl; } @@ -81,6 +87,14 @@ public DataStoreTO getStore() { return this.store; } + public String getNfsVersion() { + return nfsVersion; + } + + public void setNfsVersion(String nfsVersion) { + this.nfsVersion = nfsVersion; + } + @Override public boolean executeInSequence() { return false; diff --git a/core/src/com/cloud/agent/api/SecStorageSetupCommand.java b/core/src/com/cloud/agent/api/SecStorageSetupCommand.java index 28e55c2f4efc..316e4698dc50 100644 --- a/core/src/com/cloud/agent/api/SecStorageSetupCommand.java +++ b/core/src/com/cloud/agent/api/SecStorageSetupCommand.java @@ -28,6 +28,7 @@ public class SecStorageSetupCommand extends Command { private String secUrl; private KeystoreManager.Certificates certs; private String postUploadKey; + private String nfsVersion; public SecStorageSetupCommand() { @@ -74,4 +75,12 @@ public String getPostUploadKey() { public void setPostUploadKey(String postUploadKey) { this.postUploadKey = postUploadKey; } + + public String getNfsVersion() { + return nfsVersion; + } + + public void setNfsVersion(String nfsVersion) { + this.nfsVersion = nfsVersion; + } } diff --git a/core/src/com/cloud/agent/api/VmStatsEntry.java b/core/src/com/cloud/agent/api/VmStatsEntry.java index 0f30b6af5302..e6063b9ab5b0 100644 --- a/core/src/com/cloud/agent/api/VmStatsEntry.java +++ b/core/src/com/cloud/agent/api/VmStatsEntry.java @@ -30,13 +30,19 @@ public class VmStatsEntry implements VmStats { double diskWriteIOs; double diskReadKBs; double diskWriteKBs; + double memoryKBs; + double intfreememoryKBs; + double targetmemoryKBs; int numCPUs; String entityType; public VmStatsEntry() { } - public VmStatsEntry(double cpuUtilization, double networkReadKBs, double networkWriteKBs, int numCPUs, String entityType) { + public VmStatsEntry(double memoryKBs,double intfreememoryKBs,double targetmemoryKBs, double cpuUtilization, double networkReadKBs, double networkWriteKBs, int numCPUs, String entityType) { + this.memoryKBs = memoryKBs; + this.intfreememoryKBs = intfreememoryKBs; + this.targetmemoryKBs = targetmemoryKBs; this.cpuUtilization = cpuUtilization; this.networkReadKBs = networkReadKBs; this.networkWriteKBs = networkWriteKBs; @@ -117,6 +123,33 @@ public void setDiskWriteKBs(double diskWriteKBs) { this.diskWriteKBs = diskWriteKBs; } + @Override + public double getMemoryKBs() { + return memoryKBs; + } + + public void setMemoryKBs(double memoryKBs) { + this.memoryKBs = memoryKBs; + } + + @Override + public double getIntFreeMemoryKBs() { + return intfreememoryKBs; + } + + public void setIntFreeMemoryKBs(double intfreememoryKBs) { + this.intfreememoryKBs = intfreememoryKBs; + } + + @Override + public double getTargetMemoryKBs() { + return targetmemoryKBs; + } + + public void setTargetMemoryKBs(double targetmemoryKBs) { + this.targetmemoryKBs = targetmemoryKBs; + } + public int getNumCPUs() { return numCPUs; } diff --git a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java index 43c84ee2bc0b..7ab822c03bc3 100644 --- a/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java +++ b/core/src/com/cloud/agent/api/storage/CopyVolumeCommand.java @@ -32,6 +32,7 @@ public class CopyVolumeCommand extends Command { boolean toSecondaryStorage; String vmName; boolean executeInSequence = false; + String nfsVersion; public CopyVolumeCommand() { } @@ -75,4 +76,12 @@ public boolean toSecondaryStorage() { public String getVmName() { return vmName; } + + public String getNfsVersion() { + return nfsVersion; + } + + public void setNfsVersion(String nfsVersion) { + this.nfsVersion = nfsVersion; + } } diff --git a/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java b/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java index 855095280d7d..bacc83aea50a 100644 --- a/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java +++ b/core/src/com/cloud/agent/api/storage/ListTemplateCommand.java @@ -23,6 +23,7 @@ public class ListTemplateCommand extends StorageCommand { private DataStoreTO store; + private String nfsVersion; //private String secUrl; @@ -34,6 +35,11 @@ public ListTemplateCommand(DataStoreTO store) { // this.secUrl = url; } + public ListTemplateCommand(DataStoreTO store, String nfsVersion) { + this.store = store; + this.nfsVersion = nfsVersion; + } + @Override public boolean executeInSequence() { return true; @@ -43,6 +49,10 @@ public DataStoreTO getDataStore() { return store; } + public String getNfsVersion() { + return nfsVersion; + } + // public String getSecUrl() { // return secUrl; // } diff --git a/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java b/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java index ce8ed217a562..9dae513b989b 100644 --- a/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java +++ b/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java @@ -35,6 +35,7 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand { String secondaryStorageUrl; String primaryStorageUrl; + String nfsVersion; protected PrimaryStorageDownloadCommand() { } @@ -87,4 +88,12 @@ public String getPrimaryStorageUrl() { public boolean executeInSequence() { return true; } + + public String getNfsVersion() { + return nfsVersion; + } + + public void setNfsVersion(String nfsVersion) { + this.nfsVersion = nfsVersion; + } } diff --git a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java index 5d1e56bd7733..bfcd9ae9b41d 100644 --- a/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java +++ b/core/src/org/apache/cloudstack/storage/command/TemplateOrVolumePostUploadCommand.java @@ -53,6 +53,8 @@ public class TemplateOrVolumePostUploadCommand { private long accountId; + private String nfsVersion; + public TemplateOrVolumePostUploadCommand(long entityId, String entityUUID, String absolutePath, String checksum, String type, String name, String imageFormat, String dataTo, String dataToRole) { this.entityId = entityId; @@ -196,4 +198,12 @@ public void setAccountId(long accountId) { public long getAccountId() { return accountId; } + + public String getNfsVersion() { + return nfsVersion; + } + + public void setNfsVersion(String nfsVersion) { + this.nfsVersion = nfsVersion; + } } diff --git a/debian/changelog b/debian/changelog index a09834ea5863..04ae4f75373a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,16 +1,16 @@ -cloudstack (4.7.2-SNAPSHOT) unstable; urgency=low +cloudstack (4.9.0-SNAPSHOT) unstable; urgency=low [ Remi Bergsma ] - * Update the version to 4.7.2-SNAPSHOT + * Update the version to 4.9.0.snapshot - -- the Apache CloudStack project Tue, 26 Jan 2016 09:30:53 +0100 + -- the Apache CloudStack project Wed, 20 Jan 2016 23:43:35 +0100 -cloudstack (4.7.2-SNAPSHOT) unstable; urgency=low +cloudstack (4.8.0-SNAPSHOT) unstable; urgency=low [ Remi Bergsma ] - * Update the version to 4.7.2-SNAPSHOT + * Update the version to 4.8.0.snapshot - -- the Apache CloudStack project Sun, 13 Dec 2015 21:09:53 +0100 + -- the Apache CloudStack project Sun, 21 Dec 2015 22:11:55 +0100 cloudstack (4.7.0-SNAPSHOT) unstable; urgency=low diff --git a/developer/pom.xml b/developer/pom.xml index f5284ed6dd9e..b7d70004b064 100644 --- a/developer/pom.xml +++ b/developer/pom.xml @@ -18,7 +18,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT diff --git a/engine/api/pom.xml b/engine/api/pom.xml index ee019f4c6dd6..01a6051a34ac 100644 --- a/engine/api/pom.xml +++ b/engine/api/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java index b5601e9693cf..5d552c4013f6 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java @@ -30,10 +30,7 @@ public interface DataMotionStrategy { StrategyPriority canHandle(Map volumeMap, Host srcHost, Host destHost); - Void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback); - - Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback); - - Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback); + void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback); + void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback); } diff --git a/engine/components-api/pom.xml b/engine/components-api/pom.xml index 9021bd47e2d6..7ea56d66dc50 100644 --- a/engine/components-api/pom.xml +++ b/engine/components-api/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/engine/components-api/src/com/cloud/network/NetworkStateListener.java b/engine/components-api/src/com/cloud/network/NetworkStateListener.java index 0ed1d9ea7fd8..ef8dddc1f23f 100644 --- a/engine/components-api/src/com/cloud/network/NetworkStateListener.java +++ b/engine/components-api/src/com/cloud/network/NetworkStateListener.java @@ -24,38 +24,29 @@ import javax.inject.Inject; -import com.cloud.utils.fsm.StateMachine2; -import org.apache.log4j.Logger; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; - import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.events.EventBus; import org.apache.cloudstack.framework.events.EventBusException; +import org.apache.log4j.Logger; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import com.cloud.event.EventCategory; -import com.cloud.event.dao.UsageEventDao; import com.cloud.network.Network.Event; import com.cloud.network.Network.State; -import com.cloud.network.dao.NetworkDao; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.fsm.StateListener; +import com.cloud.utils.fsm.StateMachine2; public class NetworkStateListener implements StateListener { @Inject - protected UsageEventDao _usageEventDao; - @Inject - protected NetworkDao _networkDao; - @Inject - protected ConfigurationDao _configDao; + private ConfigurationDao _configDao; - protected static EventBus s_eventBus = null; + private static EventBus s_eventBus = null; private static final Logger s_logger = Logger.getLogger(NetworkStateListener.class); - public NetworkStateListener(UsageEventDao usageEventDao, NetworkDao networkDao, ConfigurationDao configDao) { - _usageEventDao = usageEventDao; - _networkDao = networkDao; + public NetworkStateListener(ConfigurationDao configDao) { _configDao = configDao; } diff --git a/engine/network/pom.xml b/engine/network/pom.xml index 5a803210cdf9..a41ed26275cc 100644 --- a/engine/network/pom.xml +++ b/engine/network/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/engine/orchestration/pom.xml b/engine/orchestration/pom.xml index 2287db6595dd..ee3bb34200e9 100755 --- a/engine/orchestration/pom.xml +++ b/engine/orchestration/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 5c5838951f98..11c0b869dff7 100644 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -983,7 +983,7 @@ public void orchestrateStart(final String vmUuid, final Map vmMetadatum) { if(!found) { VMInstanceVO vm = _vmDao.findVMByInstanceName(name); - if(vm.getType() == VirtualMachine.Type.User) { + if(vm != null && vm.getType() == VirtualMachine.Type.User) { updateVmMetaData(vm.getId(), platform); } } @@ -3685,7 +3686,7 @@ public void setStoragePoolAllocators(final List storagePoo // @MessageHandler(topic = Topics.VM_POWER_STATE) - private void HandlePowerStateReport(final String subject, final String senderAddress, final Object args) { + protected void HandlePowerStateReport(final String subject, final String senderAddress, final Object args) { assert args != null; final Long vmId = (Long)args; @@ -4575,7 +4576,13 @@ private Pair orchestrateStart(final VmWorkStart work) th } assert vm != null; - orchestrateStart(vm.getUuid(), work.getParams(), work.getPlan(), _dpMgr.getDeploymentPlannerByName(work.getDeploymentPlanner())); + try{ + orchestrateStart(vm.getUuid(), work.getParams(), work.getPlan(), _dpMgr.getDeploymentPlannerByName(work.getDeploymentPlanner())); + } + catch (CloudRuntimeException e){ + s_logger.info("Caught CloudRuntimeException, returning job failed"); + return new Pair(JobInfo.Status.FAILED, null); + } return new Pair(JobInfo.Status.SUCCEEDED, null); } diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 5f442b3a1ccd..e4272720bc86 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -140,6 +140,7 @@ import com.cloud.network.element.StaticNatServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; +import com.cloud.network.guru.NetworkGuruAdditionalFunctions; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.rules.FirewallManager; import com.cloud.network.rules.FirewallRule; @@ -169,6 +170,7 @@ import com.cloud.user.dao.AccountDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; +import com.cloud.utils.UuidUtils; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; @@ -576,7 +578,7 @@ public void doInTransactionWithoutResult(final TransactionStatus status) { _agentMgr.registerForHostEvents(this, true, false, true); - Network.State.getStateMachine().registerListener(new NetworkStateListener(_usageEventDao, _networksDao, _configDao)); + Network.State.getStateMachine().registerListener(new NetworkStateListener(_configDao)); s_logger.info("Network Manager is configured."); @@ -674,8 +676,14 @@ public void doInTransactionWithoutResult(final TransactionStatus status) { vpcId, offering.getRedundantRouter()); vo.setDisplayNetwork(isDisplayNetworkEnabled == null ? true : isDisplayNetworkEnabled); vo.setStrechedL2Network(offering.getSupportsStrechedL2()); - networks.add(_networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, - finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId()))); + final NetworkVO networkPersisted = _networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated, + finalizeServicesAndProvidersForNetwork(offering, plan.getPhysicalNetworkId())); + networks.add(networkPersisted); + + if (predefined instanceof NetworkVO && guru instanceof NetworkGuruAdditionalFunctions){ + final NetworkGuruAdditionalFunctions functions = (NetworkGuruAdditionalFunctions) guru; + functions.finalizeNetworkDesign(networkPersisted.getId(), ((NetworkVO)predefined).getVlanIdAsUUID()); + } if (domainId != null && aclType == ACLType.Domain) { _networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null ? true : subdomainAccess); @@ -1024,6 +1032,9 @@ public Pair implementNetwork(final long networkId, final } catch (final NoTransitionException e) { s_logger.error(e.getMessage()); return null; + } catch (final CloudRuntimeException e) { + s_logger.error("Caught exception: " + e.getMessage()); + return null; } finally { if (implemented.first() == null) { s_logger.debug("Cleaning up because we're unable to implement the network " + network); @@ -1478,7 +1489,7 @@ public void prepareAllNicsForMigration(final VirtualMachineProfile vm, final Dep //Create nic profile for migration s_logger.debug("Creating nic profile for migration. BroadcastUri: "+broadcastUri.toString()+" NetworkId: "+ntwkId+" Vm: "+vm.getId()); final NetworkVO network = _networksDao.findById(ntwkId); - final Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId()); + _networkModel.getNetworkRate(network.getId(), vm.getId()); final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName()); final NicProfile profile = new NicProfile(); profile.setDeviceId(255); //dummyId @@ -1915,43 +1926,45 @@ public Network createGuestNetwork(final long networkOfferingId, final String nam throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for dynamic vlan allocation for the guest network in zone " + zone.getName()); } - final String uri = BroadcastDomainType.fromString(vlanId).toString(); - // For Isolated networks, don't allow to create network with vlan that already exists in the zone - if (ntwkOff.getGuestType() == GuestType.Isolated) { - if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) { - throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId); - } else { - final List dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId.toString()); - //for the network that is created as part of private gateway, - //the vnet is not coming from the data center vnet table, so the list can be empty - if (!dcVnets.isEmpty()) { - final DataCenterVnetVO dcVnet = dcVnets.get(0); - // Fail network creation if specified vlan is dedicated to a different account - if (dcVnet.getAccountGuestVlanMapId() != null) { - final Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId(); - final AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId); - if (map.getAccountId() != owner.getAccountId()) { - throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account"); - } - // Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool - } else { - final List maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId()); - if (maps != null && !maps.isEmpty()) { - final int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId()); - final int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId()); - if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) { - throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner " - + owner.getAccountName()); + if (! UuidUtils.validateUUID(vlanId)){ + final String uri = BroadcastDomainType.fromString(vlanId).toString(); + // For Isolated networks, don't allow to create network with vlan that already exists in the zone + if (ntwkOff.getGuestType() == GuestType.Isolated) { + if (_networksDao.countByZoneAndUri(zoneId, uri) > 0) { + throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId); + } else { + final List dcVnets = _datacenterVnetDao.findVnet(zoneId, vlanId.toString()); + //for the network that is created as part of private gateway, + //the vnet is not coming from the data center vnet table, so the list can be empty + if (!dcVnets.isEmpty()) { + final DataCenterVnetVO dcVnet = dcVnets.get(0); + // Fail network creation if specified vlan is dedicated to a different account + if (dcVnet.getAccountGuestVlanMapId() != null) { + final Long accountGuestVlanMapId = dcVnet.getAccountGuestVlanMapId(); + final AccountGuestVlanMapVO map = _accountGuestVlanMapDao.findById(accountGuestVlanMapId); + if (map.getAccountId() != owner.getAccountId()) { + throw new InvalidParameterValueException("Vlan " + vlanId + " is dedicated to a different account"); + } + // Fail network creation if owner has a dedicated range of vlans but the specified vlan belongs to the system pool + } else { + final List maps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByAccount(owner.getAccountId()); + if (maps != null && !maps.isEmpty()) { + final int vnetsAllocatedToAccount = _datacenterVnetDao.countVnetsAllocatedToAccount(zoneId, owner.getAccountId()); + final int vnetsDedicatedToAccount = _datacenterVnetDao.countVnetsDedicatedToAccount(zoneId, owner.getAccountId()); + if (vnetsAllocatedToAccount < vnetsDedicatedToAccount) { + throw new InvalidParameterValueException("Specified vlan " + vlanId + " doesn't belong" + " to the vlan range dedicated to the owner " + + owner.getAccountName()); + } } } } } - } - } else { - // don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or - // shared network with same Vlan ID in the zone - if (_networksDao.countByZoneUriAndGuestType(zoneId, uri, GuestType.Isolated) > 0 ) { - throw new InvalidParameterValueException("There is a isolated/shared network with vlan id: " + vlanId + " already exists " + "in zone " + zoneId); + } else { + // don't allow to creating shared network with given Vlan ID, if there already exists a isolated network or + // shared network with same Vlan ID in the zone + if (_networksDao.countByZoneUriAndGuestType(zoneId, uri, GuestType.Isolated) > 0 ) { + throw new InvalidParameterValueException("There is a isolated/shared network with vlan id: " + vlanId + " already exists " + "in zone " + zoneId); + } } } @@ -2042,7 +2055,14 @@ public Network doInTransaction(final TransactionStatus status) { if (vlanIdFinal != null) { if (isolatedPvlan == null) { - final URI uri = BroadcastDomainType.fromString(vlanIdFinal); + URI uri = null; + if (UuidUtils.validateUUID(vlanIdFinal)){ + //Logical router's UUID provided as VLAN_ID + userNetwork.setVlanIdAsUUID(vlanIdFinal); //Set transient field + } + else { + uri = BroadcastDomainType.fromString(vlanIdFinal); + } userNetwork.setBroadcastUri(uri); if (!vlanIdFinal.equalsIgnoreCase(Vlan.UNTAGGED)) { userNetwork.setBroadcastDomainType(BroadcastDomainType.Vlan); @@ -2656,6 +2676,27 @@ public List listVmNics(final long vmId, final Long nicId, final L } else { result = _nicDao.listByVmIdAndNicIdAndNtwkId(vmId, nicId, networkId); } + + for (final NicVO nic : result) { + if (_networkModel.isProviderForNetwork(Provider.NiciraNvp, nic.getNetworkId())) { + //For NSX Based networks, add nsxlogicalswitch, nsxlogicalswitchport to each result + s_logger.info("Listing NSX logical switch and logical switch por for each nic"); + final NetworkVO network = _networksDao.findById(nic.getNetworkId()); + final NetworkGuru guru = AdapterBase.getAdapterByName(networkGurus, network.getGuruName()); + final NetworkGuruAdditionalFunctions guruFunctions = (NetworkGuruAdditionalFunctions) guru; + + final Map nsxParams = guruFunctions.listAdditionalNicParams(nic.getUuid()); + if (nsxParams != null){ + final String lswitchUuuid = nsxParams.containsKey(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID) + ? (String) nsxParams.get(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID) : null; + final String lswitchPortUuuid = nsxParams.containsKey(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID) + ? (String) nsxParams.get(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID) : null; + nic.setNsxLogicalSwitchUuid(lswitchUuuid); + nic.setNsxLogicalSwitchPortUuid(lswitchPortUuuid); + } + } + } + return result; } diff --git a/engine/pom.xml b/engine/pom.xml index 3cac76c10a4d..c3c0b28e76bf 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/engine/schema/pom.xml b/engine/schema/pom.xml index 4a0d4c356817..4d0b90d6de0d 100644 --- a/engine/schema/pom.xml +++ b/engine/schema/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/engine/schema/src/com/cloud/network/dao/NetworkVO.java b/engine/schema/src/com/cloud/network/dao/NetworkVO.java index 65929d5c9245..5b8ded766499 100644 --- a/engine/schema/src/com/cloud/network/dao/NetworkVO.java +++ b/engine/schema/src/com/cloud/network/dao/NetworkVO.java @@ -172,6 +172,17 @@ public class NetworkVO implements Network { @Column(name = "streched_l2") boolean strechedL2Network = false; + @Transient + transient String vlanIdAsUUID; + + public String getVlanIdAsUUID() { + return vlanIdAsUUID; + } + + public void setVlanIdAsUUID(String vlanIdAsUUID) { + this.vlanIdAsUUID = vlanIdAsUUID; + } + public NetworkVO() { uuid = UUID.randomUUID().toString(); } diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java b/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java index f24e853aede8..fc44c4f5e376 100644 --- a/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java +++ b/engine/schema/src/com/cloud/upgrade/DatabaseUpgradeChecker.java @@ -61,7 +61,9 @@ import com.cloud.upgrade.dao.Upgrade460to461; import com.cloud.upgrade.dao.Upgrade461to470; import com.cloud.upgrade.dao.Upgrade470to471; -import com.cloud.upgrade.dao.Upgrade471to472; +import com.cloud.upgrade.dao.Upgrade471to480; +import com.cloud.upgrade.dao.Upgrade480to481; +import com.cloud.upgrade.dao.Upgrade481to490; import com.cloud.upgrade.dao.UpgradeSnapshot217to224; import com.cloud.upgrade.dao.UpgradeSnapshot223to224; import com.cloud.upgrade.dao.VersionDao; @@ -109,7 +111,7 @@ public DatabaseUpgradeChecker() { new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), - new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.1.8", new DbUpgrade[] {new Upgrade218to22(), new Upgrade221to222(), new UpgradeSnapshot217to224(), new Upgrade222to224(), new Upgrade218to224DomainVlans(), new Upgrade224to225(), new Upgrade225to226(), @@ -117,7 +119,7 @@ public DatabaseUpgradeChecker() { new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.1.9", new DbUpgrade[] {new Upgrade218to22(), new Upgrade221to222(), new UpgradeSnapshot217to224(), new Upgrade222to224(), new Upgrade218to224DomainVlans(), new Upgrade224to225(), new Upgrade225to226(), @@ -125,161 +127,167 @@ public DatabaseUpgradeChecker() { new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), - new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.1", new DbUpgrade[] {new Upgrade221to222(), new UpgradeSnapshot223to224(), new Upgrade222to224(), new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), - new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.2", new DbUpgrade[] {new Upgrade222to224(), new UpgradeSnapshot223to224(), new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.3", new DbUpgrade[] {new Upgrade222to224(), new UpgradeSnapshot223to224(), new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.4", new DbUpgrade[] {new Upgrade224to225(), new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.5", new DbUpgrade[] {new Upgrade225to226(), new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), - new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.6", new DbUpgrade[] {new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.7", new DbUpgrade[] {new Upgrade227to228(), new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), - new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.8", new DbUpgrade[] {new Upgrade228to229(), new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30() , new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.9", new DbUpgrade[] {new Upgrade229to2210(), new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.10", new DbUpgrade[] {new Upgrade2210to2211(), new Upgrade2211to2212(), new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), - new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.12", new DbUpgrade[] {new Upgrade2212to2213(), new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), - new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.13", new DbUpgrade[] {new Upgrade2213to2214(), new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.14", new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), - new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("3.0.0", new DbUpgrade[] {new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), - new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("3.0.1", new DbUpgrade[] {new Upgrade301to302(), new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("3.0.2", new DbUpgrade[] {new Upgrade302to40(), new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), - new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.0.0", new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.0.0", new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.0.1", new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.0.1", new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.0.2", new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.0.2", new DbUpgrade[] {new Upgrade40to41(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.1.0", new DbUpgrade[] {new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.1.0", new DbUpgrade[] {new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.1.1", new DbUpgrade[] {new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.1.1", new DbUpgrade[] {new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.2.0", new DbUpgrade[] {new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.2.0", new DbUpgrade[] {new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.2.1", new DbUpgrade[] {new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.2.1", new DbUpgrade[] {new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.3.0", new DbUpgrade[] {new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.3.0", new DbUpgrade[] {new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.3.1", new DbUpgrade[] {new Upgrade431to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.3.1", new DbUpgrade[] {new Upgrade431to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.3.2", new DbUpgrade[] {new Upgrade432to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.3.2", new DbUpgrade[] {new Upgrade432to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.4.0", new DbUpgrade[] {new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.4.0", new DbUpgrade[] {new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.4.1", new DbUpgrade[] {new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472() }); + _upgradeMap.put("4.4.1", new DbUpgrade[] {new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490() }); - _upgradeMap.put("4.4.2", new DbUpgrade[] {new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.4.2", new DbUpgrade[] {new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.4.3", new DbUpgrade[] {new Upgrade443to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.4.3", new DbUpgrade[] {new Upgrade443to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.4.4", new DbUpgrade[] {new Upgrade444to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.4.4", new DbUpgrade[] {new Upgrade444to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.5.0", new DbUpgrade[] {new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.5.0", new DbUpgrade[] {new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.5.1", new DbUpgrade[] {new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.5.1", new DbUpgrade[] {new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.5.2", new DbUpgrade[] {new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.5.2", new DbUpgrade[] {new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.5.3", new DbUpgrade[] {new Upgrade453to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.5.3", new DbUpgrade[] {new Upgrade453to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.6.0", new DbUpgrade[] {new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.6.0", new DbUpgrade[] {new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.6.1", new DbUpgrade[] {new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.6.1", new DbUpgrade[] {new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.6.2", new DbUpgrade[] {new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.6.2", new DbUpgrade[] {new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.7.0", new DbUpgrade[] {new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("4.7.0", new DbUpgrade[] {new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("4.7.1", new DbUpgrade[] {new Upgrade471to472()}); + _upgradeMap.put("4.7.1", new DbUpgrade[] {new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); + + _upgradeMap.put("4.7.2", new DbUpgrade[] {new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); + + _upgradeMap.put("4.8.0", new DbUpgrade[] {new Upgrade480to481(), new Upgrade481to490()}); + + _upgradeMap.put("4.8.1", new DbUpgrade[] {new Upgrade481to490()}); //CP Upgrades _upgradeMap.put("3.0.3", new DbUpgrade[] {new Upgrade303to304(), new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), - new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("3.0.4", new DbUpgrade[] {new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), - new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("3.0.5", new DbUpgrade[] {new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), - new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("3.0.6", new DbUpgrade[] {new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), - new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); - _upgradeMap.put("3.0.7", new DbUpgrade[] {new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + _upgradeMap.put("3.0.7", new DbUpgrade[] {new Upgrade307to410(), new Upgrade410to420(), new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.15", new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to303(), new Upgrade303to304(), new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), - new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); _upgradeMap.put("2.2.16", new DbUpgrade[] {new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to303(), new Upgrade303to304(), new Upgrade304to305(), new Upgrade305to306(), new Upgrade306to307(), new Upgrade307to410(), new Upgrade410to420(), - new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to472()}); + new Upgrade420to421(), new Upgrade421to430(), new Upgrade430to440(), new Upgrade440to441(), new Upgrade441to442(), new Upgrade442to450(), new Upgrade450to451(), new Upgrade451to452(), new Upgrade452to460(), new Upgrade460to461(), new Upgrade461to470(), new Upgrade470to471(), new Upgrade471to480(), new Upgrade480to481(), new Upgrade481to490()}); } protected void runScript(Connection conn, File file) { diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade471to472.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade471to480.java similarity index 84% rename from engine/schema/src/com/cloud/upgrade/dao/Upgrade471to472.java rename to engine/schema/src/com/cloud/upgrade/dao/Upgrade471to480.java index 7c36e0024761..bde4c0ff24e6 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade471to472.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade471to480.java @@ -24,17 +24,17 @@ import java.io.File; import java.sql.Connection; -public class Upgrade471to472 implements DbUpgrade { - final static Logger s_logger = Logger.getLogger(Upgrade471to472.class); +public class Upgrade471to480 implements DbUpgrade { + final static Logger s_logger = Logger.getLogger(Upgrade471to480.class); @Override public String[] getUpgradableVersionRange() { - return new String[] {"4.7.1", "4.7.2"}; + return new String[] {"4.7.1", "4.8.0"}; } @Override public String getUpgradedVersion() { - return "4.7.2"; + return "4.8.0"; } @Override @@ -44,9 +44,9 @@ public boolean supportsRollingUpgrade() { @Override public File[] getPrepareScripts() { - String script = Script.findScript("", "db/schema-471to472.sql"); + String script = Script.findScript("", "db/schema-471to480.sql"); if (script == null) { - throw new CloudRuntimeException("Unable to find db/schema-471to472.sql"); + throw new CloudRuntimeException("Unable to find db/schema-471to480.sql"); } return new File[] {new File(script)}; } @@ -57,9 +57,9 @@ public void performDataMigration(Connection conn) { @Override public File[] getCleanupScripts() { - String script = Script.findScript("", "db/schema-471to472-cleanup.sql"); + String script = Script.findScript("", "db/schema-471to480-cleanup.sql"); if (script == null) { - throw new CloudRuntimeException("Unable to find db/schema-471to472-cleanup.sql"); + throw new CloudRuntimeException("Unable to find db/schema-471to480-cleanup.sql"); } return new File[] {new File(script)}; diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade480to481.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade480to481.java new file mode 100644 index 000000000000..26e7d125ec84 --- /dev/null +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade480to481.java @@ -0,0 +1,67 @@ +// 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.upgrade.dao; + +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; +import org.apache.log4j.Logger; + +import java.io.File; +import java.sql.Connection; + +public class Upgrade480to481 implements DbUpgrade { + final static Logger s_logger = Logger.getLogger(Upgrade480to481.class); + + @Override + public String[] getUpgradableVersionRange() { + return new String[] {"4.8.0", "4.8.1"}; + } + + @Override + public String getUpgradedVersion() { + return "4.8.1"; + } + + @Override + public boolean supportsRollingUpgrade() { + return false; + } + + @Override + public File[] getPrepareScripts() { + String script = Script.findScript("", "db/schema-480to481.sql"); + if (script == null) { + throw new CloudRuntimeException("Unable to find db/schema-480to481.sql"); + } + return new File[] {new File(script)}; + } + + @Override + public void performDataMigration(Connection conn) { + } + + @Override + public File[] getCleanupScripts() { + String script = Script.findScript("", "db/schema-480to481-cleanup.sql"); + if (script == null) { + throw new CloudRuntimeException("Unable to find db/schema-480to481-cleanup.sql"); + } + + return new File[] {new File(script)}; + } +} diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade481to490.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade481to490.java new file mode 100644 index 000000000000..9e5213478eb0 --- /dev/null +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade481to490.java @@ -0,0 +1,67 @@ +// 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.upgrade.dao; + +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; +import org.apache.log4j.Logger; + +import java.io.File; +import java.sql.Connection; + +public class Upgrade481to490 implements DbUpgrade { + final static Logger s_logger = Logger.getLogger(Upgrade481to490.class); + + @Override + public String[] getUpgradableVersionRange() { + return new String[] {"4.8.1", "4.9.0"}; + } + + @Override + public String getUpgradedVersion() { + return "4.9.0"; + } + + @Override + public boolean supportsRollingUpgrade() { + return false; + } + + @Override + public File[] getPrepareScripts() { + String script = Script.findScript("", "db/schema-481to490.sql"); + if (script == null) { + throw new CloudRuntimeException("Unable to find db/schema-481to490.sql"); + } + return new File[] {new File(script)}; + } + + @Override + public void performDataMigration(Connection conn) { + } + + @Override + public File[] getCleanupScripts() { + String script = Script.findScript("", "db/schema-481to490-cleanup.sql"); + if (script == null) { + throw new CloudRuntimeException("Unable to find db/schema-481to490-cleanup.sql"); + } + + return new File[] {new File(script)}; + } +} diff --git a/engine/schema/src/com/cloud/vm/NicVO.java b/engine/schema/src/com/cloud/vm/NicVO.java index 815429736090..2a7c6962cbd4 100644 --- a/engine/schema/src/com/cloud/vm/NicVO.java +++ b/engine/schema/src/com/cloud/vm/NicVO.java @@ -28,6 +28,7 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; +import javax.persistence.Transient; import com.cloud.network.Networks.AddressFormat; import com.cloud.network.Networks.Mode; @@ -123,6 +124,12 @@ protected NicVO() { @Column(name = "secondary_ip") boolean secondaryIp; + @Transient + transient String nsxLogicalSwitchUuid; + + @Transient + transient String nsxLogicalSwitchPortUuid; + public NicVO(String reserver, Long instanceId, long configurationId, VirtualMachine.Type vmType) { this.reserver = reserver; this.instanceId = instanceId; @@ -371,4 +378,20 @@ public void setSecondaryIp(boolean secondaryIp) { public void setVmType(VirtualMachine.Type vmType) { this.vmType = vmType; } + + public String getNsxLogicalSwitchUuid() { + return nsxLogicalSwitchUuid; + } + + public void setNsxLogicalSwitchUuid(String nsxLogicalSwitchUuid) { + this.nsxLogicalSwitchUuid = nsxLogicalSwitchUuid; + } + + public String getNsxLogicalSwitchPortUuid() { + return nsxLogicalSwitchPortUuid; + } + + public void setNsxLogicalSwitchPortUuid(String nsxLogicalSwitchPortUuid) { + this.nsxLogicalSwitchPortUuid = nsxLogicalSwitchPortUuid; + } } diff --git a/engine/service/pom.xml b/engine/service/pom.xml index 4a99f3353148..38b6035e8719 100644 --- a/engine/service/pom.xml +++ b/engine/service/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT cloud-engine-service war diff --git a/engine/storage/cache/pom.xml b/engine/storage/cache/pom.xml index a0da87ead90a..976a2e75a836 100644 --- a/engine/storage/cache/pom.xml +++ b/engine/storage/cache/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/datamotion/pom.xml b/engine/storage/datamotion/pom.xml index 9f0bbc58d6ce..3324270198c6 100644 --- a/engine/storage/datamotion/pom.xml +++ b/engine/storage/datamotion/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 24ecff57e9c6..3124666db19e 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -23,9 +23,6 @@ import javax.inject.Inject; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; @@ -41,7 +38,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.StorageAction; import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -49,6 +45,8 @@ import org.apache.cloudstack.storage.RemoteHostEndPoint; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.MigrateVolumeAnswer; @@ -61,9 +59,9 @@ import com.cloud.configuration.Config; import com.cloud.host.Host; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StoragePool; import com.cloud.storage.VolumeVO; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.DB; @@ -99,22 +97,14 @@ protected boolean needCacheStorage(DataObject srcData, DataObject destData) { DataStoreTO srcStoreTO = srcTO.getDataStore(); if (srcStoreTO instanceof NfsTO || srcStoreTO.getRole() == DataStoreRole.ImageCache) { - //|| - // (srcStoreTO instanceof PrimaryDataStoreTO && ((PrimaryDataStoreTO)srcStoreTO).getPoolType() == StoragePoolType.NetworkFilesystem)) { return false; } - DataTO destTO = destData.getTO(); DataStoreTO destStoreTO = destTO.getDataStore(); if (destStoreTO instanceof NfsTO || destStoreTO.getRole() == DataStoreRole.ImageCache) { return false; } - - if (srcData.getType() == DataObjectType.TEMPLATE) { - TemplateInfo template = (TemplateInfo)srcData; - } - if (s_logger.isDebugEnabled()) { s_logger.debug("needCacheStorage true, dest at " + destTO.getPath() + " dest role " + destStoreTO.getRole().toString() + srcTO.getPath() + " src role " + srcStoreTO.getRole().toString()); @@ -429,7 +419,7 @@ protected Answer migrateVolumeToPool(DataObject srcData, DataObject destData) { // Note: destHost is currently only used if the copyObject method is invoked @Override - public Void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { Answer answer = null; String errMsg = null; try { @@ -465,12 +455,6 @@ public Void copyAsync(DataObject srcData, DataObject destData, Host destHost, As CopyCommandResult result = new CopyCommandResult(null, answer); result.setResult(errMsg); callback.complete(result); - return null; - } - - @Override - public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { - return copyAsync(srcData, destData, null, callback); } @DB @@ -569,11 +553,9 @@ protected Answer copySnapshot(DataObject srcData, DataObject destData) { } @Override - public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { CopyCommandResult result = new CopyCommandResult(null, null); result.setResult("Unsupported operation requested for copying data."); callback.complete(result); - - return null; } } diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java index 3c9334df73f1..cdcab754e91d 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java @@ -24,30 +24,29 @@ import javax.inject.Inject; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; -import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.CopyCmdAnswer; +import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.to.DiskTO; @@ -64,8 +63,8 @@ import com.cloud.storage.DataStoreRole; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.SnapshotVO; -import com.cloud.storage.VolumeVO; import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.SnapshotDetailsDao; @@ -127,7 +126,7 @@ public StrategyPriority canHandle(Map volumeMap, Host src } @Override - public Void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { if (srcData instanceof SnapshotInfo) { SnapshotInfo snapshotInfo = (SnapshotInfo)srcData; @@ -137,23 +136,22 @@ public Void copyAsync(DataObject srcData, DataObject destData, Host destHost, As if (canHandleSrc && destData instanceof TemplateInfo && (destData.getDataStore().getRole() == DataStoreRole.Image || destData.getDataStore().getRole() == DataStoreRole.ImageCache)) { - return handleCreateTemplateFromSnapshot(snapshotInfo, (TemplateInfo)destData, callback); + handleCreateTemplateFromSnapshot(snapshotInfo, (TemplateInfo)destData, callback); + return; } if (destData instanceof VolumeInfo) { VolumeInfo volumeInfo = (VolumeInfo)destData; - boolean canHandleDest = canHandle(destData.getDataStore()); if (canHandleSrc && canHandleDest) { - return handleCreateVolumeFromSnapshotBothOnStorageSystem(snapshotInfo, volumeInfo, callback); + handleCreateVolumeFromSnapshotBothOnStorageSystem(snapshotInfo, volumeInfo, callback); + return; } - if (canHandleSrc) { throw new UnsupportedOperationException("This operation is not supported (DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT " + "not supported by destination storage plug-in)."); } - if (canHandleDest) { throw new UnsupportedOperationException("This operation is not supported (DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT " + "not supported by source storage plug-in)."); @@ -413,18 +411,9 @@ public HostVO getHost(long dataStoreId) { } @Override - public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { - return copyAsync(srcData, destData, null, callback); - } - - @Override - public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { CopyCommandResult result = new CopyCommandResult(null, null); - result.setResult("Unsupported operation requested for copying data."); - callback.complete(result); - - return null; } } diff --git a/engine/storage/image/pom.xml b/engine/storage/image/pom.xml index a183fbdc6706..779f1399abdc 100644 --- a/engine/storage/image/pom.xml +++ b/engine/storage/image/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml b/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml index db517dbd863d..51be9d99faa8 100644 --- a/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml +++ b/engine/storage/image/resources/META-INF/cloudstack/core/spring-engine-storage-image-core-context.xml @@ -29,7 +29,7 @@ + depends-on="dataObjectManagerImpl, dataStoreManagerImpl, dataMotionServiceImpl, objectInDataStoreManagerImpl, defaultEndPointSelector, templateDataFactoryImpl, imageStoreDetailsUtil" /> diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 9ab35953711d..a1d10e328077 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -73,6 +73,7 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.ImageStoreDetailsUtil; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.StoragePool; @@ -135,6 +136,8 @@ public class TemplateServiceImpl implements TemplateService { ConfigurationDao _configDao; @Inject StorageCacheManager _cacheMgr; + @Inject + ImageStoreDetailsUtil imageStoreDetailsUtil; class TemplateOpContext extends AsyncRpcContext { final TemplateObject template; @@ -564,7 +567,7 @@ public void associateCrosszoneTemplatesToZone(long dcId) { } private Map listTemplate(DataStore ssStore) { - ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO()); + ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO(), imageStoreDetailsUtil.getNfsVersion(ssStore.getId())); EndPoint ep = _epSelector.select(ssStore); Answer answer = null; if (ep == null) { diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index 832e4a1db46a..d64812957418 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java index 896342890c82..5c41dcab0ee5 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java @@ -51,7 +51,7 @@ public MockLocalNfsSecondaryStorageResource() { } @Override - public String getRootDir(String secUrl) { + public String getRootDir(String secUrl, String nfsVersion) { return "/mnt"; } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java index accfeb5318e4..757d96cabad2 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java @@ -19,25 +19,17 @@ package org.apache.cloudstack.storage.test; import java.util.Map; -import java.util.UUID; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.command.CopyCmdAnswer; -import org.apache.cloudstack.storage.to.SnapshotObjectTO; -import org.apache.cloudstack.storage.to.TemplateObjectTO; -import com.cloud.agent.api.to.DataObjectType; -import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.host.Host; -import com.cloud.storage.Storage; public class MockStorageMotionStrategy implements DataMotionStrategy { @@ -58,46 +50,13 @@ public StrategyPriority canHandle(Map volumeMap, Host src } @Override - public Void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { throw new UnsupportedOperationException(); } @Override - public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { - CopyCmdAnswer answer = null; - DataTO data = null; - if (!success) { - CopyCommandResult result = new CopyCommandResult(null, null); - result.setResult("Failed"); - callback.complete(result); - } - if (destData.getType() == DataObjectType.SNAPSHOT) { - SnapshotInfo srcSnapshot = (SnapshotInfo)srcData; - - SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); - newSnapshot.setPath(UUID.randomUUID().toString()); - if (srcSnapshot.getParent() != null) { - newSnapshot.setParentSnapshotPath(srcSnapshot.getParent().getPath()); - } - data = newSnapshot; - } else if (destData.getType() == DataObjectType.TEMPLATE) { - TemplateObjectTO newTemplate = new TemplateObjectTO(); - newTemplate.setPath(UUID.randomUUID().toString()); - newTemplate.setFormat(Storage.ImageFormat.QCOW2); - newTemplate.setSize(10L); - newTemplate.setPhysicalSize(10L); - data = newTemplate; - } - answer = new CopyCmdAnswer(data); - CopyCommandResult result = new CopyCommandResult("something", answer); - callback.complete(result); - return null; - } - - @Override - public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { CopyCommandResult result = new CopyCommandResult("something", null); callback.complete(result); - return null; } } diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml index 73a2e94c52b1..cf9a8ea97372 100644 --- a/engine/storage/pom.xml +++ b/engine/storage/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml b/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml index 8040d801b3e5..a45e4ee3e40c 100644 --- a/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml +++ b/engine/storage/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml @@ -69,5 +69,7 @@ + + diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml index 71054f9c636f..97ca7f21e33d 100644 --- a/engine/storage/snapshot/pom.xml +++ b/engine/storage/snapshot/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/engine/storage/volume/pom.xml b/engine/storage/volume/pom.xml index 7f9058d89658..e790df12dd9d 100644 --- a/engine/storage/volume/pom.xml +++ b/engine/storage/volume/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-engine - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/framework/cluster/pom.xml b/framework/cluster/pom.xml index 0cb801b20029..d14e5c455d13 100644 --- a/framework/cluster/pom.xml +++ b/framework/cluster/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-framework - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/framework/config/pom.xml b/framework/config/pom.xml index a511f5bdec1a..349e9f29d3ad 100644 --- a/framework/config/pom.xml +++ b/framework/config/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-framework - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/framework/db/pom.xml b/framework/db/pom.xml index a7797a3ae3ac..71b9af36b4d7 100644 --- a/framework/db/pom.xml +++ b/framework/db/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-framework - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/framework/events/pom.xml b/framework/events/pom.xml index 664401040ef4..a633a779fca5 100644 --- a/framework/events/pom.xml +++ b/framework/events/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-framework - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/framework/ipc/pom.xml b/framework/ipc/pom.xml index e4a09472c5e6..0341ff7dea49 100644 --- a/framework/ipc/pom.xml +++ b/framework/ipc/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-framework - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/framework/jobs/pom.xml b/framework/jobs/pom.xml index 3bed3244eb7c..ff17f483580a 100644 --- a/framework/jobs/pom.xml +++ b/framework/jobs/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-framework - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java index 3e1ed9c017ae..121246bc11c9 100644 --- a/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java +++ b/framework/jobs/src/org/apache/cloudstack/framework/jobs/impl/AsyncJobManagerImpl.java @@ -1006,6 +1006,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { job.setStatus(JobInfo.Status.FAILED); job.setResultCode(ApiErrorCode.INTERNAL_ERROR.getHttpCode()); job.setResult("job cancelled because of management server restart or shutdown"); + job.setCompleteMsid(msid); _jobDao.update(job.getId(), job); if (s_logger.isDebugEnabled()) { s_logger.debug("Purge queue item for cancelled job-" + job.getId()); diff --git a/framework/managed-context/pom.xml b/framework/managed-context/pom.xml index 399b8788df24..e2058fe03f1a 100644 --- a/framework/managed-context/pom.xml +++ b/framework/managed-context/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-maven-standard - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../maven-standard/pom.xml diff --git a/framework/pom.xml b/framework/pom.xml index d73ad1c65711..a60841c75055 100644 --- a/framework/pom.xml +++ b/framework/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT install diff --git a/framework/quota/pom.xml b/framework/quota/pom.xml index 0b393e0dc560..82d43cdd4d5a 100644 --- a/framework/quota/pom.xml +++ b/framework/quota/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-framework - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/framework/quota/src/org/apache/cloudstack/quota/QuotaManagerImpl.java b/framework/quota/src/org/apache/cloudstack/quota/QuotaManagerImpl.java index b039e26a9b57..ac14718fd4e9 100644 --- a/framework/quota/src/org/apache/cloudstack/quota/QuotaManagerImpl.java +++ b/framework/quota/src/org/apache/cloudstack/quota/QuotaManagerImpl.java @@ -220,7 +220,9 @@ public void processQuotaBalanceForAccount(final AccountVO account, final List details; + Map details = new HashMap(); - // This flag is required to tell if the offering is dynamic once the cpu, memory and speed are set. - // In some cases cpu, memory and speed are set to non-null values even if the offering is dynamic. @Transient boolean isDynamic; @@ -90,7 +86,7 @@ protected ServiceOfferingVO() { } public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText, - ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) { + ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) { super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true); this.cpu = cpu; this.ramSize = ramSize; @@ -105,7 +101,8 @@ public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer spee } public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitCpuUse, - boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, Long domainId) { + boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, + VirtualMachine.Type vmType, Long domainId) { super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true, domainId); this.cpu = cpu; this.ramSize = ramSize; @@ -118,68 +115,26 @@ public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer spee this.vmType = vmType == null ? null : vmType.toString().toLowerCase(); } - public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, - boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, - VirtualMachine.Type vmType, Long domainId, String hostTag) { - this(name, - cpu, - ramSize, - speed, - rateMbps, - multicastRateMbps, - offerHA, - limitResourceUse, - volatileVm, - displayText, - provisioningType, - useLocalStorage, - recreatable, - tags, - systemUse, - vmType, - domainId); + public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse, + boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, + VirtualMachine.Type vmType, Long domainId, String hostTag) { + this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm, displayText, provisioningType, useLocalStorage, recreatable, tags, + systemUse, vmType, domainId); this.hostTag = hostTag; } - public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, - boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, - VirtualMachine.Type vmType, Long domainId, String hostTag, String deploymentPlanner) { - this(name, - cpu, - ramSize, - speed, - rateMbps, - multicastRateMbps, - offerHA, - limitResourceUse, - volatileVm, - displayText, - provisioningType, - useLocalStorage, - recreatable, - tags, - systemUse, - vmType, - domainId, - hostTag); + public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitResourceUse, + boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, + VirtualMachine.Type vmType, Long domainId, String hostTag, String deploymentPlanner) { + this(name, cpu, ramSize, speed, rateMbps, multicastRateMbps, offerHA, limitResourceUse, volatileVm, displayText, provisioningType, useLocalStorage, recreatable, tags, + systemUse, vmType, domainId, hostTag); this.deploymentPlanner = deploymentPlanner; } public ServiceOfferingVO(ServiceOfferingVO offering) { - super(offering.getId(), - offering.getName(), - offering.getDisplayText(), - offering.getProvisioningType(), - false, - offering.getTags(), - offering.isRecreatable(), - offering.getUseLocalStorage(), - offering.getSystemUse(), - true, - offering.isCustomizedIops()== null ? false:offering.isCustomizedIops(), - offering.getDomainId(), - offering.getMinIops(), - offering.getMaxIops()); + super(offering.getId(), offering.getName(), offering.getDisplayText(), offering.getProvisioningType(), false, offering.getTags(), offering.isRecreatable(), + offering.getUseLocalStorage(), offering.getSystemUse(), true, offering.isCustomizedIops() == null ? false : offering.isCustomizedIops(), offering.getDomainId(), + offering.getMinIops(), offering.getMaxIops()); cpu = offering.getCpu(); ramSize = offering.getRamSize(); speed = offering.getSpeed(); @@ -310,14 +265,10 @@ public Map getDetails() { } public String getDetail(String name) { - assert (details != null) : "Did you forget to load the details?"; - - return details != null ? details.get(name) : null; + return details.get(name); } - public void setDetail(String name, String value) { - assert (details != null) : "Did you forget to load the details?"; - + public void addDetail(String name, String value) { details.put(name, value); } diff --git a/framework/rest/pom.xml b/framework/rest/pom.xml index e8c8707e7f7d..830b7ec94d5f 100644 --- a/framework/rest/pom.xml +++ b/framework/rest/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-framework - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml cloud-framework-rest diff --git a/framework/security/pom.xml b/framework/security/pom.xml index 2e45a65e023c..cfe04de079c2 100644 --- a/framework/security/pom.xml +++ b/framework/security/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-framework - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/framework/spring/lifecycle/pom.xml b/framework/spring/lifecycle/pom.xml index 3a3670d5fbc8..93160c472c75 100644 --- a/framework/spring/lifecycle/pom.xml +++ b/framework/spring/lifecycle/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-maven-standard - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../../maven-standard/pom.xml diff --git a/framework/spring/module/pom.xml b/framework/spring/module/pom.xml index e259718668b3..6f89f53530b0 100644 --- a/framework/spring/module/pom.xml +++ b/framework/spring/module/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-maven-standard - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../../maven-standard/pom.xml diff --git a/maven-standard/pom.xml b/maven-standard/pom.xml index a4b838dae77e..6f8530a0f517 100644 --- a/maven-standard/pom.xml +++ b/maven-standard/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/plugins/acl/static-role-based/pom.xml b/plugins/acl/static-role-based/pom.xml index 9b89ce4bb606..62ba16696ffd 100644 --- a/plugins/acl/static-role-based/pom.xml +++ b/plugins/acl/static-role-based/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/explicit-dedication/pom.xml b/plugins/affinity-group-processors/explicit-dedication/pom.xml index 10e09971b9f9..d4fc0f1a2c51 100644 --- a/plugins/affinity-group-processors/explicit-dedication/pom.xml +++ b/plugins/affinity-group-processors/explicit-dedication/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/affinity-group-processors/host-anti-affinity/pom.xml b/plugins/affinity-group-processors/host-anti-affinity/pom.xml index 3b065aa19dab..58e205d18b29 100644 --- a/plugins/affinity-group-processors/host-anti-affinity/pom.xml +++ b/plugins/affinity-group-processors/host-anti-affinity/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/alert-handlers/snmp-alerts/pom.xml b/plugins/alert-handlers/snmp-alerts/pom.xml index 5b9a6f8e6c25..7cbca893fd52 100644 --- a/plugins/alert-handlers/snmp-alerts/pom.xml +++ b/plugins/alert-handlers/snmp-alerts/pom.xml @@ -22,7 +22,7 @@ cloudstack-plugins org.apache.cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/plugins/alert-handlers/syslog-alerts/pom.xml b/plugins/alert-handlers/syslog-alerts/pom.xml index 62cdede5aad9..e4616acd072a 100644 --- a/plugins/alert-handlers/syslog-alerts/pom.xml +++ b/plugins/alert-handlers/syslog-alerts/pom.xml @@ -22,7 +22,7 @@ cloudstack-plugins org.apache.cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/plugins/api/discovery/pom.xml b/plugins/api/discovery/pom.xml index acf287446e2d..049061abfaae 100644 --- a/plugins/api/discovery/pom.xml +++ b/plugins/api/discovery/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/rate-limit/pom.xml b/plugins/api/rate-limit/pom.xml index 3fe0ac42aff0..3e826c2b495d 100644 --- a/plugins/api/rate-limit/pom.xml +++ b/plugins/api/rate-limit/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/api/solidfire-intg-test/pom.xml b/plugins/api/solidfire-intg-test/pom.xml index 21f40ebb308e..a15d7b3e85f5 100644 --- a/plugins/api/solidfire-intg-test/pom.xml +++ b/plugins/api/solidfire-intg-test/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/database/mysql-ha/pom.xml b/plugins/database/mysql-ha/pom.xml index e9c2ade78463..c275743cefa3 100644 --- a/plugins/database/mysql-ha/pom.xml +++ b/plugins/database/mysql-ha/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/database/quota/pom.xml b/plugins/database/quota/pom.xml index 9c03c74b5e95..b429c0ddd9e4 100644 --- a/plugins/database/quota/pom.xml +++ b/plugins/database/quota/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java index 1b6f400f4075..ab66289448b3 100644 --- a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java @@ -174,10 +174,12 @@ private QuotaSummaryResponse getQuotaSummaryResponse(final Account account) { @Override public QuotaBalanceResponse createQuotaBalanceResponse(List quotaBalance, Date startDate, Date endDate) { if (quotaBalance == null || quotaBalance.isEmpty()) { - new InvalidParameterValueException("The request period does not contain balance entries."); + throw new InvalidParameterValueException("The request period does not contain balance entries."); } Collections.sort(quotaBalance, new Comparator() { public int compare(QuotaBalanceVO o1, QuotaBalanceVO o2) { + o1 = o1 == null ? new QuotaBalanceVO() : o1; + o2 = o2 == null ? new QuotaBalanceVO() : o2; return o2.getUpdatedOn().compareTo(o1.getUpdatedOn()); // desc } }); @@ -186,7 +188,7 @@ public int compare(QuotaBalanceVO o1, QuotaBalanceVO o2) { //check that there is at least one balance entry for (Iterator it = quotaBalance.iterator(); it.hasNext();) { QuotaBalanceVO entry = it.next(); - if (entry.getCreditsId() > 0) { + if (entry.isBalanceEntry()) { have_balance_entries = true; break; } diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/response/QuotaResponseBuilderImplTest.java b/plugins/database/quota/test/org/apache/cloudstack/api/response/QuotaResponseBuilderImplTest.java index 73ead4a71bf2..c113e551647b 100644 --- a/plugins/database/quota/test/org/apache/cloudstack/api/response/QuotaResponseBuilderImplTest.java +++ b/plugins/database/quota/test/org/apache/cloudstack/api/response/QuotaResponseBuilderImplTest.java @@ -118,7 +118,7 @@ private QuotaTariffVO makeTariffTestData() { tariffVO.setUsageType(QuotaTypes.IP_ADDRESS); tariffVO.setUsageName("ip address"); tariffVO.setUsageUnit("IP-Month"); - tariffVO.setCurrencyValue(new BigDecimal(100.19)); + tariffVO.setCurrencyValue(BigDecimal.valueOf(100.19)); tariffVO.setEffectiveOn(new Date()); tariffVO.setUsageDiscriminator(""); return tariffVO; diff --git a/plugins/dedicated-resources/pom.xml b/plugins/dedicated-resources/pom.xml index d97da61db368..040e936d49ca 100644 --- a/plugins/dedicated-resources/pom.xml +++ b/plugins/dedicated-resources/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/plugins/deployment-planners/implicit-dedication/pom.xml b/plugins/deployment-planners/implicit-dedication/pom.xml index 8e989fd26ad6..f0f817ce9fb6 100644 --- a/plugins/deployment-planners/implicit-dedication/pom.xml +++ b/plugins/deployment-planners/implicit-dedication/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/deployment-planners/user-concentrated-pod/pom.xml b/plugins/deployment-planners/user-concentrated-pod/pom.xml index 7e4d67586402..d27188dcc878 100644 --- a/plugins/deployment-planners/user-concentrated-pod/pom.xml +++ b/plugins/deployment-planners/user-concentrated-pod/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/deployment-planners/user-dispersing/pom.xml b/plugins/deployment-planners/user-dispersing/pom.xml index f04cdd3318ef..413993f24f4e 100644 --- a/plugins/deployment-planners/user-dispersing/pom.xml +++ b/plugins/deployment-planners/user-dispersing/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/inmemory/pom.xml b/plugins/event-bus/inmemory/pom.xml index 0001e89d3b8f..efbf29086df4 100644 --- a/plugins/event-bus/inmemory/pom.xml +++ b/plugins/event-bus/inmemory/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/kafka/pom.xml b/plugins/event-bus/kafka/pom.xml index 951df6c599ff..b6827a176b0b 100644 --- a/plugins/event-bus/kafka/pom.xml +++ b/plugins/event-bus/kafka/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/event-bus/rabbitmq/pom.xml b/plugins/event-bus/rabbitmq/pom.xml index fbd57806e3c3..bc8f78cab507 100644 --- a/plugins/event-bus/rabbitmq/pom.xml +++ b/plugins/event-bus/rabbitmq/pom.xml @@ -24,14 +24,14 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml com.rabbitmq amqp-client - 3.4.2 + 3.5.4 org.apache.cloudstack diff --git a/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java b/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java index eb989dd2871b..5c0d6ce60478 100644 --- a/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java +++ b/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java @@ -29,6 +29,8 @@ import javax.naming.ConfigurationException; +import com.cloud.utils.exception.CloudRuntimeException; +import com.rabbitmq.client.BlockedListener; import org.apache.log4j.Logger; import com.rabbitmq.client.AMQP; @@ -91,6 +93,7 @@ public static void setUseSsl(String useSsl) { private ExecutorService executorService; private static DisconnectHandler disconnectHandler; + private static BlockedConnectionHandler blockedConnectionHandler; private static final Logger s_logger = Logger.getLogger(RabbitMQEventBus.class); @Override @@ -134,6 +137,7 @@ public boolean configure(String name, Map params) throws Configu s_subscribers = new ConcurrentHashMap>(); executorService = Executors.newCachedThreadPool(); disconnectHandler = new DisconnectHandler(); + blockedConnectionHandler = new BlockedConnectionHandler(); return true; } @@ -382,6 +386,7 @@ private synchronized Connection createConnection() throws Exception { } Connection connection = factory.newConnection(); connection.addShutdownListener(disconnectHandler); + connection.addBlockedListener(blockedConnectionHandler); s_connection = connection; return s_connection; } catch (Exception e) { @@ -505,6 +510,21 @@ public synchronized boolean stop() { return true; } + //logic to deal with blocked connection. connections are blocked for example when the rabbitmq server is out of space. https://www.rabbitmq.com/connection-blocked.html + private class BlockedConnectionHandler implements BlockedListener { + + @Override + public void handleBlocked(String reason) throws IOException { + s_logger.error("rabbitmq connection is blocked with reason: " + reason); + closeConnection(); + throw new CloudRuntimeException("unblocking the parent thread as publishing to rabbitmq server is blocked with reason: " + reason); + } + + @Override + public void handleUnblocked() throws IOException { + s_logger.info("rabbitmq connection in unblocked"); + } + } // logic to deal with loss of connection to AMQP server private class DisconnectHandler implements ShutdownListener { diff --git a/plugins/file-systems/netapp/pom.xml b/plugins/file-systems/netapp/pom.xml index 0c3fba7f4301..2b2c7bd92313 100644 --- a/plugins/file-systems/netapp/pom.xml +++ b/plugins/file-systems/netapp/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/ha-planners/skip-heurestics/pom.xml b/plugins/ha-planners/skip-heurestics/pom.xml index 6728719a41d1..1511f8da0d3f 100644 --- a/plugins/ha-planners/skip-heurestics/pom.xml +++ b/plugins/ha-planners/skip-heurestics/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/host-allocators/random/pom.xml b/plugins/host-allocators/random/pom.xml index be1267ea0627..62284c229fa0 100644 --- a/plugins/host-allocators/random/pom.xml +++ b/plugins/host-allocators/random/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/baremetal/pom.xml b/plugins/hypervisors/baremetal/pom.xml index 9187a4232ae6..6e569cf680be 100755 --- a/plugins/hypervisors/baremetal/pom.xml +++ b/plugins/hypervisors/baremetal/pom.xml @@ -21,7 +21,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-baremetal diff --git a/plugins/hypervisors/hyperv/pom.xml b/plugins/hypervisors/hyperv/pom.xml index 7d1bd799880b..d88fd141885e 100644 --- a/plugins/hypervisors/hyperv/pom.xml +++ b/plugins/hypervisors/hyperv/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/hyperv/src/org/apache/cloudstack/storage/motion/HypervStorageMotionStrategy.java b/plugins/hypervisors/hyperv/src/org/apache/cloudstack/storage/motion/HypervStorageMotionStrategy.java index 8a1c414fb464..19c655b8f21f 100644 --- a/plugins/hypervisors/hyperv/src/org/apache/cloudstack/storage/motion/HypervStorageMotionStrategy.java +++ b/plugins/hypervisors/hyperv/src/org/apache/cloudstack/storage/motion/HypervStorageMotionStrategy.java @@ -48,9 +48,9 @@ import com.cloud.exception.OperationTimedoutException; import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StoragePool; import com.cloud.storage.VolumeVO; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; @@ -82,21 +82,12 @@ public StrategyPriority canHandle(Map volumeMap, Host src } @Override - public Void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { throw new UnsupportedOperationException(); } @Override - public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { - CopyCommandResult result = new CopyCommandResult(null, null); - result.setResult("Unsupported operation requested for copying data."); - callback.complete(result); - - return null; - } - - @Override - public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, + public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { Answer answer = null; String errMsg = null; @@ -115,7 +106,6 @@ public Void copyAsync(Map volumeMap, VirtualMachineTO vmT CopyCommandResult result = new CopyCommandResult(null, answer); result.setResult(errMsg); callback.complete(result); - return null; } private Answer migrateVmWithVolumes(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, diff --git a/plugins/hypervisors/kvm/.pydevproject b/plugins/hypervisors/kvm/.pydevproject deleted file mode 100644 index d4a984a39095..000000000000 --- a/plugins/hypervisors/kvm/.pydevproject +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -Default -python 2.7 - diff --git a/plugins/hypervisors/kvm/pom.xml b/plugins/hypervisors/kvm/pom.xml index aa26e7a38e24..f8100a50c067 100644 --- a/plugins/hypervisors/kvm/pom.xml +++ b/plugins/hypervisors/kvm/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml 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 old mode 100755 new mode 100644 index 883c8c99429d..02cf872d9271 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -57,6 +57,7 @@ import org.libvirt.Domain; import org.libvirt.DomainBlockStats; import org.libvirt.DomainInfo; +import org.libvirt.MemoryStatistic; import org.libvirt.DomainInfo.DomainState; import org.libvirt.DomainInterfaceStats; import org.libvirt.LibvirtException; @@ -190,6 +191,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private long _hvVersion; private long _kernelVersion; private int _timeout; + private static final int NUMMEMSTATS =2; private KVMHAMonitor _monitor; public static final String SSHKEYSPATH = "/root/.ssh"; @@ -3018,6 +3020,9 @@ private class VmStats { long _ioWrote; long _bytesRead; long _bytesWrote; + long _intmemfree; + long _memory; + long _maxmemory; Calendar _timestamp; } @@ -3026,11 +3031,16 @@ public VmStatsEntry getVmStat(final Connect conn, final String vmName) throws Li try { dm = getDomain(conn, vmName); final DomainInfo info = dm.getInfo(); + final MemoryStatistic[] mems = dm.memoryStats(NUMMEMSTATS); //number of memory statistics required. final VmStatsEntry stats = new VmStatsEntry(); + stats.setNumCPUs(info.nrVirtCpu); stats.setEntityType("vm"); + stats.setMemoryKBs(info.maxMem); + stats.setTargetMemoryKBs(info.memory); + stats.setIntFreeMemoryKBs((double) mems[0].getValue()); /* get cpu utilization */ VmStats oldStats = null; @@ -3115,6 +3125,9 @@ public VmStatsEntry getVmStat(final Connect conn, final String vmName) throws Li newStat._bytesRead = bytes_rd; newStat._bytesWrote = bytes_wr; newStat._timestamp = now; + newStat._intmemfree = mems[0].getValue(); + newStat._memory = info.memory; + newStat._maxmemory = info.maxMem; _vmStats.put(vmName, newStat); return stats; } finally { diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java index 04a27f3d8c70..47b9c40b8802 100644 --- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java @@ -66,6 +66,8 @@ import org.libvirt.LibvirtException; import org.libvirt.NodeInfo; import org.libvirt.StorageVol; +import org.libvirt.MemoryStatistic; + import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; @@ -417,7 +419,10 @@ public void testGetVmStat() throws LibvirtException { final Connect connect = Mockito.mock(Connect.class); final Domain domain = Mockito.mock(Domain.class); final DomainInfo domainInfo = new DomainInfo(); + final MemoryStatistic[] domainMem = new MemoryStatistic[2]; + domainMem[0] = Mockito.mock(MemoryStatistic.class); Mockito.when(domain.getInfo()).thenReturn(domainInfo); + Mockito.when(domain.memoryStats(2)).thenReturn(domainMem); Mockito.when(connect.domainLookupByName(VMNAME)).thenReturn(domain); final NodeInfo nodeInfo = new NodeInfo(); nodeInfo.cpus = 8; @@ -484,6 +489,10 @@ public List getDisks(final Connect conn, final String vmName) { // IO traffic as generated by the logic above, must be greater than zero Assert.assertTrue(vmStat.getDiskReadKBs() > 0); Assert.assertTrue(vmStat.getDiskWriteKBs() > 0); + // Memory limit of VM must be greater than zero + Assert.assertTrue(vmStat.getIntFreeMemoryKBs() >= 0); + Assert.assertTrue(vmStat.getMemoryKBs() >= 0); + Assert.assertTrue(vmStat.getTargetMemoryKBs() >= vmStat.getMemoryKBs()); } @Test @@ -5021,4 +5030,4 @@ public void testIsInterface () { } } } -} \ No newline at end of file +} diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelperTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelperTest.java index bb7a3f53fa0e..a43b342228fa 100644 --- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelperTest.java +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtUtilitiesHelperTest.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.hypervisor.kvm.resource.wrapper; +import java.io.File; import java.util.UUID; import com.cloud.utils.script.Script; @@ -37,8 +38,8 @@ public void testSSHKeyPaths() { * Hardcoded paths are not what we want in the longer run */ assertEquals("/root/.ssh", helper.retrieveSshKeysPath()); - assertEquals("/root/.ssh/id_rsa.pub.cloud", helper.retrieveSshPubKeyPath()); - assertEquals("/root/.ssh/id_rsa.cloud", helper.retrieveSshPrvKeyPath()); + assertEquals("/root/.ssh" + File.separator + "id_rsa.pub.cloud", helper.retrieveSshPubKeyPath()); + assertEquals("/root/.ssh" + File.separator + "id_rsa.cloud", helper.retrieveSshPrvKeyPath()); } public void testBashScriptPath() { diff --git a/plugins/hypervisors/ovm/pom.xml b/plugins/hypervisors/ovm/pom.xml index a495630f05d8..e754e632a8da 100644 --- a/plugins/hypervisors/ovm/pom.xml +++ b/plugins/hypervisors/ovm/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml index 301051249ac2..8da1430137cb 100644 --- a/plugins/hypervisors/ovm3/pom.xml +++ b/plugins/hypervisors/ovm3/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml index 9f3de6c1611e..dbebba0146cf 100644 --- a/plugins/hypervisors/simulator/pom.xml +++ b/plugins/hypervisors/simulator/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-simulator diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java index 6602e1f1ad07..9863b22dd84a 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java @@ -319,7 +319,7 @@ public Answer getVmStats(final GetVmStatsCommand cmd) { final HashMap vmStatsNameMap = new HashMap(); final List vmNames = cmd.getVmNames(); for (final String vmName : vmNames) { - final VmStatsEntry entry = new VmStatsEntry(0, 0, 0, 0, "vm"); + final VmStatsEntry entry = new VmStatsEntry(0, 0, 0, 0, 0, 0, 0, "vm"); entry.setNetworkReadKBs(32768); // default values 256 KBps entry.setNetworkWriteKBs(16384); entry.setCPUUtilization(10); diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java index 751da9e3d2a3..9b1f091db71b 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java @@ -109,7 +109,7 @@ public boolean configure(String name, Map params) throws Configu } @Override - public String getRootDir(String url) { + public String getRootDir(String url, String nfsVersion) { // TODO Auto-generated method stub return null; } diff --git a/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/motion/SimulatorDataMotionStrategy.java b/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/motion/SimulatorDataMotionStrategy.java index 40909629c705..5e72babf0810 100644 --- a/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/motion/SimulatorDataMotionStrategy.java +++ b/plugins/hypervisors/simulator/src/org/apache/cloudstack/storage/motion/SimulatorDataMotionStrategy.java @@ -43,21 +43,13 @@ public StrategyPriority canHandle(Map volumeMap, Host src } @Override - public Void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { throw new UnsupportedOperationException(); } @Override - public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { + public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { CopyCommandResult result = new CopyCommandResult("something", null); callback.complete(result); - return null; - } - - @Override - public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { - CopyCommandResult result = new CopyCommandResult("something", null); - callback.complete(result); - return null; } } diff --git a/plugins/hypervisors/ucs/pom.xml b/plugins/hypervisors/ucs/pom.xml index 7ec0256fa5fa..c8a14d19b07d 100755 --- a/plugins/hypervisors/ucs/pom.xml +++ b/plugins/hypervisors/ucs/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml cloud-plugin-hypervisor-ucs diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml index 35ccaa4b878e..455fb5819d63 100644 --- a/plugins/hypervisors/vmware/pom.xml +++ b/plugins/hypervisors/vmware/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java index fd96bc8357cc..986000aa9389 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java @@ -200,10 +200,10 @@ public VirtualMachineTO implement(VirtualMachineProfile vm) { } } - String diskDeviceType = details.get(VmDetailConstants.ROOK_DISK_CONTROLLER); + String diskDeviceType = details.get(VmDetailConstants.ROOT_DISK_CONTROLLER); if (userVm) { if (diskDeviceType == null) { - details.put(VmDetailConstants.ROOK_DISK_CONTROLLER, _vmwareMgr.getRootDiskController()); + details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, _vmwareMgr.getRootDiskController()); } } String diskController = details.get(VmDetailConstants.DATA_DISK_CONTROLLER); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java index 72ee2184e399..65590500a07f 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java @@ -36,7 +36,7 @@ public interface VmwareManager { String getSystemVMDefaultNicAdapterType(); - void prepareSecondaryStorageStore(String strStorageUrl); + void prepareSecondaryStorageStore(String strStorageUrl, Long storeId); void setupResourceStartupParams(Map params); @@ -48,7 +48,7 @@ public interface VmwareManager { String getManagementPortGroupName(); - String getSecondaryStorageStoreUrl(long dcId); + Pair getSecondaryStorageStoreUrlAndId(long dcId); File getSystemVMKeyFile(); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 575801fa6034..f27e938e7334 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -105,6 +105,7 @@ import com.cloud.org.Cluster.ClusterType; import com.cloud.secstorage.CommandExecLogDao; import com.cloud.server.ConfigurationServer; +import com.cloud.storage.ImageStoreDetailsUtil; import com.cloud.storage.JavaStorageLayer; import com.cloud.storage.StorageLayer; import com.cloud.utils.FileUtil; @@ -167,6 +168,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw private ManagementServerHostPeerDao _mshostPeerDao; @Inject private ClusterManager _clusterMgr; + @Inject + private ImageStoreDetailsUtil imageStoreDetailsUtil; private String _mountParent; private StorageLayer _storage; @@ -439,12 +442,14 @@ public List addHostToPodCluster(VmwareContext serviceCon } @Override - public String getSecondaryStorageStoreUrl(long dcId) { + public Pair getSecondaryStorageStoreUrlAndId(long dcId) { String secUrl = null; + Long secId = null; DataStore secStore = _dataStoreMgr.getImageStore(dcId); if (secStore != null) { secUrl = secStore.getUri(); + secId = secStore.getId(); } if (secUrl == null) { @@ -453,12 +458,13 @@ public String getSecondaryStorageStoreUrl(long dcId) { DataStore cacheStore = _dataStoreMgr.getImageCacheStore(dcId); if (cacheStore != null) { secUrl = cacheStore.getUri(); + secId = cacheStore.getId(); } else { s_logger.warn("No staging storage is found when non-NFS secondary storage is used"); } } - return secUrl; + return new Pair(secUrl, secId); } @Override @@ -546,8 +552,8 @@ public boolean needRecycle(String workerTag) { } @Override - public void prepareSecondaryStorageStore(String storageUrl) { - String mountPoint = getMountPoint(storageUrl); + public void prepareSecondaryStorageStore(String storageUrl, Long storeId) { + String mountPoint = getMountPoint(storageUrl, imageStoreDetailsUtil.getNfsVersion(storeId)); GlobalLock lock = GlobalLock.getInternLock("prepare.systemvm"); try { @@ -655,7 +661,7 @@ public void run() { } @Override - public String getMountPoint(String storageUrl) { + public String getMountPoint(String storageUrl, String nfsVersion) { String mountPoint = null; synchronized (_storageMounts) { mountPoint = _storageMounts.get(storageUrl); @@ -670,7 +676,8 @@ public String getMountPoint(String storageUrl) { s_logger.error("Invalid storage URL format ", e); throw new CloudRuntimeException("Unable to create mount point due to invalid storage URL format " + storageUrl); } - mountPoint = mount(uri.getHost() + ":" + uri.getPath(), _mountParent); + + mountPoint = mount(uri.getHost() + ":" + uri.getPath(), _mountParent, nfsVersion); if (mountPoint == null) { s_logger.error("Unable to create mount point for " + storageUrl); return "/mnt/sec"; // throw new CloudRuntimeException("Unable to create mount point for " + storageUrl); @@ -745,7 +752,7 @@ private void shutdownCleanup() { } } - protected String mount(String path, String parent) { + protected String mount(String path, String parent, String nfsVersion) { String mountPoint = setupMountPoint(parent); if (mountPoint == null) { s_logger.warn("Unable to create a mount point"); @@ -756,6 +763,9 @@ protected String mount(String path, String parent) { String result = null; Script command = new Script(true, "mount", _timeout, s_logger); command.add("-t", "nfs"); + if (nfsVersion != null){ + command.add("-o", "vers=" + nfsVersion); + } // command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0"); if ("Mac OS X".equalsIgnoreCase(System.getProperty("os.name"))) { command.add("-o", "resvport"); @@ -1234,4 +1244,5 @@ public boolean hasNexusVSM(Long clusterId) { return true; } } + } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java index 4109ff2345b9..c7c53bacba99 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java @@ -92,6 +92,9 @@ import com.cloud.vm.snapshot.VMSnapshot; public class VmwareStorageManagerImpl implements VmwareStorageManager { + + private String _nfsVersion; + @Override public boolean execute(VmwareHostService hostService, CreateEntityDownloadURLCommand cmd) { DataTO data = cmd.getData(); @@ -138,6 +141,12 @@ public VmwareStorageManagerImpl(VmwareStorageMount mountService) { _mountService = mountService; } + public VmwareStorageManagerImpl(VmwareStorageMount mountService, String nfsVersion) { + assert (mountService != null); + _mountService = mountService; + _nfsVersion = nfsVersion; + } + public void configure(Map params) { s_logger.info("Configure VmwareStorageManagerImpl"); @@ -156,7 +165,7 @@ public String createOvaForTemplate(TemplateObjectTO template) { String secStorageUrl = nfsStore.getUrl(); assert (secStorageUrl != null); String installPath = template.getPath(); - String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); + String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, _nfsVersion); String installFullPath = secondaryMountPoint + "/" + installPath; try { if (installFullPath.endsWith(".ova")) { @@ -194,7 +203,7 @@ public String createOvaForVolume(VolumeObjectTO volume) { String installPath = volume.getPath(); int index = installPath.lastIndexOf(File.separator); String volumeUuid = installPath.substring(index + 1); - String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); + String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, _nfsVersion); //The real volume path String volumePath = installPath + File.separator + volumeUuid + ".ova"; String installFullPath = secondaryMountPoint + "/" + installPath; @@ -271,7 +280,8 @@ public Answer execute(VmwareHostService hostService, PrimaryStorageDownloadComma assert (morDs != null); DatastoreMO primaryStorageDatastoreMo = new DatastoreMO(context, morDs); - copyTemplateFromSecondaryToPrimary(hyperHost, primaryStorageDatastoreMo, secondaryStorageUrl, mountPoint, templateName, templateUuidName); + copyTemplateFromSecondaryToPrimary(hyperHost, primaryStorageDatastoreMo, secondaryStorageUrl, mountPoint, templateName, templateUuidName, + cmd.getNfsVersion()); } else { s_logger.info("Template " + templateName + " has already been setup, skip the template setup process in primary storage"); } @@ -345,7 +355,7 @@ public Answer execute(VmwareHostService hostService, BackupSnapshotCommand cmd) snapshotBackupUuid = backupSnapshotToSecondaryStorage(vmMo, accountId, volumeId, cmd.getVolumePath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid, - hostService.getWorkerName(context, cmd, 1)); + hostService.getWorkerName(context, cmd, 1), cmd.getNfsVersion()); success = (snapshotBackupUuid != null); if (success) { @@ -413,7 +423,7 @@ public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVo Ternary result = createTemplateFromVolume(vmMo, accountId, templateId, cmd.getUniqueName(), secondaryStoragePoolURL, volumePath, - hostService.getWorkerName(context, cmd, 0)); + hostService.getWorkerName(context, cmd, 0), cmd.getNfsVersion()); return new CreatePrivateTemplateAnswer(cmd, true, null, result.first(), result.third(), result.second(), cmd.getUniqueName(), ImageFormat.OVA); @@ -441,7 +451,8 @@ public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromSn VmwareContext context = hostService.getServiceContext(cmd); try { - Ternary result = createTemplateFromSnapshot(accountId, newTemplateId, uniqeName, secondaryStorageUrl, volumeId, backedUpSnapshotUuid); + Ternary result = createTemplateFromSnapshot(accountId, newTemplateId, uniqeName, secondaryStorageUrl, volumeId, backedUpSnapshotUuid, + cmd.getNfsVersion()); return new CreatePrivateTemplateAnswer(cmd, true, null, result.first(), result.third(), result.second(), uniqeName, ImageFormat.OVA); } catch (Throwable e) { @@ -471,7 +482,7 @@ public Answer execute(VmwareHostService hostService, CopyVolumeCommand cmd) { if (cmd.toSecondaryStorage()) { result = copyVolumeToSecStorage(hostService, hyperHost, cmd, vmName, volumeId, cmd.getPool().getUuid(), volumePath, secondaryStorageURL, - hostService.getWorkerName(context, cmd, 0)); + hostService.getWorkerName(context, cmd, 0), cmd.getNfsVersion()); } else { StorageFilerTO poolTO = cmd.getPool(); @@ -484,8 +495,9 @@ public Answer execute(VmwareHostService hostService, CopyVolumeCommand cmd) { } } - result = copyVolumeFromSecStorage(hyperHost, volumeId, new DatastoreMO(context, morDatastore), secondaryStorageURL, volumePath); - deleteVolumeDirOnSecondaryStorage(volumeId, secondaryStorageURL); + result = copyVolumeFromSecStorage(hyperHost, volumeId, new DatastoreMO(context, morDatastore), secondaryStorageURL, volumePath, + cmd.getNfsVersion()); + deleteVolumeDirOnSecondaryStorage(volumeId, secondaryStorageURL, cmd.getNfsVersion()); } return new CopyVolumeAnswer(cmd, true, null, result.first(), result.second()); } catch (Throwable e) { @@ -523,7 +535,8 @@ public Answer execute(VmwareHostService hostService, CreateVolumeFromSnapshotCom } DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs); - details = createVolumeFromSnapshot(hyperHost, primaryDsMo, newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid); + details = createVolumeFromSnapshot(hyperHost, primaryDsMo, newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid, + cmd.getNfsVersion()); if (details == null) { success = true; } @@ -542,12 +555,12 @@ public Answer execute(VmwareHostService hostService, CreateVolumeFromSnapshotCom // templateName: name in secondary storage // templateUuid: will be used at hypervisor layer private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl, - String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception { + String templatePathAtSecondaryStorage, String templateName, String templateUuid, String nfsVersion) throws Exception { s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage + ", templateName: " + templateName); - String secondaryMountPoint = _mountService.getMountPoint(secondaryStorageUrl); + String secondaryMountPoint = _mountService.getMountPoint(secondaryStorageUrl, nfsVersion); s_logger.info("Secondary storage mount point: " + secondaryMountPoint); String srcOVAFileName = secondaryMountPoint + "/" + templatePathAtSecondaryStorage + templateName + "." + ImageFormat.OVA.getFileExtension(); @@ -598,9 +611,9 @@ private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, } private Ternary createTemplateFromVolume(VirtualMachineMO vmMo, long accountId, long templateId, String templateUniqueName, String secStorageUrl, - String volumePath, String workerVmName) throws Exception { + String volumePath, String workerVmName, String nfsVersion) throws Exception { - String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); + String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion); String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId); String installFullPath = secondaryMountPoint + "/" + installPath; synchronized (installPath.intern()) { @@ -663,9 +676,9 @@ private Ternary createTemplateFromVolume(VirtualMachineMO vm } private Ternary createTemplateFromSnapshot(long accountId, long templateId, String templateUniqueName, String secStorageUrl, long volumeId, - String backedUpSnapshotUuid) throws Exception { + String backedUpSnapshotUuid, String nfsVersion) throws Exception { - String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); + String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion); String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId); String installFullPath = secondaryMountPoint + "/" + installPath; String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova"; //Note: volss for tmpl @@ -847,16 +860,16 @@ private void writeMetaOvaForTemplate(String installFullPath, String ovfFilename, } private String createVolumeFromSnapshot(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, long accountId, long volumeId, - String secStorageUrl, String snapshotBackupUuid) throws Exception { + String secStorageUrl, String snapshotBackupUuid, String nfsVersion) throws Exception { - restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), snapshotBackupUuid); + restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), snapshotBackupUuid, nfsVersion); return null; } private void restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, String secStorageUrl, String secStorageDir, - String backupName) throws Exception { + String backupName, String nfsVersion) throws Exception { - String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); + String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion); String srcOVAFileName = secondaryMountPoint + "/" + secStorageDir + "/" + backupName + "." + ImageFormat.OVA.getFileExtension(); String snapshotDir = ""; if (backupName.contains("/")) { @@ -914,17 +927,17 @@ private void restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, Datasto } private String backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, long accountId, long volumeId, String volumePath, String snapshotUuid, String secStorageUrl, - String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception { + String prevSnapshotUuid, String prevBackupUuid, String workerVmName, String nfsVersion) throws Exception { String backupUuid = UUID.randomUUID().toString(); - exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), backupUuid, workerVmName); + exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), backupUuid, workerVmName, nfsVersion); return backupUuid + "/" + backupUuid; } private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir, String exportName, - String workerVmName) throws Exception { + String workerVmName, String nfsVersion) throws Exception { - String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); + String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion); String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName; synchronized (exportPath.intern()) { @@ -967,7 +980,7 @@ private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volume } private Pair copyVolumeToSecStorage(VmwareHostService hostService, VmwareHypervisorHost hyperHost, CopyVolumeCommand cmd, String vmName, - long volumeId, String poolId, String volumePath, String secStorageUrl, String workerVmName) throws Exception { + long volumeId, String poolId, String volumePath, String secStorageUrl, String workerVmName, String nfsVersion) throws Exception { String volumeFolder = String.valueOf(volumeId) + "/"; VirtualMachineMO workerVm = null; @@ -1004,7 +1017,7 @@ private Pair copyVolumeToSecStorage(VmwareHostService hostServic vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false); exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, "volumes/" + volumeFolder, exportName, - hostService.getWorkerName(hyperHost.getContext(), cmd, 1)); + hostService.getWorkerName(hyperHost.getContext(), cmd, 1), nfsVersion); return new Pair(volumeFolder, exportName); } finally { @@ -1025,12 +1038,12 @@ private String getVolumePathInDatastore(DatastoreMO dsMo, String volumeFileName) return datastoreVolumePath; } - private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, long volumeId, DatastoreMO dsMo, String secStorageUrl, String exportName) + private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, long volumeId, DatastoreMO dsMo, String secStorageUrl, String exportName, String nfsVersion) throws Exception { String volumeFolder = String.valueOf(volumeId) + "/"; String newVolume = UUID.randomUUID().toString().replaceAll("-", ""); - restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, "volumes/" + volumeFolder, exportName); + restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, "volumes/" + volumeFolder, exportName, nfsVersion); return new Pair(volumeFolder, newVolume); } @@ -1445,8 +1458,8 @@ public RevertToVMSnapshotAnswer execute(VmwareHostService hostService, RevertToV } } - private String deleteVolumeDirOnSecondaryStorage(long volumeId, String secStorageUrl) throws Exception { - String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); + private String deleteVolumeDirOnSecondaryStorage(long volumeId, String secStorageUrl, String nfsVersion) throws Exception { + String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion); String volumeMountRoot = secondaryMountPoint + "/" + getVolumeRelativeDirInSecStroage(volumeId); return deleteDir(volumeMountRoot); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java index dd07029766c4..54b52f6dff4c 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageMount.java @@ -17,5 +17,5 @@ package com.cloud.hypervisor.vmware.manager; public interface VmwareStorageMount { - String getMountPoint(String storageUrl); + String getMountPoint(String storageUrl, String nfsVersion); } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index fdbc244997d0..4d04abca4fa7 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -94,11 +94,13 @@ import com.vmware.vim25.VirtualMachineRelocateSpec; import com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator; import com.vmware.vim25.VirtualMachineRuntimeInfo; +import com.vmware.vim25.VirtualMachineVideoCard; import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.commons.lang.math.NumberUtils; import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; @@ -1412,7 +1414,7 @@ protected StartAnswer execute(StartCommand cmd) { String vmInternalCSName = names.first(); String vmNameOnVcenter = names.second(); String dataDiskController = vmSpec.getDetails().get(VmDetailConstants.DATA_DISK_CONTROLLER); - String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOK_DISK_CONTROLLER); + String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER); // If root disk controller is scsi, then data disk controller would also be scsi instead of using 'osdefault' // This helps avoid mix of different scsi subtype controllers in instance. @@ -1636,12 +1638,14 @@ protected StartAnswer execute(StartCommand cmd) { // prepare systemvm patch ISO if (vmSpec.getType() != VirtualMachine.Type.User) { // attach ISO (for patching of system VM) - String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId)); + Pair secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId)); + String secStoreUrl = secStoreUrlAndId.first(); + Long secStoreId = secStoreUrlAndId.second(); if (secStoreUrl == null) { String msg = "secondary storage for dc " + _dcId + " is not ready yet?"; throw new Exception(msg); } - mgr.prepareSecondaryStorageStore(secStoreUrl); + mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId); ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl); if (morSecDs == null) { @@ -1895,6 +1899,8 @@ protected StartAnswer execute(StartCommand cmd) { postDiskConfigBeforeStart(vmMo, vmSpec, sortedDisks, ideControllerKey, scsiControllerKey, iqnToPath, hyperHost, context); + postVideoCardMemoryConfigBeforeStart(vmMo, vmSpec); + // // Power-on VM // @@ -1943,6 +1949,79 @@ protected StartAnswer execute(StartCommand cmd) { } } + /** + * Sets video card memory to the one provided in detail svga.vramSize (if provided). + * 64MB was always set before. + * Size must be in KB. + * @param vmMo virtual machine mo + * @param vmSpec virtual machine specs + */ + protected void postVideoCardMemoryConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec) { + String paramVRamSize = "svga.vramSize"; + if (vmSpec.getDetails().containsKey(paramVRamSize)){ + String value = vmSpec.getDetails().get(paramVRamSize); + try { + long svgaVmramSize = Long.parseLong(value); + setNewVRamSizeVmVideoCard(vmMo, svgaVmramSize); + } + catch (NumberFormatException e){ + s_logger.error("Unexpected value, cannot parse " + value + " to long due to: " + e.getMessage()); + } + catch (Exception e){ + s_logger.error("Error while reconfiguring vm due to: " + e.getMessage()); + } + } + } + + /** + * Search for vm video card iterating through vm device list + * @param vmMo virtual machine mo + * @param svgaVmramSize new svga vram size (in KB) + */ + private void setNewVRamSizeVmVideoCard(VirtualMachineMO vmMo, long svgaVmramSize) throws Exception { + for (VirtualDevice device : vmMo.getAllDeviceList()){ + if (device instanceof VirtualMachineVideoCard){ + VirtualMachineVideoCard videoCard = (VirtualMachineVideoCard) device; + modifyVmVideoCardVRamSize(videoCard, vmMo, svgaVmramSize); + } + } + } + + /** + * Modifies vm vram size if it was set to a different size to the one provided in svga.vramSize (user_vm_details or template_vm_details) + * @param videoCard vm's video card device + * @param vmMo virtual machine mo + * @param svgaVmramSize new svga vram size (in KB) + */ + private void modifyVmVideoCardVRamSize(VirtualMachineVideoCard videoCard, VirtualMachineMO vmMo, long svgaVmramSize) throws Exception { + if (videoCard.getVideoRamSizeInKB().longValue() != svgaVmramSize){ + s_logger.info("Video card memory was set " + videoCard.getVideoRamSizeInKB().longValue() + "kb instead of " + svgaVmramSize + "kb"); + VirtualMachineConfigSpec newSizeSpecs = configSpecVideoCardNewVRamSize(videoCard, svgaVmramSize); + boolean res = vmMo.configureVm(newSizeSpecs); + if (res) { + s_logger.info("Video card memory successfully updated to " + svgaVmramSize + "kb"); + } + } + } + + /** + * Returns a VirtualMachineConfigSpec to edit its svga vram size + * @param videoCard video card device to edit providing the svga vram size + * @param svgaVmramSize new svga vram size (in KB) + */ + private VirtualMachineConfigSpec configSpecVideoCardNewVRamSize(VirtualMachineVideoCard videoCard, long svgaVmramSize){ + videoCard.setVideoRamSizeInKB(svgaVmramSize); + videoCard.setUseAutoDetect(false); + + VirtualDeviceConfigSpec arrayVideoCardConfigSpecs = new VirtualDeviceConfigSpec(); + arrayVideoCardConfigSpecs.setDevice(videoCard); + arrayVideoCardConfigSpecs.setOperation(VirtualDeviceConfigSpecOperation.EDIT); + + VirtualMachineConfigSpec changeVideoCardSpecs = new VirtualMachineConfigSpec(); + changeVideoCardSpecs.getDeviceChange().add(arrayVideoCardConfigSpecs); + return changeVideoCardSpecs; + } + private void tearDownVm(VirtualMachineMO vmMo) throws Exception{ if(vmMo == null) return; @@ -2322,14 +2401,14 @@ private int getDiskController(VirtualMachineDiskInfo matchingExistingDisk, DiskT if (vol.getType() == Volume.Type.ROOT) { Map vmDetails = vmSpec.getDetails(); - if (vmDetails != null && vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER) != null) { - if (vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER).equalsIgnoreCase("scsi")) { + if (vmDetails != null && vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER) != null) { + if (vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER).equalsIgnoreCase("scsi")) { s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi, based on root disk controller settings: " + - vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER)); + vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER)); controllerKey = scsiControllerKey; } else { s_logger.info("Chose disk controller for vol " + vol.getType() + " -> ide, based on root disk controller settings: " + - vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER)); + vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER)); controllerKey = ideControllerKey; } } else { @@ -3134,12 +3213,14 @@ protected Answer execute(PrepareForMigrationCommand cmd) { prepareNetworkFromNicInfo(new HostMO(getServiceContext(), _morHyperHost), nic, false, cmd.getVirtualMachine().getType()); } - String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId)); + Pair secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId)); + String secStoreUrl = secStoreUrlAndId.first(); + Long secStoreId = secStoreUrlAndId.second(); if (secStoreUrl == null) { String msg = "secondary storage for dc " + _dcId + " is not ready yet?"; throw new Exception(msg); } - mgr.prepareSecondaryStorageStore(secStoreUrl); + mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId); ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl); if (morSecDs == null) { @@ -3350,12 +3431,14 @@ protected Answer execute(MigrateWithStorageCommand cmd) { } // Ensure secondary storage mounted on target host - String secStoreUrl = mgr.getSecondaryStorageStoreUrl(Long.parseLong(_dcId)); + Pair secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId)); + String secStoreUrl = secStoreUrlAndId.first(); + Long secStoreId = secStoreUrlAndId.second(); if (secStoreUrl == null) { String msg = "secondary storage for dc " + _dcId + " is not ready yet?"; throw new Exception(msg); } - mgr.prepareSecondaryStorageStore(secStoreUrl); + mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId); ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnSpecificHost(secStoreUrl, tgtHyperHost); if (morSecDs == null) { String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl; @@ -4862,8 +4945,14 @@ private HashMap getVmStats(List vmNames) throws Ex } String instanceNameCustomField = "value[" + key + "]"; + final String numCpuStr = "summary.config.numCpu"; + final String cpuUseStr = "summary.quickStats.overallCpuUsage"; + final String guestMemUseStr = "summary.quickStats.guestMemoryUsage"; + final String memLimitStr = "resourceConfig.memoryAllocation.limit"; + final String memMbStr = "config.hardware.memoryMB"; + ObjectContent[] ocs = - hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", "summary.config.numCpu", "summary.quickStats.overallCpuUsage", instanceNameCustomField}); + hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", numCpuStr, cpuUseStr ,guestMemUseStr ,memLimitStr ,memMbStr, instanceNameCustomField}); if (ocs != null && ocs.length > 0) { for (ObjectContent oc : ocs) { List objProps = oc.getPropSet(); @@ -4871,6 +4960,9 @@ private HashMap getVmStats(List vmNames) throws Ex String name = null; String numberCPUs = null; String maxCpuUsage = null; + String memlimit = null; + String memkb = null; + String guestMemusage = null; String vmNameOnVcenter = null; String vmInternalCSName = null; for (DynamicProperty objProp : objProps) { @@ -4879,10 +4971,16 @@ private HashMap getVmStats(List vmNames) throws Ex } else if (objProp.getName().contains(instanceNameCustomField)) { if (objProp.getVal() != null) vmInternalCSName = ((CustomFieldStringValue)objProp.getVal()).getValue(); - } else if (objProp.getName().equals("summary.config.numCpu")) { + }else if(objProp.getName().equals(guestMemusage)){ + guestMemusage = objProp.getVal().toString(); + }else if (objProp.getName().equals(numCpuStr)) { numberCPUs = objProp.getVal().toString(); - } else if (objProp.getName().equals("summary.quickStats.overallCpuUsage")) { + } else if (objProp.getName().equals(cpuUseStr)) { maxCpuUsage = objProp.getVal().toString(); + } else if (objProp.getName().equals(memLimitStr)) { + memlimit = objProp.getVal().toString(); + } else if (objProp.getName().equals(memMbStr)) { + memkb = objProp.getVal().toString(); } } new VirtualMachineMO(hyperHost.getContext(), oc.getObj()); @@ -4951,7 +5049,7 @@ private HashMap getVmStats(List vmNames) throws Ex } } } - vmResponseMap.put(name, new VmStatsEntry(Integer.parseInt(maxCpuUsage), networkReadKBs, networkWriteKBs, Integer.parseInt(numberCPUs), "vm")); + vmResponseMap.put(name, new VmStatsEntry( NumberUtils.toDouble(memkb)*1024,NumberUtils.toDouble(guestMemusage)*1024,NumberUtils.toDouble(memlimit)*1024, NumberUtils.toDouble(maxCpuUsage), networkReadKBs, networkWriteKBs, NumberUtils.toInt(numberCPUs), "vm")); } } } @@ -5191,8 +5289,8 @@ else if (value != null && value.equalsIgnoreCase("ide")) value = (String)params.get("scripts.timeout"); int timeout = NumbersUtil.parseInt(value, 1440) * 1000; - _storageProcessor = new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null); - storageHandler = new VmwareStorageSubsystemCommandHandler(_storageProcessor); + _storageProcessor = new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null, (String)params.get("nfsVersion")); + storageHandler = new VmwareStorageSubsystemCommandHandler(_storageProcessor, (String)params.get("nfsVersion")); _vrResource = new VirtualRoutingResource(this); if (!_vrResource.configure(name, params)) { diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java index 8e4a0d2a83db..1ec4958509bc 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java @@ -102,7 +102,7 @@ public boolean configure(String name, Map params) throws Configu VmwareSecondaryStorageContextFactory.initFactoryEnvironment(); } - registerHandler(Hypervisor.HypervisorType.VMware, new VmwareSecondaryStorageResourceHandler(this)); + registerHandler(Hypervisor.HypervisorType.VMware, new VmwareSecondaryStorageResourceHandler(this, (String)params.get("nfsVersion"))); return true; } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java index 8a277991aac6..3c4e6340d31f 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java @@ -66,13 +66,13 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe * private Map _activeHosts = new HashMap(); */ - public VmwareSecondaryStorageResourceHandler(PremiumSecondaryStorageResource resource) { + public VmwareSecondaryStorageResourceHandler(PremiumSecondaryStorageResource resource, String nfsVersion) { _resource = resource; - _storageMgr = new VmwareStorageManagerImpl(this); + _storageMgr = new VmwareStorageManagerImpl(this, nfsVersion); _gson = GsonHelper.getGsonLogger(); - VmwareStorageProcessor storageProcessor = new VmwareStorageProcessor(this, true, this, resource.getTimeout(), null, null, _resource); - VmwareStorageSubsystemCommandHandler vmwareStorageSubsystemCommandHandler = new VmwareStorageSubsystemCommandHandler(storageProcessor); + VmwareStorageProcessor storageProcessor = new VmwareStorageProcessor(this, true, this, resource.getTimeout(), null, null, _resource, nfsVersion); + VmwareStorageSubsystemCommandHandler vmwareStorageSubsystemCommandHandler = new VmwareStorageSubsystemCommandHandler(storageProcessor, nfsVersion); vmwareStorageSubsystemCommandHandler.setStorageResource(_resource); vmwareStorageSubsystemCommandHandler.setStorageManager(_storageMgr); storageSubsystemHandler = vmwareStorageSubsystemCommandHandler; @@ -304,7 +304,7 @@ public String getWorkerName(VmwareContext context, Command cmd, int workerSequen } @Override - public String getMountPoint(String storageUrl) { - return _resource.getRootDir(storageUrl); + public String getMountPoint(String storageUrl, String nfsVersion) { + return _resource.getRootDir(storageUrl, nfsVersion); } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index fa2f369afaf6..f3bf91c4e58a 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -109,6 +109,7 @@ import com.cloud.vm.VmDetailConstants; public class VmwareStorageProcessor implements StorageProcessor { + private static final Logger s_logger = Logger.getLogger(VmwareStorageProcessor.class); private static final int DEFAULT_NFS_PORT = 2049; @@ -120,9 +121,10 @@ public class VmwareStorageProcessor implements StorageProcessor { protected Integer _shutdownWaitMs; private final Gson _gson; private final StorageLayer _storage = new JavaStorageLayer(); + private String _nfsVersion; public VmwareStorageProcessor(VmwareHostService hostService, boolean fullCloneFlag, VmwareStorageMount mountService, Integer timeout, VmwareResource resource, - Integer shutdownWaitMs, PremiumSecondaryStorageResource storageResource) { + Integer shutdownWaitMs, PremiumSecondaryStorageResource storageResource, String nfsVersion) { this.hostService = hostService; _fullCloneFlag = fullCloneFlag; this.mountService = mountService; @@ -130,6 +132,7 @@ public VmwareStorageProcessor(VmwareHostService hostService, boolean fullCloneFl this.resource = resource; _shutdownWaitMs = shutdownWaitMs; _gson = GsonHelper.getGsonLogger(); + _nfsVersion = nfsVersion; } @Override @@ -155,12 +158,12 @@ private String getOVFFilePath(String srcOVAFileName) { } private VirtualMachineMO copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl, - String templatePathAtSecondaryStorage, String templateName, String templateUuid, boolean createSnapshot) throws Exception { + String templatePathAtSecondaryStorage, String templateName, String templateUuid, boolean createSnapshot, String nfsVersion) throws Exception { s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage + ", templateName: " + templateName); - String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl); + String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, nfsVersion); s_logger.info("Secondary storage mount point: " + secondaryMountPoint); String srcOVAFileName = @@ -316,7 +319,7 @@ public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) { if (managed) { VirtualMachineMO vmMo = copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(), - managedStoragePoolRootVolumeName, false); + managedStoragePoolRootVolumeName, false, _nfsVersion); vmMo.unregisterVm(); @@ -333,7 +336,7 @@ public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) { } else { copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(), - templateUuidName, true); + templateUuidName, true, _nfsVersion); } } else { s_logger.info("Template " + templateInfo.second() + " has already been setup, skip the template setup process in primary storage"); @@ -518,7 +521,7 @@ public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) { } } - private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, String srcVolumePath, DatastoreMO dsMo, String secStorageUrl, long wait) throws Exception { + private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, String srcVolumePath, DatastoreMO dsMo, String secStorageUrl, long wait, String nfsVersion) throws Exception { String volumeFolder = null; String volumeName = null; @@ -533,13 +536,13 @@ private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyper } String newVolume = VmwareHelper.getVCenterSafeUuid(); - restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, volumeFolder, volumeName, wait); + restoreVolumeFromSecStorage(hyperHost, dsMo, newVolume, secStorageUrl, volumeFolder, volumeName, wait, nfsVersion); return new Pair(volumeFolder, newVolume); } - private String deleteVolumeDirOnSecondaryStorage(String volumeDir, String secStorageUrl) throws Exception { - String secondaryMountPoint = mountService.getMountPoint(secStorageUrl); + private String deleteVolumeDirOnSecondaryStorage(String volumeDir, String secStorageUrl, String nfsVersion) throws Exception { + String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion); String volumeMountRoot = secondaryMountPoint + File.separator + volumeDir; return deleteDir(volumeMountRoot); @@ -578,8 +581,8 @@ public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) { } } - Pair result = copyVolumeFromSecStorage(hyperHost, srcVolume.getPath(), new DatastoreMO(context, morDatastore), srcStore.getUrl(), (long)cmd.getWait() * 1000); - deleteVolumeDirOnSecondaryStorage(result.first(), srcStore.getUrl()); + Pair result = copyVolumeFromSecStorage(hyperHost, srcVolume.getPath(), new DatastoreMO(context, morDatastore), srcStore.getUrl(), (long)cmd.getWait() * 1000, _nfsVersion); + deleteVolumeDirOnSecondaryStorage(result.first(), srcStore.getUrl(), _nfsVersion); VolumeObjectTO newVolume = new VolumeObjectTO(); newVolume.setPath(result.second()); return new CopyCmdAnswer(newVolume); @@ -636,7 +639,7 @@ private Pair copyVolumeToSecStorage(VmwareHostService hostServic vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false); - exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1)); + exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1), _nfsVersion); return new Pair(destVolumePath, exportName); } finally { @@ -720,9 +723,9 @@ private void postCreatePrivateTemplate(String installFullPath, long templateId, } private Ternary createTemplateFromVolume(VirtualMachineMO vmMo, String installPath, long templateId, String templateUniqueName, - String secStorageUrl, String volumePath, String workerVmName) throws Exception { + String secStorageUrl, String volumePath, String workerVmName, String nfsVersion) throws Exception { - String secondaryMountPoint = mountService.getMountPoint(secStorageUrl); + String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion); String installFullPath = secondaryMountPoint + "/" + installPath; synchronized (installPath.intern()) { Script command = new Script(false, "mkdir", _timeout, s_logger); @@ -838,7 +841,7 @@ public Answer createTemplateFromVolume(CopyCommand cmd) { Ternary result = createTemplateFromVolume(vmMo, template.getPath(), template.getId(), template.getName(), secondaryStoragePoolURL, volumePath, - hostService.getWorkerName(context, cmd, 0)); + hostService.getWorkerName(context, cmd, 0), _nfsVersion); TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(result.first()); @@ -885,7 +888,7 @@ private void writeMetaOvaForTemplate(String installFullPath, String ovfFilename, } private Ternary createTemplateFromSnapshot(String installPath, String templateUniqueName, String secStorageUrl, String snapshotPath, - Long templateId, long wait) throws Exception { + Long templateId, long wait, String nfsVersion) throws Exception { //Snapshot path is decoded in this form: /snapshots/account/volumeId/uuid/uuid String backupSSUuid; String snapshotFolder; @@ -899,7 +902,7 @@ private Ternary createTemplateFromSnapshot(String installPat snapshotFolder = StringUtils.join(tokens, File.separator, 0, tokens.length - 1); } - String secondaryMountPoint = mountService.getMountPoint(secStorageUrl); + String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion); String installFullPath = secondaryMountPoint + "/" + installPath; String installFullOVAName = installFullPath + "/" + templateUniqueName + ".ova"; //Note: volss for tmpl String snapshotRoot = secondaryMountPoint + "/" + snapshotFolder; @@ -1029,7 +1032,7 @@ public Answer createTemplateFromSnapshot(CopyCommand cmd) { } NfsTO nfsSvr = (NfsTO)imageStore; - Ternary result = createTemplateFromSnapshot(template.getPath(), uniqeName, nfsSvr.getUrl(), snapshot.getPath(), template.getId(), (long)cmd.getWait() * 1000); + Ternary result = createTemplateFromSnapshot(template.getPath(), uniqeName, nfsSvr.getUrl(), snapshot.getPath(), template.getId(), (long)cmd.getWait() * 1000, _nfsVersion); TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(result.first()); @@ -1052,9 +1055,9 @@ public Answer createTemplateFromSnapshot(CopyCommand cmd) { // return Pair private Pair exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir, - String exportName, String workerVmName) throws Exception { + String exportName, String workerVmName, String nfsVersion) throws Exception { - String secondaryMountPoint = mountService.getMountPoint(secStorageUrl); + String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion); String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName; synchronized (exportPath.intern()) { @@ -1096,10 +1099,10 @@ private Pair exportVolumeToSecondaryStroage(VirtualMachineMO v // Ternary private Ternary backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, String installPath, String volumePath, String snapshotUuid, - String secStorageUrl, String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception { + String secStorageUrl, String prevSnapshotUuid, String prevBackupUuid, String workerVmName, String nfsVersion) throws Exception { String backupUuid = UUID.randomUUID().toString(); - Pair snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName); + Pair snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName, nfsVersion); return new Ternary(backupUuid, snapshotInfo.first(), snapshotInfo.second()); } @@ -1174,7 +1177,7 @@ public Answer backupSnapshot(CopyCommand cmd) { backupResult = backupSnapshotToSecondaryStorage(vmMo, destSnapshot.getPath(), srcSnapshot.getVolume().getPath(), snapshotUuid, secondaryStorageUrl, - prevSnapshotUuid, prevBackupUuid, hostService.getWorkerName(context, cmd, 1)); + prevSnapshotUuid, prevBackupUuid, hostService.getWorkerName(context, cmd, 1), _nfsVersion); snapshotBackupUuid = backupResult.first(); success = (snapshotBackupUuid != null); @@ -1186,7 +1189,7 @@ public Answer backupSnapshot(CopyCommand cmd) { // Get snapshot physical size long physicalSize = 0l; - String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl); + String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, _nfsVersion); String snapshotDir = destSnapshot.getPath() + "/" + snapshotBackupUuid; File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles(); if(files != null) { @@ -1364,7 +1367,7 @@ private Answer attachVolume(Command cmd, DiskTO disk, boolean isAttach, boolean if (isAttach) { String dataDiskController = controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER); - String rootDiskController = controllerInfo.get(VmDetailConstants.ROOK_DISK_CONTROLLER); + String rootDiskController = controllerInfo.get(VmDetailConstants.ROOT_DISK_CONTROLLER); DiskControllerType rootDiskControllerType = DiskControllerType.getType(rootDiskController); if (dataDiskController == null) { @@ -2144,9 +2147,9 @@ private List getManagedIqnsFromVirtualDisks(List virtualDis } private Long restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, String secStorageUrl, String secStorageDir, - String backupName, long wait) throws Exception { + String backupName, long wait, String nfsVersion) throws Exception { - String secondaryMountPoint = mountService.getMountPoint(secStorageUrl); + String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, null); String srcOVAFileName = null; String srcOVFFileName = null; @@ -2248,7 +2251,7 @@ public Answer createVolumeFromSnapshot(CopyCommand cmd) { backedUpSnapshotUuid = backedUpSnapshotUuid.replace(".ovf", ""); } DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs); - restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secondaryStorageUrl, backupPath, backedUpSnapshotUuid, (long)cmd.getWait() * 1000); + restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secondaryStorageUrl, backupPath, backedUpSnapshotUuid, (long)cmd.getWait() * 1000, _nfsVersion); VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(newVolumeName); diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java index 431286248b2d..40fa47b03bb3 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageSubsystemCommandHandler.java @@ -21,7 +21,6 @@ import java.io.File; import org.apache.log4j.Logger; - import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.DeleteCommand; @@ -40,9 +39,11 @@ import com.cloud.storage.DataStoreRole; public class VmwareStorageSubsystemCommandHandler extends StorageSubsystemCommandHandlerBase { + private static final Logger s_logger = Logger.getLogger(VmwareStorageSubsystemCommandHandler.class); private VmwareStorageManager storageManager; private PremiumSecondaryStorageResource storageResource; + private String _nfsVersion; public PremiumSecondaryStorageResource getStorageResource() { return storageResource; @@ -60,8 +61,9 @@ public void setStorageManager(VmwareStorageManager storageManager) { this.storageManager = storageManager; } - public VmwareStorageSubsystemCommandHandler(StorageProcessor processor) { + public VmwareStorageSubsystemCommandHandler(StorageProcessor processor, String nfsVersion) { super(processor); + this._nfsVersion = nfsVersion; } @Override @@ -82,7 +84,7 @@ protected Answer execute(CopyCommand cmd) { //need to take extra processing for vmware, such as packing to ova, before sending to S3 if (srcData.getObjectType() == DataObjectType.VOLUME) { NfsTO cacheStore = (NfsTO)srcDataStore; - String parentPath = storageResource.getRootDir(cacheStore.getUrl()); + String parentPath = storageResource.getRootDir(cacheStore.getUrl(), _nfsVersion); VolumeObjectTO vol = (VolumeObjectTO)srcData; String path = vol.getPath(); int index = path.lastIndexOf(File.separator); @@ -95,7 +97,7 @@ protected Answer execute(CopyCommand cmd) { } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT) { // pack ova first // sync snapshot from NFS cache to S3 in NFS migration to S3 case - String parentPath = storageResource.getRootDir(srcDataStore.getUrl()); + String parentPath = storageResource.getRootDir(srcDataStore.getUrl(), _nfsVersion); SnapshotObjectTO snap = (SnapshotObjectTO)srcData; String path = snap.getPath(); int index = path.lastIndexOf(File.separator); @@ -138,7 +140,7 @@ protected Answer execute(CopyCommand cmd) { return answer; } NfsTO cacheStore = (NfsTO)cmd.getCacheTO().getDataStore(); - String parentPath = storageResource.getRootDir(cacheStore.getUrl()); + String parentPath = storageResource.getRootDir(cacheStore.getUrl(), _nfsVersion); SnapshotObjectTO newSnapshot = (SnapshotObjectTO)answer.getNewData(); String path = newSnapshot.getPath(); int index = path.lastIndexOf(File.separator); diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java index 4b77aab61706..23b32a3d255c 100644 --- a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java +++ b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java @@ -25,9 +25,6 @@ import javax.inject.Inject; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -38,6 +35,8 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -87,21 +86,12 @@ public StrategyPriority canHandle(Map volumeMap, Host src } @Override - public Void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { throw new UnsupportedOperationException(); } @Override - public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { - CopyCommandResult result = new CopyCommandResult(null, null); - result.setResult("Unsupported operation requested for copying data."); - callback.complete(result); - - return null; - } - - @Override - public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { Answer answer = null; String errMsg = null; try { @@ -123,7 +113,6 @@ public Void copyAsync(Map volumeMap, VirtualMachineTO vmT CopyCommandResult result = new CopyCommandResult(null, answer); result.setResult(errMsg); callback.complete(result); - return null; } private Answer migrateVmWithVolumesAcrossCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java index 3b3dd4794991..fec2aba40f64 100644 --- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java +++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java @@ -25,18 +25,19 @@ import java.util.UUID; import javax.inject.Inject; -import javax.naming.ConfigurationException; import com.cloud.user.User; + import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; @@ -48,12 +49,13 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.AnnotationConfigContextLoader; - import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd; import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.apache.cloudstack.test.utils.SpringUtils; import com.cloud.agent.AgentManager; @@ -86,6 +88,7 @@ import com.cloud.org.Managed.ManagedState; import com.cloud.secstorage.CommandExecLogDao; import com.cloud.server.ConfigurationServer; +import com.cloud.storage.ImageStoreDetailsUtil; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountService; @@ -98,6 +101,7 @@ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = AnnotationConfigContextLoader.class) +@PrepareForTest({ComponentContext.class, ApplicationContext.class}) public class VmwareDatacenterApiUnitTest { @Inject @@ -155,10 +159,6 @@ public class VmwareDatacenterApiUnitTest { @Mock private static RemoveVmwareDcCmd removeCmd; - @BeforeClass - public static void setUp() throws ConfigurationException { - } - @Before public void testSetUp() { Mockito.when(_configDao.isPremium()).thenReturn(true); @@ -431,6 +431,22 @@ public DataStoreManager dataStoreManager() { return Mockito.mock(DataStoreManager.class); } + @Bean + public ImageStoreDetailsUtil imageStoreDetailsUtil() { + return Mockito.mock(ImageStoreDetailsUtil.class); + } + + //Mocks for ImageStoreDetailsUtil + @Bean + public ImageStoreDao imageStoreDao() { + return Mockito.mock(ImageStoreDao.class); + } + + @Bean + public ImageStoreDetailsDao imageStoreDetailsDao() { + return Mockito.mock(ImageStoreDetailsDao.class); + } + public static class Library implements TypeFilter { @Override diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java index 2e3d41c0485d..f554da9b3951 100644 --- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java +++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java @@ -19,6 +19,12 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.any; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import org.junit.Before; import org.junit.Test; @@ -26,8 +32,9 @@ import org.mockito.MockitoAnnotations; import org.mockito.Spy; +import com.vmware.vim25.VirtualDevice; import com.vmware.vim25.VirtualMachineConfigSpec; - +import com.vmware.vim25.VirtualMachineVideoCard; import com.cloud.agent.api.Command; import com.cloud.agent.api.ScaleVmAnswer; import com.cloud.agent.api.ScaleVmCommand; @@ -64,6 +71,10 @@ public VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd) { VirtualMachineMO vmMo; @Mock VirtualMachineConfigSpec vmConfigSpec; + @Mock + VirtualMachineMO vmMo3dgpu; + @Mock + VirtualMachineTO vmSpec3dgpu; @Before public void setup() { @@ -90,4 +101,20 @@ public void testScaleVMF1() throws Exception { verify(_resource).execute(cmd); } + @Test + public void testStartVm3dgpuEnabled() throws Exception{ + Map specDetails = new HashMap(); + specDetails.put("svga.vramSize", "131072"); + when(vmSpec3dgpu.getDetails()).thenReturn(specDetails); + + VirtualMachineVideoCard videoCard = mock(VirtualMachineVideoCard.class); + when(videoCard.getVideoRamSizeInKB()).thenReturn(65536l); + when(vmMo3dgpu.getAllDeviceList()).thenReturn(Arrays.asList((VirtualDevice) videoCard)); + + when(vmMo3dgpu.configureVm(any(VirtualMachineConfigSpec.class))).thenReturn(true); + + _resource.postVideoCardMemoryConfigBeforeStart(vmMo3dgpu, vmSpec3dgpu); + verify(vmMo3dgpu).configureVm(any(VirtualMachineConfigSpec.class)); + } + } diff --git a/plugins/hypervisors/xenserver/pom.xml b/plugins/hypervisors/xenserver/pom.xml index c66a43f3e232..d03ae541a5c9 100644 --- a/plugins/hypervisors/xenserver/pom.xml +++ b/plugins/hypervisors/xenserver/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java index 265573d7e4a5..cf2bd76f3cc2 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixHelper.java @@ -236,4 +236,15 @@ public static String getProductVersion(final Host.Record record) { } return prodVersion; } + + public static String getPVbootloaderArgs(String guestOS) { + if (guestOS.startsWith("SUSE Linux Enterprise Server")) { + if (guestOS.contains("64-bit")) { + return "--kernel /boot/vmlinuz-xen --ramdisk /boot/initrd-xen"; + } else if (guestOS.contains("32-bit")) { + return "--kernel /boot/vmlinuz-xenpae --ramdisk /boot/initrd-xenpae"; + } + } + return ""; + } } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index e1f7d3d61e58..665ed77cbb07 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -1352,6 +1352,7 @@ public VM createVmFromTemplate(final Connection conn, final VirtualMachineTO vmS } } else if (vmSpec.getBootloader() == BootloaderType.PyGrub) { vm.setPVBootloader(conn, "pygrub"); + vm.setPVBootloaderArgs(conn,CitrixHelper.getPVbootloaderArgs(guestOsTypeName)); } else { vm.destroy(conn); throw new CloudRuntimeException("Unable to handle boot loader type: " + vmSpec.getBootloader()); @@ -3277,7 +3278,7 @@ public HashMap getVmStats(final Connection conn, final Get final HashMap vmResponseMap = new HashMap(); for (final String vmUUID : vmUUIDs) { - vmResponseMap.put(vmUUID, new VmStatsEntry(0, 0, 0, 0, "vm")); + vmResponseMap.put(vmUUID, new VmStatsEntry(0,0,0,0, 0, 0, 0, "vm")); } final Object[] rrdData = getRRDData(conn, 2); // call rrddata with 2 for @@ -3331,7 +3332,14 @@ public HashMap getVmStats(final Connection conn, final Get vmStatsAnswer.setDiskReadKBs(vmStatsAnswer.getDiskReadKBs() + getDataAverage(dataNode, col, numRows) / 1000); } else if (param.matches("vbd_.*_write")) { vmStatsAnswer.setDiskWriteKBs(vmStatsAnswer.getDiskWriteKBs() + getDataAverage(dataNode, col, numRows) / 1000); + } else if (param.contains("memory_internal_free")) { + vmStatsAnswer.setIntFreeMemoryKBs(vmStatsAnswer.getIntFreeMemoryKBs() + getDataAverage(dataNode, col, numRows) / 1024); + } else if (param.contains("memory_target")) { + vmStatsAnswer.setTargetMemoryKBs(vmStatsAnswer.getTargetMemoryKBs() + getDataAverage(dataNode, col, numRows) / 1024); + } else if (param.contains("memory")) { + vmStatsAnswer.setMemoryKBs(vmStatsAnswer.getMemoryKBs() + getDataAverage(dataNode, col, numRows) / 1024); } + } } @@ -3347,6 +3355,7 @@ public HashMap getVmStats(final Connection conn, final Get s_logger.debug("Vm cpu utilization " + vmStatsAnswer.getCPUUtilization()); } } + return vmResponseMap; } @@ -5393,4 +5402,4 @@ public boolean attachConfigDriveToMigratedVm(Connection conn, String vmName, Str } -} \ No newline at end of file +} diff --git a/plugins/hypervisors/xenserver/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java b/plugins/hypervisors/xenserver/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java index 36b8ad6ccf5b..7de96b0a9e11 100644 --- a/plugins/hypervisors/xenserver/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java +++ b/plugins/hypervisors/xenserver/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java @@ -24,9 +24,6 @@ import javax.inject.Inject; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -37,6 +34,8 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -92,21 +91,12 @@ public StrategyPriority canHandle(Map volumeMap, Host src } @Override - public Void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcData, DataObject destData, Host destHost, AsyncCompletionCallback callback) { throw new UnsupportedOperationException(); } @Override - public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { - CopyCommandResult result = new CopyCommandResult(null, null); - result.setResult("Unsupported operation requested for copying data."); - callback.complete(result); - - return null; - } - - @Override - public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback) { Answer answer = null; String errMsg = null; try { @@ -128,7 +118,6 @@ public Void copyAsync(Map volumeMap, VirtualMachineTO vmT CopyCommandResult result = new CopyCommandResult(null, answer); result.setResult(errMsg); callback.complete(result); - return null; } private Answer migrateVmWithVolumesAcrossCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixHelperTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixHelperTest.java new file mode 100644 index 000000000000..330106e59a90 --- /dev/null +++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/CitrixHelperTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 The Apache Software Foundation. + * + * Licensed 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.hypervisor.xenserver.resource; + +import junit.framework.Assert; +import org.junit.Test; + + +/** + * Created by ajna123 on 12/11/2015. + */ +public class CitrixHelperTest { + + @Test + public void testGetPVbootloaderArgs() throws Exception { + + String os_name_Suse10Sp2_64 = "SUSE Linux Enterprise Server 10 SP2 (64-bit)"; + String os_name_Suse10Sp2_32 = "SUSE Linux Enterprise Server 10 SP2 (32-bit)"; + String os_name_Suse11Sp3_64 = "SUSE Linux Enterprise Server 11 SP3 (64-bit)"; + String os_name_Suse11Sp3_32 = "SUSE Linux Enterprise Server 11 SP3 (32-bit)"; + + String os_name_Windows8_64 = "Windows 8 (64-bit)"; + String os_name_Windows8_32 = "Windows 8 (32-bit)"; + + String pvBootLoaderArgs_32 = "--kernel /boot/vmlinuz-xenpae --ramdisk /boot/initrd-xenpae"; + String pvBootLoaderArgs_64 = "--kernel /boot/vmlinuz-xen --ramdisk /boot/initrd-xen"; + + Assert.assertEquals(CitrixHelper.getPVbootloaderArgs(os_name_Suse10Sp2_32), pvBootLoaderArgs_32); + Assert.assertEquals(CitrixHelper.getPVbootloaderArgs(os_name_Suse10Sp2_64),pvBootLoaderArgs_64); + Assert.assertEquals(CitrixHelper.getPVbootloaderArgs(os_name_Suse11Sp3_32),pvBootLoaderArgs_32); + Assert.assertEquals(CitrixHelper.getPVbootloaderArgs(os_name_Suse11Sp3_64),pvBootLoaderArgs_64); + + Assert.assertEquals(CitrixHelper.getPVbootloaderArgs(os_name_Windows8_32),""); + Assert.assertEquals(CitrixHelper.getPVbootloaderArgs(os_name_Windows8_64),""); + } +} \ No newline at end of file diff --git a/plugins/network-elements/bigswitch/pom.xml b/plugins/network-elements/bigswitch/pom.xml index 4b7c804c77ad..05603a61fd09 100644 --- a/plugins/network-elements/bigswitch/pom.xml +++ b/plugins/network-elements/bigswitch/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/brocade-vcs/pom.xml b/plugins/network-elements/brocade-vcs/pom.xml index 481493c97a09..c0ed17c1449c 100644 --- a/plugins/network-elements/brocade-vcs/pom.xml +++ b/plugins/network-elements/brocade-vcs/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/cisco-vnmc/pom.xml b/plugins/network-elements/cisco-vnmc/pom.xml index d4332c099be1..2c8bb7f7194b 100644 --- a/plugins/network-elements/cisco-vnmc/pom.xml +++ b/plugins/network-elements/cisco-vnmc/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/dns-notifier/pom.xml b/plugins/network-elements/dns-notifier/pom.xml index cb2d0464d82b..7db075f0aaff 100644 --- a/plugins/network-elements/dns-notifier/pom.xml +++ b/plugins/network-elements/dns-notifier/pom.xml @@ -22,7 +22,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml cloud-plugin-example-dns-notifier diff --git a/plugins/network-elements/elastic-loadbalancer/pom.xml b/plugins/network-elements/elastic-loadbalancer/pom.xml index 391e0597b6c1..c52cc042debe 100644 --- a/plugins/network-elements/elastic-loadbalancer/pom.xml +++ b/plugins/network-elements/elastic-loadbalancer/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/f5/pom.xml b/plugins/network-elements/f5/pom.xml index e4f257d529c0..54533e7aa76d 100644 --- a/plugins/network-elements/f5/pom.xml +++ b/plugins/network-elements/f5/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/globodns/pom.xml b/plugins/network-elements/globodns/pom.xml index d7747420f98e..9e177a53d684 100644 --- a/plugins/network-elements/globodns/pom.xml +++ b/plugins/network-elements/globodns/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/internal-loadbalancer/pom.xml b/plugins/network-elements/internal-loadbalancer/pom.xml index 7b7879abf233..0eb15232540b 100644 --- a/plugins/network-elements/internal-loadbalancer/pom.xml +++ b/plugins/network-elements/internal-loadbalancer/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml index 710579bb2aab..cac4d593d523 100644 --- a/plugins/network-elements/juniper-contrail/pom.xml +++ b/plugins/network-elements/juniper-contrail/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/juniper-srx/pom.xml b/plugins/network-elements/juniper-srx/pom.xml index 0a432f3108a2..ba3ecd7a95d6 100644 --- a/plugins/network-elements/juniper-srx/pom.xml +++ b/plugins/network-elements/juniper-srx/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/midonet/pom.xml b/plugins/network-elements/midonet/pom.xml index b586ea4ea524..00ca4aef7c18 100644 --- a/plugins/network-elements/midonet/pom.xml +++ b/plugins/network-elements/midonet/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/netscaler/pom.xml b/plugins/network-elements/netscaler/pom.xml index 11f10673a462..2475c413636e 100644 --- a/plugins/network-elements/netscaler/pom.xml +++ b/plugins/network-elements/netscaler/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/nicira-nvp/pom.xml b/plugins/network-elements/nicira-nvp/pom.xml index 38fc3a9add43..7ed0f235d6c0 100644 --- a/plugins/network-elements/nicira-nvp/pom.xml +++ b/plugins/network-elements/nicira-nvp/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml @@ -34,7 +34,7 @@ org.apache.cloudstack cloud-utils - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT test-jar test diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkUuidAnswer.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkUuidAnswer.java new file mode 100644 index 000000000000..46fc8f5476db --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkUuidAnswer.java @@ -0,0 +1,32 @@ +// +// 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.agent.api; + +public class ConfigureSharedNetworkUuidAnswer extends Answer { + + public ConfigureSharedNetworkUuidAnswer(final Command command, final boolean success, final String details) { + super(command, success, details); + } + + public ConfigureSharedNetworkUuidAnswer(final Command command, final Exception e) { + super(command, e); + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkUuidCommand.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkUuidCommand.java new file mode 100644 index 000000000000..4dd361b6b0d2 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkUuidCommand.java @@ -0,0 +1,85 @@ +// +// 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.agent.api; + +public class ConfigureSharedNetworkUuidCommand extends Command { + + private String logicalRouterUuid; + private String logicalSwitchUuid; + private String portIpAddress; + private String ownerName; + private long networkId; + + public ConfigureSharedNetworkUuidCommand(final String logicalRouterUuid, final String logicalSwitchUuid, + final String portIpAddress, final String ownerName, final long networkId) { + super(); + this.logicalRouterUuid = logicalRouterUuid; + this.logicalSwitchUuid = logicalSwitchUuid; + this.portIpAddress = portIpAddress; + this.ownerName = ownerName; + this.networkId = networkId; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public String getLogicalSwitchUuid() { + return logicalSwitchUuid; + } + + public void setLogicalSwitchUuid(String logicalSwitchUuid) { + this.logicalSwitchUuid = logicalSwitchUuid; + } + + public String getPortIpAddress() { + return portIpAddress; + } + + public void setPortIpAddress(String portIpAddress) { + this.portIpAddress = portIpAddress; + } + + public String getOwnerName() { + return ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + public long getNetworkId() { + return networkId; + } + + public void setNetworkId(long networkId) { + this.networkId = networkId; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkVlanIdAnswer.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkVlanIdAnswer.java new file mode 100644 index 000000000000..12955693b454 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkVlanIdAnswer.java @@ -0,0 +1,31 @@ +// +// 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.agent.api; + +public class ConfigureSharedNetworkVlanIdAnswer extends Answer { + + public ConfigureSharedNetworkVlanIdAnswer(final Command command, final boolean success, final String details) { + super(command, success, details); + } + + public ConfigureSharedNetworkVlanIdAnswer(final Command command, final Exception e) { + super(command, e); + } +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkVlanIdCommand.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkVlanIdCommand.java new file mode 100644 index 000000000000..c6837dd1b09b --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/ConfigureSharedNetworkVlanIdCommand.java @@ -0,0 +1,84 @@ +// +// 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.agent.api; + +public class ConfigureSharedNetworkVlanIdCommand extends Command { + + private String logicalSwitchUuid; + private String l2GatewayServiceUuid; + private long vlanId; + private String ownerName; + private long networkId; + + public ConfigureSharedNetworkVlanIdCommand(final String logicalSwitchUuid, final String l2GatewayServiceUuid, + final long vlanId, final String ownerName, final long networkId) { + this.logicalSwitchUuid = logicalSwitchUuid; + this.l2GatewayServiceUuid = l2GatewayServiceUuid; + this.vlanId = vlanId; + this.ownerName = ownerName; + this.networkId = networkId; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getLogicalSwitchUuid() { + return logicalSwitchUuid; + } + + public void setLogicalSwitchUuid(String logicalSwitchUuid) { + this.logicalSwitchUuid = logicalSwitchUuid; + } + + public String getL2GatewayServiceUuid() { + return l2GatewayServiceUuid; + } + + public void setL2GatewayServiceUuid(String l2GatewayServiceUuid) { + this.l2GatewayServiceUuid = l2GatewayServiceUuid; + } + + public long getVlanId() { + return vlanId; + } + + public void setVlanId(long vlanId) { + this.vlanId = vlanId; + } + + public String getOwnerName() { + return ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + public long getNetworkId() { + return networkId; + } + + public void setNetworkId(long networkId) { + this.networkId = networkId; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/DeleteLogicalRouterPortAnswer.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/DeleteLogicalRouterPortAnswer.java new file mode 100644 index 000000000000..2850047aedad --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/DeleteLogicalRouterPortAnswer.java @@ -0,0 +1,31 @@ +// +// 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.agent.api; + +public class DeleteLogicalRouterPortAnswer extends Answer { + + public DeleteLogicalRouterPortAnswer(final Command command, final boolean success, final String details) { + super(command, success, details); + } + + public DeleteLogicalRouterPortAnswer(final Command command, final Exception e) { + super(command, e); + } +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/DeleteLogicalRouterPortCommand.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/DeleteLogicalRouterPortCommand.java new file mode 100644 index 000000000000..729535831f31 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/DeleteLogicalRouterPortCommand.java @@ -0,0 +1,53 @@ +// +// 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.agent.api; + +public class DeleteLogicalRouterPortCommand extends Command { + + private String logicalRouterUuid; + private String logicalRouterPortUuid; + + public DeleteLogicalRouterPortCommand(String logicalRouterUuid, String logicalRouterPortUuid) { + this.logicalRouterUuid = logicalRouterUuid; + this.logicalRouterPortUuid = logicalRouterPortUuid; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public String getLogicalRouterPortUuid() { + return logicalRouterPortUuid; + } + + public void setLogicalRouterPortUuid(String logicalRouterPortUuid) { + this.logicalRouterPortUuid = logicalRouterPortUuid; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindL2GatewayServiceAnswer.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindL2GatewayServiceAnswer.java new file mode 100644 index 000000000000..16f24eb7e198 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindL2GatewayServiceAnswer.java @@ -0,0 +1,38 @@ +// +// 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.agent.api; + +public class FindL2GatewayServiceAnswer extends Answer { + + private String gatewayServiceUuid; + + public FindL2GatewayServiceAnswer(final Command command, final boolean success, final String details, final String gatewayServiceUuid) { + super(command, success, details); + this.gatewayServiceUuid = gatewayServiceUuid; + } + + public FindL2GatewayServiceAnswer(final Command command, final Exception e) { + super(command, e); + } + + public String getGatewayServiceUuid() { + return gatewayServiceUuid; + } +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindL2GatewayServiceCommand.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindL2GatewayServiceCommand.java new file mode 100644 index 000000000000..a3ec1dcc18f4 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindL2GatewayServiceCommand.java @@ -0,0 +1,46 @@ +// +// 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.agent.api; + +import com.cloud.network.nicira.GatewayServiceConfig; +import com.cloud.network.nicira.L2GatewayServiceConfig; + +public class FindL2GatewayServiceCommand extends Command { + + private L2GatewayServiceConfig gatewayServiceConfig; + + public FindL2GatewayServiceCommand(L2GatewayServiceConfig config) { + this.gatewayServiceConfig = config; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public GatewayServiceConfig getGatewayServiceConfig() { + return gatewayServiceConfig; + } + + public void setGatewayServiceConfig(L2GatewayServiceConfig gatewayServiceConfig) { + this.gatewayServiceConfig = gatewayServiceConfig; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindLogicalRouterPortAnswer.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindLogicalRouterPortAnswer.java new file mode 100644 index 000000000000..2ec211b41324 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindLogicalRouterPortAnswer.java @@ -0,0 +1,38 @@ +// +// 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.agent.api; + +public class FindLogicalRouterPortAnswer extends Answer { + + private String logicalRouterPortUuid; + + public FindLogicalRouterPortAnswer(final Command command, final boolean success, final String details, final String lRouterPortUuid) { + super(command, success, details); + this.logicalRouterPortUuid = lRouterPortUuid; + } + + public FindLogicalRouterPortAnswer(final Command command, final Exception e) { + super(command, e); + } + + public String getLogicalRouterPortUuid() { + return logicalRouterPortUuid; + } +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindLogicalRouterPortCommand.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindLogicalRouterPortCommand.java new file mode 100644 index 000000000000..965f65b8c137 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/agent/api/FindLogicalRouterPortCommand.java @@ -0,0 +1,59 @@ +// +// 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.agent.api; + +public class FindLogicalRouterPortCommand extends Command { + + private String logicalRouterUuid; + private String attachmentLswitchUuid; + + public FindLogicalRouterPortCommand(String logicalRouterUuid) { + super(); + this.logicalRouterUuid = logicalRouterUuid; + } + + public FindLogicalRouterPortCommand(String logicalRouterUuid, String attachmentLswitchUuid) { + super(); + this.logicalRouterUuid = logicalRouterUuid; + this.attachmentLswitchUuid = attachmentLswitchUuid; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public String getAttachmentLswitchUuid() { + return attachmentLswitchUuid; + } + + public void setAttachmentLswitchUuid(String attachmentLswitchUuid) { + this.attachmentLswitchUuid = attachmentLswitchUuid; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java index 1a9be2854c31..1bde3b736098 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java @@ -80,6 +80,12 @@ public class AddNiciraNvpDeviceCmd extends BaseAsyncCmd { description = "The L3 Gateway Service UUID configured on the Nicira Controller") private String l3gatewayserviceuuid; + @Parameter(name = ApiConstants.NICIRA_NVP_L2_GATEWAYSERVICE_UUID, + type = CommandType.STRING, + required = false, + description = "The L2 Gateway Service UUID configured on the Nicira Controller") + private String l2gatewayserviceuuid; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -108,6 +114,10 @@ public String getL3GatewayServiceUuid() { return l3gatewayserviceuuid; } + public String getL2GatewayServiceUuid() { + return l2gatewayserviceuuid; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/response/NiciraNvpDeviceResponse.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/response/NiciraNvpDeviceResponse.java index 46287aa1f093..dedccefcc919 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/response/NiciraNvpDeviceResponse.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/api/response/NiciraNvpDeviceResponse.java @@ -58,6 +58,10 @@ public class NiciraNvpDeviceResponse extends BaseResponse { @Param(description = "this L3 gateway service Uuid") private String l3GatewayServiceUuid; + @SerializedName(ApiConstants.NICIRA_NVP_L2_GATEWAYSERVICE_UUID) + @Param(description = "this L2 gateway service Uuid") + private String l2GatewayServiceUuid; + public void setId(String nvpDeviceId) { this.id = nvpDeviceId; } @@ -86,4 +90,7 @@ public void setL3GatewayServiceUuid(final String l3GatewayServiceUuid) { this.l3GatewayServiceUuid = l3GatewayServiceUuid; } + public void setL2GatewayServiceUuid(final String l2GatewayServiceUuid) { + this.l2GatewayServiceUuid = l2GatewayServiceUuid; + } } diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDao.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDao.java index b64fb90b9a5a..b7e999b30b76 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDao.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDao.java @@ -25,4 +25,6 @@ public interface NiciraNvpRouterMappingDao extends GenericDao { public NiciraNvpRouterMappingVO findByNetworkId(long id); + + public boolean existsMappingForNetworkId(long id); } diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java index 239072f885f7..ef6acb40df96 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java @@ -19,6 +19,7 @@ package com.cloud.network.dao; +import java.util.List; import org.springframework.stereotype.Component; @@ -46,4 +47,12 @@ public NiciraNvpRouterMappingVO findByNetworkId(final long id) { return findOneBy(sc); } + @Override + public boolean existsMappingForNetworkId(long id) { + SearchCriteria sc = networkSearch.create(); + sc.setParameters("network_id", id); + List mappings = search(sc, null); + return mappings.size() > 0; + } + } diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java index 909134dbb649..1146a5435ca4 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java @@ -33,7 +33,6 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice; @@ -42,6 +41,10 @@ import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterCommand; import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigureSharedNetworkUuidAnswer; +import com.cloud.agent.api.ConfigureSharedNetworkUuidCommand; +import com.cloud.agent.api.ConfigureSharedNetworkVlanIdAnswer; +import com.cloud.agent.api.ConfigureSharedNetworkVlanIdCommand; import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterCommand; import com.cloud.agent.api.CreateLogicalRouterAnswer; @@ -67,6 +70,7 @@ import com.cloud.api.response.NiciraNvpDeviceResponse; import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.Vlan; +import com.cloud.dc.VlanVO; import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; @@ -82,6 +86,7 @@ import com.cloud.network.IpAddressManager; import com.cloud.network.Network; import com.cloud.network.Network.Capability; +import com.cloud.network.Network.GuestType; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.NetworkModel; @@ -239,8 +244,14 @@ public boolean implement(Network network, NetworkOffering offering, DeployDestin * multiple operations that should be done only once. */ - // Implement SourceNat immediately as we have al the info already - if (networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.NiciraNvp)) { + if (network.getGuestType().equals(GuestType.Shared)){ + //Support Shared Networks + String lSwitchUuid = BroadcastDomainType.getValue(network.getBroadcastUri()); + String ownerName = context.getDomain().getName() + "-" + context.getAccount().getAccountName(); + return sharedNetworkSupport(network, lSwitchUuid, ownerName, niciraNvpHost); + } + else if (network.getGuestType().equals(GuestType.Isolated) && networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.NiciraNvp)) { + // Implement SourceNat immediately as we have al the info already s_logger.debug("Apparently we are supposed to provide SourceNat on this network"); PublicIp sourceNatIp = ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network); @@ -271,14 +282,74 @@ public boolean implement(Network network, NetworkOffering offering, DeployDestin return false; } - // Store the uuid so we can easily find it during cleanup NiciraNvpRouterMappingVO routermapping = new NiciraNvpRouterMappingVO(answer.getLogicalRouterUuid(), network.getId()); niciraNvpRouterMappingDao.persist(routermapping); + + } + + return true; + } + + private boolean sharedNetworkSupport(Network network, String lSwitchUuid, String ownerName, HostVO niciraNvpHost) { + //Support Shared Networks, we won’t be creating logical router, 2 cases: + //Case 1) UUID Supplied for VLAN -> This is UUID of the logical router to attach lswitch + //Case 2) Numerical ID supplied for VLAN -> lswitch is connected to L2 gateway service that we have as an attribute of the NVP device. If no L2 gateway attribute exists then exception. + + if (niciraNvpRouterMappingDao.existsMappingForNetworkId(network.getId())){ + //Case 1) + return sharedNetworkSupportUUIDVlanId(network, lSwitchUuid, ownerName, niciraNvpHost); + } + else { + //Case 2) + return sharedNetworkSupportNumericalVlanId(network, lSwitchUuid, ownerName, niciraNvpHost); + } + } + + private boolean sharedNetworkSupportUUIDVlanId(Network network, String lSwitchUuid, String ownerName, HostVO niciraNvpHost) { + String networkCidr = network.getCidr(); + String vlanGateway = network.getGateway(); + String portIpAddress = createLogicalRouterPortIpAddress(networkCidr, vlanGateway); + NiciraNvpRouterMappingVO mapRouterNetwork = niciraNvpRouterMappingDao.findByNetworkId(network.getId()); + String lRouterUuid = mapRouterNetwork.getLogicalRouterUuid(); + ConfigureSharedNetworkUuidCommand cmd = + new ConfigureSharedNetworkUuidCommand(lRouterUuid, lSwitchUuid, portIpAddress, ownerName, network.getId()); + ConfigureSharedNetworkUuidAnswer answer = (ConfigureSharedNetworkUuidAnswer)agentMgr.easySend(niciraNvpHost.getId(), cmd); + if (answer.getResult() == false) { + s_logger.error("Failed to configure Logical Router for Shared network " + network.getDisplayText()); + return false; } + return true; + } + private boolean sharedNetworkSupportNumericalVlanId(Network network, String lSwitchUuid, String ownerName, HostVO niciraNvpHost) { + List networkVlans = vlanDao.listVlansByNetworkId(network.getId()); + if (networkVlans.size() == 1){ + for (VlanVO vlanVO : networkVlans) { + long vlanId = Long.parseLong(vlanVO.getVlanTag()); + String l2GatewayServiceUuid = niciraNvpHost.getDetail("l2gatewayserviceuuid"); + if (l2GatewayServiceUuid == null){ + throw new CloudRuntimeException("No L2 Gateway Service Uuid found on " + niciraNvpHost.getName()); + } + ConfigureSharedNetworkVlanIdCommand cmd = + new ConfigureSharedNetworkVlanIdCommand(lSwitchUuid, l2GatewayServiceUuid , vlanId, ownerName, network.getId()); + ConfigureSharedNetworkVlanIdAnswer answer = (ConfigureSharedNetworkVlanIdAnswer)agentMgr.easySend(niciraNvpHost.getId(), cmd); + if (answer.getResult() == false) { + s_logger.error("Failed to configure Shared network " + network.getDisplayText()); + return false; + } + } + } return true; } + + private String createLogicalRouterPortIpAddress(String networkCidr, String vlanGateway) { + if (networkCidr != null && vlanGateway != null){ + return networkCidr.replaceFirst("[\\d]{1,3}.[\\d]{1,3}.[\\d]{1,3}.[\\d]{1,3}", vlanGateway); + } + return null; + } + @Override public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { @@ -393,7 +464,8 @@ public boolean shutdown(Network network, ReservationContext context, boolean cle NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); HostVO niciraNvpHost = hostDao.findById(niciraNvpDevice.getHostId()); - if (networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.NiciraNvp)) { + //Dont destroy logical router when removing Shared Networks + if (! network.getGuestType().equals(GuestType.Shared) && networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.NiciraNvp)) { s_logger.debug("Apparently we were providing SourceNat on this network"); // Deleting the LogicalRouter will also take care of all provisioned @@ -537,6 +609,9 @@ public NiciraNvpDeviceVO addNiciraNvpDevice(AddNiciraNvpDeviceCmd cmd) { if (cmd.getL3GatewayServiceUuid() != null) { params.put("l3gatewayserviceuuid", cmd.getL3GatewayServiceUuid()); } + if (cmd.getL2GatewayServiceUuid() != null) { + params.put("l2gatewayserviceuuid", cmd.getL2GatewayServiceUuid()); + } Map hostdetails = new HashMap(); hostdetails.putAll(params); @@ -582,6 +657,7 @@ public NiciraNvpDeviceResponse createNiciraNvpDeviceResponse(NiciraNvpDeviceVO n response.setHostName(niciraNvpHost.getDetail("ip")); response.setTransportZoneUuid(niciraNvpHost.getDetail("transportzoneuuid")); response.setL3GatewayServiceUuid(niciraNvpHost.getDetail("l3gatewayserviceuuid")); + response.setL2GatewayServiceUuid(niciraNvpHost.getDetail("l2gatewayserviceuuid")); response.setObjectName("niciranvpdevice"); return response; } diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java index fc41286f0c84..551269cc84c4 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuru.java @@ -21,7 +21,9 @@ import java.net.URI; import java.net.URISyntaxException; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.inject.Inject; @@ -30,8 +32,14 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.CreateLogicalSwitchAnswer; import com.cloud.agent.api.CreateLogicalSwitchCommand; +import com.cloud.agent.api.DeleteLogicalRouterPortAnswer; +import com.cloud.agent.api.DeleteLogicalRouterPortCommand; import com.cloud.agent.api.DeleteLogicalSwitchAnswer; import com.cloud.agent.api.DeleteLogicalSwitchCommand; +import com.cloud.agent.api.FindL2GatewayServiceAnswer; +import com.cloud.agent.api.FindL2GatewayServiceCommand; +import com.cloud.agent.api.FindLogicalRouterPortAnswer; +import com.cloud.agent.api.FindLogicalRouterPortCommand; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.dao.DataCenterDao; @@ -50,13 +58,18 @@ import com.cloud.network.NetworkProfile; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.NiciraNvpDeviceVO; +import com.cloud.network.NiciraNvpNicMappingVO; +import com.cloud.network.NiciraNvpRouterMappingVO; import com.cloud.network.PhysicalNetwork; import com.cloud.network.PhysicalNetwork.IsolationMethod; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.NiciraNvpDao; +import com.cloud.network.dao.NiciraNvpNicMappingDao; +import com.cloud.network.dao.NiciraNvpRouterMappingDao; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.nicira.L2GatewayServiceConfig; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; import com.cloud.resource.ResourceManager; @@ -66,7 +79,7 @@ import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachineProfile; -public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru { +public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru implements NetworkGuruAdditionalFunctions{ private static final int MAX_NAME_LENGTH = 40; private static final Logger s_logger = Logger.getLogger(NiciraNvpGuestNetworkGuru.class); @@ -93,6 +106,10 @@ public class NiciraNvpGuestNetworkGuru extends GuestNetworkGuru { protected HostDetailsDao hostDetailsDao; @Inject protected NetworkOfferingServiceMapDao ntwkOfferingSrvcDao; + @Inject + protected NiciraNvpRouterMappingDao niciraNvpRouterMappingDao; + @Inject + protected NiciraNvpNicMappingDao niciraNvpNicMappingDao; public NiciraNvpGuestNetworkGuru() { super(); @@ -102,15 +119,24 @@ public NiciraNvpGuestNetworkGuru() { @Override protected boolean canHandle(final NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) { // This guru handles only Guest Isolated network that supports Source nat service - if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated + if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) + && supportedGuestTypes(offering, Network.GuestType.Isolated, Network.GuestType.Shared) && isMyIsolationMethod(physicalNetwork) && ntwkOfferingSrvcDao.areServicesSupportedByNetworkOffering(offering.getId(), Service.Connectivity)) { return true; } else { - s_logger.trace("We only take care of Guest networks of type " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced); return false; } } + private boolean supportedGuestTypes(NetworkOffering offering, GuestType... types) { + for (GuestType guestType : types) { + if (offering.getGuestType().equals(guestType)){ + return true; + } + } + return false; + } + @Override public Network design(final NetworkOffering offering, final DeploymentPlan plan, final Network userSpecified, final Account owner) { // Check of the isolation type of the related physical network is supported @@ -134,6 +160,9 @@ public Network design(final NetworkOffering offering, final DeploymentPlan plan, return null; } networkObject.setBroadcastDomainType(BroadcastDomainType.Lswitch); + if (offering.getGuestType().equals(GuestType.Shared)){ + networkObject.setState(State.Allocated); + } return networkObject; } @@ -183,6 +212,16 @@ public Network implement(final Network network, final NetworkOffering offering, final String transportzoneuuid = niciraNvpHost.getDetail("transportzoneuuid"); final String transportzoneisotype = niciraNvpHost.getDetail("transportzoneisotype"); + if (offering.getGuestType().equals(GuestType.Shared)) { + try { + checkL2GatewayServiceSharedNetwork(niciraNvpHost); + } + catch (Exception e){ + s_logger.error("L2 Gateway Service Issue: " + e.getMessage()); + return null; + } + } + final CreateLogicalSwitchCommand cmd = new CreateLogicalSwitchCommand(transportzoneuuid, transportzoneisotype, name, context.getDomain().getName() + "-" + context.getAccount().getAccountName()); final CreateLogicalSwitchAnswer answer = (CreateLogicalSwitchAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmd); @@ -204,6 +243,26 @@ public Network implement(final Network network, final NetworkOffering offering, return implemented; } + private void checkL2GatewayServiceSharedNetwork(HostVO niciraNvpHost) throws Exception { + String l2GatewayServiceUuid = niciraNvpHost.getDetail("l2gatewayserviceuuid"); + if (l2GatewayServiceUuid == null){ + throw new Exception("No L2 Gateway Service found"); + } + else { + final FindL2GatewayServiceCommand cmdL2GWService = new FindL2GatewayServiceCommand(new L2GatewayServiceConfig(l2GatewayServiceUuid)); + final FindL2GatewayServiceAnswer answerL2GWService = (FindL2GatewayServiceAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmdL2GWService); + if (answerL2GWService == null || !answerL2GWService.getResult()){ + throw new Exception("No L2 Gateway Service found with uuid " + l2GatewayServiceUuid); + } + else { + String uuidFound = answerL2GWService.getGatewayServiceUuid(); + if (! uuidFound.equals(l2GatewayServiceUuid)){ + throw new Exception("Found L2 Gateway Service " + uuidFound + " instead of " + l2GatewayServiceUuid); + } + } + } + } + @Override public void reserve(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { @@ -231,7 +290,13 @@ public void shutdown(final NetworkProfile profile, final NetworkOffering offerin final NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); final HostVO niciraNvpHost = hostDao.findById(niciraNvpDevice.getHostId()); - final DeleteLogicalSwitchCommand cmd = new DeleteLogicalSwitchCommand(BroadcastDomainType.getValue(networkObject.getBroadcastUri())); + String logicalSwitchUuid = BroadcastDomainType.getValue(networkObject.getBroadcastUri()); + + if (offering.getGuestType().equals(GuestType.Shared)){ + sharedNetworksCleanup(networkObject, logicalSwitchUuid, niciraNvpHost); + } + + final DeleteLogicalSwitchCommand cmd = new DeleteLogicalSwitchCommand(logicalSwitchUuid); final DeleteLogicalSwitchAnswer answer = (DeleteLogicalSwitchAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmd); if (answer == null || !answer.getResult()) { @@ -241,9 +306,65 @@ public void shutdown(final NetworkProfile profile, final NetworkOffering offerin super.shutdown(profile, offering); } + private void sharedNetworksCleanup(NetworkVO networkObject, String logicalSwitchUuid, HostVO niciraNvpHost) { + NiciraNvpRouterMappingVO routermapping = niciraNvpRouterMappingDao.findByNetworkId(networkObject.getId()); + if (routermapping == null) { + // Case 1: Numerical Vlan Provided -> No lrouter used. + s_logger.info("Shared Network " + networkObject.getDisplayText() + " didn't use Logical Router"); + } + else { + //Case 2: Logical Router's UUID provided as Vlan id -> Remove lrouter port but not lrouter. + String lRouterUuid = routermapping.getLogicalRouterUuid(); + s_logger.debug("Finding Logical Router Port on Logical Router " + lRouterUuid + " with attachment_lswitch_uuid=" + logicalSwitchUuid + " to delete it"); + final FindLogicalRouterPortCommand cmd = new FindLogicalRouterPortCommand(lRouterUuid, logicalSwitchUuid); + final FindLogicalRouterPortAnswer answer = (FindLogicalRouterPortAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmd); + + if (answer != null && answer.getResult()) { + String logicalRouterPortUuid = answer.getLogicalRouterPortUuid(); + s_logger.debug("Found Logical Router Port " + logicalRouterPortUuid + ", deleting it"); + final DeleteLogicalRouterPortCommand cmdDeletePort = new DeleteLogicalRouterPortCommand(lRouterUuid, logicalRouterPortUuid); + final DeleteLogicalRouterPortAnswer answerDelete = (DeleteLogicalRouterPortAnswer) agentMgr.easySend(niciraNvpHost.getId(), cmdDeletePort); + + if (answerDelete != null && answerDelete.getResult()){ + s_logger.info("Successfully deleted Logical Router Port " + logicalRouterPortUuid); + } + else { + s_logger.error("Could not delete Logical Router Port " + logicalRouterPortUuid); + } + } + else { + s_logger.error("Find Logical Router Port failed"); + } + } + } + @Override public boolean trash(final Network network, final NetworkOffering offering) { + //Since NVP Plugin supports Shared networks, remove mapping when deleting network implemented or allocated + if (network.getGuestType() == GuestType.Shared && niciraNvpRouterMappingDao.existsMappingForNetworkId(network.getId())){ + NiciraNvpRouterMappingVO mappingVO = niciraNvpRouterMappingDao.findByNetworkId(network.getId()); + niciraNvpRouterMappingDao.remove(mappingVO.getId()); + } return super.trash(network, offering); } + @Override + public void finalizeNetworkDesign(long networkId, String vlanIdAsUUID) { + if (vlanIdAsUUID == null) return; + NiciraNvpRouterMappingVO routermapping = new NiciraNvpRouterMappingVO(vlanIdAsUUID, networkId); + niciraNvpRouterMappingDao.persist(routermapping); + } + + @Override + public Map listAdditionalNicParams(String nicUuid) { + NiciraNvpNicMappingVO mapping = niciraNvpNicMappingDao.findByNicUuid(nicUuid); + if (mapping != null){ + Map result = new HashMap(); + result.put(NetworkGuruAdditionalFunctions.NSX_LSWITCH_UUID, mapping.getLogicalSwitchUuid()); + result.put(NetworkGuruAdditionalFunctions.NSX_LSWITCHPORT_UUID, mapping.getLogicalSwitchPortUuid()); + return result; + } + return null; + } + } diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/GatewayServiceConfig.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/GatewayServiceConfig.java new file mode 100644 index 000000000000..abfd273683d7 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/GatewayServiceConfig.java @@ -0,0 +1,47 @@ +// +// 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.network.nicira; + +import java.io.Serializable; + +public abstract class GatewayServiceConfig implements Serializable { + + private String uuid; + private String displayName; + private String type; + + public GatewayServiceConfig(String uuid, String type) { + this.uuid = uuid; + this.type = type; + } + + public String getUuid() { + return uuid; + } + + public String getDisplayName() { + return displayName; + } + + public String getType() { + return type; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/L2GatewayAttachment.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/L2GatewayAttachment.java new file mode 100644 index 000000000000..2ef294ed7a1c --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/L2GatewayAttachment.java @@ -0,0 +1,53 @@ +// +// 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.network.nicira; + +public class L2GatewayAttachment extends Attachment { + + private String l2GatewayServiceUuid; + private final String type = "L2GatewayAttachment"; + private Long vlanId; + + public L2GatewayAttachment(String l2GatewayServiceUuid) { + this.l2GatewayServiceUuid = l2GatewayServiceUuid; + } + + public L2GatewayAttachment(final String l2GatewayServiceUuid, final long vlanId) { + this.l2GatewayServiceUuid = l2GatewayServiceUuid; + this.vlanId = vlanId; + } + + public String getL2GatewayServiceUuid() { + return l2GatewayServiceUuid; + } + public void setL2GatewayServiceUuid(String l2GatewayServiceUuid) { + this.l2GatewayServiceUuid = l2GatewayServiceUuid; + } + public Long getVlanId() { + return vlanId; + } + public void setVlanId(Long vlanId) { + this.vlanId = vlanId; + } + public String getType() { + return type; + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/L2GatewayServiceConfig.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/L2GatewayServiceConfig.java new file mode 100644 index 000000000000..7f2a41aec99f --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/L2GatewayServiceConfig.java @@ -0,0 +1,30 @@ +// +// 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.network.nicira; + +public class L2GatewayServiceConfig extends GatewayServiceConfig { + + private static final String L2GWTServiceConfigType = "L2GatewayServiceConfig"; + + public L2GatewayServiceConfig(String uuid) { + super(uuid, L2GWTServiceConfigType); + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraConstants.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraConstants.java index 31adf9d3e2d1..f89b8ad09312 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraConstants.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraConstants.java @@ -25,6 +25,7 @@ public class NiciraConstants { public static final String ACL_URI_PREFIX = "/ws.v1/acl"; public static final String SWITCH_URI_PREFIX = "/ws.v1/lswitch"; public static final String ROUTER_URI_PREFIX = "/ws.v1/lrouter"; + public static final String GATEWAY_SERVICE_PREFIX = "/ws.v1/gateway-service"; public static final String LOGIN_URL = "/ws.v1/login"; public static final String CONTROL_CLUSTER_STATUS_URL = "/ws.v1/control-cluster/status"; @@ -35,8 +36,10 @@ public class NiciraConstants { public static final String ATTACHMENT_VIF_UUID_QUERY_PARAMETER_NAME = "attachment_vif_uuid"; public static final String ATTACHMENT_VLAN_PARAMETER = "attachment_vlan"; public static final String ATTACHMENT_GWSVC_UUID_QUERY_PARAMETER = "attachment_gwsvc_uuid"; + public static final String ATTACHMENT_LSWITCH_UUID = "attachment_lswitch_uuid"; public static final String WILDCARD_QUERY_PARAMETER = "*"; public static final String UUID_QUERY_PARAMETER = "uuid"; public static final String FIELDS_QUERY_PARAMETER = "fields"; + public static final String TYPES_QUERY_PARAMETER = "types"; } diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraNvpApi.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraNvpApi.java index 093d90da1ae6..293c5a857639 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraNvpApi.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraNvpApi.java @@ -42,6 +42,7 @@ public class NiciraNvpApi { private static final String SWITCH_URI_PREFIX = NiciraConstants.SWITCH_URI_PREFIX; private static final String ROUTER_URI_PREFIX = NiciraConstants.ROUTER_URI_PREFIX; + private static final String GATEWAY_SERVICE_PREFIX = NiciraConstants.GATEWAY_SERVICE_PREFIX; private static final String ATTACHMENT_PATH_SEGMENT = NiciraConstants.ATTACHMENT_PATH_SEGMENT; private static final String NAT_PATH_SEGMENT = NiciraConstants.NAT_PATH_SEGMENT; @@ -51,6 +52,7 @@ public class NiciraNvpApi { private static final String WILDCARD_QUERY_PARAMETER = NiciraConstants.WILDCARD_QUERY_PARAMETER; private static final String UUID_QUERY_PARAMETER = NiciraConstants.UUID_QUERY_PARAMETER; private static final String FIELDS_QUERY_PARAMETER = NiciraConstants.FIELDS_QUERY_PARAMETER; + private static final String TYPES_QUERY_PARAMETER = NiciraConstants.TYPES_QUERY_PARAMETER; private static final int DEFAULT_MAX_RETRIES = 5; @@ -131,7 +133,7 @@ private T createWithUri(final T entity, final String uri) throws NiciraNvpAp try { createdEntity = restConnector.executeCreateObject(entity, uri, Collections. emptyMap()); } catch (final CloudstackRESTException e) { - throw new NiciraNvpApiException(e); + throw new NiciraNvpApiException(e, e.getErrorCode()); } return createdEntity; @@ -157,7 +159,7 @@ private List find(final Optional uuid, final Class clazz) thro try { entities = restConnector.executeRetrieveObject(listTypeMap.get(clazz), uri, params); } catch (final CloudstackRESTException e) { - throw new NiciraNvpApiException(e); + throw new NiciraNvpApiException(e, e.getErrorCode()); } if (entities == null) { @@ -190,7 +192,7 @@ private void updateWithUri(final T item, final String uri) throws NiciraNvpA try { restConnector.executeUpdateObject(item, uri, Collections. emptyMap()); } catch (final CloudstackRESTException e) { - throw new NiciraNvpApiException(e); + throw new NiciraNvpApiException(e, e.getErrorCode()); } } @@ -215,7 +217,7 @@ private void deleteWithUri(final String uri) throws NiciraNvpApiException { try { restConnector.executeDeleteObject(uri); } catch (final CloudstackRESTException e) { - throw new NiciraNvpApiException(e); + throw new NiciraNvpApiException(e, e.getErrorCode()); } } @@ -394,7 +396,7 @@ public String findLogicalSwitchPortUuidByVifAttachmentUuid(final String logicalS }.getType(); niciraList = restConnector.executeRetrieveObject(niciraListType, uri, params); } catch (final CloudstackRESTException e) { - throw new NiciraNvpApiException(e); + throw new NiciraNvpApiException(e, e.getErrorCode()); } final List lspl = niciraList.getResults(); @@ -413,7 +415,7 @@ public ControlClusterStatus getControlClusterStatus() throws NiciraNvpApiExcepti try { return restConnector.executeRetrieveObject(ControlClusterStatus.class, uri, new HashMap()); } catch (final CloudstackRESTException e) { - throw new NiciraNvpApiException(e); + throw new NiciraNvpApiException(e, e.getErrorCode()); } } @@ -427,7 +429,7 @@ public List findLogicalSwitchPortsByUuid(final String logical }.getType(); return restConnector.> executeRetrieveObject(niciraListType, uri, params).getResults(); } catch (final CloudstackRESTException e) { - throw new NiciraNvpApiException(e); + throw new NiciraNvpApiException(e, e.getErrorCode()); } } @@ -441,7 +443,7 @@ public List findLogicalRouterPortsByUuid(final String logical }.getType(); return restConnector.> executeRetrieveObject(niciraListType, uri, params).getResults(); } catch (final CloudstackRESTException e) { - throw new NiciraNvpApiException(e); + throw new NiciraNvpApiException(e, e.getErrorCode()); } } @@ -522,7 +524,21 @@ public List findLogicalRouterPortByGatewayServiceAndVlanId(fi }.getType(); return restConnector.> executeRetrieveObject(niciraListType, uri, params).getResults(); } catch (final CloudstackRESTException e) { - throw new NiciraNvpApiException(e); + throw new NiciraNvpApiException(e, e.getErrorCode()); + } + } + + public List findLogicalRouterPortByAttachmentLSwitchUuid(final String logicalRouterUuid, final String attachmentLSwitchUuid) throws NiciraNvpApiException{ + final String uri = buildLogicalRouterElementUri(logicalRouterUuid, LPORT_PATH_SEGMENT); + final Map params = buildBasicParametersMap(WILDCARD_QUERY_PARAMETER); + params.put(NiciraConstants.ATTACHMENT_LSWITCH_UUID, attachmentLSwitchUuid); + + try{ + final Type niciraListType = new TypeToken>() { + }.getType(); + return restConnector.> executeRetrieveObject(niciraListType, uri, params).getResults(); + } catch (final CloudstackRESTException e) { + throw new NiciraNvpApiException(e, e.getErrorCode()); } } @@ -535,7 +551,7 @@ public List findNatRulesByLogicalRouterUuid(final String logicalRouterU }.getType(); return restConnector.> executeRetrieveObject(niciraListType, uri, params).getResults(); } catch (final CloudstackRESTException e) { - throw new NiciraNvpApiException(e); + throw new NiciraNvpApiException(e, e.getErrorCode()); } } @@ -550,10 +566,30 @@ public List findLogicalRouterPortByGatewayServiceUuid(final S }.getType(); return restConnector.> executeRetrieveObject(niciraListType, uri, params).getResults(); } catch (final CloudstackRESTException e) { - throw new NiciraNvpApiException(e); + throw new NiciraNvpApiException(e, e.getErrorCode()); } } + public List findL2GatewayServiceByUuidAndType(final String gatewayServiceUuid, final String serviceConfigType) throws NiciraNvpApiException{ + final String uri = buildGatewayServiceUri(); + final Map params = buildBasicParametersMap(WILDCARD_QUERY_PARAMETER); + params.put(UUID_QUERY_PARAMETER, gatewayServiceUuid); + params.put(TYPES_QUERY_PARAMETER, serviceConfigType); + + try { + final Type niciraListType = new TypeToken>() { + }.getType(); + return restConnector.> executeRetrieveObject(niciraListType, uri, params).getResults(); + } + catch (final CloudstackRESTException e){ + throw new NiciraNvpApiException(e, e.getErrorCode()); + } + } + + private static String buildGatewayServiceUri(){ + return GATEWAY_SERVICE_PREFIX; + } + private static Map buildBasicParametersMap(final String fieldsQueryValue) { final Map params = new HashMap(); params.put(FIELDS_QUERY_PARAMETER, fieldsQueryValue); diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraNvpApiException.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraNvpApiException.java index 0d2782007f51..f8b3c0763cb2 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraNvpApiException.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraNvpApiException.java @@ -21,6 +21,8 @@ public class NiciraNvpApiException extends Exception { + private int errorCode; + public NiciraNvpApiException() { } @@ -36,4 +38,27 @@ public NiciraNvpApiException(final String message, final Throwable cause) { super(message, cause); } + public NiciraNvpApiException(final String message, final int errorCode){ + super(message); + this.errorCode = errorCode; + } + + public NiciraNvpApiException(final Throwable cause, final int errorCode) { + super(cause); + this.errorCode = errorCode; + } + + public NiciraNvpApiException(final String message, final Throwable cause, final int errorCode) { + super(message, cause); + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } + + public void setErrorCode(int errorCode) { + this.errorCode = errorCode; + } + } diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraRestClient.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraRestClient.java index de58a42607fa..fb66066893cc 100644 --- a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraRestClient.java +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/nicira/NiciraRestClient.java @@ -91,8 +91,10 @@ private CloseableHttpResponse execute(final HttpUriRequest request, final int pr return handleUnauthorizedResponse(request, previousStatusCode, response, statusCode); } else if (HttpStatusCodeHelper.isSuccess(statusCode)) { return handleSuccessResponse(request, response); + } else if (HttpStatusCodeHelper.isConflict(statusCode)) { + throw new CloudstackRESTException("Conflict: " + statusLine.getReasonPhrase(), statusCode); } else { - throw new CloudstackRESTException("Unexpecetd status code: " + statusCode); + throw new CloudstackRESTException("Unexpected status code: " + statusCode, statusCode); } } @@ -201,4 +203,4 @@ public NiciraRestClient build() { } } -} \ No newline at end of file +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpConfigureSharedNetworkUuidCommandWrapper.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpConfigureSharedNetworkUuidCommandWrapper.java new file mode 100644 index 000000000000..3a1d2cb9db03 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpConfigureSharedNetworkUuidCommandWrapper.java @@ -0,0 +1,196 @@ +// +// 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.network.resource.wrapper; + +import static com.cloud.network.resource.NiciraNvpResource.NAME_MAX_LEN; +import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.ConfigureSharedNetworkUuidAnswer; +import com.cloud.agent.api.ConfigureSharedNetworkUuidCommand; +import com.cloud.network.nicira.LogicalRouterPort; +import com.cloud.network.nicira.LogicalSwitch; +import com.cloud.network.nicira.LogicalSwitchPort; +import com.cloud.network.nicira.NiciraNvpApi; +import com.cloud.network.nicira.NiciraNvpApiException; +import com.cloud.network.nicira.NiciraNvpTag; +import com.cloud.network.nicira.PatchAttachment; +import com.cloud.network.resource.NiciraNvpResource; +import com.cloud.network.utils.CommandRetryUtility; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.rest.HttpStatusCodeHelper; + +@ResourceWrapper(handles = ConfigureSharedNetworkUuidCommand.class) +public final class NiciraNvpConfigureSharedNetworkUuidCommandWrapper extends CommandWrapper{ + + private static final Logger s_logger = Logger.getLogger(NiciraNvpConfigureSharedNetworkUuidCommandWrapper.class); + + @Override + public Answer execute(ConfigureSharedNetworkUuidCommand command, NiciraNvpResource niciraNvpResource) { + final String logicalRouterUuid = command.getLogicalRouterUuid(); + final String logicalSwitchUuid = command.getLogicalSwitchUuid(); + final String portIpAddress = command.getPortIpAddress(); + final List tags = new ArrayList(); + tags.add(new NiciraNvpTag("cs_account", command.getOwnerName())); + final long networkId = command.getNetworkId(); + + final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi(); + + s_logger.debug("Attaching Logical Switch " + logicalSwitchUuid + " on Logical Router " + logicalRouterUuid + " for Shared Network " + networkId); + + //Step 1: Get lSwitch displayName + s_logger.info("Looking for Logical Switch " + logicalSwitchUuid + " display name"); + String logicalSwitchDisplayName; + try{ + List lSwitchList = niciraNvpApi.findLogicalSwitch(logicalSwitchUuid); + if (lSwitchList != null){ + if (lSwitchList.size() == 1){ + logicalSwitchDisplayName = lSwitchList.get(0).getDisplayName(); + } + else { + s_logger.error("More than one Logical Switch found with uuid " + logicalSwitchUuid); + throw new CloudRuntimeException("More than one Logical Switch found with uuid=" + logicalSwitchUuid); + } + } + else { + s_logger.error("Logical Switch " + logicalSwitchUuid + " not found"); + throw new CloudRuntimeException("Logical Switch " + logicalSwitchUuid + " not found"); + } + } + catch (NiciraNvpApiException e){ + s_logger.warn("Logical Switch " + logicalSwitchUuid + " not found, retrying"); + final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility(); + retryUtility.addRetry(command, NUM_RETRIES); + return retryUtility.retry(command, ConfigureSharedNetworkUuidAnswer.class, e); + } + catch (CloudRuntimeException e){ + s_logger.info("Shared network UUID vlan id failed due to : " + e.getMessage()); + return new ConfigureSharedNetworkUuidAnswer(command, false, e.getMessage()); + } + s_logger.info("Found display name " + logicalSwitchDisplayName + " for Logical Switch " + logicalSwitchUuid); + + + //Step 2: Create lRouterPort + s_logger.debug("Creating Logical Router Port in Logical Router " + logicalRouterUuid); + LogicalRouterPort lRouterPort = null; + try { + lRouterPort = new LogicalRouterPort(); + lRouterPort.setAdminStatusEnabled(true); + lRouterPort.setDisplayName(niciraNvpResource.truncate(logicalSwitchDisplayName + "-uplink", NAME_MAX_LEN)); + lRouterPort.setTags(tags); + final List ipAddresses = new ArrayList(); + ipAddresses.add(portIpAddress); + lRouterPort.setIpAddresses(ipAddresses); + lRouterPort = niciraNvpApi.createLogicalRouterPort(logicalRouterUuid, lRouterPort); + } + catch (NiciraNvpApiException e){ + s_logger.warn("Could not create Logical Router Port on Logical Router " + logicalRouterUuid + " due to: " + e.getMessage() + ", retrying"); + return handleException(e, command, niciraNvpResource); + } + s_logger.debug("Logical Router Port " + lRouterPort.getUuid() + " (" + lRouterPort.getDisplayName() + ") successfully created in Logical Router " + logicalRouterUuid); + + + //Step 3: Create lSwitchPort + s_logger.debug("Creating Logical Switch Port in Logical Switch " + logicalSwitchUuid + " (" + logicalSwitchDisplayName + ")"); + LogicalSwitchPort lSwitchPort = null; + try { + lSwitchPort = new LogicalSwitchPort(niciraNvpResource.truncate("lrouter-uplink", NAME_MAX_LEN), tags, true); + lSwitchPort = niciraNvpApi.createLogicalSwitchPort(logicalSwitchUuid, lSwitchPort); + } + catch (NiciraNvpApiException e){ + s_logger.warn("Could not create Logical Switch Port on Logical Switch " + logicalSwitchUuid + " (" + logicalSwitchDisplayName + ") due to: " + e.getMessage()); + cleanupLRouterPort(logicalRouterUuid, lRouterPort, niciraNvpApi); + return handleException(e, command, niciraNvpResource); + } + s_logger.debug("Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") successfully created in Logical Switch " + logicalSwitchUuid + " (" + logicalSwitchDisplayName + ")"); + + + //Step 4: Attach lRouterPort to lSwitchPort with a PatchAttachment + s_logger.debug("Attaching Logical Router Port " + lRouterPort.getUuid() + " (" + lRouterPort.getDisplayName() + ") to Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") with a PatchAttachment"); + try { + niciraNvpApi.updateLogicalRouterPortAttachment(logicalRouterUuid, lRouterPort.getUuid(), new PatchAttachment(lSwitchPort.getUuid())); + } + catch (NiciraNvpApiException e) { + s_logger.warn("Could not attach Logical Router Port " + lRouterPort.getUuid() + " (" + lRouterPort.getDisplayName() + ") to Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") due to: " + e.getMessage() + ", retrying"); + cleanupLRouterPort(logicalRouterUuid, lRouterPort, niciraNvpApi); + cleanupLSwitchPort(logicalSwitchUuid, lSwitchPort, niciraNvpApi); + return handleException(e, command, niciraNvpResource); + } + s_logger.debug("Logical Router Port " + lRouterPort.getUuid() + " (" + lRouterPort.getDisplayName() + ") successfully attached to to Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") with a PatchAttachment"); + + + //Step 5: Attach lSwitchPort to lRouterPort with a PatchAttachment + s_logger.debug("Attaching Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") to Logical Router Port " + lRouterPort.getUuid() + " (" + lRouterPort.getDisplayName() + ") with a PatchAttachment"); + try { + niciraNvpApi.updateLogicalSwitchPortAttachment(logicalSwitchUuid, lSwitchPort.getUuid(), new PatchAttachment(lRouterPort.getUuid())); + } + catch (NiciraNvpApiException e){ + s_logger.warn("Could not attach Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") to Logical Router Port " + lRouterPort.getUuid() + " (" + lRouterPort.getDisplayName() + ") due to: " + e.getMessage() + ", retrying"); + cleanupLRouterPort(logicalRouterUuid, lRouterPort, niciraNvpApi); + cleanupLSwitchPort(logicalSwitchUuid, lSwitchPort, niciraNvpApi); + return handleException(e, command, niciraNvpResource); + } + s_logger.debug("Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") successfully attached to to Logical Router Port " + lRouterPort.getUuid() + " (" + lRouterPort.getDisplayName() + ") with a PatchAttachment"); + + s_logger.info("Successfully attached Logical Switch " + logicalSwitchUuid + " on Logical Router " + logicalRouterUuid + " for Shared Network " + networkId); + return new ConfigureSharedNetworkUuidAnswer(command, true, "OK"); + } + + private void cleanupLSwitchPort(String logicalSwitchUuid, LogicalSwitchPort lSwitchPort, NiciraNvpApi niciraNvpApi) { + s_logger.warn("Deleting previously created Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") from Logical Switch " + logicalSwitchUuid); + try { + niciraNvpApi.deleteLogicalSwitchPort(logicalSwitchUuid, lSwitchPort.getUuid()); + } catch (NiciraNvpApiException exceptionDeleteLSwitchPort) { + s_logger.error("Error while deleting Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") from Logical Switch " + logicalSwitchUuid + " due to: " + exceptionDeleteLSwitchPort.getMessage()); + } + s_logger.warn("Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") successfully deleted"); + } + + private void cleanupLRouterPort(String logicalRouterUuid, LogicalRouterPort lRouterPort, NiciraNvpApi niciraNvpApi) { + s_logger.warn("Deleting previously created Logical Router Port " + lRouterPort.getUuid() + " (" + lRouterPort.getDisplayName() + ") from Logical Router " + logicalRouterUuid + " and retrying"); + try { + niciraNvpApi.deleteLogicalRouterPort(logicalRouterUuid, lRouterPort.getUuid()); + } catch (NiciraNvpApiException exceptionDelete) { + s_logger.error("Error while deleting Logical Router Port " + lRouterPort.getUuid() + " (" + lRouterPort.getDisplayName() + ") from Logical Router " + logicalRouterUuid + " due to: " + exceptionDelete.getMessage()); + } + s_logger.warn("Logical Router Port " + lRouterPort.getUuid() + " (" + lRouterPort.getDisplayName() + ") successfully deleted"); + } + + private Answer handleException(NiciraNvpApiException e, ConfigureSharedNetworkUuidCommand command, NiciraNvpResource niciraNvpResource) { + if (HttpStatusCodeHelper.isConflict(e.getErrorCode())){ + s_logger.warn("There's been a conflict in NSX side, aborting implementation"); + return new ConfigureSharedNetworkUuidAnswer(command, false, "FAILED: There's been a conflict in NSX side"); + } + else { + s_logger.warn("Error code: " + e.getErrorCode() + ", retrying"); + final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility(); + retryUtility.addRetry(command, NUM_RETRIES); + return retryUtility.retry(command, ConfigureSharedNetworkUuidAnswer.class, e); + } + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpConfigureSharedNetworkVlanIdCommandWrapper.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpConfigureSharedNetworkVlanIdCommandWrapper.java new file mode 100644 index 000000000000..4fa9876976b0 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpConfigureSharedNetworkVlanIdCommandWrapper.java @@ -0,0 +1,118 @@ +// +// 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.network.resource.wrapper; + +import static com.cloud.network.resource.NiciraNvpResource.NAME_MAX_LEN; +import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.ConfigureSharedNetworkVlanIdAnswer; +import com.cloud.agent.api.ConfigureSharedNetworkVlanIdCommand; +import com.cloud.network.nicira.L2GatewayAttachment; +import com.cloud.network.nicira.LogicalSwitchPort; +import com.cloud.network.nicira.NiciraNvpApi; +import com.cloud.network.nicira.NiciraNvpApiException; +import com.cloud.network.nicira.NiciraNvpTag; +import com.cloud.network.resource.NiciraNvpResource; +import com.cloud.network.utils.CommandRetryUtility; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; +import com.cloud.utils.rest.HttpStatusCodeHelper; + +@ResourceWrapper(handles = ConfigureSharedNetworkVlanIdCommand.class) +public class NiciraNvpConfigureSharedNetworkVlanIdCommandWrapper extends CommandWrapper{ + + private static final Logger s_logger = Logger.getLogger(NiciraNvpConfigureSharedNetworkVlanIdCommandWrapper.class); + + @Override + public Answer execute(ConfigureSharedNetworkVlanIdCommand command, NiciraNvpResource niciraNvpResource) { + final String logicalSwitchUuid = command.getLogicalSwitchUuid(); + final String l2GatewayServiceUuid = command.getL2GatewayServiceUuid(); + long vlanId = command.getVlanId(); + final List tags = new ArrayList(); + tags.add(new NiciraNvpTag("cs_account", command.getOwnerName())); + final long networkId = command.getNetworkId(); + + s_logger.debug("Connecting Logical Switch " + logicalSwitchUuid + " to L2 Gateway Service " + l2GatewayServiceUuid + ", vlan id " + vlanId + " network " + networkId); + final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi(); + + s_logger.debug("Creating Logical Switch Port in Logical Switch " + logicalSwitchUuid); + LogicalSwitchPort lSwitchPort = null; + try { + lSwitchPort = new LogicalSwitchPort(); + lSwitchPort.setAdminStatusEnabled(true); + lSwitchPort.setDisplayName(niciraNvpResource.truncate(networkId + "-l2Gateway-port", NAME_MAX_LEN)); + lSwitchPort.setTags(tags); + lSwitchPort = niciraNvpApi.createLogicalSwitchPort(logicalSwitchUuid, lSwitchPort); + } + catch (NiciraNvpApiException e){ + s_logger.warn("Could not create Logical Switch Port on Logical Switch " + logicalSwitchUuid + " due to: " + e.getMessage() + ", retrying"); + return handleException(e, command, niciraNvpResource); + } + s_logger.debug("Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") successfully created in Logical Switch " + logicalSwitchUuid); + + s_logger.debug("Attaching Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") on VLAN " + command.getVlanId() + " using L2GatewayAttachment"); + try { + final L2GatewayAttachment attachment = new L2GatewayAttachment(l2GatewayServiceUuid); + if (command.getVlanId() != 0) { + attachment.setVlanId(command.getVlanId()); + } + niciraNvpApi.updateLogicalSwitchPortAttachment(logicalSwitchUuid, lSwitchPort.getUuid(), attachment); + } + catch (NiciraNvpApiException e){ + s_logger.warn("Could not attach Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") to Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") due to: " + e.getMessage() + ", errorCode: " + e.getErrorCode()); + cleanup(logicalSwitchUuid, lSwitchPort, niciraNvpApi); + return handleException(e, command, niciraNvpResource); + } + s_logger.debug("Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") successfully attached on VLAN " + command.getVlanId() + " using L2GatewayAttachment"); + + s_logger.debug("Successfully connected Logical Switch " + logicalSwitchUuid + " to L2 Gateway Service " + l2GatewayServiceUuid + ", vlan id " + vlanId + ", network " + networkId + ", through Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ")"); + return new ConfigureSharedNetworkVlanIdAnswer(command, true, "OK"); + } + + private void cleanup(String logicalSwitchUuid, LogicalSwitchPort lSwitchPort, NiciraNvpApi niciraNvpApi) { + s_logger.warn("Deleting previously created Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") from Logical Switch " + logicalSwitchUuid); + try { + niciraNvpApi.deleteLogicalSwitchPort(logicalSwitchUuid, lSwitchPort.getUuid()); + } catch (NiciraNvpApiException exceptionDeleteLSwitchPort) { + s_logger.error("Error while deleting Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") from Logical Switch " + logicalSwitchUuid + " due to: " + exceptionDeleteLSwitchPort.getMessage()); + } + s_logger.warn("Logical Switch Port " + lSwitchPort.getUuid() + " (" + lSwitchPort.getDisplayName() + ") successfully deteled"); + } + + private Answer handleException(NiciraNvpApiException e, ConfigureSharedNetworkVlanIdCommand command, NiciraNvpResource niciraNvpResource) { + if (HttpStatusCodeHelper.isConflict(e.getErrorCode())){ + s_logger.warn("There's been a conflict in NSX side, aborting implementation"); + return new ConfigureSharedNetworkVlanIdAnswer(command, false, "FAILED: There's been a conflict in NSX side"); + } + else { + s_logger.warn("Error code: " + e.getErrorCode() + ", retrying"); + final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility(); + retryUtility.addRetry(command, NUM_RETRIES); + return retryUtility.retry(command, ConfigureSharedNetworkVlanIdAnswer.class, e); + } + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpDeleteLogicalRouterPortCommandWrapper.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpDeleteLogicalRouterPortCommandWrapper.java new file mode 100644 index 000000000000..a087f0731974 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpDeleteLogicalRouterPortCommandWrapper.java @@ -0,0 +1,59 @@ +// +// 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.network.resource.wrapper; + +import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.DeleteLogicalRouterPortAnswer; +import com.cloud.agent.api.DeleteLogicalRouterPortCommand; +import com.cloud.network.nicira.NiciraNvpApi; +import com.cloud.network.nicira.NiciraNvpApiException; +import com.cloud.network.resource.NiciraNvpResource; +import com.cloud.network.utils.CommandRetryUtility; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = DeleteLogicalRouterPortCommand.class) +public class NiciraNvpDeleteLogicalRouterPortCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(NiciraNvpDeleteLogicalRouterPortCommandWrapper.class); + + @Override + public Answer execute(DeleteLogicalRouterPortCommand command, NiciraNvpResource niciraNvpResource) { + final String logicalRouterUuid = command.getLogicalRouterUuid(); + final String logicalRouterPortUuid = command.getLogicalRouterPortUuid(); + final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi(); + + s_logger.debug("Deleting Logical Router Port " + logicalRouterPortUuid + " in Logical Router " + logicalRouterUuid); + try { + niciraNvpApi.deleteLogicalRouterPort(logicalRouterUuid, logicalRouterPortUuid); + return new DeleteLogicalRouterPortAnswer(command, true, "Logical Router Port " + logicalRouterPortUuid + " deleted"); + } + catch (NiciraNvpApiException e){ + final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility(); + retryUtility.addRetry(command, NUM_RETRIES); + return retryUtility.retry(command, DeleteLogicalRouterPortAnswer.class, e); + } + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpFindL2GatewayServiceCommandWrapper.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpFindL2GatewayServiceCommandWrapper.java new file mode 100644 index 000000000000..621f503d0634 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpFindL2GatewayServiceCommandWrapper.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.network.resource.wrapper; + +import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; + +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.FindL2GatewayServiceAnswer; +import com.cloud.agent.api.FindL2GatewayServiceCommand; +import com.cloud.network.nicira.GatewayServiceConfig; +import com.cloud.network.nicira.L2GatewayServiceConfig; +import com.cloud.network.nicira.NiciraNvpApi; +import com.cloud.network.nicira.NiciraNvpApiException; +import com.cloud.network.resource.NiciraNvpResource; +import com.cloud.network.utils.CommandRetryUtility; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = FindL2GatewayServiceCommand.class) +public class NiciraNvpFindL2GatewayServiceCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(NiciraNvpFindL2GatewayServiceCommandWrapper.class); + + @Override + public Answer execute(FindL2GatewayServiceCommand command, NiciraNvpResource niciraNvpResource) { + final GatewayServiceConfig config = command.getGatewayServiceConfig(); + final String uuid = config.getUuid(); + final String type = config.getType(); + final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi(); + + s_logger.info("Looking for L2 Gateway Service " + uuid + " of type " + type); + + try { + List lstGW = niciraNvpApi.findL2GatewayServiceByUuidAndType(uuid, type); + if (lstGW.size() == 0) { + return new FindL2GatewayServiceAnswer(command, false, "L2 Gateway Service not found", null); + } else { + return new FindL2GatewayServiceAnswer(command, true, "L2 Gateway Service " + lstGW.get(0).getDisplayName()+ " found", lstGW.get(0).getUuid()); + } + } catch (NiciraNvpApiException e) { + s_logger.error("Error finding Gateway Service due to: " + e.getMessage()); + final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility(); + retryUtility.addRetry(command, NUM_RETRIES); + return retryUtility.retry(command, FindL2GatewayServiceAnswer.class, e); + } + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpFindLogicalRouterPortCommandWrapper.java b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpFindLogicalRouterPortCommandWrapper.java new file mode 100644 index 000000000000..364d478ae162 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/resource/wrapper/NiciraNvpFindLogicalRouterPortCommandWrapper.java @@ -0,0 +1,68 @@ +// +// 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.network.resource.wrapper; + +import static com.cloud.network.resource.NiciraNvpResource.NUM_RETRIES; + +import java.util.List; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.FindLogicalRouterPortAnswer; +import com.cloud.agent.api.FindLogicalRouterPortCommand; +import com.cloud.network.nicira.LogicalRouterPort; +import com.cloud.network.nicira.NiciraNvpApi; +import com.cloud.network.nicira.NiciraNvpApiException; +import com.cloud.network.resource.NiciraNvpResource; +import com.cloud.network.utils.CommandRetryUtility; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = FindLogicalRouterPortCommand.class) +public class NiciraNvpFindLogicalRouterPortCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(NiciraNvpFindLogicalRouterPortCommandWrapper.class); + + @Override + public Answer execute(FindLogicalRouterPortCommand command, NiciraNvpResource niciraNvpResource) { + final String logicalRouterUuid = command.getLogicalRouterUuid(); + final String attachmentLswitchUuid = command.getAttachmentLswitchUuid(); + final NiciraNvpApi niciraNvpApi = niciraNvpResource.getNiciraNvpApi(); + + s_logger.debug("Finding Logical Router Port in Logical Router " + logicalRouterUuid + " and attachmentLSwitchUuid " + attachmentLswitchUuid); + + try{ + List lRouterPorts = niciraNvpApi.findLogicalRouterPortByAttachmentLSwitchUuid(logicalRouterUuid, attachmentLswitchUuid); + if (lRouterPorts.size() == 0) { + return new FindLogicalRouterPortAnswer(command, false, "Logical Router Port not found", null); + } else { + return new FindLogicalRouterPortAnswer(command, true, "Logical Router Port found", lRouterPorts.get(0).getUuid()); + } + } + catch (NiciraNvpApiException e){ + s_logger.error("Error finding Logical Router Port due to: " + e.getMessage()); + final CommandRetryUtility retryUtility = niciraNvpResource.getRetryUtility(); + retryUtility.addRetry(command, NUM_RETRIES); + return retryUtility.retry(command, FindLogicalRouterPortAnswer.class, e); + } + } + +} diff --git a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/element/NiciraNvpElementTest.java b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/element/NiciraNvpElementTest.java index bf8ce18491d9..858e908f52bb 100644 --- a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/element/NiciraNvpElementTest.java +++ b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/element/NiciraNvpElementTest.java @@ -29,7 +29,10 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -40,12 +43,17 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentMatcher; - import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Command; import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigureSharedNetworkUuidAnswer; +import com.cloud.agent.api.ConfigureSharedNetworkVlanIdAnswer; +import com.cloud.agent.api.CreateLogicalRouterAnswer; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; import com.cloud.domain.Domain; import com.cloud.exception.ConcurrentOperationException; @@ -61,21 +69,27 @@ import com.cloud.network.NetworkModel; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.TrafficType; +import com.cloud.network.IpAddressManager; import com.cloud.network.NiciraNvpDeviceVO; import com.cloud.network.NiciraNvpRouterMappingVO; import com.cloud.network.PublicIpAddress; +import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.dao.NiciraNvpDao; import com.cloud.network.dao.NiciraNvpRouterMappingDao; import com.cloud.offering.NetworkOffering; import com.cloud.resource.ResourceManager; import com.cloud.user.Account; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.vm.ReservationContext; public class NiciraNvpElementTest { private static final long NETWORK_ID = 42L; + private static final long NICIRA_NVP_HOST_ID = 9L; + private static final String NETWORK_CIDR = "10.0.0.0/24"; + private static final String NETWORK_GATEWAY = "10.0.0.1"; NiciraNvpElement element = new NiciraNvpElement(); NetworkOrchestrationService networkManager = mock(NetworkOrchestrationService.class); NetworkModel networkModel = mock(NetworkModel.class); @@ -84,6 +98,8 @@ public class NiciraNvpElementTest { HostDao hostDao = mock(HostDao.class); NiciraNvpDao niciraNvpDao = mock(NiciraNvpDao.class); NiciraNvpRouterMappingDao niciraNvpRouterMappingDao = mock(NiciraNvpRouterMappingDao.class); + VlanDao vlanDao = mock(VlanDao.class); + IpAddressManager ipAddressManager = mock(IpAddressManager.class); @Before public void setUp() throws ConfigurationException { @@ -95,6 +111,8 @@ public void setUp() throws ConfigurationException { element.hostDao = hostDao; element.niciraNvpDao = niciraNvpDao; element.niciraNvpRouterMappingDao = niciraNvpRouterMappingDao; + element.vlanDao = vlanDao; + element.ipAddrMgr = ipAddressManager; // Standard responses when(networkModel.isProviderForNetwork(Provider.NiciraNvp, NETWORK_ID)).thenReturn(true); @@ -133,17 +151,32 @@ public void canHandleTest() { } @Test - public void implementTest() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + public void implementIsolatedNetworkTest() throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, URISyntaxException { final Network network = mock(Network.class); when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(network.getBroadcastUri()).thenReturn(new URI("lswitch:aaaaa")); when(network.getId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getGuestType()).thenReturn(GuestType.Isolated); + + when(networkModel.isProviderForNetwork(Provider.NiciraNvp, NETWORK_ID)).thenReturn(true); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); + + final NiciraNvpDeviceVO device = mock(NiciraNvpDeviceVO.class); + when(niciraNvpDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NiciraNvpDeviceVO[] {device})); + when(device.getId()).thenReturn(1L); + when(device.getHostId()).thenReturn(NICIRA_NVP_HOST_ID); + + HostVO niciraNvpHost = mock(HostVO.class); + when(niciraNvpHost.getId()).thenReturn(NICIRA_NVP_HOST_ID); + when(hostDao.findById(NICIRA_NVP_HOST_ID)).thenReturn(niciraNvpHost); final NetworkOffering offering = mock(NetworkOffering.class); when(offering.getId()).thenReturn(NETWORK_ID); when(offering.getTrafficType()).thenReturn(TrafficType.Guest); when(offering.getGuestType()).thenReturn(GuestType.Isolated); - mock(DeployDestination.class); + final DeployDestination dest = mock(DeployDestination.class); final Domain dom = mock(Domain.class); when(dom.getName()).thenReturn("domain"); @@ -152,6 +185,26 @@ public void implementTest() throws ConcurrentOperationException, ResourceUnavail final ReservationContext context = mock(ReservationContext.class); when(context.getDomain()).thenReturn(dom); when(context.getAccount()).thenReturn(acc); + + //ISOLATED NETWORK + when(networkModel.isProviderSupportServiceInNetwork(NETWORK_ID, Service.SourceNat, Provider.NiciraNvp)).thenReturn(true); + + PublicIp sourceNatIp = mock(PublicIp.class); + Ip ip = mock(Ip.class); + when(ip.addr()).thenReturn("10.0.0.0"); + when(sourceNatIp.getAddress()).thenReturn(ip); + when(sourceNatIp.getVlanNetmask()).thenReturn("255.255.255.0"); + when(sourceNatIp.getVlanTag()).thenReturn("111"); + + when(ipAddressManager.assignSourceNatIpAddressToGuestNetwork(acc, network)).thenReturn(sourceNatIp); + when(network.getGateway()).thenReturn(NETWORK_GATEWAY); + when(network.getCidr()).thenReturn(NETWORK_CIDR); + + final CreateLogicalRouterAnswer answer = mock(CreateLogicalRouterAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NICIRA_NVP_HOST_ID), (Command)any())).thenReturn(answer); + + assertTrue(element.implement(network, offering, dest, context)); } @Test @@ -214,4 +267,158 @@ public boolean matches(final Object argument) { } })); } + + @Test + public void implementSharedNetworkUuidVlanIdTest() throws URISyntaxException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + // SHARED NETWORKS CASE 1: LOGICAL ROUTER'S UUID AS VLAN ID + final Network network = mock(Network.class); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(network.getBroadcastUri()).thenReturn(new URI("lswitch:aaaaa")); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getGuestType()).thenReturn(GuestType.Shared); + + when(networkModel.isProviderForNetwork(Provider.NiciraNvp, NETWORK_ID)).thenReturn(true); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); + + final NiciraNvpDeviceVO device = mock(NiciraNvpDeviceVO.class); + when(niciraNvpDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NiciraNvpDeviceVO[] {device})); + when(device.getId()).thenReturn(1L); + when(device.getHostId()).thenReturn(NICIRA_NVP_HOST_ID); + + HostVO niciraNvpHost = mock(HostVO.class); + when(niciraNvpHost.getId()).thenReturn(NICIRA_NVP_HOST_ID); + when(hostDao.findById(NICIRA_NVP_HOST_ID)).thenReturn(niciraNvpHost); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Shared); + + final DeployDestination dest = mock(DeployDestination.class); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext context = mock(ReservationContext.class); + when(context.getDomain()).thenReturn(dom); + when(context.getAccount()).thenReturn(acc); + + //SHARED NETWORKS CASE 1 + when(niciraNvpRouterMappingDao.existsMappingForNetworkId(NETWORK_ID)).thenReturn(true); + when(network.getCidr()).thenReturn(NETWORK_CIDR); + when(network.getGateway()).thenReturn(NETWORK_GATEWAY); + + NiciraNvpRouterMappingVO mapping = mock(NiciraNvpRouterMappingVO.class); + when(mapping.getLogicalRouterUuid()).thenReturn("xxxx-xxxx-xxxx"); + when(niciraNvpRouterMappingDao.findByNetworkId(NETWORK_ID)).thenReturn(mapping); + + final ConfigureSharedNetworkUuidAnswer answer = mock(ConfigureSharedNetworkUuidAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NICIRA_NVP_HOST_ID), (Command)any())).thenReturn(answer); + + assertTrue(element.implement(network, offering, dest, context)); + } + + @Test + public void implementSharedNetworkNumericalVlanIdTest() throws URISyntaxException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + // SHARED NETWORKS CASE 2: NUMERICAL VLAN ID + final Network network = mock(Network.class); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(network.getBroadcastUri()).thenReturn(new URI("lswitch:aaaaa")); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getGuestType()).thenReturn(GuestType.Shared); + + when(networkModel.isProviderForNetwork(Provider.NiciraNvp, NETWORK_ID)).thenReturn(true); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); + + final NiciraNvpDeviceVO device = mock(NiciraNvpDeviceVO.class); + when(niciraNvpDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NiciraNvpDeviceVO[] {device})); + when(device.getId()).thenReturn(1L); + when(device.getHostId()).thenReturn(NICIRA_NVP_HOST_ID); + + HostVO niciraNvpHost = mock(HostVO.class); + when(niciraNvpHost.getId()).thenReturn(NICIRA_NVP_HOST_ID); + when(hostDao.findById(NICIRA_NVP_HOST_ID)).thenReturn(niciraNvpHost); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Shared); + + final DeployDestination dest = mock(DeployDestination.class); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext context = mock(ReservationContext.class); + when(context.getDomain()).thenReturn(dom); + when(context.getAccount()).thenReturn(acc); + + //SHARED NETWORKS CASE 2 + when(niciraNvpRouterMappingDao.existsMappingForNetworkId(NETWORK_ID)).thenReturn(false); + + VlanVO vlanVO = mock(VlanVO.class); + when(vlanVO.getVlanTag()).thenReturn("111"); + when(vlanDao.listVlansByNetworkId(NETWORK_ID)).thenReturn(Arrays.asList(new VlanVO[] {vlanVO})); + + when(niciraNvpHost.getDetail("l2gatewayserviceuuid")).thenReturn("bbbb-bbbb-bbbb"); + + final ConfigureSharedNetworkVlanIdAnswer answer = mock(ConfigureSharedNetworkVlanIdAnswer.class); + when(answer.getResult()).thenReturn(true); + when(agentManager.easySend(eq(NICIRA_NVP_HOST_ID), (Command)any())).thenReturn(answer); + + assertTrue(element.implement(network, offering, dest, context)); + } + + @Test(expected=CloudRuntimeException.class) + public void implementSharedNetworkNumericalVlanIdWithoutL2GatewayService() throws URISyntaxException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException{ + final Network network = mock(Network.class); + when(network.getBroadcastDomainType()).thenReturn(BroadcastDomainType.Lswitch); + when(network.getBroadcastUri()).thenReturn(new URI("lswitch:aaaaa")); + when(network.getId()).thenReturn(NETWORK_ID); + when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getGuestType()).thenReturn(GuestType.Shared); + + when(networkModel.isProviderForNetwork(Provider.NiciraNvp, NETWORK_ID)).thenReturn(true); + when(ntwkSrvcDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NiciraNvp)).thenReturn(true); + + final NiciraNvpDeviceVO device = mock(NiciraNvpDeviceVO.class); + when(niciraNvpDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NiciraNvpDeviceVO[] {device})); + when(device.getId()).thenReturn(1L); + when(device.getHostId()).thenReturn(NICIRA_NVP_HOST_ID); + + HostVO niciraNvpHost = mock(HostVO.class); + when(niciraNvpHost.getId()).thenReturn(NICIRA_NVP_HOST_ID); + when(hostDao.findById(NICIRA_NVP_HOST_ID)).thenReturn(niciraNvpHost); + + final NetworkOffering offering = mock(NetworkOffering.class); + when(offering.getId()).thenReturn(NETWORK_ID); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); + when(offering.getGuestType()).thenReturn(GuestType.Shared); + + final DeployDestination dest = mock(DeployDestination.class); + + final Domain dom = mock(Domain.class); + when(dom.getName()).thenReturn("domain"); + final Account acc = mock(Account.class); + when(acc.getAccountName()).thenReturn("accountname"); + final ReservationContext context = mock(ReservationContext.class); + when(context.getDomain()).thenReturn(dom); + when(context.getAccount()).thenReturn(acc); + + //SHARED NETWORKS CASE 2 + when(niciraNvpRouterMappingDao.existsMappingForNetworkId(NETWORK_ID)).thenReturn(false); + + VlanVO vlanVO = mock(VlanVO.class); + when(vlanVO.getVlanTag()).thenReturn("111"); + when(vlanDao.listVlansByNetworkId(NETWORK_ID)).thenReturn(Arrays.asList(new VlanVO[] {vlanVO})); + + when(niciraNvpHost.getDetail("l2gatewayserviceuuid")).thenReturn(null); + + element.implement(network, offering, dest, context); + } } \ No newline at end of file diff --git a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java index 36e4643401e8..f1737c1bf08c 100644 --- a/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java +++ b/plugins/network-elements/nicira-nvp/src/test/java/com/cloud/network/guru/NiciraNvpGuestNetworkGuruTest.java @@ -129,10 +129,10 @@ public void testCanHandle() { when(offering.getTrafficType()).thenReturn(TrafficType.Management); assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); - // Not supported: GuestType Shared + // Supported: GuestType Shared when(offering.getTrafficType()).thenReturn(TrafficType.Guest); when(offering.getGuestType()).thenReturn(GuestType.Shared); - assertFalse(guru.canHandle(offering, NetworkType.Advanced, physnet) == true); + assertTrue(guru.canHandle(offering, NetworkType.Advanced, physnet)); // Not supported: Basic networking when(offering.getGuestType()).thenReturn(GuestType.Isolated); @@ -473,4 +473,4 @@ public void testShutdown() throws InsufficientVirtualNetworkCapacityException, U verify(agentmgr, times(1)).easySend(eq(NETWORK_ID), (Command)any()); verify(implementednetwork, times(1)).setBroadcastUri(null); } -} +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/pom.xml b/plugins/network-elements/nuage-vsp/pom.xml index 40549702128f..402f9a3829ab 100644 --- a/plugins/network-elements/nuage-vsp/pom.xml +++ b/plugins/network-elements/nuage-vsp/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/opendaylight/pom.xml b/plugins/network-elements/opendaylight/pom.xml index e7e1a2dec373..a5f2a2678166 100644 --- a/plugins/network-elements/opendaylight/pom.xml +++ b/plugins/network-elements/opendaylight/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/ovs/pom.xml b/plugins/network-elements/ovs/pom.xml index dd38c9a505db..4f5adf9d65c1 100644 --- a/plugins/network-elements/ovs/pom.xml +++ b/plugins/network-elements/ovs/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/palo-alto/pom.xml b/plugins/network-elements/palo-alto/pom.xml index 792609264ae8..555ef7ab3f2d 100644 --- a/plugins/network-elements/palo-alto/pom.xml +++ b/plugins/network-elements/palo-alto/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/stratosphere-ssp/pom.xml b/plugins/network-elements/stratosphere-ssp/pom.xml index b80983cf25ac..89e84db27baa 100644 --- a/plugins/network-elements/stratosphere-ssp/pom.xml +++ b/plugins/network-elements/stratosphere-ssp/pom.xml @@ -25,7 +25,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/network-elements/vxlan/pom.xml b/plugins/network-elements/vxlan/pom.xml index e97ee28efc40..46e5af03ed9c 100644 --- a/plugins/network-elements/vxlan/pom.xml +++ b/plugins/network-elements/vxlan/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/pom.xml b/plugins/pom.xml index cdf75797cb60..bafe299da9c1 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT diff --git a/plugins/storage-allocators/random/pom.xml b/plugins/storage-allocators/random/pom.xml index 2db77fa4b6f2..87cd5b582cdb 100644 --- a/plugins/storage-allocators/random/pom.xml +++ b/plugins/storage-allocators/random/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml index 5643d23bc9d4..b9c641cfd9d8 100644 --- a/plugins/storage/image/default/pom.xml +++ b/plugins/storage/image/default/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml index 3442b4edda32..d7ee4372d05f 100644 --- a/plugins/storage/image/s3/pom.xml +++ b/plugins/storage/image/s3/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml index 2f91cde3340d..c63929e79a69 100644 --- a/plugins/storage/image/sample/pom.xml +++ b/plugins/storage/image/sample/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml index 23ad7a176eb6..a6c7dd1164c7 100644 --- a/plugins/storage/image/swift/pom.xml +++ b/plugins/storage/image/swift/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/cloudbyte/pom.xml b/plugins/storage/volume/cloudbyte/pom.xml index 26ddb62c5be5..2a4e02dd8e5f 100755 --- a/plugins/storage/volume/cloudbyte/pom.xml +++ b/plugins/storage/volume/cloudbyte/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/default/pom.xml b/plugins/storage/volume/default/pom.xml index 98bbff49834b..1cba83893948 100644 --- a/plugins/storage/volume/default/pom.xml +++ b/plugins/storage/volume/default/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/nexenta/pom.xml b/plugins/storage/volume/nexenta/pom.xml index a3035403d2c7..e4d8ebe069fd 100644 --- a/plugins/storage/volume/nexenta/pom.xml +++ b/plugins/storage/volume/nexenta/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/sample/pom.xml b/plugins/storage/volume/sample/pom.xml index 8146c7d8ec54..d649df248ddf 100644 --- a/plugins/storage/volume/sample/pom.xml +++ b/plugins/storage/volume/sample/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/storage/volume/solidfire/pom.xml b/plugins/storage/volume/solidfire/pom.xml index 1b943b1d9f48..21b3636ddbc9 100644 --- a/plugins/storage/volume/solidfire/pom.xml +++ b/plugins/storage/volume/solidfire/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../../pom.xml diff --git a/plugins/user-authenticators/ldap/pom.xml b/plugins/user-authenticators/ldap/pom.xml index 0c8ae2480c8a..a2af7187378e 100644 --- a/plugins/user-authenticators/ldap/pom.xml +++ b/plugins/user-authenticators/ldap/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/md5/pom.xml b/plugins/user-authenticators/md5/pom.xml index f7c9c33db9fe..f436f90e32e9 100644 --- a/plugins/user-authenticators/md5/pom.xml +++ b/plugins/user-authenticators/md5/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/pbkdf2/pom.xml b/plugins/user-authenticators/pbkdf2/pom.xml index 95506f16746e..b26636bd7e01 100644 --- a/plugins/user-authenticators/pbkdf2/pom.xml +++ b/plugins/user-authenticators/pbkdf2/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/plain-text/pom.xml b/plugins/user-authenticators/plain-text/pom.xml index 7d6c7217c343..3598cc168d6e 100644 --- a/plugins/user-authenticators/plain-text/pom.xml +++ b/plugins/user-authenticators/plain-text/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/saml2/pom.xml b/plugins/user-authenticators/saml2/pom.xml index b09ceb69f4fd..a97886046142 100644 --- a/plugins/user-authenticators/saml2/pom.xml +++ b/plugins/user-authenticators/saml2/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/plugins/user-authenticators/sha256salted/pom.xml b/plugins/user-authenticators/sha256salted/pom.xml index 3f236df3cd8f..fe5fa6f5eda9 100644 --- a/plugins/user-authenticators/sha256salted/pom.xml +++ b/plugins/user-authenticators/sha256salted/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-plugins - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/pom.xml b/pom.xml index 3530569e6096..c18c377cf226 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT pom Apache CloudStack Apache CloudStack is an IaaS (“Infrastructure as a Service”) cloud orchestration platform. diff --git a/quickcloud/pom.xml b/quickcloud/pom.xml index bfa0fca2a3d0..841a9c518555 100644 --- a/quickcloud/pom.xml +++ b/quickcloud/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloud-maven-standard - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../maven-standard/pom.xml diff --git a/scripts/.pydevproject b/scripts/.pydevproject deleted file mode 100644 index 43efe469ed20..000000000000 --- a/scripts/.pydevproject +++ /dev/null @@ -1,28 +0,0 @@ - - - - - -Default -python 2.6 - -/scripts - - diff --git a/scripts/vm/network/security_group.py b/scripts/vm/network/security_group.py index 4392d4871e63..915a8afb06f6 100755 --- a/scripts/vm/network/security_group.py +++ b/scripts/vm/network/security_group.py @@ -818,7 +818,7 @@ def add_network_rules(vm_name, vm_id, vm_ip, signature, seqno, vmMac, rules, vif execute("iptables -F " + egress_vmchain) except: logging.debug("Error flushing iptables rules for " + vmchain + ". Presuming firewall rules deleted, re-initializing." ) - default_network_rules(vm_name, vm_id, vm_ip, vmMac, vif, brname) + default_network_rules(vm_name, vm_id, vm_ip, vmMac, vif, brname, sec_ips) egressrule = 0 for line in lines: tokens = line.split(':') diff --git a/server/pom.xml b/server/pom.xml index d8833f221ddf..b8e3598e3e61 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index c8eb5f41f21a..1c256440d4b8 100644 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -3468,6 +3468,15 @@ public NicResponse createNicResponse(Nic result) { response.setDeviceId(String.valueOf(result.getDeviceId())); response.setIsDefault(result.isDefaultNic()); + + if (result instanceof NicVO){ + if (((NicVO)result).getNsxLogicalSwitchUuid() != null){ + response.setNsxLogicalSwitch(((NicVO)result).getNsxLogicalSwitchUuid()); + } + if (((NicVO)result).getNsxLogicalSwitchPortUuid() != null){ + response.setNsxLogicalSwitchPort(((NicVO)result).getNsxLogicalSwitchPortUuid()); + } + } return response; } diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java index 7983065f31ae..a1e3dc911ab4 100644 --- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java @@ -207,14 +207,21 @@ public UserVmResponse newUserVmResponse(ResponseView view, String objectName, Us userVmResponse.setNetworkKbsWrite((long)vmStats.getNetworkWriteKBs()); - if ((userVm.getHypervisorType() != null) && (userVm.getHypervisorType().equals(HypervisorType.KVM) || userVm.getHypervisorType().equals(HypervisorType.XenServer))) { // support KVM and XenServer only util 2013.06.25 + if ((userVm.getHypervisorType() != null) && (userVm.getHypervisorType().equals(HypervisorType.KVM) || userVm.getHypervisorType().equals(HypervisorType.XenServer) || userVm.getHypervisorType().equals(HypervisorType.VMware))) { // support KVM and XenServer only util 2013.06.25 . supporting Vmware from 2015.09.02 userVmResponse.setDiskKbsRead((long)vmStats.getDiskReadKBs()); - userVmResponse.setDiskKbsWrite((long)vmStats.getDiskWriteKBs()); + userVmResponse.setDiskKbsWrite((long) vmStats.getDiskWriteKBs()); - userVmResponse.setDiskIORead((long)vmStats.getDiskReadIOs()); + userVmResponse.setDiskIORead((long) vmStats.getDiskReadIOs()); + + userVmResponse.setDiskIOWrite((long) vmStats.getDiskWriteIOs()); + + userVmResponse.setMemoryKBs((long) vmStats.getMemoryKBs()); + + userVmResponse.setMemoryIntFreeKBs((long) vmStats.getIntFreeMemoryKBs()); + + userVmResponse.setMemoryTargetKBs((long) vmStats.getTargetMemoryKBs()); - userVmResponse.setDiskIOWrite((long)vmStats.getDiskWriteIOs()); } } } diff --git a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java index 6d8a8ab5527a..54d1ca164e29 100644 --- a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java @@ -81,14 +81,18 @@ public VolumeResponse newVolumeResponse(ResponseView view, VolumeJoinVO volume) volResponse.setZoneId(volume.getDataCenterUuid()); volResponse.setZoneName(volume.getDataCenterName()); - volResponse.setVolumeType(volume.getVolumeType().toString()); + if (volume.getVolumeType() != null) { + volResponse.setVolumeType(volume.getVolumeType().toString()); + } volResponse.setDeviceId(volume.getDeviceId()); long instanceId = volume.getVmId(); if (instanceId > 0 && volume.getState() != Volume.State.Destroy) { volResponse.setVirtualMachineId(volume.getVmUuid()); volResponse.setVirtualMachineName(volume.getVmName()); - volResponse.setVirtualMachineState(volume.getVmState().toString()); + if (volume.getVmState() != null) { + volResponse.setVirtualMachineState(volume.getVmState().toString()); + } if (volume.getVmDisplayName() != null) { volResponse.setVirtualMachineDisplayName(volume.getVmDisplayName()); } else { @@ -96,7 +100,9 @@ public VolumeResponse newVolumeResponse(ResponseView view, VolumeJoinVO volume) } } - volResponse.setProvisioningType(volume.getProvisioningType().toString()); + if (volume.getProvisioningType() != null) { + volResponse.setProvisioningType(volume.getProvisioningType().toString()); + } // Show the virtual size of the volume volResponse.setSize(volume.getSize()); @@ -105,7 +111,9 @@ public VolumeResponse newVolumeResponse(ResponseView view, VolumeJoinVO volume) volResponse.setMaxIops(volume.getMaxIops()); volResponse.setCreated(volume.getCreated()); - volResponse.setState(volume.getState().toString()); + if (volume.getState() != null) { + volResponse.setState(volume.getState().toString()); + } if (volume.getState() == Volume.State.UploadOp) { // com.cloud.storage.VolumeHostVO volumeHostRef = // ApiDBUtils.findVolumeHostRef(volume.getId(), diff --git a/server/src/com/cloud/consoleproxy/AgentBasedStandaloneConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedStandaloneConsoleProxyManager.java index b473f7e7f380..70afd8ab1d92 100644 --- a/server/src/com/cloud/consoleproxy/AgentBasedStandaloneConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/AgentBasedStandaloneConsoleProxyManager.java @@ -18,7 +18,6 @@ import java.util.List; - import org.apache.log4j.Logger; import com.cloud.host.Host; @@ -26,6 +25,10 @@ import com.cloud.info.ConsoleProxyInfo; import com.cloud.vm.UserVmVO; +/** + * This class is intended to replace the use of console proxy VMs managed by the Apache CloudStack (ACS) + * to non ACS console proxy services. The documentation that describe its use and requirements can be found in QuickCloud. + */ public class AgentBasedStandaloneConsoleProxyManager extends AgentBasedConsoleProxyManager { private static final Logger s_logger = Logger.getLogger(AgentBasedStandaloneConsoleProxyManager.class); @@ -58,26 +61,30 @@ public ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId) { } } if (allocatedHost == null) { - if (s_logger.isDebugEnabled()) + if (s_logger.isDebugEnabled()) { s_logger.debug("Failed to find a console proxy at host: " + host.getName() + " and in the pod: " + host.getPodId() + " to user vm " + userVmId); + } return null; } - if (s_logger.isDebugEnabled()) - s_logger.debug("Assign standalone console proxy running at " + allocatedHost.getName() + " to user vm " + userVmId + " with public IP " + - allocatedHost.getPublicIpAddress()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Assign standalone console proxy running at " + allocatedHost.getName() + " to user vm " + userVmId + " with public IP " + + allocatedHost.getPublicIpAddress()); + } // only private IP, public IP, host id have meaningful values, rest of all are place-holder values String publicIp = allocatedHost.getPublicIpAddress(); if (publicIp == null) { - if (s_logger.isDebugEnabled()) - s_logger.debug("Host " + allocatedHost.getName() + "/" + allocatedHost.getPrivateIpAddress() + - " does not have public interface, we will return its private IP for cosole proxy."); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Host " + allocatedHost.getName() + "/" + allocatedHost.getPrivateIpAddress() + + " does not have public interface, we will return its private IP for cosole proxy."); + } publicIp = allocatedHost.getPrivateIpAddress(); } int urlPort = _consoleProxyUrlPort; - if (allocatedHost.getProxyPort() != null && allocatedHost.getProxyPort().intValue() > 0) + if (allocatedHost.getProxyPort() != null && allocatedHost.getProxyPort().intValue() > 0) { urlPort = allocatedHost.getProxyPort().intValue(); + } return new ConsoleProxyInfo(_sslEnabled, publicIp, _consoleProxyPort, urlPort, _consoleProxyUrlDomain); } else { diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java index d4da5fae24c2..e65adb60f7d5 100644 --- a/server/src/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/com/cloud/network/IpAddressManagerImpl.java @@ -401,7 +401,7 @@ public boolean configure(String name, Map params) { AssignIpAddressFromPodVlanSearch.join("vlan", podVlanSearch, podVlanSearch.entity().getId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER); AssignIpAddressFromPodVlanSearch.done(); - Network.State.getStateMachine().registerListener(new NetworkStateListener(_usageEventDao, _networksDao, _configDao)); + Network.State.getStateMachine().registerListener(new NetworkStateListener(_configDao)); s_logger.info("Network Manager is configured."); diff --git a/server/src/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/com/cloud/network/guru/DirectNetworkGuru.java index f7416516b30d..09afd6b7aa29 100644 --- a/server/src/com/cloud/network/guru/DirectNetworkGuru.java +++ b/server/src/com/cloud/network/guru/DirectNetworkGuru.java @@ -120,7 +120,8 @@ public TrafficType[] getSupportedTrafficType() { protected boolean canHandle(NetworkOffering offering, DataCenter dc) { // this guru handles only Guest networks in Advance zone with source nat service disabled if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == GuestType.Shared - && !_ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NuageVsp)) { + && !_ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NuageVsp) + && !_ntwkOfferingSrvcDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.NiciraNvp)) { return true; } else { s_logger.trace("We only take care of Guest networks of type " + GuestType.Shared); diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index ca86cfd08049..387639f4b2e3 100644 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -36,7 +36,6 @@ import org.apache.cloudstack.utils.usage.UsageUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; @@ -90,6 +89,7 @@ import com.cloud.resource.ResourceState; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.ImageStoreDetailsUtil; import com.cloud.storage.StorageManager; import com.cloud.storage.StorageStats; import com.cloud.storage.VolumeStats; @@ -198,6 +198,8 @@ public String toString() { private ServiceOfferingDao _serviceOfferingDao; @Inject private HostGpuGroupsDao _hostGpuGroupsDao; + @Inject + private ImageStoreDetailsUtil imageStoreDetailsUtil; private ConcurrentHashMap _hostStats = new ConcurrentHashMap(); private final ConcurrentHashMap _VmStats = new ConcurrentHashMap(); @@ -462,6 +464,9 @@ protected void runInContext() { statsInMemory.setDiskReadIOs(statsInMemory.getDiskReadIOs() + statsForCurrentIteration.getDiskReadIOs()); statsInMemory.setDiskWriteIOs(statsInMemory.getDiskWriteIOs() + statsForCurrentIteration.getDiskWriteIOs()); statsInMemory.setDiskReadKBs(statsInMemory.getDiskReadKBs() + statsForCurrentIteration.getDiskReadKBs()); + statsInMemory.setMemoryKBs(statsForCurrentIteration.getMemoryKBs()); + statsInMemory.setIntFreeMemoryKBs(statsForCurrentIteration.getIntFreeMemoryKBs()); + statsInMemory.setTargetMemoryKBs(statsForCurrentIteration.getTargetMemoryKBs()); _VmStats.put(vmId, statsInMemory); } @@ -482,6 +487,10 @@ protected void runInContext() { metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.read_kbs", statsForCurrentIteration.getDiskReadKBs()); metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.write_iops", statsForCurrentIteration.getDiskWriteIOs()); metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.read_iops", statsForCurrentIteration.getDiskReadIOs()); + metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.total_kbs", statsForCurrentIteration.getMemoryKBs()); + metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.internalfree_kbs", statsForCurrentIteration.getIntFreeMemoryKBs()); + metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.target_kbs", statsForCurrentIteration.getTargetMemoryKBs()); + } } @@ -715,7 +724,7 @@ protected void runInContext() { continue; } - GetStorageStatsCommand command = new GetStorageStatsCommand(store.getTO()); + GetStorageStatsCommand command = new GetStorageStatsCommand(store.getTO(), imageStoreDetailsUtil.getNfsVersion(store.getId())); EndPoint ssAhost = _epSelector.select(store); if (ssAhost == null) { s_logger.debug("There is no secondary storage VM for secondary storage host " + store.getName()); @@ -762,6 +771,7 @@ protected void runInContext() { s_logger.error("Error trying to retrieve storage stats", t); } } + } class AutoScaleMonitor extends ManagedContextRunnable { diff --git a/server/src/com/cloud/storage/ImageStoreDetailsUtil.java b/server/src/com/cloud/storage/ImageStoreDetailsUtil.java new file mode 100755 index 000000000000..63bd5c54d67d --- /dev/null +++ b/server/src/com/cloud/storage/ImageStoreDetailsUtil.java @@ -0,0 +1,67 @@ +// 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.storage; + +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; + +public class ImageStoreDetailsUtil { + + @Inject + protected ImageStoreDao imageStoreDao; + @Inject + protected ImageStoreDetailsDao imageStoreDetailsDao; + + /** + * Obtain NFS protocol version (if provided) for a store id.
+ * It can be set by adding an entry in {@code image_store_details} table, providing {@code name=nfs.version} and {@code value=X} (e.g. 3) + * @param storeId image store id + * @return {@code null} if {@code nfs.version} is not found for storeId
+ * {@code X} if {@code nfs.version} is found found for storeId + */ + public String getNfsVersion(long storeId) { + String nfsVersion = null; + if (imageStoreDetailsDao.getDetails(storeId) != null){ + Map storeDetails = imageStoreDetailsDao.getDetails(storeId); + if (storeDetails != null && storeDetails.containsKey("nfs.version")){ + nfsVersion = storeDetails.get("nfs.version"); + } + } + return nfsVersion; + } + + /** + * Obtain NFS protocol version (if provided) for a store uuid.
+ * It can be set by adding an entry in {@code image_store_details} table, providing {@code name=nfs.version} and {@code value=X} (e.g. 3) + * @param storeId image store id + * @return {@code null} if {@code nfs.version} is not found for storeUuid
+ * {@code X} if {@code nfs.version} is found found for storeUuid + */ + public String getNfsVersionByUuid(String storeUuid){ + ImageStoreVO imageStore = imageStoreDao.findByUuid(storeUuid); + if (imageStore != null){ + return getNfsVersion(imageStore.getId()); + } + return null; + } + +} diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 5a53f9c531d0..742450ab5665 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -2472,7 +2472,7 @@ private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, L } _userVmDao.loadDetails(vm); Map controllerInfo = new HashMap(); - controllerInfo.put(VmDetailConstants.ROOK_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOK_DISK_CONTROLLER)); + controllerInfo.put(VmDetailConstants.ROOT_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER)); controllerInfo.put(VmDetailConstants.DATA_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER)); cmd.setControllerInfo(controllerInfo); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index c586e14a8194..26a48f43779e 100644 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2831,7 +2831,7 @@ public UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, Service if (networkIdList == null || networkIdList.isEmpty()) { Network networkWithSecurityGroup = _networkModel.getNetworkWithSGWithFreeIPs(zone.getId()); if (networkWithSecurityGroup == null) { - throw new InvalidParameterValueException("No network with security enabled is found in zone id=" + zone.getId()); + throw new InvalidParameterValueException("No network with security enabled is found in zone id=" + zone.getUuid()); } networkList.add(_networkDao.findById(networkWithSecurityGroup.getId())); @@ -3221,18 +3221,14 @@ protected UserVm createVirtualMachine(DataCenter zone, ServiceOffering serviceOf Long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), ntwkOffering.getTags(), ntwkOffering.getTrafficType()); if (physicalNetworkId == null) { - s_logger.warn("Network id " + network.getId() + " could not be streched to the zone " + zone.getId() - + " as valid phyical network could not be found"); throw new InvalidParameterValueException("Network in which is VM getting deployed could not be" + - " streched to the zone."); + " streched to the zone, as we could not find a valid physical network"); } String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Connectivity); if (!_networkModel.isProviderEnabledInPhysicalNetwork(physicalNetworkId, provider)) { - s_logger.warn("Network id " + network.getId() + " could not be streched to the zone " +zone.getId() - + " as Connectivity service provider is not enabled in the zone " + zone.getId()); throw new InvalidParameterValueException("Network in which is VM getting deployed could not be" + - " streched to the zone."); + " streched to the zone, as we could not find a valid physical network"); } } @@ -3509,15 +3505,15 @@ public UserVmVO doInTransaction(TransactionStatus status) throws InsufficientCap if (hypervisorType.equals(HypervisorType.VMware)) { if (guestOS.getDisplayName().toLowerCase().contains("apple mac os")) { vm.setDetail("smc.present", "TRUE"); - vm.setDetail(VmDetailConstants.ROOK_DISK_CONTROLLER, "scsi"); + vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, "scsi"); vm.setDetail(VmDetailConstants.DATA_DISK_CONTROLLER, "scsi"); vm.setDetail("firmware", "efi"); s_logger.info("guestOS is OSX : overwrite root disk controller to scsi, use smc and efi"); } else { String controllerSetting = _configDao.getValue("vmware.root.disk.controller"); // Don't override if VM already has root/data disk controller detail - if (vm.getDetail(VmDetailConstants.ROOK_DISK_CONTROLLER) == null) { - vm.setDetail(VmDetailConstants.ROOK_DISK_CONTROLLER, controllerSetting); + if (vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER) == null) { + vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, controllerSetting); } if (vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER) == null) { if (controllerSetting.equalsIgnoreCase("scsi")) { @@ -3645,7 +3641,8 @@ protected UserVm startVirtualMachine(DeployVMCmd cmd, Map imgStoreDetails = new HashMap(); + imgStoreDetails.put("nfs.version", NFS_VERSION); + when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails); + + ImageStoreVO imgStoreVO = mock(ImageStoreVO.class); + when(imgStoreVO.getId()).thenReturn(Long.valueOf(STORE_ID)); + when(imgStoreDao.findByUuid(STORE_UUID)).thenReturn(imgStoreVO); + + imageStoreDetailsUtil.imageStoreDao = imgStoreDao; + imageStoreDetailsUtil.imageStoreDetailsDao = imgStoreDetailsDao; + } + + @Test + public void testGetNfsVersion(){ + String nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID); + assertEquals(NFS_VERSION, nfsVersion); + } + + @Test + public void testGetNfsVersionNotFound(){ + Map imgStoreDetails = new HashMap(); + imgStoreDetails.put("other.prop", "propValue"); + when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails); + + String nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID); + assertNull(nfsVersion); + } + + @Test + public void testGetNfsVersionNoDetails(){ + Map imgStoreDetails = new HashMap(); + when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails); + + String nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID); + assertNull(nfsVersion); + } + + @Test + public void testGetNfsVersionByUuid(){ + String nfsVersion = imageStoreDetailsUtil.getNfsVersionByUuid(STORE_UUID); + assertEquals(NFS_VERSION, nfsVersion); + } + + @Test + public void testGetNfsVersionByUuidNoImgStore(){ + when(imgStoreDao.findByUuid(STORE_UUID)).thenReturn(null); + String nfsVersion = imageStoreDetailsUtil.getNfsVersionByUuid(STORE_UUID); + assertNull(nfsVersion); + } +} \ No newline at end of file diff --git a/services/console-proxy-rdp/rdpconsole/pom.xml b/services/console-proxy-rdp/rdpconsole/pom.xml index ca39bc3466d9..ba311830af7c 100755 --- a/services/console-proxy-rdp/rdpconsole/pom.xml +++ b/services/console-proxy-rdp/rdpconsole/pom.xml @@ -27,7 +27,7 @@ org.apache.cloudstack cloudstack-services - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/services/console-proxy/plugin/pom.xml b/services/console-proxy/plugin/pom.xml index 5ed89814f666..dbaf85791c77 100644 --- a/services/console-proxy/plugin/pom.xml +++ b/services/console-proxy/plugin/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/services/console-proxy/pom.xml b/services/console-proxy/pom.xml index f90775abf616..9d5feec38689 100644 --- a/services/console-proxy/pom.xml +++ b/services/console-proxy/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-services - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml index 780c570fa466..541d242013ef 100644 --- a/services/console-proxy/server/pom.xml +++ b/services/console-proxy/server/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-console-proxy - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/services/iam/plugin/pom.xml b/services/iam/plugin/pom.xml index c752a24b0f62..974d2166bf68 100644 --- a/services/iam/plugin/pom.xml +++ b/services/iam/plugin/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-iam - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/services/iam/server/pom.xml b/services/iam/server/pom.xml index 0241639b748b..b2ad0a4f52ec 100644 --- a/services/iam/server/pom.xml +++ b/services/iam/server/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-iam - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/services/pom.xml b/services/pom.xml index e7961947a04d..f315b5e8b1c0 100644 --- a/services/pom.xml +++ b/services/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/controller/pom.xml b/services/secondary-storage/controller/pom.xml index 3e34929a72fb..bb8878010f0b 100644 --- a/services/secondary-storage/controller/pom.xml +++ b/services/secondary-storage/controller/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java index 4891b71967ac..2ff54c8dc9a7 100644 --- a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java +++ b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java @@ -101,6 +101,7 @@ import com.cloud.resource.UnableDeleteHostException; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.ImageStoreDetailsUtil; import com.cloud.storage.Storage; import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateVO; @@ -239,6 +240,8 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar TemplateDataStoreDao _tmplStoreDao; @Inject VolumeDataStoreDao _volumeStoreDao; + @Inject + private ImageStoreDetailsUtil imageStoreDetailsUtil; private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL; private int _secStorageVmMtuSize; @@ -310,6 +313,8 @@ public boolean generateSetupCommand(Long ssHostId) { setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, certs); } + setupCmd.setNfsVersion(imageStoreDetailsUtil.getNfsVersion(ssStore.getId())); + //template/volume file upload key String postUploadKey = _configDao.getValue(Config.SSVMPSK.key()); setupCmd.setPostUploadKey(postUploadKey); @@ -1046,7 +1051,6 @@ private String getSecStorageVmLockName(long id) { @Override public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { - SecondaryStorageVmVO vm = _secStorageVmDao.findById(profile.getId()); Map details = _vmDetailsDao.listDetailsKeyPairs(vm.getId()); vm.setDetails(details); @@ -1131,6 +1135,8 @@ public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, Depl if (dc.getDns2() != null) { buf.append(" dns2=").append(dc.getDns2()); } + String nfsVersion = imageStoreDetailsUtil != null ? imageStoreDetailsUtil.getNfsVersion(secStore.getId()) : null; + buf.append(" nfsVersion=").append(nfsVersion); String bootArgs = buf.toString(); if (s_logger.isDebugEnabled()) { @@ -1430,4 +1436,5 @@ public List getSecondaryStorageVmAllocators() { public void setSecondaryStorageVmAllocators(List ssVmAllocators) { _ssVmAllocators = ssVmAllocators; } + } diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml index 07d2d2ee257d..bce61d66f150 100644 --- a/services/secondary-storage/pom.xml +++ b/services/secondary-storage/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack-services - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/server/pom.xml b/services/secondary-storage/server/pom.xml index 417e0a60a7e9..b6bfbf7df737 100644 --- a/services/secondary-storage/server/pom.xml +++ b/services/secondary-storage/server/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack-service-secondary-storage - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java index 9393ee217a10..6f189ef5f3c6 100644 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java @@ -53,10 +53,10 @@ public Answer executeRequest(Command cmd) { } @Override - synchronized public String getRootDir(String secUrl) { + synchronized public String getRootDir(String secUrl, String nfsVersion) { try { URI uri = new URI(secUrl); - String dir = mountUri(uri); + String dir = mountUri(uri, nfsVersion); return _parent + "/" + dir; } catch (Exception e) { String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString(); @@ -66,14 +66,14 @@ synchronized public String getRootDir(String secUrl) { } @Override - protected void mount(String localRootPath, String remoteDevice, URI uri) { + protected void mount(String localRootPath, String remoteDevice, URI uri, String nfsVersion) { ensureLocalRootPathExists(localRootPath, uri); if (mountExists(localRootPath, uri)) { return; } - attemptMount(localRootPath, remoteDevice, uri); + attemptMount(localRootPath, remoteDevice, uri, nfsVersion); // Change permissions for the mountpoint - seems to bypass authentication Script script = new Script(true, "chmod", _timeout, s_logger); diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java index bdfe7e837f26..d953338c911d 100644 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java @@ -72,7 +72,7 @@ public void disconnected() { } @Override - public String getRootDir(String url) { + public String getRootDir(String url, String nfsVersion) { return getRootDir(); } diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 768a177cdc52..663699aad2e8 100644 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -52,6 +52,7 @@ import com.cloud.utils.EncryptionUtil; import com.google.gson.Gson; import com.google.gson.GsonBuilder; + import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; @@ -65,6 +66,7 @@ import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; + import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand; import org.apache.cloudstack.storage.template.UploadEntity; import org.apache.cloudstack.utils.imagestore.ImageStoreUtil; @@ -161,6 +163,7 @@ import com.cloud.utils.script.OutputInterpreter; import com.cloud.utils.script.Script; import com.cloud.vm.SecondaryStorageVm; + import org.joda.time.DateTime; import org.joda.time.format.ISODateTimeFormat; @@ -205,6 +208,7 @@ public void setTimeout(int timeout) { private String _storageIp; private String _storageNetmask; private String _storageGateway; + private String _nfsVersion; private final List nfsIps = new ArrayList(); protected String _parent = "/mnt/SecStorage"; final private String _tmpltpp = "template.properties"; @@ -352,7 +356,7 @@ protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO swi final String storagePath = destImageStore.getUrl(); final String destPath = destData.getPath(); try { - String downloadPath = determineStorageTemplatePath(storagePath, destPath); + String downloadPath = determineStorageTemplatePath(storagePath, destPath, _nfsVersion); final File downloadDirectory = _storage.getFile(downloadPath); if (downloadDirectory.exists()) { @@ -379,7 +383,7 @@ protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataT try { - String downloadPath = determineStorageTemplatePath(storagePath, destPath); + String downloadPath = determineStorageTemplatePath(storagePath, destPath, _nfsVersion); final File downloadDirectory = _storage.getFile(downloadPath); if (downloadDirectory.exists()) { @@ -412,7 +416,7 @@ protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataT protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) { - String srcMountPoint = getRootDir(srcDataStore.getUrl()); + String srcMountPoint = getRootDir(srcDataStore.getUrl(), _nfsVersion); String snapshotPath = srcData.getPath(); int index = snapshotPath.lastIndexOf("/"); String snapshotName = snapshotPath.substring(index + 1); @@ -422,7 +426,7 @@ protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, Sn snapshotPath = snapshotPath.substring(0, index); snapshotPath = srcMountPoint + File.separator + snapshotPath; - String destMountPoint = getRootDir(destDataStore.getUrl()); + String destMountPoint = getRootDir(destDataStore.getUrl(), _nfsVersion); String destPath = destMountPoint + File.separator + destData.getPath(); String errMsg = null; @@ -480,8 +484,8 @@ protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObj if (srcData.getHypervisorType() == HypervisorType.XenServer) { return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore); } else if (srcData.getHypervisorType() == HypervisorType.KVM) { - File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl()); - File destFile = getFile(destData.getPath(), destDataStore.getUrl()); + File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl(), _nfsVersion); + File destFile = getFile(destData.getPath(), destDataStore.getUrl(), _nfsVersion); VolumeObjectTO volumeObjectTO = srcData.getVolume(); ImageFormat srcFormat = null; @@ -565,8 +569,8 @@ protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObj return new CopyCmdAnswer(""); } - protected File getFile(String path, String nfsPath) { - String filePath = getRootDir(nfsPath) + File.separator + path; + protected File getFile(String path, String nfsPath, String nfsVersion) { + String filePath = getRootDir(nfsPath, nfsVersion) + File.separator + path; File f = new File(filePath); if (!f.exists()) { _storage.mkdirs(filePath); @@ -598,7 +602,7 @@ protected Answer createTemplateFromSnapshot(CopyCommand cmd) { } s_logger.debug("starting copy template to swift"); DataTO newTemplate = answer.getNewData(); - File templateFile = getFile(newTemplate.getPath(), ((NfsTO)srcDataStore).getUrl()); + File templateFile = getFile(newTemplate.getPath(), ((NfsTO)srcDataStore).getUrl(), _nfsVersion); SwiftTO swift = (SwiftTO)destDataStore; String containterName = SwiftUtil.getContainerName(destData.getObjectType().toString(), destData.getId()); String swiftPath = SwiftUtil.putObject(swift, templateFile, containterName, templateFile.getName()); @@ -705,8 +709,8 @@ protected Long determineS3VolumeIdFromKey(String key) { return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR)); } - private String determineStorageTemplatePath(final String storagePath, String dataPath) { - return join(asList(getRootDir(storagePath), dataPath), File.separator); + private String determineStorageTemplatePath(final String storagePath, String dataPath, String nfsVersion) { + return join(asList(getRootDir(storagePath, nfsVersion), dataPath), File.separator); } protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String name) { @@ -720,7 +724,7 @@ protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String n throw new CloudRuntimeException("Failed to get url: " + url); } - String nfsMountPath = getRootDir(nfs.getUrl()); + String nfsMountPath = getRootDir(nfs.getUrl(), _nfsVersion); String filePath = nfsMountPath + File.separator + path; File directory = new File(filePath); @@ -885,7 +889,7 @@ protected Answer copyFromNfsToS3(CopyCommand cmd) { final S3TO s3 = (S3TO)destDataStore; try { - final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath()); + final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath(), _nfsVersion); if (s_logger.isDebugEnabled()) { s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3."); @@ -1098,7 +1102,7 @@ public Answer execute(DeleteSnapshotsDirCommand cmd) { if (dstore instanceof NfsTO) { NfsTO nfs = (NfsTO)dstore; String relativeSnapshotPath = cmd.getDirectory(); - String parent = getRootDir(nfs.getUrl()); + String parent = getRootDir(nfs.getUrl(), _nfsVersion); if (relativeSnapshotPath.startsWith(File.separator)) { relativeSnapshotPath = relativeSnapshotPath.substring(1); @@ -1176,7 +1180,7 @@ private Answer execute(ComputeChecksumCommand cmd) { return new Answer(cmd, false, "can't handle non nfs data store"); } NfsTO nfsStore = (NfsTO)store; - String parent = getRootDir(nfsStore.getUrl()); + String parent = getRootDir(nfsStore.getUrl(), _nfsVersion); if (relativeTemplatePath.startsWith(File.separator)) { relativeTemplatePath = relativeTemplatePath.substring(1); @@ -1310,7 +1314,8 @@ private Answer execute(SecStorageSetupCommand cmd) { String nfsHostIp = getUriHostIp(uri); addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp); - String dir = mountUri(uri); + + String dir = mountUri(uri, cmd.getNfsVersion()); configCerts(cmd.getCerts()); @@ -1386,7 +1391,7 @@ protected Answer deleteSnapshot(final DeleteCommand cmd) { DataStoreTO dstore = obj.getDataStore(); if (dstore instanceof NfsTO) { NfsTO nfs = (NfsTO)dstore; - String parent = getRootDir(nfs.getUrl()); + String parent = getRootDir(nfs.getUrl(), _nfsVersion); if (!parent.endsWith(File.separator)) { parent += File.separator; } @@ -1557,7 +1562,7 @@ private Answer execute(ListTemplateCommand cmd) { if (store instanceof NfsTO) { NfsTO nfs = (NfsTO)store; String secUrl = nfs.getUrl(); - String root = getRootDir(secUrl); + String root = getRootDir(secUrl, cmd.getNfsVersion()); Map templateInfos = _dlMgr.gatherTemplateInfo(root); return new ListTemplateAnswer(secUrl, templateInfos); } else if (store instanceof SwiftTO) { @@ -1579,7 +1584,7 @@ private Answer execute(ListVolumeCommand cmd) { } DataStoreTO store = cmd.getDataStore(); if (store instanceof NfsTO) { - String root = getRootDir(cmd.getSecUrl()); + String root = getRootDir(cmd.getSecUrl(), _nfsVersion); Map templateInfos = _dlMgr.gatherVolumeInfo(root); return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos); } else if (store instanceof S3TO) { @@ -1714,7 +1719,7 @@ protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) { return new GetStorageStatsAnswer(cmd, infinity, 0L); } - String rootDir = getRootDir(((NfsTO)store).getUrl()); + String rootDir = getRootDir(((NfsTO)store).getUrl(), cmd.getNfsVersion()); final long usedSize = getUsedSize(rootDir); final long totalSize = getTotalSize(rootDir); if (usedSize == -1 || totalSize == -1) { @@ -1748,7 +1753,7 @@ protected Answer deleteTemplate(DeleteCommand cmd) { if (dstore instanceof NfsTO) { NfsTO nfs = (NfsTO)dstore; String relativeTemplatePath = obj.getPath(); - String parent = getRootDir(nfs.getUrl()); + String parent = getRootDir(nfs.getUrl(), _nfsVersion); if (relativeTemplatePath.startsWith(File.separator)) { relativeTemplatePath = relativeTemplatePath.substring(1); @@ -1852,7 +1857,7 @@ protected Answer deleteVolume(final DeleteCommand cmd) { if (dstore instanceof NfsTO) { NfsTO nfs = (NfsTO)dstore; String relativeVolumePath = obj.getPath(); - String parent = getRootDir(nfs.getUrl()); + String parent = getRootDir(nfs.getUrl(), _nfsVersion); if (relativeVolumePath.startsWith(File.separator)) { relativeVolumePath = relativeVolumePath.substring(1); @@ -1954,13 +1959,13 @@ protected Answer deleteVolume(final DeleteCommand cmd) { } @Override - synchronized public String getRootDir(String secUrl) { + synchronized public String getRootDir(String secUrl, String nfsVersion) { if (!_inSystemVM) { return _parent; } try { URI uri = new URI(secUrl); - String dir = mountUri(uri); + String dir = mountUri(uri, nfsVersion); return _parent + "/" + dir; } catch (Exception e) { String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString(); @@ -2117,6 +2122,7 @@ public boolean configure(String name, Map params) throws Configu startAdditionalServices(); _params.put("install.numthreads", "50"); _params.put("secondary.storage.vm", "true"); + _nfsVersion = (String)params.get("nfsVersion"); } try { @@ -2291,10 +2297,11 @@ private String configureIpFirewall(List ipList, boolean isAppend) { * @param uri * crresponding to the remote device. Will throw for unsupported * scheme. + * @param imgStoreId * @return name of folder in _parent that device was mounted. * @throws UnknownHostException */ - protected String mountUri(URI uri) throws UnknownHostException { + protected String mountUri(URI uri, String nfsVersion) throws UnknownHostException { String uriHostIp = getUriHostIp(uri); String nfsPath = uriHostIp + ":" + uri.getPath(); @@ -2312,7 +2319,7 @@ protected String mountUri(URI uri) throws UnknownHostException { s_logger.debug("Mounting device with nfs-style path of " + remoteDevice); } - mount(localRootPath, remoteDevice, uri); + mount(localRootPath, remoteDevice, uri, nfsVersion); return dir; } @@ -2340,15 +2347,15 @@ protected void umount(String localRootPath, URI uri) { s_logger.debug("Successfully umounted " + localRootPath); } - protected void mount(String localRootPath, String remoteDevice, URI uri) { - s_logger.debug("mount " + uri.toString() + " on " + localRootPath); + protected void mount(String localRootPath, String remoteDevice, URI uri, String nfsVersion) { + s_logger.debug("mount " + uri.toString() + " on " + localRootPath + ((nfsVersion != null) ? " nfsVersion="+nfsVersion : "")); ensureLocalRootPathExists(localRootPath, uri); if (mountExists(localRootPath, uri)) { return; } - attemptMount(localRootPath, remoteDevice, uri); + attemptMount(localRootPath, remoteDevice, uri, nfsVersion); // XXX: Adding the check for creation of snapshots dir here. Might have // to move it somewhere more logical later. @@ -2356,9 +2363,10 @@ protected void mount(String localRootPath, String remoteDevice, URI uri) { checkForVolumesDir(localRootPath); } - protected void attemptMount(String localRootPath, String remoteDevice, URI uri) { + protected void attemptMount(String localRootPath, String remoteDevice, URI uri, String nfsVersion) { String result; - s_logger.debug("Make cmdline call to mount " + remoteDevice + " at " + localRootPath + " based on uri " + uri); + s_logger.debug("Make cmdline call to mount " + remoteDevice + " at " + localRootPath + " based on uri " + uri + + ((nfsVersion != null) ? " nfsVersion=" + nfsVersion : "")); Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger); String scheme = uri.getScheme().toLowerCase(); @@ -2370,7 +2378,7 @@ protected void attemptMount(String localRootPath, String remoteDevice, URI uri) command.add("-o", "resvport"); } if (_inSystemVM) { - command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0"); + command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0" + ((nfsVersion != null) ? ",vers=" + nfsVersion : "")); } } else if (scheme.equals("cifs")) { String extraOpts = parseCifsMountOptions(uri); @@ -2647,7 +2655,7 @@ public UploadEntity createUploadEntity(String uuid, String metadata, long conten //relative path with out ssvm mount info. uploadEntity.setTemplatePath(absolutePath); String dataStoreUrl = cmd.getDataTo(); - String installPathPrefix = this.getRootDir(dataStoreUrl) + File.separator + absolutePath; + String installPathPrefix = this.getRootDir(dataStoreUrl, cmd.getNfsVersion()) + File.separator + absolutePath; uploadEntity.setInstallPathPrefix(installPathPrefix); uploadEntity.setHvm(cmd.getRequiresHvm()); uploadEntity.setChksum(cmd.getChecksum()); @@ -2669,7 +2677,7 @@ public UploadEntity createUploadEntity(String uuid, String metadata, long conten } private synchronized void checkSecondaryStorageResourceLimit(TemplateOrVolumePostUploadCommand cmd, int contentLengthInGB) { - String rootDir = this.getRootDir(cmd.getDataTo()) + File.separator; + String rootDir = this.getRootDir(cmd.getDataTo(), cmd.getNfsVersion()) + File.separator; long accountId = cmd.getAccountId(); long accountTemplateDirSize = 0; @@ -2716,7 +2724,7 @@ private String getSnapshotPathForAccount(long accountId) { private boolean isOneTimePostUrlUsed(TemplateOrVolumePostUploadCommand cmd) { String uuid = cmd.getEntityUUID(); - String uploadPath = this.getRootDir(cmd.getDataTo()) + File.separator + cmd.getAbsolutePath(); + String uploadPath = this.getRootDir(cmd.getDataTo(), cmd.getNfsVersion()) + File.separator + cmd.getAbsolutePath(); return uploadEntityStateMap.containsKey(uuid) || new File(uploadPath).exists(); } diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java index 4d3f04819e84..3c24b6c6de3e 100644 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java @@ -23,6 +23,6 @@ */ public interface SecondaryStorageResource extends ServerResource { - String getRootDir(String cmd); + String getRootDir(String cmd, String nfsVersion); } diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java index 9cf37e56596c..affe8a716a72 100644 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java @@ -89,6 +89,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager StorageLayer _storage; public Map _processors; + private String _nfsVersion; + public class Completion implements DownloadCompleteCallback { private final String jobId; @@ -708,7 +710,7 @@ public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, D String installPathPrefix = cmd.getInstallPath(); // for NFS, we need to get mounted path if (dstore instanceof NfsTO) { - installPathPrefix = resource.getRootDir(((NfsTO)dstore).getUrl()) + File.separator + installPathPrefix; + installPathPrefix = resource.getRootDir(((NfsTO)dstore).getUrl(), _nfsVersion) + File.separator + installPathPrefix; } String user = null; String password = null; @@ -982,6 +984,7 @@ public boolean configure(String name, Map params) throws Configu String inSystemVM = (String)params.get("secondary.storage.vm"); if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) { s_logger.info("DownloadManager: starting additional services since we are inside system vm"); + _nfsVersion = (String)params.get("nfsVersion"); startAdditionalServices(); blockOutgoingOnPrivate(); } diff --git a/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java index 13ddb3531a82..9da5c53a9034 100644 --- a/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java +++ b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java @@ -80,7 +80,7 @@ public void testMount() throws Exception { if (!sampleMount.isEmpty()) { s_logger.info("functional test, mount " + sampleMount); URI realMntUri = new URI(sampleMount); - String mntSubDir = resource.mountUri(realMntUri); + String mntSubDir = resource.mountUri(realMntUri, null); s_logger.info("functional test, umount " + mntSubDir); resource.umount(resource.getMountingRoot() + mntSubDir, realMntUri); } else { diff --git a/setup/bindir/cloud-set-guest-sshkey.in b/setup/bindir/cloud-set-guest-sshkey.in index 0472a7c006c7..03d57f536605 100755 --- a/setup/bindir/cloud-set-guest-sshkey.in +++ b/setup/bindir/cloud-set-guest-sshkey.in @@ -81,8 +81,8 @@ if [ ! -e $authorized ]; then chmod 600 $authorized fi -cat $authorized|grep -v "$publickey"|tee $authorized > /dev/null -echo "$publickey" >> $authorized +sed -i "/ cloudstack@apache.org$/d" $authorized +echo "$publickey cloudstack@apache.org" >> $authorized which restorecon && restorecon -R -v $sshdir diff --git a/setup/db/db/schema-461to470.sql b/setup/db/db/schema-461to470.sql index dc9f1ce9e28e..7c701992c4d7 100644 --- a/setup/db/db/schema-461to470.sql +++ b/setup/db/db/schema-461to470.sql @@ -247,3 +247,7 @@ CREATE VIEW `cloud`.`domain_router_view` AS and async_job.instance_type = 'DomainRouter' and async_job.job_status = 0; +INSERT IGNORE INTO `cloud`.`hypervisor_capabilities` values (25,UUID(),'VMware','6.0',128,0,13,32,1,1); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(),'VMware', '5.5', 'rhel7_64Guest', 245, utc_timestamp(), 0); +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'VMware', '6.0', guest_os_name, guest_os_id, utc_timestamp(), 0 FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='VMware' AND hypervisor_version='5.5' AND (guest_os_id NOT IN (1,2,3,4,62,63,64,65,156,157,221,222) AND guest_os_id NOT BETWEEN 121 AND 130); + diff --git a/setup/db/db/schema-471to472.sql b/setup/db/db/schema-471to480-cleanup.sql similarity index 95% rename from setup/db/db/schema-471to472.sql rename to setup/db/db/schema-471to480-cleanup.sql index 7be41cd0a670..67f10e9c2474 100644 --- a/setup/db/db/schema-471to472.sql +++ b/setup/db/db/schema-471to480-cleanup.sql @@ -16,5 +16,5 @@ -- under the License. --; --- Schema upgrade from 4.7.1 to 4.7.2; +-- Schema cleanup from 4.7.1 to 4.8.0; --; diff --git a/setup/db/db/schema-471to480.sql b/setup/db/db/schema-471to480.sql new file mode 100644 index 000000000000..b79af7f544d7 --- /dev/null +++ b/setup/db/db/schema-471to480.sql @@ -0,0 +1,29 @@ +-- 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. + +--; +-- Schema upgrade from 4.7.1 to 4.8.0; +--; + +ALTER TABLE `cloud`.`nicira_nvp_router_map` DROP INDEX `logicalrouter_uuid` ; + +ALTER TABLE `cloud`.`volume_host_ref` MODIFY COLUMN `url` varchar(2048); +ALTER TABLE `cloud`.`object_datastore_ref` MODIFY COLUMN `url` varchar(2048); +ALTER TABLE `cloud`.`image_store` MODIFY COLUMN `url` varchar(2048); +ALTER TABLE `cloud`.`template_store_ref` MODIFY COLUMN `url` varchar(2048); +ALTER TABLE `cloud`.`volume_store_ref` MODIFY COLUMN `url` varchar(2048); +ALTER TABLE `cloud`.`volume_store_ref` MODIFY COLUMN `download_url` varchar(2048); diff --git a/setup/db/db/schema-471to472-cleanup.sql b/setup/db/db/schema-480to481-cleanup.sql similarity index 95% rename from setup/db/db/schema-471to472-cleanup.sql rename to setup/db/db/schema-480to481-cleanup.sql index 67c1a6d9bfef..04b11c6a79f1 100644 --- a/setup/db/db/schema-471to472-cleanup.sql +++ b/setup/db/db/schema-480to481-cleanup.sql @@ -16,5 +16,5 @@ -- under the License. --; --- Schema cleanup from 4.7.1 to 4.7.2; +-- Schema cleanup from 4.8.0 to 4.8.1; --; diff --git a/setup/db/db/schema-480to481.sql b/setup/db/db/schema-480to481.sql new file mode 100644 index 000000000000..3b2d40b3d82c --- /dev/null +++ b/setup/db/db/schema-480to481.sql @@ -0,0 +1,20 @@ +-- 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. + +--; +-- Schema upgrade from 4.8.0 to 4.8.1; +--; diff --git a/setup/db/db/schema-481to490-cleanup.sql b/setup/db/db/schema-481to490-cleanup.sql new file mode 100644 index 000000000000..c74fa41533e2 --- /dev/null +++ b/setup/db/db/schema-481to490-cleanup.sql @@ -0,0 +1,20 @@ +-- 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. + +--; +-- Schema cleanup from 4.8.1 to 4.9.0; +--; diff --git a/setup/db/db/schema-481to490.sql b/setup/db/db/schema-481to490.sql new file mode 100644 index 000000000000..0f27e4558232 --- /dev/null +++ b/setup/db/db/schema-481to490.sql @@ -0,0 +1,23 @@ +-- 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. + +--; +-- Schema upgrade from 4.8.1 to 4.9.0; +--; + +ALTER TABLE `event` ADD INDEX `archived` (`archived`); +ALTER TABLE `event` ADD INDEX `state` (`state`); diff --git a/systemvm/patches/debian/config/opt/cloud/bin/configure.py b/systemvm/patches/debian/config/opt/cloud/bin/configure.py index ab134fcfca71..c37059b5a6b1 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/configure.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/configure.py @@ -775,41 +775,46 @@ def processForwardRule(self, rule): self.forward_vr(rule) def forward_vr(self, rule): + #prefetch iptables variables + public_fwinterface = self.getDeviceByIp(rule['public_ip']) + internal_fwinterface = self.getDeviceByIp(rule['internal_ip']) + public_fwports = self.portsToString(rule['public_ports'], ':') + internal_fwports = self.portsToString(rule['internal_ports'], '-') fw1 = "-A PREROUTING -d %s/32 -i %s -p %s -m %s --dport %s -j DNAT --to-destination %s:%s" % \ ( rule['public_ip'], - self.getDeviceByIp(rule['public_ip']), + public_fwinterface, rule['protocol'], rule['protocol'], - self.portsToString(rule['public_ports'], ':'), + public_fwports, rule['internal_ip'], - self.portsToString(rule['internal_ports'], '-') + internal_fwports ) fw2 = "-A PREROUTING -d %s/32 -i %s -p %s -m %s --dport %s -j DNAT --to-destination %s:%s" % \ ( rule['public_ip'], - self.getDeviceByIp(rule['internal_ip']), + internal_fwinterface, rule['protocol'], rule['protocol'], - self.portsToString(rule['public_ports'], ':'), + public_fwports, rule['internal_ip'], - self.portsToString(rule['internal_ports'], '-') + internal_fwports ) fw3 = "-A OUTPUT -d %s/32 -p %s -m %s --dport %s -j DNAT --to-destination %s:%s" % \ ( rule['public_ip'], rule['protocol'], rule['protocol'], - self.portsToString(rule['public_ports'], ':'), + public_fwports, rule['internal_ip'], - self.portsToString(rule['internal_ports'], '-') + internal_fwports ) fw4 = "-j SNAT --to-source %s -A POSTROUTING -s %s -d %s/32 -o %s -p %s -m %s --dport %s" % \ ( self.getGuestIp(), self.getNetworkByIp(rule['internal_ip']), rule['internal_ip'], - self.getDeviceByIp(rule['internal_ip']), + internal_fwinterface, rule['protocol'], rule['protocol'], self.portsToString(rule['internal_ports'], ':') @@ -817,24 +822,24 @@ def forward_vr(self, rule): fw5 = "-A PREROUTING -d %s/32 -i %s -p %s -m %s --dport %s -j MARK --set-xmark %s/0xffffffff" % \ ( rule['public_ip'], - self.getDeviceByIp(rule['public_ip']), + public_fwinterface, rule['protocol'], rule['protocol'], - self.portsToString(rule['public_ports'], ':'), - hex(int(self.getDeviceByIp(rule['public_ip'])[3:])) + public_fwports, + hex(int(public_fwinterface[3:])) ) fw6 = "-A PREROUTING -d %s/32 -i %s -p %s -m %s --dport %s -m state --state NEW -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff" % \ ( rule['public_ip'], - self.getDeviceByIp(rule['public_ip']), + public_fwinterface, rule['protocol'], rule['protocol'], - self.portsToString(rule['public_ports'], ':'), + public_fwports, ) fw7 = "-A FORWARD -i %s -o %s -p %s -m %s --dport %s -m state --state NEW,ESTABLISHED -j ACCEPT" % \ ( - self.getDeviceByIp(rule['public_ip']), - self.getDeviceByIp(rule['internal_ip']), + public_fwinterface, + internal_fwinterface, rule['protocol'], rule['protocol'], self.portsToString(rule['internal_ports'], ':') diff --git a/systemvm/pom.xml b/systemvm/pom.xml index c87f7166b0e1..c72b56df6732 100644 --- a/systemvm/pom.xml +++ b/systemvm/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/test/integration/component/maint/testpath_disable_enable_zone.py b/test/integration/component/maint/testpath_disable_enable_zone.py index a15173ebbd8f..1537fc5457a5 100644 --- a/test/integration/component/maint/testpath_disable_enable_zone.py +++ b/test/integration/component/maint/testpath_disable_enable_zone.py @@ -21,6 +21,11 @@ from marvin.cloudstackTestCase import cloudstackTestCase from marvin.lib.utils import (cleanup_resources, validateList) +from marvin.cloudstackAPI import (dedicateCluster, + listDedicatedClusters, + releaseDedicatedCluster, + listAffinityGroups) + from marvin.lib.base import (Account, VirtualMachine, ServiceOffering, @@ -40,7 +45,10 @@ get_template, list_volumes, list_snapshots, - get_builtin_template_info + get_builtin_template_info, + list_routers, + list_virtual_machines, + list_hosts ) from marvin.cloudstackAPI import (updateZone, @@ -280,7 +288,7 @@ def test_01_disable_enable_zone(self): self.testdata["privatetemplate"]["hypervisor"] = builtin_info[1] self.testdata["privatetemplate"]["format"] = builtin_info[2] """ - //commenting it for now will uncomment once expected behaviour is known + //commenting it for now will uncomment once expected behaviour is known Template.register( self.apiclient, self.testdata["privatetemplate"], @@ -295,7 +303,7 @@ def test_01_disable_enable_zone(self): diskofferingid=self.disk_offering.id ) """ - //commenting it for now will uncomment once expected behaviour is known + //commenting it for now will uncomment once expected behaviour is known Iso.create( self.apiclient, self.testdata["iso2"], @@ -1691,3 +1699,188 @@ def test_01_disable_enable_host(self): ) return + + +class TestClusterDedication(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + testClient = super(TestClusterDedication, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.testdata = testClient.getParsedTestDataConfig() + cls.hypervisor = cls.testClient.getHypervisorInfo() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) + + cls.template = get_template( + cls.apiclient, + cls.zone.id, + cls.testdata["ostype"]) + + cls.Skiptest = False + cls._cleanup = [] + cls.clusters = Cluster.list(cls.apiclient, zoneid=cls.zone.id) + if len(cls.clusters) < 2: + cls.Skiptest = True + + try: + # Create an account + cls.account_1 = Account.create( + cls.apiclient, + cls.testdata["account"], + domainid=cls.domain.id + ) + + cls._cleanup.append(cls.account_1) + + cls.account_2 = Account.create( + cls.apiclient, + cls.testdata["account"], + domainid=cls.domain.id + ) + + cls._cleanup.append(cls.account_2) + # Create user api client of the account + cls.userapiclient_1 = testClient.getUserApiClient( + UserName=cls.account_1.name, + DomainName=cls.account_1.domain + ) + cls.userapiclient_2 = testClient.getUserApiClient( + UserName=cls.account_2.name, + DomainName=cls.account_2.domain + ) + + # Create Service offering + cls.service_offering = ServiceOffering.create( + cls.apiclient, + cls.testdata["service_offering"], + ) + cls._cleanup.append(cls.service_offering) + + cls.disk_offering = DiskOffering.create( + cls.apiclient, + cls.testdata["disk_offering"], + ) + + cls._cleanup.append(cls.disk_offering) + + except Exception as e: + cls.tearDownClass() + raise e + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.apiclient, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def setUp(self): + + if self.Skiptest: + self.skipTest("Insufficient clusters to run the test") + + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + def tearDown(self): + try: + listClusterscmd = listDedicatedClusters.listDedicatedClustersCmd() + listClusterscmd.clusterid = self.clusters[0].id + ret_list = self.apiclient.listDedicatedClusters(listClusterscmd) + if ret_list: + dedicateCmd = releaseDedicatedCluster.\ + releaseDedicatedClusterCmd() + dedicateCmd.clusterid = self.clusters[0].id + self.apiclient.releaseDedicatedCluster(dedicateCmd) + + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(tags=["basic", "advanced"], required_hardware="false") + def test_01_dedicated_cluster_allocation(self): + """ Dedicated cluster and router allocation + 1. Dedicate a cluster to one account + 2. Deploy a VM on dedicated account + 3. Deploy another VM on another account. + 4. Verify the dedicated cluster is not used for + virtual routers that belong to non-dedicated account + """ + + # Step 1 + dedicateCmd = dedicateCluster.dedicateClusterCmd() + dedicateCmd.clusterid = self.clusters[0].id + dedicateCmd.domainid = self.domain.id + dedicateCmd.account = self.account_1.name + self.apiclient.dedicateCluster(dedicateCmd) + + afcmd = listAffinityGroups.listAffinityGroupsCmd() + afcmd.account = self.account_1.name + afcmd.domainid = self.account_1.domainid + affinitygr_list = self.apiclient.listAffinityGroups(afcmd) + + # Step 2 + self.vm = VirtualMachine.create( + self.userapiclient_1, + self.testdata["small"], + templateid=self.template.id, + accountid=self.account_1.name, + domainid=self.account_1.domainid, + serviceofferingid=self.service_offering.id, + affinitygroupids=[affinitygr_list[0].id], + zoneid=self.zone.id, + mode=self.zone.networktype + ) + # Steps to verify if VM is created on dedicated account + vmlist = list_virtual_machines(self.apiclient, + id=self.vm.id) + + hostlist = list_hosts(self.apiclient, + id=vmlist[0].hostid) + + self.assertEqual(hostlist[0].clusterid, + self.clusters[0].id, + "check if vm gets deployed on dedicated clusture" + ) + # Step 3 + self.vm_1 = VirtualMachine.create( + self.userapiclient_2, + self.testdata["small"], + templateid=self.template.id, + accountid=self.account_2.name, + domainid=self.account_2.domainid, + serviceofferingid=self.service_offering.id, + zoneid=self.zone.id, + mode=self.zone.networktype + ) + + # Steps to verify if VM is created on dedicated account + vmlist_1 = list_virtual_machines(self.apiclient, + id=self.vm_1.id) + + hostlist_1 = list_hosts(self.apiclient, + id=vmlist_1[0].hostid) + + self.assertNotEqual(hostlist_1[0].clusterid, + self.clusters[0].id, + "check if vm gets deployed on correct clusture" + ) + + # Step 4 + routerList = list_routers(self.apiclient, + clusterid=self.clusters[0].id, + networkid=self.vm_1.nic[0].networkid + ) + self.assertEqual( + routerList, + None, + "Check Dedicated cluster is used for virtual routers \ + that belong to non-dedicated account") + + return diff --git a/test/integration/component/test_invalid_gw_nm.py b/test/integration/component/test_invalid_gw_nm.py new file mode 100644 index 000000000000..eb4043a28247 --- /dev/null +++ b/test/integration/component/test_invalid_gw_nm.py @@ -0,0 +1,127 @@ +# 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. +""" BVT tests for Network Life Cycle +""" + +from marvin.cloudstackTestCase import cloudstackTestCase +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (Account, + Network, + NetworkOffering + ) +from marvin.lib.common import (get_domain, + get_zone + ) +from nose.plugins.attrib import attr + + +class TestIsolatedNetworkInvalidGw(cloudstackTestCase): + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + + @classmethod + def setUpClass(cls): + testClient = super(TestIsolatedNetworkInvalidGw, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) + cls.services['mode'] = cls.zone.networktype + # Create Accounts + cls.account = Account.create( + cls.apiclient, + cls.services["account"], + admin=True, + domainid=cls.domain.id + ) + + cls.services["network"]["zoneid"] = cls.zone.id + + cls.network_offering = NetworkOffering.create( + cls.apiclient, + cls.services["network_offering"], + ) + # Enable Network offering + cls.network_offering.update(cls.apiclient, state='Enabled') + + cls.services["network"]["networkoffering"] = cls.network_offering.id + cls._cleanup = [ + cls.account, + cls.network_offering + ] + return + + @classmethod + def tearDownClass(cls): + try: + # Cleanup resources used + cleanup_resources(cls.apiclient, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(tags=["advanced", "advancedns", "smoke", "dvs"], required_hardware="false") + def test_isolated_nw_invalid_gw(self): + + self.debug("Trying to create a network with Gateway as 192.168.3.0. This should fail") + with self.assertRaises(Exception): + Network.create( + self.apiclient, + self.services["network"], + self.account.name, + self.account.domainid, + gateway="192.168.3.0", + netmask="255.255.255.0", + ) + + self.debug("Trying to create a network with Gateway as 192.168.3.255") + with self.assertRaises(Exception): + Network.create( + self.apiclient, + self.services["network"], + self.account.name, + self.account.domainid, + gateway="192.168.3.255", + netmask="255.255.255.0" + ) + + self.debug("Trying to create a network with Gateway as 192.168.3.0 and Subnet mask as 255.0.255.0") + with self.assertRaises(Exception): + Network.create( + self.apiclient, + self.services["network"], + self.account.name, + self.account.domainid, + gateway="192.168.3.0", + netmask="255.0.255.0", + ) + + self.debug("Trying to create a network with Subnet mask as 255.0.255.0") + with self.assertRaises(Exception): + Network.create( + self.apiclient, + self.services["network"], + self.account.name, + self.account.domainid, + gateway="192.168.3.1", + netmask="255.0.255.0", + ) + return + diff --git a/test/integration/component/test_nuage_vsp.py b/test/integration/component/test_nuage_vsp.py deleted file mode 100644 index e7bd10e20193..000000000000 --- a/test/integration/component/test_nuage_vsp.py +++ /dev/null @@ -1,334 +0,0 @@ -# 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. - -""" P1 tests for NuageVsp network Plugin -""" -# Import Local Modules -from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.cloudstackAPI import (listPhysicalNetworks, - listNetworkServiceProviders, - addNetworkServiceProvider, - deleteNetworkServiceProvider, - deleteNuageVspDevice, - updateNetworkServiceProvider, - addNuageVspDevice, - destroyVirtualMachine) -from marvin.lib.utils import (cleanup_resources) -from marvin.lib.base import (Account, - VirtualMachine, - ServiceOffering, - NetworkOffering, - Network) -from marvin.lib.common import (get_domain, - get_zone, - get_template) - -import logging -import unittest - - -class Services: - - """Test NuageVsp plugin - """ - - def __init__(self): - print "in __init__" - self.services = { - "account": { - "email": "cloudstack@cloudmonkey.com", - "firstname": "cloudstack", - "lastname": "bob", - "username": "admin", - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 128, # In MBs - }, - "virtual_machine": { - "displayname": "TestVM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'KVM', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "nuage_vsp_device": { - "hostname": '172.31.222.162', - "username": 'cloudstackuser1', - "password": 'cloudstackuser1', - "port": '8443', - "apiversion": 'v3_2', - "retrycount": '4', - "retryinterval": '60' - }, - # services supported by Nuage for isolated networks. - "network_offering": { - "name": 'nuage_marvin', - "displaytext": 'nuage_marvin', - "guestiptype": 'Isolated', - "supportedservices": - 'Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall', - "traffictype": 'GUEST', - "availability": 'Optional', - "serviceProviderList": { - "UserData": 'VirtualRouter', - "Dhcp": 'NuageVsp', - "Connectivity": 'NuageVsp', - "StaticNat": 'NuageVsp', - "SourceNat": 'NuageVsp', - "Firewall": 'NuageVsp' - }, - "serviceCapabilityList": { - "SourceNat": {"SupportedSourceNatTypes": "perzone"}, - } - }, - "network": { - "name": "nuage", - "displaytext": "nuage", - }, - "ostype": 'CentOS 5.5 (64-bit)', - "sleep": 60, - "timeout": 10 - } - - -class TestNuageVsp(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - print "In setup class" - cls._cleanup = [] - cls.testClient = super(TestNuageVsp, cls).getClsTestClient() - cls.api_client = cls.testClient.getApiClient() - - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client) - cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - # nuage vsp device brings the Nuage virtual service platform into play - cls.nuage_services = cls.services["nuage_vsp_device"] - try: - - resp = listPhysicalNetworks.listPhysicalNetworksCmd() - print "in cls.setupClass- resp: %s" % resp - resp.zoneid = cls.zone.id - physical_networks = cls.api_client.listPhysicalNetworks(resp) - for pn in physical_networks: - if pn.isolationmethods=='VSP': - physical_network = pn - #if isinstance(physical_networks, list): - # physical_network = physical_networks[1] - resp = listNetworkServiceProviders.listNetworkServiceProvidersCmd() - resp.name = 'NuageVsp' - resp.physicalnetworkid = physical_network.id - nw_service_providers = cls.api_client.listNetworkServiceProviders( - resp) - if not isinstance(nw_service_providers, list): - # create network service provider and add nuage vsp device - resp_add_nsp =\ - addNetworkServiceProvider.addNetworkServiceProviderCmd() - resp_add_nsp.name = 'NuageVsp' - resp_add_nsp.physicalnetworkid = physical_network.id - cls.api_client.addNetworkServiceProvider(resp_add_nsp) - #Get NSP ID - nw_service_providers = cls.api_client.listNetworkServiceProviders( - resp) - cls.debug("NuageVsp NSP ID: %s" % nw_service_providers[0].id) - - resp_add_device = addNuageVspDevice.addNuageVspDeviceCmd() - resp_add_device.physicalnetworkid = physical_network.id - resp_add_device.username = cls.nuage_services["username"] - resp_add_device.password = cls.nuage_services["password"] - resp_add_device.hostname = cls.nuage_services["hostname"] - resp_add_device.port = cls.nuage_services["port"] - resp_add_device.apiversion = cls.nuage_services[ - "apiversion"] - resp_add_device.retrycount = cls.nuage_services[ - "retrycount"] - resp_add_device.retryinterval = cls.nuage_services[ - "retryinterval"] - cls.nuage = cls.api_client.addNuageVspDevice( - resp_add_device) - #Enable NuageVsp NSP - cls.debug("NuageVsp NSP ID : %s" % nw_service_providers[0].id) - resp_up_nsp = \ - updateNetworkServiceProvider.updateNetworkServiceProviderCmd() - resp_up_nsp.id = nw_service_providers[0].id - resp_up_nsp.state = 'Enabled' - cls.api_client.updateNetworkServiceProvider(resp_up_nsp) - - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - cls._cleanup.append(cls.network_offering) - - cls.network_offering.update(cls.api_client, state='Enabled') - 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._cleanup.append(cls.service_offering) - except Exception as e: - cls.tearDownClass() - raise unittest.SkipTest("Unable to add VSP device") - return - - @classmethod - def tearDownClass(cls): - try: - 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 = [self.account] - return - - - def tearDown(self): - try: - self.debug("Cleaning up the resources") - cleanup_resources(self.apiclient, self.cleanup) - self.debug("Cleanup complete!") - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced"]) - def test_network_vsp(self): - """Test nuage Network and VM Creation - """ - - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - self.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, - gateway = "10.1.1.1", - netmask = '255.255.255.0' - ) - self.debug("Created network with ID: %s" % self.network.id) - - self.debug("Deploying VM in account: %s" % self.account.name) - - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - list_vm_response = VirtualMachine.list( - self.apiclient, - id=virtual_machine_1.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" - % virtual_machine_1.id - ) - - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - vm_response = list_vm_response[0] - - self.assertEqual( - vm_response.state, - "Running", - "VM state should be running after deployment" - ) - - self.debug("Deploying another VM in account: %s" % - self.account.name) - - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - list_vm_response = VirtualMachine.list( - self.apiclient, - id=virtual_machine_2.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" - % virtual_machine_2.id - ) - - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - vm_response = list_vm_response[0] - - self.assertEqual( - vm_response.state, - "Running", - "VM state should be running after deployment" - ) - - VirtualMachine.delete(virtual_machine_1, self.apiclient, expunge=True) - - # # Deleting a single VM - VirtualMachine.delete(virtual_machine_2, self.apiclient, expunge=True) - - # Delete Network - Network.delete(self.network, self.apiclient) - - return diff --git a/test/integration/component/test_persistent_networks.py b/test/integration/component/test_persistent_networks.py index ae1842451186..f8beed019e9b 100644 --- a/test/integration/component/test_persistent_networks.py +++ b/test/integration/component/test_persistent_networks.py @@ -17,7 +17,7 @@ """ Tests for Persistent Networks without running VMs feature""" from marvin.lib.utils import (cleanup_resources, validateList, - get_hypervisor_type) + get_hypervisor_type, get_process_status) from marvin.lib.base import (Account, VPC, VirtualMachine, @@ -40,7 +40,7 @@ get_template, verifyNetworkState, add_netscaler, - wait_for_cleanup) + wait_for_cleanup,list_routers,list_hosts) from nose.plugins.attrib import attr from marvin.codes import PASS, FAIL, FAILED from marvin.sshClient import SshClient @@ -1459,6 +1459,116 @@ def test_delete_account(self): return + @attr(tags=["advanced"], required_hardware="true") + def test_volume_delete_event_errorState(self): + """ + @summary: Test volume delete event generation in error state condition + @Steps: + Step1: Create a network using network created in Step1 + Step2: Verifying that network creation is successful + Step3: Login to Virtual router and add iptable rule to block insertion of vm rules + Step6: deploy a vm using network created in step2 + Step7: check the Vm status for failure + Step8: destroy and expunge the vm + Step9: list the generated events for volume delete event. + """ + + # Listing all the networks available + + account = Account.create( + self.api_client, + self.services["account"], + domainid=self.domain.id) + network = Network.create( + self.apiclient, + self.services["isolated_network"], + networkofferingid=self.isolated_persistent_network_offering.id, + accountid=self.account.name, + domainid=self.domain.id, + zoneid=self.zone.id) + response = verifyNetworkState( + self.apiclient, + network.id, + "implemented") + exceptionOccured = response[0] + isNetworkInDesiredState = response[1] + exceptionMessage = response[2] + + if (exceptionOccured or (not isNetworkInDesiredState)): + self.fail(exceptionMessage) + self.assertIsNotNone( + network.vlan, + "vlan must not be null for persistent network") + try: + list_router_response = list_routers( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid + ) + + self.assertEqual(validateList(list_router_response)[0], PASS, "Check list response returns a valid list") + router = list_router_response[0] + + self.debug("Router ID: %s, state: %s" % (router.id, router.state)) + + self.assertEqual( + router.state, + 'Running', + "Check list router response for router state" + ) + self.hypervisor = self.testClient.getHypervisorInfo() + if self.hypervisor.lower() in ('vmware', 'hyperv'): + result = get_process_status( + self.apiclient.connection.mgtSvr, + 22, + self.apiclient.connection.user, + self.apiclient.connection.passwd, + router.linklocalip, + "iptables -I INPUT 1 -j DROP", + hypervisor=self.hypervisor + ) + else: + try: + hosts = list_hosts( + self.apiclient, + zoneid=router.zoneid, + type='Routing', + state='Up', + id=router.hostid + ) + self.assertEqual(validateList(hosts)[0],PASS,"Check list host returns a valid list") + host = hosts[0] + result = get_process_status( + host.ipaddress,22, self.services["acl"]["host"]["username"],self.services["acl"]["host"]["password"], router.linklocalip, + "iptables -I INPUT 1 -j DROP" + ) + except Exception as e: + raise Exception("Exception raised in accessing/running the command on hosts : %s " % e) + except Exception as e: + raise Exception("Exception raised in getting hostcredentials: %s " % e) + + with self.assertRaises(Exception) as context: + virtual_machine = VirtualMachine.create( + self.apiclient, + self.services["virtual_machine"], + networkids=[ + network.id], + serviceofferingid=self.service_offering.id, + accountid=self.account.name, + domainid=self.domain.id) + #self.assertTrue('This is broken' in context.exception) + try: + account.delete(self.api_client) + except Exception as e: + self.cleanup.append(account) + qresultset = self.dbclient.execute( + "select id from usage_event where type = '%s' ORDER BY id DESC LIMIT 1;" % + str("VOLUME.DELETE")) + self.assertNotEqual( + len(qresultset), + 0, + "Check DB Query result set") + return @ddt class TestAssignVirtualMachine(cloudstackTestCase): diff --git a/test/integration/component/test_vpcnetwork_nuage.py b/test/integration/component/test_vpcnetwork_nuage.py deleted file mode 100644 index be76fa65ecb2..000000000000 --- a/test/integration/component/test_vpcnetwork_nuage.py +++ /dev/null @@ -1,295 +0,0 @@ -# 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 for NuageNetwork VPC -""" -#Import Local Modules -from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.lib.utils import (cleanup_resources) -from marvin.cloudstackAPI import (listPhysicalNetworks, - listNetworkServiceProviders, - addNetworkServiceProvider, - updateNetworkServiceProvider, - addNuageVspDevice, - destroyVirtualMachine) -from marvin.lib.base import (VirtualMachine, - ServiceOffering, - Account, - NetworkOffering, - Network, - VPC, - VpcOffering, - NetworkACL, - NetworkACLList) -from marvin.lib.common import (get_zone, - get_domain, - get_template, - wait_for_cleanup, - list_networks) - -from nose.plugins.attrib import attr - -class Services: - - """Test NuageVsp plugin - """ - - def __init__(self): - self.services = { - "account": { - "email": "cloudstack@cloudmonkey.com", - "firstname": "cloudstack", - "lastname": "bob", - "username": "admin", - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 128, # In MBs - }, - "virtual_machine": { - "displayname": "TestVM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'KVM', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "nuage_vsp_device": { - #"hostname": '192.168.0.7', - #"hostname": '10.31.43.226', - "hostname": '172.31.222.162', - "username": 'cloudstackuser1', - "password": 'cloudstackuser1', - "port": '8443', - "apiversion": 'v3_2', - "retrycount": '4', - "retryinterval": '60' - }, - # services supported by Nuage for VPC networks. - "vpc_network_offering": { - "name": 'nuage_vpc_marvin', - "displaytext": 'nuage_vpc_marvin', - "guestiptype": 'Isolated', - "supportedservices": 'UserData,Dhcp,SourceNat,StaticNat,NetworkACL,Connectivity', - "traffictype": 'GUEST', - "useVpc": 'on', - "serviceProviderList": { - "Dhcp": "NuageVsp", - "SourceNat": "NuageVsp", - "StaticNat": "NuageVsp", - "NetworkACL": "NuageVsp", - "UserData": "VpcVirtualRouter", - "Connectivity": "NuageVsp" - }, - "serviceCapabilityList": { - "SourceNat": {"SupportedSourceNatTypes": "perzone"} - } - }, - "vpc": { - "name": "vpc-networkacl-nuage", - "displaytext": "vpc-networkacl-nuage", - "cidr": '10.1.0.0/16' - }, - "vpcnetwork": { - "name": "nuagevpcnetwork", - "displaytext": "nuagevpcnetwork", - "netmask": '255.255.255.128' - }, - "ostype": 'CentOS 5.5 (64-bit)', - "sleep": 60, - "timeout": 10 - } - - -class TestVpcNetworkNuage(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - cls._cleanup = [] - cls.testClient = super(TestVpcNetworkNuage, cls).getClsTestClient() - cls.api_client = cls.testClient.getApiClient() - - cls.services = Services().services - # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client) - cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - # nuage vsp device brings the Nuage virtual service platform into play - cls.nuage_services = cls.services["nuage_vsp_device"] - try: - - resp = listPhysicalNetworks.listPhysicalNetworksCmd() - print "in cls.setupClass- resp: %s" % resp - resp.zoneid = cls.zone.id - physical_networks = cls.api_client.listPhysicalNetworks(resp) - for pn in physical_networks: - if pn.isolationmethods=='VSP': - physical_network = pn - #if isinstance(physical_networks, list): - # physical_network = physical_networks[1] - resp = listNetworkServiceProviders.listNetworkServiceProvidersCmd() - resp.name = 'NuageVsp' - resp.physicalnetworkid = physical_network.id - nw_service_providers = cls.api_client.listNetworkServiceProviders( - resp) - if not isinstance(nw_service_providers, list): - # create network service provider and add nuage vsp device - resp_add_nsp = \ - addNetworkServiceProvider.addNetworkServiceProviderCmd() - resp_add_nsp.name = 'NuageVsp' - resp_add_nsp.physicalnetworkid = physical_network.id - cls.api_client.addNetworkServiceProvider(resp_add_nsp) - #Get NSP ID - nw_service_providers = cls.api_client.listNetworkServiceProviders( - resp) - cls.debug("NuageVsp NSP ID: %s" % nw_service_providers[0].id) - - resp_add_device = addNuageVspDevice.addNuageVspDeviceCmd() - resp_add_device.physicalnetworkid = physical_network.id - resp_add_device.username = cls.nuage_services["username"] - resp_add_device.password = cls.nuage_services["password"] - resp_add_device.hostname = cls.nuage_services["hostname"] - resp_add_device.port = cls.nuage_services["port"] - resp_add_device.apiversion = cls.nuage_services[ - "apiversion"] - resp_add_device.retrycount = cls.nuage_services[ - "retrycount"] - resp_add_device.retryinterval = cls.nuage_services[ - "retryinterval"] - cls.nuage = cls.api_client.addNuageVspDevice( - resp_add_device) - #Enable NuageVsp NSP - cls.debug("NuageVsp NSP ID : %s" % nw_service_providers[0].id) - resp_up_nsp = \ - updateNetworkServiceProvider.updateNetworkServiceProviderCmd() - resp_up_nsp.id = nw_service_providers[0].id - resp_up_nsp.state = 'Enabled' - cls.api_client.updateNetworkServiceProvider(resp_up_nsp) - - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["vpc_network_offering"], - conservemode=False - ) - cls._cleanup.append(cls.network_offering) - - cls.network_offering.update(cls.api_client, state='Enabled') - 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._cleanup.append(cls.service_offering) - except Exception as e: - cls.tearDownClass() - raise unittest.SkipTest("Unable to add VSP device") - return - - @attr(tags=["advanced"]) - def test_vpcnetwork_nuage(self): - """Test network VPC for Nuage""" - - # 1) Create VPC with Nuage VPC offering - vpcOffering = VpcOffering.list(self.apiclient,name="Nuage VSP VPC offering") - self.assert_(vpcOffering is not None and len(vpcOffering)>0, "Nuage VPC offering not found") - vpc = VPC.create( - apiclient=self.apiclient, - services=self.services["vpc"], - networkDomain="vpc.networkacl", - vpcofferingid=vpcOffering[0].id, - zoneid=self.zone.id, - account=self.account.name, - domainid=self.account.domainid - ) - self.assert_(vpc is not None, "VPC creation failed") - - # 2) Create ACL - aclgroup = NetworkACLList.create(apiclient=self.apiclient, services={}, name="acl", description="acl", vpcid=vpc.id) - self.assertIsNotNone(aclgroup, "Failed to create NetworkACL list") - self.debug("Created a network ACL list %s" % aclgroup.name) - - # 3) Create ACL Item - aclitem = NetworkACL.create(apiclient=self.apiclient, services={}, - protocol="TCP", number="10", action="Deny", aclid=aclgroup.id, cidrlist=["0.0.0.0/0"]) - self.assertIsNotNone(aclitem, "Network failed to aclItem") - self.debug("Added a network ACL %s to ACL list %s" % (aclitem.id, aclgroup.name)) - - # 4) Create network with ACL - nwNuage = Network.create( - self.apiclient, - self.services["vpcnetwork"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id, - vpcid=vpc.id, - aclid=aclgroup.id, - gateway='10.1.0.1' - ) - self.debug("Network %s created in VPC %s" %(nwNuage.id, vpc.id)) - - # 5) Deploy a vm - vm = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(nwNuage.id)] - ) - self.assert_(vm is not None, "VM failed to deploy") - self.assert_(vm.state == 'Running', "VM is not running") - self.debug("VM %s deployed in VPC %s" %(vm.id, vpc.id)) - - @classmethod - def tearDownClass(cls): - try: - 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 = [self.account] - return - - def tearDown(self): - try: - self.debug("Cleaning up the resources") - cleanup_resources(self.apiclient, self.cleanup) - self.debug("Cleanup complete!") - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return diff --git a/test/integration/plugins/nuagevsp/__init__.py b/test/integration/plugins/nuagevsp/__init__.py new file mode 100644 index 000000000000..13a83393a912 --- /dev/null +++ b/test/integration/plugins/nuagevsp/__init__.py @@ -0,0 +1,16 @@ +# 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. diff --git a/test/integration/plugins/nuagevsp/nuageTestCase.py b/test/integration/plugins/nuagevsp/nuageTestCase.py new file mode 100644 index 000000000000..55199d5d8088 --- /dev/null +++ b/test/integration/plugins/nuagevsp/nuageTestCase.py @@ -0,0 +1,804 @@ +# 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. + +""" Custom base class for NuageVsp SDN Plugin specific Marvin tests +""" +# Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.lib.base import (NetworkServiceProvider, + ServiceOffering, + NetworkOffering, + Network, + Router, + Nuage, + VPC, + VpcOffering, + PublicIPAddress, + VirtualMachine, + StaticNATRule, + NetworkACLList, + NetworkACL, + FireWallRule, + EgressFireWallRule, + Host) +from marvin.lib.common import (get_zone, + get_domain, + get_template, + list_templates, + wait_for_cleanup) +from marvin.lib.utils import cleanup_resources +from marvin.cloudstackAPI import (listPhysicalNetworks, + updateConfiguration, + updateTemplate, + listConfigurations, + listHypervisors, + stopRouter, + startRouter) +# Import System Modules +import socket +import importlib +import logging + + +class nuageTestCase(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.debug("setUpClass nuageTestCase") + + # We want to fail quicker, if it's a failure + socket.setdefaulttimeout(60) + + test_client = super(nuageTestCase, cls).getClsTestClient() + cls.api_client = test_client.getApiClient() + cls.db_client = test_client.getDbConnection() + cls.test_data = test_client.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.zone = get_zone(cls.api_client) + cls.domain = get_domain(cls.api_client) + cls.template = get_template(cls.api_client, + cls.zone.id, + cls.test_data["ostype"] + ) + cls.test_data["virtual_machine"]["zoneid"] = cls.zone.id + cls.test_data["virtual_machine"]["template"] = cls.template.id + + # Create service offering + cls.service_offering = ServiceOffering.create(cls.api_client, + cls.test_data["service_offering"] + ) + cls._cleanup = [cls.service_offering] + + # Get configured Nuage Vsp device details + try: + resp = listPhysicalNetworks.listPhysicalNetworksCmd() + resp.zoneid = cls.zone.id + physical_networks = cls.api_client.listPhysicalNetworks(resp) + for pn in physical_networks: + if pn.isolationmethods == 'VSP': + cls.vsp_physical_network = pn + break + cls.nuage_vsp_device = Nuage.list(cls.api_client, + physicalnetworkid=cls.vsp_physical_network.id + )[0] + pns = cls.config.zones[0].physical_networks + providers = filter(lambda physical_network: 'VSP' in physical_network.isolationmethods, pns)[0].providers + devices = filter(lambda provider: provider.name == 'NuageVsp', providers)[0].devices + cls.nuage_vsp_device.username = devices[0].username + cls.nuage_vsp_device.password = devices[0].password + listConfigurationsCmd = listConfigurations.listConfigurationsCmd() + listConfigurationsCmd.name = "nuagevsp.cms.id" + listConfigurationsCmd.scopename = "global" + cs_config_dict = cls.api_client.listConfigurations(listConfigurationsCmd) + cls.cms_id = str(cs_config_dict[0].value).split(":")[1] + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Warning: Couldn't get configured Nuage Vsp device details: %s" % e) + + # Check if the host hypervisor type is simulator + resp = listHypervisors.listHypervisorsCmd() + resp.zoneid = cls.zone.id + cls.isSimulator = cls.api_client.listHypervisors(resp)[0].name == 'Simulator' + + # VSD is a Python SDK for Nuage Vsp + try: + vspk_module = "vspk." + cls.nuage_vsp_device.apiversion if int(cls.nuage_vsp_device.apiversion[1]) >= 4 \ + else "vspk.vsdk." + cls.nuage_vsp_device.apiversion + vsdk = importlib.import_module(vspk_module) + vspk_utils_module = "vspk.utils" if int(cls.nuage_vsp_device.apiversion[1]) >= 4 \ + else "vspk.vsdk." + cls.nuage_vsp_device.apiversion + ".utils" + vsdk_utils = importlib.import_module(vspk_utils_module) + set_log_level = getattr(vsdk_utils, "set_log_level") + from cms_vspk_wrapper.cms_vspk_wrapper import Cms_vspk_wrapper + except: + raise unittest.SkipTest("vspk (and/or) cms_vspk_wrapper import failure") + + # Configure VSD session + cls._session = vsdk.NUVSDSession(username=cls.nuage_vsp_device.username, + password=cls.nuage_vsp_device.password, + enterprise="csp", api_url="https://%s:%d" % + (cls.nuage_vsp_device.hostname, + cls.nuage_vsp_device.port) + ) + cls._session.start() + + # Configure cms_vspk_wrapper session + cls.log_handler = logging.getLogger("CSLog").handlers[0] + vsd_info = cls.nuage_vsp_device.__dict__ + vsd_info["port"] = str(vsd_info["port"]) + cls.vsd = Cms_vspk_wrapper(vsd_info, cls.log_handler) + + set_log_level(logging.INFO) + + cls.debug("setUpClass nuageTestCase [DONE]") + + def setUp(self): + self.cleanup = [] + return + + @classmethod + def tearDownClass(cls): + try: + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + cls.debug("Warning: Exception during cleanup : %s" % e) + return + + def tearDown(self): + # Cleanup resources used + self.debug("Cleaning up the resources") + for obj in reversed(self.cleanup): + try: + if isinstance(obj, VirtualMachine): + obj.delete(self.api_client, expunge=True) + else: + obj.delete(self.api_client) + except Exception as e: + self.error("Failed to cleanup %s, got %s" % (obj, e)) + # cleanup_resources(self.api_client, self.cleanup) + self.cleanup = [] + self.debug("Cleanup complete!") + return + + def getConfigurationValue(self, name, scope="global"): + listConfigurationsCmd = listConfigurations.listConfigurationsCmd() + listConfigurationsCmd.name = name + listConfigurationsCmd.scopename = scope + if scope is "zone": + listConfigurationsCmd.zoneid = self.zone.id + return self.api_client.listConfigurations(listConfigurationsCmd) + + def setConfigurationValue(self, name, value, scope="global"): + cmd = updateConfiguration.updateConfigurationCmd() + cmd.name = name + cmd.scopename = scope + if scope is "zone": + cmd.zoneid = self.zone.id + cmd.value = value + self.api_client.updateConfiguration(cmd) + + def updateTemplate(self, value): + self.debug("UPDATE TEMPLATE") + cmd = updateTemplate.updateTemplateCmd() + cmd.id = self.template.id + cmd.passwordenabled = value + self.api_client.updateTemplate(cmd) + list_template_response = list_templates(self.api_client, + templatefilter="all", + id=self.template.id + ) + self.template = list_template_response[0] + + # Creates the vpc offering + def create_VpcOffering(self, vpc_offering, suffix=None): + self.debug('Create VpcOffering') + if suffix: + vpc_offering["name"] = "VPC_OFF-" + str(suffix) + vpc_off = VpcOffering.create(self.api_client, + vpc_offering + ) + # Enable VPC offering + vpc_off.update(self.api_client, state='Enabled') + self.cleanup.append(vpc_off) + self.debug('Created and Enabled VpcOffering') + return vpc_off + + # create_Vpc - Takes the vpc offering as arguments and creates the VPC + def create_Vpc(self, vpc_offering, cidr='10.1.1.1/16', cleanup=True): + self.debug("Creating a VPC network in the account: %s" % self.account.name) + self.test_data["vpc"]["cidr"] = cidr + vpc = VPC.create( + self.api_client, + self.test_data["vpc"], + vpcofferingid=vpc_offering.id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.debug("Created VPC with ID: %s" % vpc.id) + if cleanup: + self.cleanup.append(vpc) + return vpc + + # create_NetworkOffering - Takes the network offering as argument and creates the Network Offering + def create_NetworkOffering(self, net_offering, suffix=None, conserve_mode=False): + self.debug('Create NetworkOffering') + if suffix: + net_offering["name"] = "NET_OFF-" + str(suffix) + nw_off = NetworkOffering.create(self.api_client, + net_offering, + conservemode=conserve_mode + ) + # Enable Network offering + nw_off.update(self.api_client, state='Enabled') + self.cleanup.append(nw_off) + self.debug('Created and Enabled NetworkOffering') + return nw_off + + # create_Network - Takes the network offering as argument and nw_key and creates the network + def create_Network(self, nw_off, nw_key="network", gateway='10.1.1.1', netmask='255.255.255.0', vpc=None, acl_list=None): + if not hasattr(nw_off, "id"): + nw_off = self.create_NetworkOffering(nw_off) + self.debug('Adding Network=%s' % self.test_data[nw_key]) + self.test_data[nw_key]["netmask"] = netmask + obj_network = Network.create(self.api_client, + self.test_data[nw_key], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=nw_off.id, + zoneid=self.zone.id, + gateway=gateway, + vpcid=vpc.id if vpc else self.vpc.id if hasattr(self, "vpc") else None, + aclid=acl_list.id if acl_list else None + ) + self.debug("Created network with ID: %s" % obj_network.id) + self.cleanup.append(obj_network) + return obj_network + + # upgrade_Network - Upgrades the given network + def upgrade_Network(self, nw_off, network): + if not hasattr(nw_off, "id"): + nw_off = self.create_NetworkOffering(nw_off, network.gateway) + self.debug('Update Network=%s' % network) + network.update( + self.api_client, + networkofferingid=nw_off.id, + changecidr=False + ) + self.debug("Updated network with ID: %s" % network.id) + + # delete_Network - Deletes the given network + def delete_Network(self, network): + self.debug('Deleting Network - %s' % network.name) + # Wait for network garbage collection before network deletion + wait_for_cleanup(self.api_client, + ["network.gc.interval", "network.gc.wait"] + ) + network.delete(self.api_client) + if network in self.cleanup: + self.cleanup.remove(network) + self.debug('Deleted Network - %s' % network.name) + + # create_VM_in_Network - Creates a VM in the given network, the vm_key - is the key for the services on the vm. + def create_VM_in_Network(self, network, vm_key="virtual_machine", host_id=None, start_vm=True): + self.debug('Creating VM in network=%s' % network.name) + self.debug('Passed vm_key=%s' % vm_key) + self.test_data[vm_key]["zoneid"] = self.zone.id + self.test_data[vm_key]["template"] = self.template.id + vm = VirtualMachine.create( + self.api_client, + self.test_data[vm_key], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)], + startvm=start_vm, + hostid=host_id + ) + self.debug('Created VM=%s in network=%s' % (vm.id, network.name)) + self.cleanup.append(vm) + return vm + + # delete_VM - Deletes the given VM + def delete_VM(self, vm): + self.debug('Deleting VM - %s' % vm.name) + vm.delete(self.api_client) + # Wait for expunge interval to cleanup VM + wait_for_cleanup(self.api_client, + ["expunge.delay", "expunge.interval"] + ) + if vm in self.cleanup: + self.cleanup.remove(vm) + self.debug('Deleted VM - %s' % vm.name) + + # acquire_Public_IP - Acquires a public IP for the given network + def acquire_Public_IP(self, network, vpc=None): + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create(self.api_client, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id if vpc is None else None, + vpcid=vpc.id if vpc else self.vpc.id if hasattr(self, "vpc") else None + ) + self.debug("Associated %s with network %s" % (public_ip.ipaddress.ipaddress, + network.id)) + return public_ip + + # create_StaticNatRule_For_VM - Creates static NAT rule for the given network , VM on the given public ip + def create_StaticNatRule_For_VM(self, vm, public_ip, network, vmguestip=None): + self.debug("Enabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + StaticNATRule.enable( + self.api_client, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=vm.id, + networkid=network.id, + vmguestip=vmguestip + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip.ipaddress.ipaddress) + + # delete_StaticNatRule_For_VM - Deletes the static NAT rule for the given VM + def delete_StaticNatRule_For_VM(self, vm, public_ip): + self.debug("Disabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + StaticNATRule.disable( + self.api_client, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=vm.id + ) + self.debug("Static NAT disabled for IP: %s" % + public_ip.ipaddress.ipaddress) + + # create_firewall_rule - Creates the Ingress firewall rule on the given public ip + def create_firewall_rule(self, public_ip, rule=None): + if not rule: + rule = self.test_data["ingress_rule"] + self.debug("Adding an Ingress Firewall rule to make Guest VMs accessible through Static NAT") + return FireWallRule.create(self.api_client, + ipaddressid=public_ip.ipaddress.id, + protocol=rule["protocol"], + cidrlist=rule["cidrlist"], + startport=rule["startport"], + endport=rule["endport"] + ) + + # create_egress_firewall_rule - Creates the Egress firewall rule on the given public ip + def create_egress_firewall_rule(self, network, rule): + self.debug("Adding an Egress Firewall rule to allow/deny outgoing traffic from Guest VMs") + return EgressFireWallRule.create(self.api_client, + networkid=network.id, + protocol=rule["protocol"], + cidrlist=rule["cidrlist"], + startport=rule["startport"], + endport=rule["endport"] + ) + + # create_network_acl_list - Creates network ACL list in the given VPC + def create_network_acl_list(self, name, description, vpc): + self.debug("Adding NetworkACL list in VPC: %s" % vpc.id) + return NetworkACLList.create(self.api_client, + services={}, + name=name, + description=description, + vpcid=vpc.id + ) + + # create_network_acl_rule - Creates network ACL rule Ingree/Egress in the given network + def create_network_acl_rule(self, rule, traffic_type="Ingress", network=None, acl_list=None): + self.debug("Adding NetworkACL rule: %s" % rule) + return NetworkACL.create(self.api_client, + networkid=network.id if network else None, + services=rule, + traffictype=traffic_type, + aclid=acl_list.id if acl_list else None + ) + + # migrate_vm - Migrates the VM to a different host if available + def migrate_vm(self, vm): + self.debug("Checking if a host is available for migration?") + hosts = Host.listForMigration(self.api_client) + self.assertEqual(isinstance(hosts, list), True, + "List hosts should return a valid list" + ) + # Remove the host of current VM from the hosts list + hosts[:] = [host for host in hosts if host.id != vm.hostid] + if len(hosts) <= 0: + self.skipTest("No host available for migration. Test requires at-least 2 hosts") + host = hosts[0] + self.debug("Migrating VM-ID: %s to Host: %s" % (vm.id, host.id)) + try: + vm.migrate(self.api_client, hostid=host.id) + except Exception as e: + self.fail("Failed to migrate instance, %s" % e) + + # get_network_router - returns the router for the given network + def get_network_router(self, network): + self.debug("Finding the virtual router for network: %s" % network.name) + routers = Router.list(self.api_client, + networkid=network.id, + listall=True + ) + self.assertEqual(isinstance(routers, list), True, + "List routers should return a valid virtual router for network" + ) + return routers[0] + + # stop_network_router - Stops the given network router + def stop_network_router(self, router): + self.debug("Stopping Router with ID: %s" % router.id) + cmd = stopRouter.stopRouterCmd() + cmd.id = router.id + self.api_client.stopRouter(cmd) + + # start_network_router - Starts the given network router + def start_network_router(self, router): + self.debug("Starting Router with ID: %s" % router.id) + cmd = startRouter.startRouterCmd() + cmd.id = router.id + self.api_client.startRouter(cmd) + + # ssh_into_vm - Gets into the shell of the given VM + def ssh_into_vm(self, vm, public_ip): + self.debug("SSH into VM=%s on public_ip=%s" % (vm.name, public_ip.ipaddress.ipaddress)) + ssh_client = vm.get_ssh_client(ipaddress=public_ip.ipaddress.ipaddress) + return ssh_client + + # execute_cmd - Executes the given command on the given ssh client + def execute_cmd(self, ssh_client, cmd): + self.debug("EXECUTE SSH COMMAND: " + cmd) + ret_data = "" + out_list = ssh_client.execute(cmd) + if out_list is not None: + ret_data = ' '.join(map(str, out_list)).strip() + self.debug("ssh execute cmd result=" + ret_data) + else: + self.debug("ssh execute cmd result is None") + return ret_data + + # wget_from_server - fetches the index.html file from the given public Ip + def wget_from_server(self, public_ip): + import urllib + self.debug("wget from a http server on public_ip=%s" % public_ip.ipaddress.ipaddress) + wget_file = urllib.urlretrieve("http://%s/index.html" % public_ip.ipaddress.ipaddress, + filename="index.html" + ) + return wget_file + + # validate_NetworkServiceProvider - Validates the Network Service Provider + # in the Nuage VSP Physical Network - matches the given provider name + # against the list of providers fetched + def validate_NetworkServiceProvider(self, provider_name, state=None): + """Validates the Network Service Provider in the Nuage VSP Physical Network""" + self.debug("Check if the Network Service Provider is created successfully ?") + providers = NetworkServiceProvider.list(self.api_client, + name=provider_name, + physicalnetworkid=self.vsp_physical_network.id) + self.assertEqual(isinstance(providers, list), True, + "List Network Service Provider should return a valid list" + ) + self.assertEqual(provider_name, providers[0].name, + "Name of the Network Service Provider should match with the returned list data" + ) + if state: + self.assertEqual(providers[0].state, state, + "Network Service Provider state should be '%s'" % state + ) + self.debug("Network Service Provider creation successfully validated - %s" % provider_name) + + # validate_vpc_offering - Validates the VPC offering, matches the given VPC off name against the list of VPC offerings fetched + def validate_vpc_offering(self, vpc_offering, state=None): + """Validates the VPC offering""" + self.debug("Check if the VPC offering is created successfully ?") + vpc_offs = VpcOffering.list(self.api_client, + id=vpc_offering.id + ) + self.assertEqual(isinstance(vpc_offs, list), True, + "List VPC offering should return a valid list" + ) + self.assertEqual(vpc_offering.name, vpc_offs[0].name, + "Name of the VPC offering should match with the returned list data" + ) + if state: + self.assertEqual(vpc_offs[0].state, state, + "VPC offering state should be '%s'" % state + ) + self.debug("VPC offering creation successfully validated - %s" % vpc_offering.name) + + # validate_vpc - Validates the given VPC matches, the given VPC name against the list of VPCs fetched + def validate_vpc(self, vpc, state=None): + """Validates the VPC""" + self.debug("Check if the VPC is created successfully ?") + vpcs = VPC.list(self.api_client, + id=vpc.id + ) + self.assertEqual(isinstance(vpcs, list), True, + "List VPC should return a valid list" + ) + self.assertEqual(vpc.name, vpcs[0].name, + "Name of the VPC should match with the returned list data" + ) + if state: + self.assertEqual(vpcs[0].state, state, + "VPC state should be '%s'" % state + ) + self.debug("VPC creation successfully validated - %s" % vpc.name) + + # validate_network_offering - Validates the given Network offering + # matches the given network offering name against the list of network + # offerings fetched + def validate_network_offering(self, net_offering, state=None): + """Validates the Network offering""" + self.debug("Check if the Network offering is created successfully ?") + net_offs = NetworkOffering.list(self.api_client, + id=net_offering.id + ) + self.assertEqual(isinstance(net_offs, list), True, + "List Network offering should return a valid list" + ) + self.assertEqual(net_offering.name, net_offs[0].name, + "Name of the Network offering should match with the returned list data" + ) + if state: + self.assertEqual(net_offs[0].state, state, + "Network offering state should be '%s'" % state + ) + self.debug("Network offering creation successfully validated - %s" % net_offering.name) + + # validate_network - Validates the network - matches the given network name against the list of networks fetched + def validate_network(self, network, state=None): + """Validates the network""" + self.debug("Check if the network is created successfully ?") + networks = Network.list(self.api_client, + id=network.id + ) + self.assertEqual(isinstance(networks, list), True, + "List network should return a valid list" + ) + self.assertEqual(network.name, networks[0].name, + "Name of the network should match with with the returned list data" + ) + if state: + self.assertEqual(networks[0].state, state, + "Network state should be '%s'" % state + ) + self.debug("Network creation successfully validated - %s" % network.name) + + # check_router_state - Fetches the list of routers and their states and matches the given router's state + def check_router_state(self, router, state=None): + self.debug("Check if the virtual router is in state - %s" % state) + routers = Router.list(self.api_client, + id=router.id, + listall=True + ) + self.assertEqual(isinstance(routers, list), True, + "List router should return a valid list" + ) + if state: + self.assertEqual(routers[0].state, state, + "Virtual router is not in the expected state" + ) + self.debug("Virtual router is in the expected state - %s" % state) + + # check_vm_state - Fetches the list of VMs and their states and matches the given VM's state + def check_vm_state(self, vm, state=None): + self.debug("Check if the VM instance is in state - %s" % state) + vms = VirtualMachine.list(self.api_client, + id=vm.id, + listall=True + ) + self.assertEqual(isinstance(vms, list), True, + "List virtual machine should return a valid list" + ) + if state: + self.assertEqual(vms[0].state, state, + "Virtual machine is not in the expected state" + ) + self.debug("Virtual machine is in the expected state - %s" % state) + + # validate_Public_IP - Looks if the given public ip is in the allocated state form the list of fetched public IPs + def validate_Public_IP(self, public_ip, network, static_nat=False, vm=None): + """Validates the Public IP""" + self.debug("Check if the Public IP is successfully assigned to the network ?") + public_ips = PublicIPAddress.list(self.api_client, + id=public_ip.ipaddress.id, + networkid=network.id, + isstaticnat=static_nat, + listall=True + ) + self.assertEqual(isinstance(public_ips, list), True, + "List public Ip for network should return a valid list" + ) + self.assertEqual(public_ips[0].ipaddress, public_ip.ipaddress.ipaddress, + "List public Ip for network should list the assigned public Ip address" + ) + self.assertEqual(public_ips[0].state, "Allocated", + "Assigned public Ip is not in the allocated state" + ) + if static_nat and vm: + self.assertEqual(public_ips[0].virtualmachineid, vm.id, + "Static NAT Rule not enabled for the VM using the assigned public Ip" + ) + self.debug("Assigned Public IP is successfully validated - %s" % public_ip.ipaddress.ipaddress) + + # VSD verifications + + def fetch_by_external_id(self, fetcher, *cs_objects): + """ Fetches a child object by external id using the given fetcher, and uuids of the given cloudstack objects. + E.G. + - fetch_by_external_id(vsdk.NUSubnet(id="954de425-b860-410b-be09-c560e7dbb474").vms, cs_vm) + - fetch_by_external_id(session.user.floating_ips, cs_network, cs_public_ip) + :param fetcher: VSPK Fetcher to use to find the child entity + :param cs_objects: Cloudstack objects to take the UUID from. + :return: the VSPK object having the correct externalID + """ + return fetcher.get_first(filter="externalID BEGINSWITH '%s'" % ":".join([o.id for o in cs_objects])) + + # VSD verifications using cms_vspk_wrapper + + def get_externalID(self, object_id): + return object_id + "@" + self.cms_id + + # verify_vsp_network - Fetches the vsd domain, vsd zone and vsd subnet and Verifies the given network/VPC values match the fetched values + def verify_vsp_network(self, domain_id, network, vpc=None): + vsd_enterprise = self.vsd.get_enterprise(name=domain_id) + if vpc: + ext_network_id = self.get_externalID(vpc.id) + else: + ext_network_id = self.get_externalID(network.id) + ext_subnet_id = self.get_externalID(network.id) + vsd_domain = self.vsd.get_domain(externalID=ext_network_id) + vsd_zone = self.vsd.get_zone(externalID=ext_network_id) + vsd_subnet = self.vsd.get_subnet(externalID=ext_subnet_id) + self.debug("SHOW ENTERPRISE DATA FORMAT IN VSD") + self.debug(vsd_enterprise) + self.assertNotEqual(vsd_enterprise, None, + "VSD Enterprise data format should not be a None type" + ) + self.debug("SHOW NETWORK DATA FORMAT IN VSD") + self.debug(vsd_domain) + self.debug(vsd_zone) + self.debug(vsd_subnet) + if vpc: + self.assertEqual(vsd_domain['description'], "VPC_" + vpc.name, + "VSD domain description should match VPC name in CloudStack" + ) + self.assertEqual(vsd_zone['description'], "VPC_" + vpc.name, + "VSD zone description should match VPC name in CloudStack" + ) + else: + self.assertEqual(vsd_domain['description'], network.name, + "VSD domain description should match Isolated Network name in CloudStack" + ) + self.assertEqual(vsd_zone['description'], network.name, + "VSD zone description should match Isolated Network name in CloudStack" + ) + self.assertEqual(vsd_subnet['description'], network.name, + "VSD subnet description should match Isolated Network name in CloudStack" + ) + + # verify_vsp_vm - Fetches the vsd vport, vsd vm and interface and Verifies the given VM values match the fetched values + def verify_vsp_vm(self, vm, stopped=None): + ext_vm_id = self.get_externalID(vm.id) + for nic in vm.nic: + ext_network_id = self.get_externalID(nic.networkid) + ext_nic_id = self.get_externalID(nic.id) + vsd_vport = self.vsd.get_vport(subnet_externalID=ext_network_id, vport_externalID=ext_nic_id) + vsd_vm_interface = self.vsd.get_vm_interface(externalID=ext_nic_id) + self.debug("SHOW VPORT and VM INTERFACE DATA FORMAT IN VSD") + self.debug(vsd_vport) + self.debug(vsd_vm_interface) + self.assertEqual(vsd_vport['active'], True, + "VSD VM vport should be active" + ) + self.assertEqual(vsd_vm_interface['IPAddress'], nic.ipaddress, + "VSD VM interface IP address should match VM's NIC IP address in CloudStack" + ) + vsd_vm = self.vsd.get_vm(externalID=ext_vm_id) + self.debug("SHOW VM DATA FORMAT IN VSD") + self.debug(vsd_vm) + if not self.isSimulator: + if stopped: + self.assertEqual(vsd_vm['status'], "DELETE_PENDING", + "VM state in VSD should be DELETE_PENDING" + ) + else: + self.assertEqual(vsd_vm['status'], vm.state.upper(), + "VM state in VSD should match its state in CloudStack" + ) + # verify_vsp_router - Fetches the vsd router and Verifies the given router status match the fetched status + + def verify_vsp_router(self, router, stopped=None): + ext_router_id = self.get_externalID(router.id) + vsd_router = self.vsd.get_vm(externalID=ext_router_id) + self.debug("SHOW VIRTUAL ROUTER DATA FORMAT IN VSD") + self.debug(vsd_router) + if not self.isSimulator: + if stopped: + self.assertEqual(vsd_router['status'], "DELETE_PENDING", + "Router state in VSD should be DELETE_PENDING" + ) + else: + self.assertEqual(vsd_router['status'], router.state.upper(), + "Router state in VSD should match its state in CloudStack" + ) + + # verify_vsp_floating_ip - Verifies the floating IPs on the given public IP against the VSD FIP + def verify_vsp_floating_ip(self, network, vm, public_ipaddress, vpc=None): + ext_fip_id = self.get_externalID(network.id + ":" + public_ipaddress.id) + vsd_fip = self.vsd.get_floating_ip(externalID=ext_fip_id) + self.debug("SHOW FLOATING IP DATA FORMAT IN VSD") + self.debug(vsd_fip) + self.assertEqual(vsd_fip['address'], public_ipaddress.ipaddress, + "Floating IP address in VSD should match acquired Public IP address in CloudStack" + ) + if vpc: + ext_network_id = self.get_externalID(vpc.id) + else: + ext_network_id = self.get_externalID(network.id) + vsd_domain = self.vsd.get_domain(externalID=ext_network_id) + self.debug("SHOW NETWORK DATA FORMAT IN VSD") + self.debug(vsd_domain) + self.assertEqual(vsd_domain['ID'], vsd_fip['parentID'], + "Floating IP in VSD should be associated with the correct VSD domain, " + "which in turn should correspond to the correct VPC (or) Isolated network in CloudStack" + ) + ext_subnet_id = self.get_externalID(network.id) + vsd_subnet = self.vsd.get_subnet(externalID=ext_subnet_id) + for nic in vm.nic: + if nic.networkname == vsd_subnet['description']: + ext_network_id = self.get_externalID(nic.networkid) + ext_nic_id = self.get_externalID(nic.id) + vsd_vport = self.vsd.get_vport(subnet_externalID=ext_network_id, vport_externalID=ext_nic_id) + self.debug("SHOW VM VPORT DATA FORMAT IN VSD") + self.debug(vsd_vport) + self.assertEqual(vsd_vport['associatedFloatingIPID'], vsd_fip['ID'], + "Floating IP in VSD should be associated to the correct VSD vport, " + "which in turn should correspond to the correct Static NAT enabled VM " + "and Isolated Network in CloudStack" + ) + + # verify_vsp_firewall_rule - Verifies the start port, destination port, + # protocol of the given firewall rule Ingress/Egress against the VSD + # firewall rule + def verify_vsp_firewall_rule(self, firewall_rule, traffic_type="Ingress"): + ext_fw_id = self.get_externalID(firewall_rule.id) + if traffic_type is "Ingress": + vsd_fw_rule = self.vsd.get_egress_acl_entry(externalID=ext_fw_id) + else: + vsd_fw_rule = self.vsd.get_ingress_acl_entry(externalID=ext_fw_id) + self.debug("SHOW ACL ENTRY IN VSD") + self.debug(vsd_fw_rule) + dest_port = str(firewall_rule.startport) + "-" + str(firewall_rule.endport) + self.assertEqual(vsd_fw_rule['destinationPort'], dest_port, + "Destination Port in VSD should match Destination Port in CloudStack" + ) + vsd_protocol = str(vsd_fw_rule['protocol']) + self.debug("vsd protocol " + vsd_protocol) + protocol = "tcp" + if vsd_protocol == 6: + protocol = "tcp" + elif vsd_protocol == 1: + protocol = "icmp" + elif vsd_protocol == 17: + protocol = "udp" + self.assertEqual(protocol, firewall_rule.protocol.lower(), + "Protocol in VSD should match Protocol in CloudStack" + ) diff --git a/test/integration/plugins/nuagevsp/test_nuage_password_reset.py b/test/integration/plugins/nuagevsp/test_nuage_password_reset.py new file mode 100644 index 000000000000..5582819d9035 --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_password_reset.py @@ -0,0 +1,276 @@ +# 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. + +""" Component tests for - userdata +""" +# Import Local Modules +from marvin.lib.base import (Account, + VirtualMachine, + Volume, + Template) +from nose.plugins.attrib import attr +from nuageTestCase import nuageTestCase +from marvin.lib.utils import cleanup_resources +from marvin.cloudstackAPI import startVirtualMachine +import base64 + + +class TestNuagePasswordReset(nuageTestCase): + + @classmethod + def setUpClass(cls): + super(TestNuagePasswordReset, cls).setUpClass() + + return + + def setUp(self): + self.cleanup = [] + self.apiclient = self.testClient.getApiClient() + + self.account = Account.create( + self.apiclient, + self.test_data["account"], + admin=True, + domainid=self.domain.id + ) + + self.cleanup.append(self.account) + self.remove_vm2 = False + return + + # tearDown() - Cleans up the setup, removes the VMs + def tearDown(self): + self.debug("CLEANUP: TEARDOWN") + self.apiclient = self.testClient.getApiClient() + self.updateTemplate(self.defaultTemplateVal) + self.vm_1.delete(self.apiclient, expunge=True) + if self.remove_vm2: + self.vm_2.delete(self.apiclient, expunge=True) + + try: + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + self.debug("Warning: Exception during cleanup : %s" % e) + return + + # create_template - Takes the VM object as the argument to create the template + def create_template(self, vm): + self.debug("CREATE TEMPLATE") + list_volume = Volume.list(self.apiclient, + virtualmachineid=vm.id, + type='ROOT', + listall=True) + if isinstance(list_volume, list): + self.volume = list_volume[0] + else: + raise Exception("Exception: Unable to find root volume for VM: %s" % vm.id) + + self.test_data["template_pr"]["ostype"] = self.test_data["ostype_pr"] + self.pw_enabled_template = Template.create( + self.apiclient, + self.test_data["template_pr"], + self.volume.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.assertEqual(self.pw_enabled_template.passwordenabled, True, "template is not passwordenabled") + self.cleanup.append(self.pw_enabled_template) + + # VM object is passed as an argument and its interface id is returned + def get_vm_interface_id(self, vm): + self.debug("GET VM INTERFACE ID") + nic_ext_id = self.get_externalID(vm.nic[0].id) + vm_interface = self.vsd.get_vm_interface(externalID=nic_ext_id) + vm_interface_id = vm_interface["ID"] + return vm_interface_id + + # VM object is passed as an argument and its userdata URL is returned + def get_userdata_url(self, vm): + self.debug("GET USER DATA URL") + nic = vm.nic[0] + gateway = str(nic.gateway) + self.debug("GATEWAY: " + gateway) + user_data_url = 'curl "http://' + gateway + ':80/latest/user-data"' + return user_data_url + + # Creates and verifies the firewall rule + def create_and_verify_fw(self, vm, public_ip, network): + self.debug("CREATE AND VERIFY FIREWALL RULE") + self.create_StaticNatRule_For_VM(vm, public_ip, network) + + # VSD verification + self.verify_vsp_floating_ip(network, vm, public_ip.ipaddress) + + fw_rule = self.create_firewall_rule(public_ip, self.test_data["ingress_rule"]) + self.verify_vsp_firewall_rule(fw_rule) + vm_interface_id = self.get_vm_interface_id(vm) + pd = self.vsd.get_vm_interface_policydecisions(id=vm_interface_id) + self.debug(pd) + egressAcls = pd['egressACLs'][0]['entries'] + gotFirewallPolicy = False + for acl in egressAcls: + if acl['destinationPort'] == "22-22": + gotFirewallPolicy = True + break + if not gotFirewallPolicy: + raise ValueError('No firewall policy decision in vm interface') + + def stop_vm(self, vm): + self.debug("STOP VM") + vm.stop(self.apiclient) + list_vm_response = VirtualMachine.list(self.apiclient, + id=vm.id) + if isinstance(list_vm_response, list): + vm = list_vm_response[0] + if vm.state != 'Stopped': + raise Exception("Failed to stop VM (ID: %s) " % + self.vm.id) + else: + raise Exception("Invalid response from list_virtual_machines VM (ID: %s) " % + self.vm.id) + + def install_cloud_set_guest_password_script(self, ssh_client): + self.debug("GET CLOUD-SET-GUEST-PASSWORD") + cmd = "cd /etc/init.d;wget http://people.apache.org/~tsp/cloud-set-guest-password" + result = self.execute_cmd(ssh_client, cmd) + self.debug("WGET CLOUD-SET-GUEST-PASSWORD: " + result) + if "200 OK" not in result: + self.fail("failed to get file cloud-set-guest-password") + cmds = ["chmod +x /etc/init.d/cloud-set-guest-password", + "chkconfig --add cloud-set-guest-password" + ] + for c in cmds: + result = self.execute_cmd(ssh_client, c) + self.debug("get_set_password_file cmd " + c) + self.debug("get_set_password_file result " + result) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_01_UserDataPasswordReset(self): + self.debug("START USER DATA PASSWORD RESET ON VM") + """ + Validate the following: + 1) user data + 2) reset vm password. + + Steps: + 1. Set password enabled to false in the template. + 2. Create an Isolated network - Test Network (10.1.1.1/24). + 3. Deploy VM1 in Test Network + 4. Verify domain,zone subnet, vm. + 5. create public ip , Create Static Nat rule firewall rule and verify + 6. SSH to VM should be successful + 7. verify userdata + 8. check cloud-set-guest-password exist. + 9. if cloud-set-guest-password exist. + 9.1 change template password enabled to true + 9.2 verify that template is password enbalded + 9.3 SSH with new password should be successful + 10. else cloud-set-guest-password does not exist. + 10.1 get the cloud-set-guest-password file + 10.2 stop vm + 10.3 create a new template with password enabled. Verify that template is password enabled. + 10.4 create vm 2 with new template in Test Network + 10.5 Verify vm. + 10.6 create public ip , Create Static Nat rule firewall rule and verify + 10.7 SSH to VM 2 should be successful + 11. Reset VM password (VM_1 if guest password file exist. else it is VM2) + 12 Starting VM and SSH to VM to verify new password + """ + + self.defaultTemplateVal = self.template.passwordenabled + if self.template.passwordenabled: + self.updateTemplate(False) + + self.debug("CREATE AN ISOLATED NETWORK") + self.network_1 = self.create_Network(self.test_data["network_offering_pr"]) + self.cleanup.append(self.network_1) + expUserData = "hello world vm1" + userdata = base64.b64encode(expUserData) + self.test_data["virtual_machine_pr"]["userdata"] = userdata + self.debug("DEPLOY VM 1 IN TEST NETWORK") + # Pass the network and name of the vm type from the testdata with the configuration for the vm + self.vm_1 = self.create_VM_in_Network(self.network_1, "virtual_machine_pr") + + self.vm_1.password = self.test_data["virtual_machine_pr"]["password"] + user_data_cmd = self.get_userdata_url(self.vm_1) + + # VSD verification + self.debug("VERIFY DOMAIN, ZONE, NETWORK , and VM 1") + self.verify_vsp_network(self.domain.id, self.network_1) + self.verify_vsp_vm(self.vm_1) + + self.debug("CREATE PUBLIC IP, STATIC NAT RULE, FLOATING IP, FIREWALL AND VERIFY") + public_ip_1 = self.acquire_Public_IP(self.network_1) + self.create_and_verify_fw(self.vm_1, public_ip_1, self.network_1) + + self.debug("SSH TO VM") + ssh = self.ssh_into_vm(self.vm_1, public_ip_1) + + self.debug("VERIFY USER DATA") + self.debug("Get User Data with command: " + user_data_cmd) + adata = self.execute_cmd(ssh, user_data_cmd) + actUserData = base64.b64decode(adata) + self.debug("Response User Data=" + actUserData + ", Expected=" + expUserData) + self.assertEqual(actUserData, expUserData, "User Data Did Not Match ") + + # check /etc/init.d/cloud-set-quest-password + ls_cmd = "ls /etc/init.d/cloud-set-guest-password" + ls_result = self.execute_cmd(ssh, ls_cmd) + ls_result = ls_result.lower() + self.debug("reponse from ls_cmd: " + ls_result) + if "no such file" in ls_result: + self.debug("NO CLOUD-SET_GUEST_PASSWORD FILE. NEED TO GET ONE") + self.install_cloud_set_guest_password_script(ssh) + self.stop_vm(self.vm_1) + self.create_template(self.vm_1) + self.debug("DEPLOY VM 2 IN TEST NETWORK WITH NEW TEMPLATE") + self.vm_2 = self.create_VM_in_Network(self.network_1, "virtual_machine_pr") + self.remove_vm2 = True + self.debug("STARTING VM_2 ") + startCmd = startVirtualMachine.startVirtualMachineCmd() + startCmd.id = self.vm_2.id + vm_2a = self.apiclient.startVirtualMachine(startCmd) + self.vm_2.password = vm_2a.password.strip() + self.vm_2.nic = vm_2a.nic + self.debug("VM - %s password %s !" % (self.vm_2.name, self.vm_2.password)) + self.assertNotEqual(self.vm_2.password, + self.test_data["virtual_machine_pr"]["password"], + "Password enabled not working. Password same as virtual_machine password " + ) + self.verify_vsp_vm(vm_2a) + self.debug("GET PUBLIC IP. CREATE AND VERIFIED FIREWALL RULES") + public_ip_2 = self.acquire_Public_IP(self.network_1) + self.create_and_verify_fw(self.vm_2, public_ip_2, self.network_1) + + ssh = self.ssh_into_vm(self.vm_2, public_ip_2) + vm_test = self.vm_2 + vm_test_public_ip = public_ip_2 + + else: + self.debug("UPDATE TEMPLATE TO PASSWORD ENABLED") + self.updateTemplate(True) + self.assertEqual(self.template.passwordenabled, True, "Template is not password enabled") + vm_test = self.vm_1 + vm_test_public_ip = public_ip_1 + + self.debug("RESETTING VM PASSWORD for VM: %s" % vm_test.name) + vm_test.password = vm_test.resetPassword(self.apiclient) + self.debug("Password reset to: %s" % vm_test.password) + self.debug("STARTING VM AND SSH TO VM TO VERIFY NEW PASSWORD") + vm_test.start(self.apiclient) + self.debug("VM - %s started!" % vm_test.name) + self.ssh_into_vm(vm_test, vm_test_public_ip) diff --git a/test/integration/plugins/nuagevsp/test_nuage_vpc_network.py b/test/integration/plugins/nuagevsp/test_nuage_vpc_network.py new file mode 100644 index 000000000000..3fc9c32cfec7 --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_vpc_network.py @@ -0,0 +1,98 @@ +# 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 for Basic VPC Network Functionality with NuageVsp network Plugin +""" +# Import Local Modules +from marvin.lib.base import Account +from nose.plugins.attrib import attr +from nuageTestCase import nuageTestCase + + +class TestVpcNetworkNuage(nuageTestCase): + """ Test Basic VPC Network Functionality with NuageVsp network Plugin + """ + + @classmethod + def setUpClass(cls): + super(TestVpcNetworkNuage, cls).setUpClass() + return + + def setUp(self): + # Create an account + self.account = Account.create(self.api_client, + self.test_data["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_nuage_vpc_network(self): + """ Test Basic VPC Network Functionality with NuageVsp network Plugin + """ + + # 1. Create Nuage VSP VPC offering, check if it is successfully created and enabled. + # 2. Create a VPC with Nuage VSP VPC offering, check if it is successfully created and enabled. + # 3. Create Nuage Vsp VPC Network offering, check if it is successfully created and enabled. + # 4. Create an ACL list in the created VPC, and add an ACL item to it. + # 5. Create a VPC Network with Nuage Vsp VPC Network offering and the created ACL list, check if it is + # successfully created, is in the "Implemented" state, and is added to the VPC VR. + # 6. Deploy a VM in the created VPC network, check if the VM is successfully deployed and is in the "Running" + # state. + # 7. Verify that the created ACL item is successfully implemented in Nuage Vsp. + + # Creating a VPC offering + self.debug("Creating Nuage VSP VPC offering...") + vpc_offering = self.create_VpcOffering(self.test_data["nuage_vsp_services"]["vpc_offering"]) + self.validate_vpc_offering(vpc_offering, state="Enabled") + + # Creating a VPC + self.debug("Creating a VPC with Nuage VSP VPC offering...") + vpc = self.create_Vpc(vpc_offering, cidr='10.1.0.0/16') + self.validate_vpc(vpc, state="Enabled") + + # Creating a network offering + self.debug("Creating Nuage Vsp VPC Network offering...") + network_offering = self.create_NetworkOffering(self.test_data["nuage_vsp_services"]["vpc_network_offering"]) + self.validate_network_offering(network_offering, state="Enabled") + + # Creating an ACL list + acl_list = self.create_network_acl_list(name="acl", description="acl", vpc=vpc) + + # Creating an ACL item + acl_item = self.create_network_acl_rule(self.test_data["ingress_rule"], acl_list=acl_list) + + # Creating a VPC network in the VPC + self.debug("Creating a VPC network with Nuage Vsp VPC Network offering...") + vpc_network = self.create_Network(network_offering, gateway='10.1.1.1', vpc=vpc, acl_list=acl_list) + self.validate_network(vpc_network, state="Implemented") + vr = self.get_network_router(vpc_network) + self.check_router_state(vr, state="Running") + + # Deploying a VM in the VPC network + vm = self.create_VM_in_Network(vpc_network) + self.check_vm_state(vm, state="Running") + + # VSPK verification + self.verify_vsp_network(self.domain.id, vpc_network, vpc) + self.verify_vsp_router(vr) + self.verify_vsp_vm(vm) + + # VSPK verification for ACL item + self.verify_vsp_firewall_rule(acl_item) diff --git a/test/integration/plugins/nuagevsp/test_nuage_vsp.py b/test/integration/plugins/nuagevsp/test_nuage_vsp.py new file mode 100644 index 000000000000..a6ec7e1feeb5 --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_vsp.py @@ -0,0 +1,106 @@ +# 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. + +""" P1 tests for NuageVsp network Plugin +""" +# Import Local Modules +from marvin.lib.base import Account +from nose.plugins.attrib import attr +from nuageTestCase import nuageTestCase + + +class TestNuageVsp(nuageTestCase): + """ Test NuageVsp network plugin + """ + + @classmethod + def setUpClass(cls): + super(TestNuageVsp, cls).setUpClass() + return + + def setUp(self): + # Create an account + self.account = Account.create(self.api_client, + self.test_data["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_nuage_vsp(self): + """ Test NuageVsp network plugin with basic Isolated Network functionality + """ + + # 1. Verify that the NuageVsp network service provider is successfully created and enabled. + # 2. Create and enable Nuage Vsp Isolated Network offering, check if it is successfully created and enabled. + # 3. Create an Isolated Network with Nuage Vsp Isolated Network offering, check if it is successfully created + # and is in the "Allocated" state. + # 4. Deploy a VM in the created Isolated network, check if the Isolated network state is changed to + # "Implemented", and both the VM & VR are successfully deployed and are in the "Running" state. + # 5. Deploy one more VM in the created Isolated network, check if the VM is successfully deployed and is in the + # "Running" state. + # 6. Delete the created Isolated Network after destroying its VMs, check if the Isolated network is successfully + # deleted. + + self.debug("Validating the NuageVsp network service provider...") + self.validate_NetworkServiceProvider("NuageVsp", state="Enabled") + + # Creating a network offering + self.debug("Creating and enabling Nuage Vsp Isolated Network offering...") + network_offering = self.create_NetworkOffering( + self.test_data["nuage_vsp_services"]["isolated_network_offering"]) + self.validate_network_offering(network_offering, state="Enabled") + + # Creating a network + self.debug("Creating an Isolated Network with Nuage Vsp Isolated Network offering...") + network = self.create_Network(network_offering, gateway='10.1.1.1') + self.validate_network(network, state="Allocated") + + # Deploying a VM in the network + vm_1 = self.create_VM_in_Network(network) + self.validate_network(network, state="Implemented") + vr = self.get_network_router(network) + self.check_router_state(vr, state="Running") + self.check_vm_state(vm_1, state="Running") + + # VSPK verification + self.verify_vsp_network(self.domain.id, network) + self.verify_vsp_router(vr) + self.verify_vsp_vm(vm_1) + + # Deploying one more VM in the network + vm_2 = self.create_VM_in_Network(network) + self.check_vm_state(vm_2, state="Running") + + # VSPK verification + self.verify_vsp_vm(vm_2) + + # Deleting the network + self.debug("Deleting the Isolated Network with Nuage Vsp Isolated Network offering...") + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_Network(network) + with self.assertRaises(Exception): + self.validate_network(network) + self.debug("Isolated Network successfully deleted in CloudStack") + + # VSPK verification + with self.assertRaises(Exception): + self.verify_vsp_network(self.domain.id, network) + self.debug("Isolated Network successfully deleted in VSD") diff --git a/test/integration/plugins/test_nicira_controller.py b/test/integration/plugins/test_nicira_controller.py index 6c625b6297bd..75f94afdb668 100644 --- a/test/integration/plugins/test_nicira_controller.py +++ b/test/integration/plugins/test_nicira_controller.py @@ -35,7 +35,8 @@ get_template, list_routers, list_hosts, - findSuitableHostForMigration + findSuitableHostForMigration, + migrate_router ) from nose.plugins.attrib import attr from marvin.codes import (FAILED, PASS) @@ -44,6 +45,23 @@ class TestNiciraContoller(cloudstackTestCase): + ''' + Example of marvin config with NSX specific values + "niciraNvp": { + "hosts": [ "nsxcon1.cloud.lan", "nsxcon2.cloud.lan", "nsxcon3.cloud.lan" ], + "shared_network": { + "l2gatewayserviceuuid": "3595ca67-959f-47d4-8f01-0492a8e96205", + "iprange" : { + "startip": "192.168.26.2", + "endip": "192.168.26.20", + "netmask": "255.255.255.0", + "gateway": "192.168.26.1", + "vlan": "50", + "vlan_uuid": "5cdaa49d-06cd-488a-9ca4-e954a3181f54" + } + } + } + ''' @classmethod def setUpClass(cls): test_case = super(TestNiciraContoller, cls) @@ -55,27 +73,54 @@ def setUpClass(cls): cls.physical_networks = cls.config.zones[0].physical_networks cls.nicira_hosts = cls.config.niciraNvp.hosts + cls.nicira_shared_network_iprange = cls.config.niciraNvp.shared_network.iprange + cls.l2gatewayserviceuuid = cls.config.niciraNvp.shared_network.l2gatewayserviceuuid + cls.physical_network_id = cls.get_nicira_enabled_physical_network_id(cls.physical_networks) - cls.network_offerring_services = { - 'name': 'NiciraEnabledNetwork', - 'displaytext': 'NiciraEnabledNetwork', - 'guestiptype': 'Isolated', - 'supportedservices': 'SourceNat,Dhcp,Dns,Firewall,PortForwarding,Connectivity', - 'traffictype': 'GUEST', - 'availability': 'Optional', - 'serviceProviderList': { - 'SourceNat': 'VirtualRouter', - 'Dhcp': 'VirtualRouter', - 'Dns': 'VirtualRouter', - 'Firewall': 'VirtualRouter', - 'PortForwarding': 'VirtualRouter', - 'Connectivity': 'NiciraNvp' + cls.network_offerring_services = [ + { + 'name': 'NiciraEnabledIsolatedNetwork', + 'displaytext': 'NiciraEnabledIsolatedNetwork', + 'guestiptype': 'Isolated', + 'supportedservices': 'SourceNat,Dhcp,Dns,Firewall,PortForwarding,Connectivity', + 'traffictype': 'GUEST', + 'availability': 'Optional', + 'serviceProviderList': { + 'SourceNat': 'VirtualRouter', + 'Dhcp': 'VirtualRouter', + 'Dns': 'VirtualRouter', + 'Firewall': 'VirtualRouter', + 'PortForwarding': 'VirtualRouter', + 'Connectivity': 'NiciraNvp' + } + }, + { + 'name': 'NiciraEnabledSharedNetwork', + 'displaytext': 'NiciraEnabledSharedNetwork', + 'guestiptype': 'Shared', + 'supportedservices': 'Connectivity,Dhcp,UserData,SourceNat,StaticNat,Lb,PortForwarding', + 'traffictype': 'GUEST', + 'availability': 'Optional', + 'specifyVlan': 'true', + 'specifyIpRanges': 'true', + 'serviceProviderList': { + 'Connectivity': 'NiciraNvp', + 'Dhcp': 'VirtualRouter', + 'SourceNat': 'VirtualRouter', + 'StaticNat': 'VirtualRouter', + 'Lb': 'VirtualRouter', + 'PortForwarding': 'VirtualRouter', + 'UserData': 'VirtualRouter' + } } - } + ] + + cls.network_offering_isolated = NetworkOffering.create(cls.api_client, cls.network_offerring_services[0]) + cls.network_offering_isolated.update(cls.api_client, state='Enabled') - cls.network_offering = NetworkOffering.create(cls.api_client, cls.network_offerring_services) - cls.network_offering.update(cls.api_client, state='Enabled') + cls.network_offering_shared = NetworkOffering.create(cls.api_client, cls.network_offerring_services[1]) + cls.network_offering_shared.update(cls.api_client, state='Enabled') cls.nicira_credentials = { 'username': 'admin', @@ -92,7 +137,9 @@ def setUpClass(cls): cls.nicira_credentials ) - cls.domain = get_domain(cls.api_client) + cls.admin_account = 'admin' + cls.admin_domain = get_domain(cls.api_client) + cls.zone = get_zone(cls.api_client, test_client.getZoneForTests()) template = get_template( @@ -123,6 +170,7 @@ def setUpClass(cls): 'cpunumber': 1, 'cpuspeed': 100, 'memory': 64, + 'offerha': 'true' } } } @@ -136,8 +184,9 @@ def setUpClass(cls): ) cls.cleanup = [ - cls.network_offering, - cls.service_offering + cls.network_offering_isolated, + cls.service_offering, + cls.network_offering_shared ] cls.logger = logging.getLogger('TestNiciraContoller') @@ -187,7 +236,7 @@ def get_transport_zone_from_controller(cls, controller_host, credentials): if result_count == 0: raise Exception('Nicira controller did not return any Transport Zones') elif result_count > 1: - self.logger.debug("Nicira controller returned %s Transport Zones, picking first one" % resultCount) + cls.logger.debug("Nicira controller returned %s Transport Zones, picking first one" % resultCount) transport_zone_api_url = list_transport_zone_response['results'][0]['_href'] r3 = requests.get( "https://%s%s" % (controller_host, transport_zone_api_url), @@ -219,7 +268,7 @@ def determine_slave_conroller(self, hosts, master_controller): raise Exception("None of the supplied hosts (%s) is a Nicira slave" % hosts) - def add_nicira_device(self, hostname): + def add_nicira_device(self, hostname, l2gatewayserviceuuid=None): nicira_device = NiciraNvp.add( self.api_client, None, @@ -227,22 +276,85 @@ def add_nicira_device(self, hostname): hostname=hostname, username=self.nicira_credentials['username'], password=self.nicira_credentials['password'], - transportzoneuuid=self.transport_zone_uuid) + transportzoneuuid=self.transport_zone_uuid, + l2gatewayserviceuuid=l2gatewayserviceuuid + ) self.test_cleanup.append(nicira_device) + def create_guest_isolated_network(self): + network_services = { + 'name' : 'nicira_enabled_network_isolated', + 'displaytext' : 'nicira_enabled_network_isolated', + 'zoneid' : self.zone.id, + 'networkoffering' : self.network_offering_isolated.id + } + network = Network.create( + self.api_client, + network_services, + accountid=self.admin_account, + domainid=self.admin_domain.id + ) + self.test_cleanup.append(network) + return network + + def create_guest_shared_network_numerical_vlanid(self): + network_services = { + 'name' : 'nicira_enabled_network_shared', + 'displaytext' : 'nicira_enabled_network_shared', + 'zoneid' : self.zone.id, + 'networkoffering' : self.network_offering_shared.id, + 'startip' : self.nicira_shared_network_iprange.startip, + 'endip' : self.nicira_shared_network_iprange.endip, + 'netmask' : self.nicira_shared_network_iprange.netmask, + 'gateway' : self.nicira_shared_network_iprange.gateway, + 'vlan' : self.nicira_shared_network_iprange.vlan + } + network = Network.create( + self.api_client, + network_services, + accountid=self.admin_account, + domainid=self.admin_domain.id + ) + self.test_cleanup.append(network) + return network + + def create_guest_shared_network_uuid_vlanid(self): + network_services = { + 'name' : 'nicira_enabled_network_shared', + 'displaytext' : 'nicira_enabled_network_shared', + 'zoneid' : self.zone.id, + 'networkoffering' : self.network_offering_shared.id, + 'startip' : self.nicira_shared_network_iprange.startip, + 'endip' : self.nicira_shared_network_iprange.endip, + 'netmask' : self.nicira_shared_network_iprange.netmask, + 'gateway' : self.nicira_shared_network_iprange.gateway, + 'vlan' : self.nicira_shared_network_iprange.vlan_uuid + } + network = Network.create( + self.api_client, + network_services, + accountid=self.admin_account, + domainid=self.admin_domain.id + ) + self.test_cleanup.append(network) + return network - def create_guest_network(self): + def create_guest_shared_network_services(self): network_services = { - 'name' : 'nicira_enabled_network', - 'displaytext' : 'nicira_enabled_network', + 'name' : 'nicira_enabled_network_shared', + 'displaytext' : 'nicira_enabled_network_shared', 'zoneid' : self.zone.id, - 'networkoffering' : self.network_offering.id + 'networkoffering' : self.network_offering_shared.id, + 'startip' : self.nicira_shared_network_iprange.startip, + 'endip' : self.nicira_shared_network_iprange.endip, + 'netmask' : self.nicira_shared_network_iprange.netmask, + 'gateway' : self.nicira_shared_network_iprange.gateway } network = Network.create( self.api_client, network_services, - accountid='admin', - domainid=self.domain.id, + accountid=self.admin_account, + domainid=self.admin_domain.id, ) self.test_cleanup.append(network) return network @@ -252,8 +364,8 @@ def create_virtual_machine(self, network): virtual_machine = VirtualMachine.create( self.api_client, self.vm_services['small'], - accountid='admin', - domainid=self.domain.id, + accountid=self.admin_account, + domainid=self.admin_domain.id, serviceofferingid=self.service_offering.id, networkids=[network.id], mode=self.vm_services['mode'] @@ -261,12 +373,25 @@ def create_virtual_machine(self, network): self.test_cleanup.append(virtual_machine) return virtual_machine + def create_virtual_machine_shared_networks(self, network): + virtual_machine = VirtualMachine.create( + self.api_client, + self.vm_services['small'], + accountid=self.admin_account, + domainid=self.admin_domain.id, + serviceofferingid=self.service_offering.id, + networkids=[network.id], + mode='BASIC' + ) + self.test_cleanup.append(virtual_machine) + return virtual_machine + def get_routers_for_network(self, network): return list_routers( self.api_client, - account='admin', - domainid=self.domain.id, + accountid=self.admin_account, + domainid=self.admin_domain.id, networkid=network.id ) @@ -274,8 +399,8 @@ def get_routers_for_network(self, network): def get_hosts(self): return list_hosts( self.api_client, - account='admin', - domainid=self.domain.id + accountid=self.admin_account, + domainid=self.admin_domain.id ) @@ -296,8 +421,8 @@ def distribute_vm_and_routers_by_hosts(self, virtual_machine, routers): self.logger.debug("Master Router VM is on the same host as VM") host = findSuitableHostForMigration(self.api_client, router.id) if host is not None: - router.migrate(self.api_client, host) - self.logger.debug("Migrated Master Router VM to host %s" % host) + migrate_router(self.api_client, router.id, host.id) + self.logger.debug("Migrated Master Router VM to host %s" % host.name) else: self.fail('No suitable host to migrate Master Router VM to') else: @@ -308,9 +433,9 @@ def acquire_publicip(self, network): self.logger.debug("Associating public IP for network: %s" % network.name) public_ip = PublicIPAddress.create( self.api_client, - accountid='admin', + accountid=self.admin_account, zoneid=self.zone.id, - domainid=self.domain.id, + domainid=self.admin_domain.id, networkid=network.id ) self.logger.debug("Associated %s with network %s" % (public_ip.ipaddress.ipaddress, network.id)) @@ -336,7 +461,7 @@ def create_natrule(self, vm, public_ip, network): def test_01_nicira_controller(self): self.add_nicira_device(self.nicira_master_controller) - network = self.create_guest_network() + network = self.create_guest_isolated_network() virtual_machine = self.create_virtual_machine(network) list_vm_response = VirtualMachine.list(self.api_client, id=virtual_machine.id) @@ -367,7 +492,7 @@ def test_02_nicira_controller_redirect(self): self.add_nicira_device(nicira_slave) - network = self.create_guest_network() + network = self.create_guest_isolated_network() virtual_machine = self.create_virtual_machine(network) list_vm_response = VirtualMachine.list(self.api_client, id=virtual_machine.id) @@ -384,7 +509,7 @@ def test_02_nicira_controller_redirect(self): @attr(tags = ["advanced", "smoke", "nicira"], required_hardware="true") def test_03_nicira_tunnel_guest_network(self): self.add_nicira_device(self.nicira_master_controller) - network = self.create_guest_network() + network = self.create_guest_isolated_network() virtual_machine = self.create_virtual_machine(network) public_ip = self.acquire_publicip(network) nat_rule = self.create_natrule(virtual_machine, public_ip, network) @@ -412,6 +537,48 @@ def test_03_nicira_tunnel_guest_network(self): result = str(ssh.execute(ssh_command)) self.logger.debug("SSH result: %s; COUNT is ==> %s" % (result, result.count("3 packets received"))) except Exception as e: - self.fail("SSH Access failed for %s: %s" % (vmObj.get_ip(), e)) + self.fail("SSH Access failed for %s: %s" % (virtual_machine.get_ip(), e)) self.assertEqual(result.count('3 packets received'), 1, 'Ping to outside world from VM should be successful') + + @attr(tags = ["advanced", "smoke", "nicira"], required_hardware="true") + def test_04_nicira_shared_networks_numerical_vlanid(self): + """ + Shared Networks Support + CASE 1) Numerical VLAN_ID provided in network creation + """ + self.debug("Starting test case 1 for Shared Networks") + self.add_nicira_device(self.nicira_master_controller, self.l2gatewayserviceuuid) + network = self.create_guest_shared_network_numerical_vlanid() + virtual_machine = self.create_virtual_machine_shared_networks(network) + + list_vm_response = VirtualMachine.list(self.api_client, id=virtual_machine.id) + self.debug("Verify listVirtualMachines response for virtual machine: %s" % virtual_machine.id) + + self.assertEqual(isinstance(list_vm_response, list), True, 'Response did not return a valid list') + self.assertNotEqual(len(list_vm_response), 0, 'List of VMs is empty') + + vm_response = list_vm_response[0] + self.assertEqual(vm_response.id, virtual_machine.id, 'Virtual machine in response does not match request') + self.assertEqual(vm_response.state, 'Running', 'VM is not in Running state') + + @attr(tags = ["advanced", "smoke", "nicira"], required_hardware="true") + def test_05_nicira_shared_networks_lrouter_uuid_vlan_id(self): + """ + Shared Networks Support + CASE 2) Logical Router's UUID as VLAN_ID provided in network creation + """ + self.debug("Starting test case 2 for Shared Networks") + self.add_nicira_device(self.nicira_master_controller, self.l2gatewayserviceuuid) + network = self.create_guest_shared_network_uuid_vlanid() + virtual_machine = self.create_virtual_machine_shared_networks(network) + + list_vm_response = VirtualMachine.list(self.api_client, id=virtual_machine.id) + self.debug("Verify listVirtualMachines response for virtual machine: %s" % virtual_machine.id) + + self.assertEqual(isinstance(list_vm_response, list), True, 'Response did not return a valid list') + self.assertNotEqual(len(list_vm_response), 0, 'List of VMs is empty') + + vm_response = list_vm_response[0] + self.assertEqual(vm_response.id, virtual_machine.id, 'Virtual machine in response does not match request') + self.assertEqual(vm_response.state, 'Running', 'VM is not in Running state') diff --git a/test/integration/smoke/test_quota.py b/test/integration/plugins/test_quota.py similarity index 69% rename from test/integration/smoke/test_quota.py rename to test/integration/plugins/test_quota.py index d4e4323e9b3d..1ae6790597aa 100644 --- a/test/integration/smoke/test_quota.py +++ b/test/integration/plugins/test_quota.py @@ -30,10 +30,30 @@ #Import System modules import time -#ENABLE THE QUOTA PLUGIN AND RESTART THE MANAGEMENT SERVER TO RUN QUOTA TESTS - class TestQuota(cloudstackTestCase): + @classmethod + def setUpClass(cls): + # Create Account + testClient = super(TestQuota, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.services = testClient.getParsedTestDataConfig() + + # Get Zone, Domain + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests()) + + # Create Account + cls.account = Account.create( + cls.apiclient, + cls.services["account"], + domainid=cls.domain.id + ) + cls._cleanup = [ + cls.account, + ] + return + def setUp(self): self.apiclient = self.testClient.getApiClient() self.hypervisor = self.testClient.getHypervisorInfo() @@ -55,6 +75,12 @@ def tearDown(self): #Check quotaTariffList API returning 22 items @attr(tags=["smoke", "advanced"], required_hardware="false") def test_01_quota(self): + if not is_config_suitable( + apiclient=self.apiclient, + name='quota.enable.service', + value='true'): + self.skipTest('quota.enable.service should be true. skipping') + cmd = quotaTariffList.quotaTariffListCmd() response = self.apiclient.quotaTariffList(cmd) @@ -75,6 +101,12 @@ def test_01_quota(self): #Check quota tariff on a particualr day @attr(tags=["smoke", "advanced"], required_hardware="false") def test_02_quota(self): + if not is_config_suitable( + apiclient=self.apiclient, + name='quota.enable.service', + value='true'): + self.skipTest('quota.enable.service should be true. skipping') + cmd = quotaTariffList.quotaTariffListCmd() cmd.startdate='2015-07-06' response = self.apiclient.quotaTariffList(cmd) @@ -89,6 +121,12 @@ def test_02_quota(self): #check quota tariff of a particular item @attr(tags=["smoke", "advanced"], required_hardware="false") def test_03_quota(self): + if not is_config_suitable( + apiclient=self.apiclient, + name='quota.enable.service', + value='true'): + self.skipTest('quota.enable.service should be true. skipping') + cmd = quotaTariffList.quotaTariffListCmd() cmd.startdate='2015-07-06' cmd.usagetype='10' @@ -107,6 +145,12 @@ def test_03_quota(self): #check the old tariff it should be same @attr(tags=["smoke", "advanced"], required_hardware="false") def test_04_quota(self): + if not is_config_suitable( + apiclient=self.apiclient, + name='quota.enable.service', + value='true'): + self.skipTest('quota.enable.service should be true. skipping') + cmd = quotaTariffList.quotaTariffListCmd() cmd.startdate='2015-07-06' cmd.usagetype='10' @@ -157,9 +201,15 @@ def test_04_quota(self): #Make credit deposit @attr(tags=["smoke", "advanced"], required_hardware="false") def test_05_quota(self): + if not is_config_suitable( + apiclient=self.apiclient, + name='quota.enable.service', + value='true'): + self.skipTest('quota.enable.service should be true. skipping') + cmd = quotaCredits.quotaCreditsCmd() - cmd.domainid = '1' - cmd.account = 'admin' + cmd.domainid = self.account.domainid + cmd.account = self.account.name cmd.value = '10' cmd.quota_enforce = '1' cmd.min_balance = '9' @@ -173,32 +223,45 @@ def test_05_quota(self): #Make credit deposit and check today balance @attr(tags=["smoke", "advanced"], required_hardware="false") def test_06_quota(self): + if not is_config_suitable( + apiclient=self.apiclient, + name='quota.enable.service', + value='true'): + self.skipTest('quota.enable.service should be true. skipping') + cmd = quotaBalance.quotaBalanceCmd() today = datetime.date.today() - cmd.domainid = '1' - cmd.account = 'admin' + cmd.domainid = self.account.domainid + cmd.account = self.account.name cmd.startdate = today response = self.apiclient.quotaBalance(cmd) self.debug("Quota Balance on: %s" % response.startdate) self.debug("is: %s" % response.startquota) - self.assertGreater( response.startquota, 9) + self.assertEqual( response.startquota, 10) return #make credit deposit and check start and end date balances @attr(tags=["smoke", "advanced"], required_hardware="false") def test_07_quota(self): + if not is_config_suitable( + apiclient=self.apiclient, + name='quota.enable.service', + value='true'): + self.skipTest('quota.enable.service should be true. skipping') + cmd = quotaBalance.quotaBalanceCmd() today = datetime.date.today() - cmd.domainid = '1' - cmd.account = 'admin' + cmd.domainid = self.account.domainid + cmd.account = self.account.name cmd.startdate = today - datetime.timedelta(days=2) - cmd.enddate = today + cmd.enddate = today response = self.apiclient.quotaBalance(cmd) self.debug("Quota Balance on: %s" % response.startdate) self.debug("is: %s" % response.startquota) - self.assertGreater( response.endquota, 9) + self.assertEqual( response.startquota, 0) + self.assertEqual( response.endquota, 10) return diff --git a/test/integration/smoke/test_routers.py b/test/integration/smoke/test_routers.py index 4478c7b8a891..c6aa4960db3f 100644 --- a/test/integration/smoke/test_routers.py +++ b/test/integration/smoke/test_routers.py @@ -313,7 +313,14 @@ def test_02_router_internal_adv(self): self.debug("Haproxy process status: %s" % res) return - @attr(tags=["advanced", "advancedns", "smoke", "dvs"], required_hardware="false") + @attr( + tags=[ + "advanced", + "basic", + "advancedns", + "smoke", + "dvs"], + required_hardware="false") def test_03_restart_network_cleanup(self): """Test restart network """ @@ -323,20 +330,30 @@ def test_03_restart_network_cleanup(self): # 2. New router should have the same public IP # Find router associated with user account - list_router_response = list_routers( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid - ) + if self.zone.networktype.lower() == "basic": + list_router_response = list_routers( + self.apiclient, + listall="true" + ) + else: + list_router_response = list_routers( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid + ) self.assertEqual( isinstance(list_router_response, list), True, "Check list response returns a valid list" ) + router = list_router_response[0] # Store old values before restart - old_publicip = router.publicip + if self.zone.networktype.lower == "basic": + old_publicip = router.guestipaddress + else: + old_publicip = router.publicip timeout = 10 # Network should be in Implemented or Setup stage before restart @@ -371,11 +388,17 @@ def test_03_restart_network_cleanup(self): self.apiclient.restartNetwork(cmd) # Get router details after restart - list_router_response = list_routers( - self.apiclient, - account=self.account.name, - domainid=self.account.domainid - ) + if self.zone.networktype.lower() == "basic": + list_router_response = list_routers( + self.apiclient, + listall="true" + ) + else: + list_router_response = list_routers( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid + ) self.assertEqual( isinstance(list_router_response, list), True, @@ -383,8 +406,12 @@ def test_03_restart_network_cleanup(self): ) router = list_router_response[0] + if self.zone.networktype.lower() == "basic": + new_publicip = router.guestipaddress + else: + new_publicip = router.publicip self.assertEqual( - router.publicip, + new_publicip, old_publicip, "Public IP of the router should remain same after network restart" ) diff --git a/test/integration/testpaths/testpath_attach_disk_zwps.py b/test/integration/testpaths/testpath_attach_disk_zwps.py index d386438310f2..1f1e0735ea75 100644 --- a/test/integration/testpaths/testpath_attach_disk_zwps.py +++ b/test/integration/testpaths/testpath_attach_disk_zwps.py @@ -34,7 +34,8 @@ ) from marvin.codes import (PASS, - ZONETAG1) + ZONETAG1, + CLUSTERTAG1) class TestAttachDataDisk(cloudstackTestCase): @@ -207,3 +208,188 @@ def test_01_attach_datadisk_to_vm_on_zwps(self): "Check: Data if Disk is attached to VM") return + + +class TestAttachDataDiskOnCWPS(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + testClient = super(TestAttachDataDiskOnCWPS, cls).getClsTestClient() + cls.apiclient = testClient.getApiClient() + cls.testdata = testClient.getParsedTestDataConfig() + cls.hypervisor = cls.testClient.getHypervisorInfo() + + # Get Zone, Domain and templates + cls.domain = get_domain(cls.apiclient) + cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests()) + cls._cleanup = [] + cls.template = get_template( + cls.apiclient, + cls.zone.id, + cls.testdata["ostype"]) + cls.skiptest = False + + try: + cls.pools = StoragePool.list( + cls.apiclient, + zoneid=cls.zone.id, + scope="CLUSTER") + except Exception as e: + cls.skiptest = True + return + try: + + # Create an account + cls.account = Account.create( + cls.apiclient, + cls.testdata["account"], + domainid=cls.domain.id + ) + cls._cleanup.append(cls.account) + + # Create user api client of the account + cls.userapiclient = testClient.getUserApiClient( + UserName=cls.account.name, + DomainName=cls.account.domain + ) + # Create Service offering + cls.service_offering = ServiceOffering.create( + cls.apiclient, + cls.testdata["service_offering"], + ) + cls._cleanup.append(cls.service_offering) + + # Create Disk offering + cls.disk_offering = DiskOffering.create( + cls.apiclient, + cls.testdata["disk_offering"], + custom=True, + tags=CLUSTERTAG1, + ) + + cls._cleanup.append(cls.disk_offering) + + except Exception as e: + cls.tearDownClass() + raise e + return + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.apiclient, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + def tearDown(self): + try: + for storagePool in self.pools: + StoragePool.update(self.apiclient, id=storagePool.id, tags="") + + if hasattr(self, "data_volume_created"): + data_volumes_list = Volume.list( + self.userapiclient, + id=self.data_volume_created.id, + virtualmachineid=self.vm.id + ) + if data_volumes_list: + self.vm.detach_volume( + self.userapiclient, + data_volumes_list[0] + ) + + status = validateList(data_volumes_list) + self.assertEqual( + status[0], + PASS, + "DATA Volume List Validation Failed") + + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(tags=["basic", "advanced"], required_hardware="true") + def test_01_attach_datadisk_to_vm_on_zwps(self): + """ Attach Data Disk on CWPS To VM + 1. Check if zwps storage pool exists. + 2. Adding tag to zone wide primary storage + 3. Launch a VM + 4. Attach data disk to vm. + 5. Verify disk is attached and in correct storage pool. + """ + + # Step 1 + if len(list(self.pools)) < 1: + self.skipTest("There must be at least one zone wide \ + storage pools available in the setup") + + # Step 2 + # Adding tags to Storage Pools + StoragePool.update( + self.apiclient, + id=self.pools[0].id, + tags=[CLUSTERTAG1]) + + # Launch VM + self.vm = VirtualMachine.create( + self.apiclient, + self.testdata["small"], + templateid=self.template.id, + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering_zone1.id, + zoneid=self.zone.id + ) + + self.testdata["volume"]["zoneid"] = self.zone.id + self.testdata["volume"]["customdisksize"] = 1 + self.data_volume_created = Volume.create_custom_disk( + self.userapiclient, + self.testdata["volume"], + account=self.account.name, + domainid=self.account.domainid, + diskofferingid=self.disk_offering.id, + ) + + self.cleanup.append(self.data_volume_created) + + # Step 4 + self.vm.attach_volume( + self.userapiclient, + self.data_volume_created + ) + + data_volumes_list = Volume.list( + self.userapiclient, + virtualmachineid=self.vm.id, + type="DATA", + listall=True + ) + + self.debug("list volumes using vm id %s" % dir(data_volumes_list[0])) + + data_volumes_list = Volume.list(self.apiclient, + id=self.data_volume_created.id, + listall=True) + data_volume = data_volumes_list[0] + status = validateList(data_volume) + # Step 5 + self.assertEqual( + status[0], + PASS, + "Check: volume list is valid") + + self.assertEqual( + data_volume.state, + "Ready", + "Check: Data volume is attached to VM") + + if data_volume.storage != self.pools[0].name: + self.fail("check if volume is created in correct storage pool") + return diff --git a/test/integration/testpaths/testpath_revert_snap.py b/test/integration/testpaths/testpath_revert_snap.py index 8026f3439197..593440091238 100644 --- a/test/integration/testpaths/testpath_revert_snap.py +++ b/test/integration/testpaths/testpath_revert_snap.py @@ -150,7 +150,12 @@ def test_01_check_revert_snapshot(self): vm_snap = VmSnapshot.create(self.apiclient, vm.id) - volume_list_validation = validateList(vm_snap) + self.assertEqual( + vm_snap.state, + "Ready", + "Check the snapshot of vm is ready!" + ) + #Step 3 with self.assertRaises(Exception): diff --git a/test/integration/testpaths/testpath_snapshot_hadrning.py b/test/integration/testpaths/testpath_snapshot_hadrning.py index 0b72a6aaf3cb..cb31f0f2fced 100755 --- a/test/integration/testpaths/testpath_snapshot_hadrning.py +++ b/test/integration/testpaths/testpath_snapshot_hadrning.py @@ -262,7 +262,6 @@ def setUpClass(cls): cls.testdata["account"], domainid=cls.domain.id ) - cls._cleanup.append(cls.account) # Create user api client of the account cls.userapiclient = testClient.getUserApiClient( @@ -327,6 +326,8 @@ def setUpClass(cls): mode=cls.zone.networktype ) cls._cleanup.append(cls.vm_ha) + + cls._cleanup.append(cls.account) cls.root_volume_ha = list_volumes( cls.userapiclient, virtualmachineid=cls.vm_ha.id, diff --git a/test/integration/testpaths/testpath_snapshot_limits.py b/test/integration/testpaths/testpath_snapshot_limits.py index a99f053e66df..7a27febe615d 100644 --- a/test/integration/testpaths/testpath_snapshot_limits.py +++ b/test/integration/testpaths/testpath_snapshot_limits.py @@ -31,10 +31,13 @@ ) from marvin.lib.common import (get_domain, get_zone, - get_template + get_template, + createChecksum, + list_volumes ) -from marvin.codes import (BACKED_UP, PASS, FAIL) +from marvin.codes import (BACKED_UP, PASS, FAIL, ROOT) +import time class TestStorageSnapshotsLimits(cloudstackTestCase): @@ -99,6 +102,7 @@ def setUpClass(cls): domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, zoneid=cls.zone.id, + mode=cls.zone.networktype ) except Exception as e: @@ -123,24 +127,24 @@ def setUp(self): "Snapshots are not supported on %s" % self.hypervisor) - def tearDown(self): try: - data_volumes_list = Volume.list( - self.userapiclient, - id=self.data_volume_created.id, - virtualmachineid=self.vm.id - ) - status = validateList(data_volumes_list) - self.assertEqual( - status[0], - PASS, - "DATA Volume List Validation Failed") - - self.vm.detach_volume( - self.userapiclient, - data_volumes_list[0] - ) + if hasattr(self, "data_volume_created"): + data_volumes_list = Volume.list( + self.userapiclient, + id=self.data_volume_created.id, + virtualmachineid=self.vm.id + ) + status = validateList(data_volumes_list) + self.assertEqual( + status[0], + PASS, + "DATA Volume List Validation Failed") + + self.vm.detach_volume( + self.userapiclient, + data_volumes_list[0] + ) cleanup_resources(self.apiclient, self.cleanup) except Exception as e: @@ -358,3 +362,129 @@ def test_01_storage_snapshots_limits(self): ) return + + @attr(tags=["advanced", "basic"], required_hardware="true") + def test_02_snapshot_size_check(self): + """ Check Snapshots size in database + 1. Create file on ROOT disk of deployed VM. + 2. Create Snapshot of ROOT disk. + 3. Check if physiacal_size parameter of snapshot_store_ref table + has physical size of snapshot + """ + if self.hypervisor.lower() not in ["xenserver", "vmware"]: + self.skipTest("Test not to be run on %s" % self.hypervisor) + + root_volumes_list = list_volumes( + self.apiclient, + virtualmachineid=self.vm.id, + type=ROOT, + listall=True + ) + + status = validateList(root_volumes_list) + self.assertEqual( + status[0], + PASS, + "Check listVolumes response for ROOT Disk") + + root_volume = root_volumes_list[0] + + # Get Secondary Storage Value from Database + qryresult_before_snapshot = self.dbclient.execute( + " select id, account_name, secondaryStorageTotal\ + from account_view where account_name = '%s';" % + self.account.name) + + self.assertNotEqual( + len(qryresult_before_snapshot), + 0, + "Check sql query to return SecondaryStorageTotal of account") + + storage_qry_result_old = qryresult_before_snapshot[0] + secondary_storage_old = storage_qry_result_old[2] + + createChecksum( + self.testdata, + self.vm, + root_volume, + "rootdiskdevice") + + time.sleep(30) + + root_vol_snapshot = Snapshot.create( + self.apiclient, + root_volume.id) + + snapshots_list = Snapshot.list(self.apiclient, + id=root_vol_snapshot.id) + + status = validateList(snapshots_list) + self.assertEqual(status[0], PASS, "Check listSnapshots response") + # Verify Snapshot state + self.assertEqual( + snapshots_list[0].state.lower() in [ + BACKED_UP, + ], + True, + "Snapshot state is not as expected. It is %s" % + snapshots_list[0].state + ) + + self.assertEqual( + snapshots_list[0].volumeid, + root_volume.id, + "Snapshot volume id is not matching with the vm's volume id") + + qryresult_snp_id = self.dbclient.execute( + "select id\ + from snapshots where uuid = '%s';" % + snapshots_list[0].id) + + self.assertNotEqual( + len(qryresult_snp_id), + 0, + "Check sql query to return physical size of the snapshot") + + snp_id_result = qryresult_snp_id[0] + snp_id = snp_id_result[0] + + qryresult_physical_size = self.dbclient.execute( + " select id, store_id, physical_size\ + from snapshot_store_ref where snapshot_id = '%s' \ + and store_role='Image';" % + snp_id) + + self.assertNotEqual( + len(qryresult_physical_size), + 0, + "Check sql query to return SecondaryStorageTotal of account") + + snapshot_physical_size_result = qryresult_physical_size[0] + snapshot_physical_size = snapshot_physical_size_result[ + 2] + + # Step 3 + qryresult_after_snapshot = self.dbclient.execute( + " select id, account_name, secondaryStorageTotal\ + from account_view where account_name = '%s';" % + self.account.name) + self.assertNotEqual( + len(qryresult_after_snapshot), + 0, + "Check sql query to return SecondaryStorageTotal of account") + + storage_qry_result_from_database = qryresult_after_snapshot[0] + secondary_storage_new = storage_qry_result_from_database[ + 2] + + secondary_storage_after_snapshot = secondary_storage_new - \ + secondary_storage_old + + self.assertEqual( + snapshot_physical_size, + secondary_storage_after_snapshot, + "Check if physical_size attribute of snapshot_store_ref table \ + stores correct value" + ) + + return diff --git a/test/integration/testpaths/testpath_storage_migration.py b/test/integration/testpaths/testpath_storage_migration.py index 3ef31f0cac78..848594daf67e 100644 --- a/test/integration/testpaths/testpath_storage_migration.py +++ b/test/integration/testpaths/testpath_storage_migration.py @@ -248,6 +248,13 @@ def setUpClass(cls): DomainName=cls.account.domain ) # Create Service offering + cls.service_offering = ServiceOffering.create( + cls.apiclient, + cls.testdata["service_offering"] + ) + + cls._cleanup.append(cls.service_offering) + cls.service_offering_zone1 = ServiceOffering.create( cls.apiclient, cls.testdata["service_offering"], diff --git a/test/integration/testpaths/testpath_uuid_event.py b/test/integration/testpaths/testpath_uuid_event.py index 29ec4497d744..71a5abcee528 100644 --- a/test/integration/testpaths/testpath_uuid_event.py +++ b/test/integration/testpaths/testpath_uuid_event.py @@ -167,9 +167,15 @@ def test_01_verify_events_table(self): self.apiclient, root_volume.id) - self.assertNotEqual( - len(snapshot), - 0, + snapshots_list = Snapshot.list(self.userapiclient, + id=snapshot.id) + + status = validateList(snapshots_list) + self.assertEqual(status[0], PASS, "Snapshots List Validation Failed") + + self.assertEqual( + snapshot.state, + "BackedUp", "Check if snapshot gets created properly" ) diff --git a/test/integration/testpaths/testpath_volume_snapshot.py b/test/integration/testpaths/testpath_volume_snapshot.py index 87c5fe480531..c0e609a289b6 100644 --- a/test/integration/testpaths/testpath_volume_snapshot.py +++ b/test/integration/testpaths/testpath_volume_snapshot.py @@ -805,13 +805,13 @@ def test_01_volume_snapshot(self): event_list_validation_result[2]) self.debug("Events list contains event SNAPSHOT.CREATE") + self.testdata["volume"]["zoneid"] = self.zone.id volumeFromSnap = Volume.create_from_snapshot( self.apiclient, data_vol_snap.id, self.testdata["volume"], account=self.account.name, domainid=self.account.domainid, - zoneid=self.zone.id ) self.assertTrue( @@ -926,13 +926,13 @@ def test_01_volume_snapshot(self): "Check resource id in list resources call" ) + self.testdata["volume"]["zoneid"] = self.zone.id volumeFromSnap_2 = Volume.create_from_snapshot( self.apiclient, data_vol_snap_2.id, self.testdata["volume"], account=self.account.name, domainid=self.account.domainid, - zoneid=self.zone.id ) self.vm_2.attach_volume( diff --git a/test/pom.xml b/test/pom.xml index dc9e9d90bb6f..3f1119f9cb4b 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -23,7 +23,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT diff --git a/tools/apidoc/pom.xml b/tools/apidoc/pom.xml index 5013ae32c9eb..75cb1650d17c 100644 --- a/tools/apidoc/pom.xml +++ b/tools/apidoc/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloud-tools - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/tools/checkstyle/pom.xml b/tools/checkstyle/pom.xml index d268eb582a8c..f4ee2b8e1faa 100644 --- a/tools/checkstyle/pom.xml +++ b/tools/checkstyle/pom.xml @@ -24,7 +24,7 @@ Apache CloudStack Developer Tools - Checkstyle Configuration org.apache.cloudstack checkstyle - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT diff --git a/tools/devcloud-kvm/pom.xml b/tools/devcloud-kvm/pom.xml index 0e1b0e7816ec..a71968e95d2e 100644 --- a/tools/devcloud-kvm/pom.xml +++ b/tools/devcloud-kvm/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloud-tools - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/tools/devcloud/pom.xml b/tools/devcloud/pom.xml index 2078fabc6c97..e8bcaebe6065 100644 --- a/tools/devcloud/pom.xml +++ b/tools/devcloud/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloud-tools - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/tools/devcloud4/pom.xml b/tools/devcloud4/pom.xml index 63a36383f458..47493931ba7d 100644 --- a/tools/devcloud4/pom.xml +++ b/tools/devcloud4/pom.xml @@ -17,7 +17,7 @@ org.apache.cloudstack cloud-tools - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/tools/logo/acslogo.jpg b/tools/logo/acsxmas.jpg similarity index 100% rename from tools/logo/acslogo.jpg rename to tools/logo/acsxmas.jpg diff --git a/tools/marvin/marvin/config/setup.cfg b/tools/marvin/marvin/config/setup.cfg index 23981f0f34d0..f694bbadaecc 100644 --- a/tools/marvin/marvin/config/setup.cfg +++ b/tools/marvin/marvin/config/setup.cfg @@ -142,6 +142,10 @@ "LogFolderPath": "/tmp/" }, "globalConfig": [ + { + "name": "quota.enable.service", + "value": "true" + }, { "name": "network.gc.wait", "value": "60" diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py index 3d4745d0cd45..352f8a230728 100644 --- a/tools/marvin/marvin/config/test_data.py +++ b/tools/marvin/marvin/config/test_data.py @@ -1695,5 +1695,115 @@ "ostype": 'CentOS 5.3 (64-bit)', "mode": 'HTTP_DOWNLOAD' } + }, + # Nuage Vsp supported services + "nuage_vsp_services": { + # Services supported by Nuage Vsp for Isolated networks + "isolated_network_offering": { + "name": 'nuage_marvin', + "displaytext": 'nuage_marvin', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'NuageVsp', + "StaticNat": 'NuageVsp', + "SourceNat": 'NuageVsp', + "Firewall": 'NuageVsp', + "Connectivity": 'NuageVsp', + "UserData": 'VirtualRouter' + }, + "serviceCapabilityList": { + "SourceNat": {"SupportedSourceNatTypes": "perzone"} + } + }, + # Services supported by Nuage Vsp for VPC networks + "vpc_network_offering": { + "name": 'nuage_vpc_marvin', + "displaytext": 'nuage_vpc_marvin', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,StaticNat,SourceNat,NetworkACL,Connectivity,UserData', + "traffictype": 'GUEST', + "availability": 'Optional', + "useVpc": 'on', + "ispersistent": 'True', + "serviceProviderList": { + "Dhcp": "NuageVsp", + "StaticNat": "NuageVsp", + "SourceNat": "NuageVsp", + "NetworkACL": "NuageVsp", + "Connectivity": "NuageVsp", + "UserData": "VpcVirtualRouter" + }, + "serviceCapabilityList": { + "SourceNat": {"SupportedSourceNatTypes": "perzone"} + } + }, + # Nuage Vsp supports only pre-defined and custom VPC offerings + "vpc_offering": { + "name": 'Nuage VSP VPC offering', + "displaytext": 'Nuage VSP VPC offering', + "supportedservices": 'Dhcp,StaticNat,SourceNat,NetworkACL,Connectivity,UserData', + "serviceProviderList": { + "Dhcp": "NuageVsp", + "StaticNat": "NuageVsp", + "SourceNat": "NuageVsp", + "NetworkACL": "NuageVsp", + "Connectivity": "NuageVsp", + "UserData": "VpcVirtualRouter" + } } + }, + + #_pr -_ passwordreset - below services used in test_nuage_password_reset + "network_offering_pr": { + "name": 'nuage_marvin', + "displaytext": 'nuage_marvin', + "guestiptype": 'Isolated', + "supportedservices": + 'Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "UserData": 'VirtualRouter', + "Dhcp": 'NuageVsp', + "Connectivity": 'NuageVsp', + "StaticNat": 'NuageVsp', + "SourceNat": 'NuageVsp', + "Firewall": 'NuageVsp' + }, + }, + "network_pr": { + "name": "Test Network", + "displaytext": "Test Network", + "netmask": '255.255.255.0' + }, + "fw_rule_pr": { + "startport": 1, + "endport": 6000, + "cidr": '0.0.0.0/0', + # Any network (For creating FW rule) + "protocol": "TCP" + }, + "virtual_machine_pr": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'kvm', + # Hypervisor type should be same as + # hypervisor type of cluster + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + "userdata": "This is sample data", + }, + "template_pr": { + "displaytext": "Cent OS Template", + "name": "Cent OS Template", + "passwordenabled": True, + }, + "ostype_pr": 'CentOS 5.5 (64-bit)', + } diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index 4e04ba82496f..e2f4a2c86449 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -1201,6 +1201,9 @@ def create_from_snapshot(cls, apiclient, snapshot, services, random_gen() ]) if random_name else services["name"] + if services["ispublic"]: + cmd.ispublic = services["ispublic"] + if "ostypeid" in services: cmd.ostypeid = services["ostypeid"] elif "ostype" in services: @@ -3857,7 +3860,7 @@ def __init__(self, items): @classmethod def add(cls, apiclient, services, physicalnetworkid, - hostname=None, username=None, password=None, transportzoneuuid=None): + hostname=None, username=None, password=None, transportzoneuuid=None, l2gatewayserviceuuid=None): cmd = addNiciraNvpDevice.addNiciraNvpDeviceCmd() cmd.physicalnetworkid = physicalnetworkid if hostname: @@ -3880,7 +3883,12 @@ def add(cls, apiclient, services, physicalnetworkid, else: cmd.transportzoneuuid = services['transportZoneUuid'] - return NiciraNvp(apiclient.addNiciraNvpDevice(cmd).__dict__) + if l2gatewayserviceuuid: + cmd.l2gatewayserviceuuid = l2gatewayserviceuuid + elif services and 'l2gatewayserviceuuid' in services: + cmd.l2gatewayserviceuuid = services['l2gatewayserviceuuid'] + + return NiciraNvp(apiclient.addNiciraNvpDevice(cmd).__dict__) def delete(self, apiclient): cmd = deleteNiciraNvpDevice.deleteNiciraNvpDeviceCmd() @@ -3949,6 +3957,61 @@ def list(cls, apiclient, **kwargs): return(apiclient.listNetworkServiceProviders(cmd)) +class Nuage: + """Manage external nuage VSD device""" + + def __init__(self, items): + self.__dict__.update(items) + + @classmethod + def add(cls, apiclient, services, physicalnetworkid, username=None, password=None): + """Add external nuage VSD device to cloudstack""" + + cmd = addNuageVspDevice.addNuageVspDeviceCmd() + cmd.physicalnetworkid = physicalnetworkid + if username: + cmd.username = username + else: + cmd.username = services["username"] + + if password: + cmd.password = password + else: + cmd.password = services["password"] + + cmd.hostname = services["hostname"] + cmd.port = services["port"] + cmd.retrycount = services["retrycount"] + cmd.retryinterval = services["retryinterval"] + cmd.apiversion = services["apiversion"] + + return Nuage(apiclient.addNuageVspDevice(cmd).__dict__) + + def update(self, apiclient, **kwargs): + """Deletes a nuage VSD device from CloudStack""" + + cmd = updateNuageVspDevice.updateNuageVspDeviceCmd() + cmd.physicalnetworkid = self.physicalnetworkid + [setattr(cmd, k, v) for k, v in kwargs.items()] + return apiclient.updateNuageVspDevice(cmd) + + def delete(self, apiclient): + """Deletes a nuage VSD device from CloudStack""" + + cmd = deleteNuageVspDevice.deleteNuageVspDeviceCmd() + cmd.vspdeviceid = self.vspdeviceid + apiclient.deleteNuageVspDevice(cmd) + return + + @classmethod + def list(cls, apiclient, **kwargs): + """List already registered netscaler devices""" + + cmd = listNuageVspDevices.listNuageVspDevicesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listNuageVspDevices(cmd)) + + class Router: """Manage router life cycle""" @@ -4059,9 +4122,9 @@ def __init__(self, items): @classmethod def create(cls, apiclient, services): """Create vpc offering""" - + import logging - + cmd = createVPCOffering.createVPCOfferingCmd() cmd.name = "-".join([services["name"], random_gen()]) cmd.displaytext = services["displaytext"] diff --git a/tools/marvin/marvin/lib/common.py b/tools/marvin/marvin/lib/common.py index fa45299030bb..5f738f4bf919 100644 --- a/tools/marvin/marvin/lib/common.py +++ b/tools/marvin/marvin/lib/common.py @@ -56,7 +56,8 @@ listVirtualRouterElements, listNetworkOfferings, listResourceLimits, - listVPCOfferings) + listVPCOfferings, + migrateSystemVm) from marvin.sshClient import SshClient from marvin.codes import (PASS, FAILED, ISOLATED_NETWORK, VPC_NETWORK, BASIC_ZONE, FAIL, NAT_RULE, STATIC_NAT_RULE, @@ -64,8 +65,8 @@ RESOURCE_CPU, RESOURCE_MEMORY, PUBLIC_TRAFFIC, GUEST_TRAFFIC, MANAGEMENT_TRAFFIC, STORAGE_TRAFFIC, VMWAREDVS) -from marvin.lib.utils import (validateList, - xsplit, +from marvin.lib.utils import (validateList, + xsplit, get_process_status, random_gen, format_volume_to_ext3) @@ -1419,13 +1420,13 @@ def isNetworkDeleted(apiclient, networkid, timeout=600): return networkDeleted -def createChecksum(service=None, - virtual_machine=None, - disk=None, +def createChecksum(service=None, + virtual_machine=None, + disk=None, disk_type=None): """ Calculate the MD5 checksum of the disk by writing \ - data on the disk where disk_type is either root disk or data disk + data on the disk where disk_type is either root disk or data disk @return: returns the calculated checksum""" random_data_0 = random_gen(size=100) @@ -1440,7 +1441,7 @@ def createChecksum(service=None, virtual_machine.username, virtual_machine.password ) - except Exception: + except Exception: raise Exception("SSH access failed for server with IP address: %s" % virtual_machine.ssh_ip) @@ -1898,3 +1899,10 @@ def verifyVCenterPortGroups( except Exception as e: return [FAIL, e] return [PASS, None] + +def migrate_router(apiclient, router_id, host_id): + cmd = migrateSystemVm.migrateSystemVmCmd() + cmd.hostid = host_id + cmd.virtualmachineid = router_id + + apiclient.migrateSystemVm(cmd) diff --git a/tools/marvin/pom.xml b/tools/marvin/pom.xml index 2c8973d8848e..391987be4b54 100644 --- a/tools/marvin/pom.xml +++ b/tools/marvin/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloud-tools - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/tools/marvin/setup.py b/tools/marvin/setup.py index 8bbecbe6819d..81fefd829c67 100644 --- a/tools/marvin/setup.py +++ b/tools/marvin/setup.py @@ -27,7 +27,7 @@ raise RuntimeError("python setuptools is required to build Marvin") -VERSION = "4.7.2-SNAPSHOT" +VERSION = "4.9.0-SNAPSHOT" setup(name="Marvin", version=VERSION, diff --git a/tools/pom.xml b/tools/pom.xml index 858e8b158457..02ad3185db2a 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -27,7 +27,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/tools/wix-cloudstack-maven-plugin/pom.xml b/tools/wix-cloudstack-maven-plugin/pom.xml index da20c0bd5325..deb4284b3d22 100644 --- a/tools/wix-cloudstack-maven-plugin/pom.xml +++ b/tools/wix-cloudstack-maven-plugin/pom.xml @@ -16,7 +16,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../../pom.xml diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 753598dadaf1..23f689266ea1 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -3554,7 +3554,7 @@ div.toolbar div.section-switcher div.section-select label { /*Breadcrumbs*/ div.toolbar div.filters { margin: 5px 0px 0 12px; - width: 168px; + width: 200px; float: left; } diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index e82ae19ebbcd..b97141ca3b83 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -934,6 +934,7 @@ dictionary = { 'label.nfs.storage': '', 'label.nic.adapter.type': '', 'label.nicira.controller.address': '', +'label.nicira.l2gatewayserviceuuid': '', 'label.nicira.l3gatewayserviceuuid': '', 'label.nicira.transportzoneuuid': '', 'label.brocade.vcs.address': '', diff --git a/ui/plugins/plugins.js b/ui/plugins/plugins.js index b629e3095b6c..21da7a07f4d0 100644 --- a/ui/plugins/plugins.js +++ b/ui/plugins/plugins.js @@ -16,7 +16,7 @@ // under the License. (function($, cloudStack) { cloudStack.plugins = [ - 'quota', - //'testPlugin' + //'testPlugin', + 'quota' ]; }(jQuery, cloudStack)); diff --git a/ui/plugins/quota/quota.js b/ui/plugins/quota/quota.js index 94a8730b5ef4..5514bd4ebed9 100644 --- a/ui/plugins/quota/quota.js +++ b/ui/plugins/quota/quota.js @@ -79,9 +79,9 @@ indicator: { 'enabled': 'on', 'disabled': 'off', - 'locked': 'off', + 'locked': 'off' } - }, + } }, dataProvider: function(args) { var data = { @@ -171,7 +171,7 @@ label: 'label.quota.enforcequota', isBoolean: true, isChecked: false - }, + } } }, @@ -196,7 +196,7 @@ }); $(window).trigger('cloudStack.fullRefresh'); } - }, + } }, tabs: { details: { @@ -207,10 +207,10 @@ } }, { startdate: { - label: 'label.quota.date', + label: 'label.quota.date' }, startquota: { - label: 'label.quota.value', + label: 'label.quota.value' } }], dataProvider: function(args) { @@ -235,8 +235,7 @@ } }); } - }, - + } } } } @@ -277,9 +276,9 @@ indicator: { 'enabled': 'on', 'disabled': 'off', - 'locked': 'off', + 'locked': 'off' } - }, + } }, dataProvider: function(args) { var data = { @@ -369,7 +368,7 @@ label: 'label.quota.enforcequota', isBoolean: true, isChecked: false - }, + } } }, @@ -394,7 +393,7 @@ }); $(window).trigger('cloudStack.fullRefresh'); } - }, + } }, tabs: { details: { @@ -405,10 +404,10 @@ } }, { startdate: { - label: 'label.quota.date', + label: 'label.quota.date' }, startquota: { - label: 'label.quota.value', + label: 'label.quota.value' } }], dataProvider: function(args) { @@ -433,7 +432,7 @@ } }); } - }, + } } } } @@ -668,7 +667,7 @@ action: function(args) { if (isAdmin()) { var data = { - usagetype: args.data.jsonObj.usageType, + usagetype: args.data.jsonObj.usageType }; var tariffVal = args.data.tariffValue.split(' '); if (tariffVal.length==2){ @@ -697,7 +696,7 @@ validation: { required: true } - }, + } } }, after: function(argsLocal) { @@ -769,7 +768,7 @@ input.datepicker({ defaultDate: new Date(), changeMonth: true, - dateFormat: "yy-mm-dd", + dateFormat: "yy-mm-dd" }); input.parent().attr('title', _l('label.quota.effectivedate')); }, @@ -800,7 +799,7 @@ label: 'label.usage.unit' }, tariffValue: { - label: 'label.quota.tariff.value', + label: 'label.quota.tariff.value' }, description: { label: 'label.quota.description', @@ -832,7 +831,7 @@ input.datepicker({ defaultDate: new Date(), changeMonth: true, - dateFormat: "yy-mm-dd", + dateFormat: "yy-mm-dd" }); input.parent().attr('title', _l('label.quota.effectivedate')); }, @@ -854,7 +853,7 @@ disableInfiniteScrolling: true, fields: { templatetype: { - label: 'label.quota.email.template', + label: 'label.quota.email.template' }, templatesubject: { label: 'label.quota.email.subject', @@ -867,7 +866,7 @@ last_updated: { label: 'label.quota.email.lastupdated', truncate: true - }, + } }, dataProvider: function(args) { var data = {}; @@ -941,8 +940,8 @@ textArea: true }, last_updated: { - label: 'label.quota.email.lastupdated', - }, + label: 'label.quota.email.lastupdated' + } }], dataProvider: function(args) { diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js index db0ab3fc34d4..0058b6902496 100644 --- a/ui/scripts/accounts.js +++ b/ui/scripts/accounts.js @@ -1337,7 +1337,7 @@ $.ajax({ url: createURL('listSamlAuthorization'), data: { - userid: context.users[0].id, + userid: context.users[0].id }, success: function(json) { var authorization = json.listsamlauthorizationsresponse.samlauthorization[0]; @@ -1881,7 +1881,7 @@ if (!args.context.projects) { $.extend(data, { domainid: args.context.sshkeypairs[0].domainid, - account: args.context.sshkeypairs[0].account, + account: args.context.sshkeypairs[0].account }); } $.ajax({ diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js index 6e41607fb464..0725bf3bef1a 100644 --- a/ui/scripts/cloudStack.js +++ b/ui/scripts/cloudStack.js @@ -181,7 +181,7 @@ } }, error: function(xhr) { // ignore any errors, fallback to the default - }, + } }); diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index a367f46bebb9..19db25702963 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -310,7 +310,7 @@ return 'label.metrics'; } } - }, + } }, dataProvider: function(args) { diff --git a/ui/scripts/metrics.js b/ui/scripts/metrics.js index 6ac376e6f159..e7b9df8e7618 100644 --- a/ui/scripts/metrics.js +++ b/ui/scripts/metrics.js @@ -23,7 +23,7 @@ name: { label: 'metrics' } - }, + } } }; @@ -546,7 +546,7 @@ 'Error': 'off', 'Connecting': 'transition', 'Rebalancing': 'transition', - 'Alert': 'warning', + 'Alert': 'warning' }, compact: true }, @@ -558,7 +558,7 @@ collapsible: true, columns: { cores: { - label: 'label.metrics.num.cpu.cores', + label: 'label.metrics.num.cpu.cores' }, cputotal: { label: 'label.metrics.cpu.total' @@ -778,7 +778,7 @@ 'Stopping': 'transition', 'Starting': 'transition', 'Migrating': 'transition', - 'Shutdowned': 'warning', + 'Shutdowned': 'warning' }, compact: true }, @@ -793,13 +793,13 @@ collapsible: true, columns: { cores: { - label: 'label.metrics.num.cpu.cores', + label: 'label.metrics.num.cpu.cores' }, cputotal: { label: 'label.metrics.cpu.total' }, cpuused: { - label: 'label.metrics.cpu.used.avg', + label: 'label.metrics.cpu.used.avg' } } }, @@ -922,7 +922,7 @@ 'Expunging': 'off', 'Migrating': 'warning', 'UploadOp': 'transition', - 'Snapshotting': 'warning', + 'Snapshotting': 'warning' }, compact: true }, @@ -937,7 +937,7 @@ }, storagepool: { label: 'label.metrics.storagepool' - }, + } }, dataProvider: function(args) { var data = {listAll: true}; @@ -1000,7 +1000,7 @@ 'ErrorInMaintenance': 'off', 'PrepareForMaintenance': 'transition', 'CancelMaintenance': 'warning', - 'Maintenance': 'warning', + 'Maintenance': 'warning' }, compact: true }, @@ -1009,7 +1009,7 @@ }, type: { label: 'label.metrics.disk.storagetype' - }, + } } }, disk: { diff --git a/ui/scripts/system.js b/ui/scripts/system.js index af69359637b0..4cb8094add32 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -870,7 +870,7 @@ var data = { id: args.context.multiRule[0].id, zoneid: args.context.multiRule[0].zoneid, - domainid: args.data.domainid, + domainid: args.data.domainid }; if (args.data.account) { $.extend(data, { @@ -5774,6 +5774,9 @@ }, l3gatewayserviceuuid: { label: 'label.nicira.l3gatewayserviceuuid' + }, + l2gatewayserviceuuid: { + label: 'label.nicira.l2gatewayserviceuuid' } } }, @@ -7869,7 +7872,7 @@ return 'label.metrics'; } } - }, + } }, detailView: { @@ -12539,6 +12542,9 @@ }, l3gatewayserviceuuid: { label: 'label.nicira.l3gatewayserviceuuid' + }, + l2gatewayserviceuuid: { + label: 'label.nicira.l2gatewayserviceuuid' } }, actions: { @@ -12569,7 +12575,10 @@ }, l3gatewayserviceuuid: { label: 'label.nicira.l3gatewayserviceuuid' - } + }, + l2gatewayserviceuuid: { + label: 'label.nicira.l2gatewayserviceuuid' + } } }, action: function (args) { @@ -12687,7 +12696,10 @@ }, l3gatewayserviceuuid: { label: 'label.nicira.l3gatewayserviceuuid' - } + }, + l2gatewayserviceuuid: { + label: 'label.nicira.l2gatewayserviceuuid' + } }], dataProvider: function (args) { $.ajax({ @@ -20324,6 +20336,11 @@ if (l3GatewayServiceUuid != null && l3GatewayServiceUuid.length > 0) { array1.push("&l3gatewayserviceuuid=" + todb(args.data.l3gatewayserviceuuid)); } + + var l2GatewayServiceUuid = args.data.l2gatewayserviceuuid; + if (l2GatewayServiceUuid != null && l2GatewayServiceUuid.length > 0) { + array1.push("&l2gatewayserviceuuid=" + todb(args.data.l2gatewayserviceuuid)); + } $.ajax({ url: createURL(apiCmd + array1.join("")), diff --git a/usage/pom.xml b/usage/pom.xml index 8eb0d43a098a..ff10e819e462 100644 --- a/usage/pom.xml +++ b/usage/pom.xml @@ -15,7 +15,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT diff --git a/utils/pom.xml b/utils/pom.xml index 2be9e2de5465..3a23a58774f6 100755 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -26,7 +26,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT ../pom.xml diff --git a/utils/src/main/java/com/cloud/utils/rest/CloudstackRESTException.java b/utils/src/main/java/com/cloud/utils/rest/CloudstackRESTException.java index 2078d576775b..9b703c6a9f4d 100644 --- a/utils/src/main/java/com/cloud/utils/rest/CloudstackRESTException.java +++ b/utils/src/main/java/com/cloud/utils/rest/CloudstackRESTException.java @@ -22,6 +22,8 @@ @SuppressWarnings("serial") public class CloudstackRESTException extends Exception { + private int errorCode; + public CloudstackRESTException(final String message) { super(message); } @@ -30,4 +32,18 @@ public CloudstackRESTException(final String message, final Throwable cause) { super(message, cause); } + public CloudstackRESTException(final String message, final int errorCode) { + super(message); + this.errorCode = errorCode; + } + + public CloudstackRESTException(final String message, final Throwable cause, final int errorCode) { + super(message, cause); + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } + } diff --git a/utils/src/main/java/com/cloud/utils/rest/HttpStatusCodeHelper.java b/utils/src/main/java/com/cloud/utils/rest/HttpStatusCodeHelper.java index 9492920b8cf5..98c88baff00d 100644 --- a/utils/src/main/java/com/cloud/utils/rest/HttpStatusCodeHelper.java +++ b/utils/src/main/java/com/cloud/utils/rest/HttpStatusCodeHelper.java @@ -31,4 +31,8 @@ public static boolean isUnauthorized(final int statusCode) { return statusCode == HttpStatus.SC_UNAUTHORIZED; } + public static boolean isConflict(final int statusCode){ + return statusCode == HttpStatus.SC_CONFLICT; + } + } diff --git a/utils/src/main/java/com/cloud/utils/rest/RESTServiceConnector.java b/utils/src/main/java/com/cloud/utils/rest/RESTServiceConnector.java index fc5bae382830..ffa2905103bb 100644 --- a/utils/src/main/java/com/cloud/utils/rest/RESTServiceConnector.java +++ b/utils/src/main/java/com/cloud/utils/rest/RESTServiceConnector.java @@ -127,7 +127,7 @@ private T readResponseBody(final CloseableHttpResponse response, final Type final HttpEntity entity = response.getEntity(); try { final String stringEntity = EntityUtils.toString(entity); - s_logger.debug("Response entity: " + stringEntity); + //s_logger.debug("Response entity: " + stringEntity); EntityUtils.consumeQuietly(entity); return gson.fromJson(stringEntity, type); } catch (final IOException e) { diff --git a/utils/src/test/java/com/cloud/utils/TestProfiler.java b/utils/src/test/java/com/cloud/utils/TestProfiler.java index 25b651844bd5..f0e163e63f96 100644 --- a/utils/src/test/java/com/cloud/utils/TestProfiler.java +++ b/utils/src/test/java/com/cloud/utils/TestProfiler.java @@ -28,9 +28,12 @@ public class TestProfiler extends Log4jEnabledTestCase { protected final static Logger s_logger = Logger.getLogger(TestProfiler.class); - private static final long ONE_SECOND = 1000l; private static final long MILLIS_FACTOR = 1000l; private static final int MARGIN = 100; + // Profiler uses System.nanoTime which is not reliable on the millisecond + // A sleep of 1000 milliseconds CAN be measured as 999 milliseconds + // Therefore make the second larger, by 10% of the margin + private static final long ONE_SECOND = 1000l + (MARGIN / 10); private static final double EXPONENT = 3d; @Test diff --git a/vmware-base/pom.xml b/vmware-base/pom.xml index f161f2d53729..e18dc8ea145c 100644 --- a/vmware-base/pom.xml +++ b/vmware-base/pom.xml @@ -24,7 +24,7 @@ org.apache.cloudstack cloudstack - 4.7.2-SNAPSHOT + 4.9.0-SNAPSHOT