mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge branch '4.19' into 4.20
This commit is contained in:
commit
4f3e8e8c5a
@ -26,7 +26,7 @@ import com.cloud.utils.SerialVersionUID;
|
|||||||
public class StorageAccessException extends RuntimeException {
|
public class StorageAccessException extends RuntimeException {
|
||||||
private static final long serialVersionUID = SerialVersionUID.StorageAccessException;
|
private static final long serialVersionUID = SerialVersionUID.StorageAccessException;
|
||||||
|
|
||||||
public StorageAccessException(String message) {
|
public StorageAccessException(String message, Exception causer) {
|
||||||
super(message);
|
super(message, causer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,14 +16,10 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.storage;
|
package com.cloud.storage;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.NotImplementedException;
|
import org.apache.commons.lang.NotImplementedException;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class Storage {
|
public class Storage {
|
||||||
public static enum ImageFormat {
|
public static enum ImageFormat {
|
||||||
@ -139,6 +135,21 @@ public class Storage {
|
|||||||
ISODISK /* Template corresponding to a iso (non root disk) present in an OVA */
|
ISODISK /* Template corresponding to a iso (non root disk) present in an OVA */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum EncryptionSupport {
|
||||||
|
/**
|
||||||
|
* Encryption not supported.
|
||||||
|
*/
|
||||||
|
Unsupported,
|
||||||
|
/**
|
||||||
|
* Will use hypervisor encryption driver (qemu -> luks)
|
||||||
|
*/
|
||||||
|
Hypervisor,
|
||||||
|
/**
|
||||||
|
* Storage pool handles encryption and just provides an encrypted volume
|
||||||
|
*/
|
||||||
|
Storage
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StoragePoolTypes carry some details about the format and capabilities of a storage pool. While not necessarily a
|
* StoragePoolTypes carry some details about the format and capabilities of a storage pool. While not necessarily a
|
||||||
* 1:1 with PrimaryDataStoreDriver (and for KVM agent, KVMStoragePool and StorageAdaptor) implementations, it is
|
* 1:1 with PrimaryDataStoreDriver (and for KVM agent, KVMStoragePool and StorageAdaptor) implementations, it is
|
||||||
@ -150,61 +161,37 @@ public class Storage {
|
|||||||
* ensure this is available on the agent side as well. This is best done by defining the StoragePoolType in a common
|
* ensure this is available on the agent side as well. This is best done by defining the StoragePoolType in a common
|
||||||
* package available on both management server and agent plugin jars.
|
* package available on both management server and agent plugin jars.
|
||||||
*/
|
*/
|
||||||
public static class StoragePoolType {
|
public static enum StoragePoolType {
|
||||||
private static final Map<String, StoragePoolType> map = new LinkedHashMap<>();
|
Filesystem(false, true, EncryptionSupport.Hypervisor), // local directory
|
||||||
|
NetworkFilesystem(true, true, EncryptionSupport.Hypervisor), // NFS
|
||||||
|
IscsiLUN(true, false, EncryptionSupport.Unsupported), // shared LUN, with a clusterfs overlay
|
||||||
|
Iscsi(true, false, EncryptionSupport.Unsupported), // for e.g., ZFS Comstar
|
||||||
|
ISO(false, false, EncryptionSupport.Unsupported), // for iso image
|
||||||
|
LVM(false, false, EncryptionSupport.Unsupported), // XenServer local LVM SR
|
||||||
|
CLVM(true, false, EncryptionSupport.Unsupported),
|
||||||
|
RBD(true, true, EncryptionSupport.Unsupported), // http://libvirt.org/storage.html#StorageBackendRBD
|
||||||
|
SharedMountPoint(true, true, EncryptionSupport.Hypervisor),
|
||||||
|
VMFS(true, true, EncryptionSupport.Unsupported), // VMware VMFS storage
|
||||||
|
PreSetup(true, true, EncryptionSupport.Unsupported), // for XenServer, Storage Pool is set up by customers.
|
||||||
|
EXT(false, true, EncryptionSupport.Unsupported), // XenServer local EXT SR
|
||||||
|
OCFS2(true, false, EncryptionSupport.Unsupported),
|
||||||
|
SMB(true, false, EncryptionSupport.Unsupported),
|
||||||
|
Gluster(true, false, EncryptionSupport.Unsupported),
|
||||||
|
PowerFlex(true, true, EncryptionSupport.Hypervisor), // Dell EMC PowerFlex/ScaleIO (formerly VxFlexOS)
|
||||||
|
ManagedNFS(true, false, EncryptionSupport.Unsupported),
|
||||||
|
Linstor(true, true, EncryptionSupport.Storage),
|
||||||
|
DatastoreCluster(true, true, EncryptionSupport.Unsupported), // for VMware, to abstract pool of clusters
|
||||||
|
StorPool(true, true, EncryptionSupport.Hypervisor),
|
||||||
|
FiberChannel(true, true, EncryptionSupport.Unsupported); // Fiber Channel Pool for KVM hypervisors is used to find the volume by WWN value (/dev/disk/by-id/wwn-<wwnvalue>)
|
||||||
|
|
||||||
public static final StoragePoolType Filesystem = new StoragePoolType("Filesystem", false, true, true);
|
|
||||||
public static final StoragePoolType NetworkFilesystem = new StoragePoolType("NetworkFilesystem", true, true, true);
|
|
||||||
public static final StoragePoolType IscsiLUN = new StoragePoolType("IscsiLUN", true, false, false);
|
|
||||||
public static final StoragePoolType Iscsi = new StoragePoolType("Iscsi", true, false, false);
|
|
||||||
public static final StoragePoolType ISO = new StoragePoolType("ISO", false, false, false);
|
|
||||||
public static final StoragePoolType LVM = new StoragePoolType("LVM", false, false, false);
|
|
||||||
public static final StoragePoolType CLVM = new StoragePoolType("CLVM", true, false, false);
|
|
||||||
public static final StoragePoolType RBD = new StoragePoolType("RBD", true, true, false);
|
|
||||||
public static final StoragePoolType SharedMountPoint = new StoragePoolType("SharedMountPoint", true, true, true);
|
|
||||||
public static final StoragePoolType VMFS = new StoragePoolType("VMFS", true, true, false);
|
|
||||||
public static final StoragePoolType PreSetup = new StoragePoolType("PreSetup", true, true, false);
|
|
||||||
public static final StoragePoolType EXT = new StoragePoolType("EXT", false, true, false);
|
|
||||||
public static final StoragePoolType OCFS2 = new StoragePoolType("OCFS2", true, false, false);
|
|
||||||
public static final StoragePoolType SMB = new StoragePoolType("SMB", true, false, false);
|
|
||||||
public static final StoragePoolType Gluster = new StoragePoolType("Gluster", true, false, false);
|
|
||||||
public static final StoragePoolType PowerFlex = new StoragePoolType("PowerFlex", true, true, true);
|
|
||||||
public static final StoragePoolType ManagedNFS = new StoragePoolType("ManagedNFS", true, false, false);
|
|
||||||
public static final StoragePoolType Linstor = new StoragePoolType("Linstor", true, true, false);
|
|
||||||
public static final StoragePoolType DatastoreCluster = new StoragePoolType("DatastoreCluster", true, true, false);
|
|
||||||
public static final StoragePoolType StorPool = new StoragePoolType("StorPool", true,true,true);
|
|
||||||
public static final StoragePoolType FiberChannel = new StoragePoolType("FiberChannel", true,true,false);
|
|
||||||
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final boolean shared;
|
private final boolean shared;
|
||||||
private final boolean overProvisioning;
|
private final boolean overProvisioning;
|
||||||
private final boolean encryption;
|
private final EncryptionSupport encryption;
|
||||||
|
|
||||||
/**
|
StoragePoolType(boolean shared, boolean overProvisioning, EncryptionSupport encryption) {
|
||||||
* New StoragePoolType, set the name to check with it in Dao (Note: Do not register it into the map of pool types).
|
|
||||||
* @param name name of the StoragePoolType.
|
|
||||||
*/
|
|
||||||
public StoragePoolType(String name) {
|
|
||||||
this.name = name;
|
|
||||||
this.shared = false;
|
|
||||||
this.overProvisioning = false;
|
|
||||||
this.encryption = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a new StoragePoolType, and register it into the map of pool types known to the management server.
|
|
||||||
* @param name Simple unique name of the StoragePoolType.
|
|
||||||
* @param shared Storage pool is shared/accessible to multiple hypervisors
|
|
||||||
* @param overProvisioning Storage pool supports overProvisioning
|
|
||||||
* @param encryption Storage pool supports encrypted volumes
|
|
||||||
*/
|
|
||||||
public StoragePoolType(String name, boolean shared, boolean overProvisioning, boolean encryption) {
|
|
||||||
this.name = name;
|
|
||||||
this.shared = shared;
|
this.shared = shared;
|
||||||
this.overProvisioning = overProvisioning;
|
this.overProvisioning = overProvisioning;
|
||||||
this.encryption = encryption;
|
this.encryption = encryption;
|
||||||
addStoragePoolType(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isShared() {
|
public boolean isShared() {
|
||||||
@ -216,50 +203,12 @@ public class Storage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean supportsEncryption() {
|
public boolean supportsEncryption() {
|
||||||
|
return encryption == EncryptionSupport.Hypervisor || encryption == EncryptionSupport.Storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EncryptionSupport encryptionSupportMode() {
|
||||||
return encryption;
|
return encryption;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addStoragePoolType(StoragePoolType storagePoolType) {
|
|
||||||
map.putIfAbsent(storagePoolType.name, storagePoolType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StoragePoolType[] values() {
|
|
||||||
return map.values().toArray(StoragePoolType[]::new).clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StoragePoolType valueOf(String name) {
|
|
||||||
if (StringUtils.isBlank(name)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
StoragePoolType storage = map.get(name);
|
|
||||||
if (storage == null) {
|
|
||||||
throw new IllegalArgumentException("StoragePoolType '" + name + "' not found");
|
|
||||||
}
|
|
||||||
return storage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String name() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
StoragePoolType that = (StoragePoolType) o;
|
|
||||||
return Objects.equals(name, that.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<StoragePoolType> getNonSharedStoragePoolTypes() {
|
public static List<StoragePoolType> getNonSharedStoragePoolTypes() {
|
||||||
|
|||||||
@ -57,6 +57,7 @@ public class ApiConstants {
|
|||||||
public static final String BASE64_IMAGE = "base64image";
|
public static final String BASE64_IMAGE = "base64image";
|
||||||
public static final String BGP_PEERS = "bgppeers";
|
public static final String BGP_PEERS = "bgppeers";
|
||||||
public static final String BGP_PEER_IDS = "bgppeerids";
|
public static final String BGP_PEER_IDS = "bgppeerids";
|
||||||
|
public static final String BATCH_SIZE = "batchsize";
|
||||||
public static final String BITS = "bits";
|
public static final String BITS = "bits";
|
||||||
public static final String BOOTABLE = "bootable";
|
public static final String BOOTABLE = "bootable";
|
||||||
public static final String BIND_DN = "binddn";
|
public static final String BIND_DN = "binddn";
|
||||||
@ -476,11 +477,12 @@ public class ApiConstants {
|
|||||||
public static final String STATE = "state";
|
public static final String STATE = "state";
|
||||||
public static final String STATS = "stats";
|
public static final String STATS = "stats";
|
||||||
public static final String STATUS = "status";
|
public static final String STATUS = "status";
|
||||||
public static final String STORAGE_TYPE = "storagetype";
|
|
||||||
public static final String STORAGE_POLICY = "storagepolicy";
|
|
||||||
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
|
|
||||||
public static final String STORAGE_CAPABILITIES = "storagecapabilities";
|
public static final String STORAGE_CAPABILITIES = "storagecapabilities";
|
||||||
public static final String STORAGE_CUSTOM_STATS = "storagecustomstats";
|
public static final String STORAGE_CUSTOM_STATS = "storagecustomstats";
|
||||||
|
public static final String STORAGE_MOTION_ENABLED = "storagemotionenabled";
|
||||||
|
public static final String STORAGE_POLICY = "storagepolicy";
|
||||||
|
public static final String STORAGE_POOL = "storagepool";
|
||||||
|
public static final String STORAGE_TYPE = "storagetype";
|
||||||
public static final String SUBNET = "subnet";
|
public static final String SUBNET = "subnet";
|
||||||
public static final String OWNER = "owner";
|
public static final String OWNER = "owner";
|
||||||
public static final String SWAP_OWNER = "swapowner";
|
public static final String SWAP_OWNER = "swapowner";
|
||||||
@ -953,7 +955,6 @@ public class ApiConstants {
|
|||||||
public static final String AUTOSCALE_VMGROUP_NAME = "autoscalevmgroupname";
|
public static final String AUTOSCALE_VMGROUP_NAME = "autoscalevmgroupname";
|
||||||
public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername";
|
public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername";
|
||||||
public static final String BAREMETAL_RCT_URL = "baremetalrcturl";
|
public static final String BAREMETAL_RCT_URL = "baremetalrcturl";
|
||||||
public static final String BATCH_SIZE = "batchsize";
|
|
||||||
public static final String UCS_DN = "ucsdn";
|
public static final String UCS_DN = "ucsdn";
|
||||||
public static final String GSLB_PROVIDER = "gslbprovider";
|
public static final String GSLB_PROVIDER = "gslbprovider";
|
||||||
public static final String EXCLUSIVE_GSLB_PROVIDER = "isexclusivegslbprovider";
|
public static final String EXCLUSIVE_GSLB_PROVIDER = "isexclusivegslbprovider";
|
||||||
@ -1190,6 +1191,7 @@ public class ApiConstants {
|
|||||||
"a boolean or a numeric value: if it results in a boolean value, the tariff value will be applied according to the result; if it results in a numeric value, the " +
|
"a boolean or a numeric value: if it results in a boolean value, the tariff value will be applied according to the result; if it results in a numeric value, the " +
|
||||||
"numeric value will be applied; if the result is neither a boolean nor a numeric value, the tariff will not be applied. If the rule is not informed, the tariff " +
|
"numeric value will be applied; if the result is neither a boolean nor a numeric value, the tariff will not be applied. If the rule is not informed, the tariff " +
|
||||||
"value will be applied.";
|
"value will be applied.";
|
||||||
|
public static final String VMWARE_DC = "vmwaredc";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This enum specifies IO Drivers, each option controls specific policies on I/O.
|
* This enum specifies IO Drivers, each option controls specific policies on I/O.
|
||||||
|
|||||||
@ -152,7 +152,7 @@ public class HostResponse extends BaseResponseWithAnnotations {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
@SerializedName("memoryallocated")
|
@SerializedName("memoryallocated")
|
||||||
@Param(description = "the amount of the host's memory currently allocated")
|
@Param(description = "the amount of the host's memory currently allocated")
|
||||||
private long memoryAllocated;
|
private Long memoryAllocated;
|
||||||
|
|
||||||
@SerializedName("memoryallocatedpercentage")
|
@SerializedName("memoryallocatedpercentage")
|
||||||
@Param(description = "the amount of the host's memory currently allocated in percentage")
|
@Param(description = "the amount of the host's memory currently allocated in percentage")
|
||||||
@ -407,7 +407,7 @@ public class HostResponse extends BaseResponseWithAnnotations {
|
|||||||
this.memWithOverprovisioning=memWithOverprovisioning;
|
this.memWithOverprovisioning=memWithOverprovisioning;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMemoryAllocated(long memoryAllocated) {
|
public void setMemoryAllocated(Long memoryAllocated) {
|
||||||
this.memoryAllocated = memoryAllocated;
|
this.memoryAllocated = memoryAllocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,8 +687,8 @@ public class HostResponse extends BaseResponseWithAnnotations {
|
|||||||
return memoryTotal;
|
return memoryTotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getMemoryAllocated() {
|
public Long getMemoryAllocated() {
|
||||||
return memoryAllocated;
|
return memoryAllocated == null ? 0 : memoryAllocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMemoryAllocatedPercentage(String memoryAllocatedPercentage) {
|
public void setMemoryAllocatedPercentage(String memoryAllocatedPercentage) {
|
||||||
|
|||||||
46
core/src/main/java/com/cloud/agent/api/CleanupVMCommand.java
Normal file
46
core/src/main/java/com/cloud/agent/api/CleanupVMCommand.java
Normal file
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This command will destroy a leftover VM during the expunge process if it wasn't destroyed before.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CleanupVMCommand extends Command {
|
||||||
|
String vmName;
|
||||||
|
boolean executeInSequence;
|
||||||
|
|
||||||
|
public CleanupVMCommand(String vmName) {
|
||||||
|
this(vmName, false);
|
||||||
|
}
|
||||||
|
public CleanupVMCommand(String vmName, boolean executeInSequence) {
|
||||||
|
this.vmName = vmName;
|
||||||
|
this.executeInSequence = executeInSequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean executeInSequence() {
|
||||||
|
return executeInSequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVmName() {
|
||||||
|
return vmName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1807,7 +1807,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
try {
|
try {
|
||||||
volService.grantAccess(volFactory.getVolume(newVol.getId()), host, destPool);
|
volService.grantAccess(volFactory.getVolume(newVol.getId()), host, destPool);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new StorageAccessException(String.format("Unable to grant access to the volume [%s] on host [%s].", newVolToString, host));
|
throw new StorageAccessException(String.format("Unable to grant access to the volume [%s] on host [%s].", newVolToString, host), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1847,7 +1847,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
try {
|
try {
|
||||||
volService.grantAccess(volFactory.getVolume(volumeId), host, volumeStore);
|
volService.grantAccess(volFactory.getVolume(volumeId), host, volumeStore);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host));
|
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1928,7 +1928,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
|
|||||||
try {
|
try {
|
||||||
volService.grantAccess(volFactory.getVolume(vol.getId()), host, store);
|
volService.grantAccess(volFactory.getVolume(vol.getId()), host, store);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host));
|
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host), e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
grantVolumeAccessToHostIfNeeded(store, vol.getId(), host, volToString);
|
grantVolumeAccessToHostIfNeeded(store, vol.getId(), host, volToString);
|
||||||
|
|||||||
@ -20,8 +20,9 @@ import java.util.Collection;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
|
||||||
|
|
||||||
public interface ClusterDetailsDao extends GenericDao<ClusterDetailsVO, Long> {
|
public interface ClusterDetailsDao extends GenericDao<ClusterDetailsVO, Long>, ResourceDetailsDao<ClusterDetailsVO> {
|
||||||
Map<String, String> findDetails(long clusterId);
|
Map<String, String> findDetails(long clusterId);
|
||||||
|
|
||||||
void persist(long clusterId, Map<String, String> details);
|
void persist(long clusterId, Map<String, String> details);
|
||||||
|
|||||||
@ -28,12 +28,13 @@ import org.apache.cloudstack.framework.config.ScopedConfigStorage;
|
|||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
import com.cloud.utils.crypt.DBEncryptionUtil;
|
import com.cloud.utils.crypt.DBEncryptionUtil;
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
import com.cloud.utils.db.TransactionLegacy;
|
import com.cloud.utils.db.TransactionLegacy;
|
||||||
|
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
|
||||||
|
|
||||||
|
public class ClusterDetailsDaoImpl extends ResourceDetailsDaoBase<ClusterDetailsVO> implements ClusterDetailsDao, ScopedConfigStorage {
|
||||||
|
|
||||||
public class ClusterDetailsDaoImpl extends GenericDaoBase<ClusterDetailsVO, Long> implements ClusterDetailsDao, ScopedConfigStorage {
|
|
||||||
protected final SearchBuilder<ClusterDetailsVO> ClusterSearch;
|
protected final SearchBuilder<ClusterDetailsVO> ClusterSearch;
|
||||||
protected final SearchBuilder<ClusterDetailsVO> DetailSearch;
|
protected final SearchBuilder<ClusterDetailsVO> DetailSearch;
|
||||||
|
|
||||||
@ -44,11 +45,11 @@ public class ClusterDetailsDaoImpl extends GenericDaoBase<ClusterDetailsVO, Long
|
|||||||
|
|
||||||
protected ClusterDetailsDaoImpl() {
|
protected ClusterDetailsDaoImpl() {
|
||||||
ClusterSearch = createSearchBuilder();
|
ClusterSearch = createSearchBuilder();
|
||||||
ClusterSearch.and("clusterId", ClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
|
ClusterSearch.and("clusterId", ClusterSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
|
||||||
ClusterSearch.done();
|
ClusterSearch.done();
|
||||||
|
|
||||||
DetailSearch = createSearchBuilder();
|
DetailSearch = createSearchBuilder();
|
||||||
DetailSearch.and("clusterId", DetailSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
|
DetailSearch.and("clusterId", DetailSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
|
||||||
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
|
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||||
DetailSearch.done();
|
DetailSearch.done();
|
||||||
}
|
}
|
||||||
@ -68,6 +69,11 @@ public class ClusterDetailsDaoImpl extends GenericDaoBase<ClusterDetailsVO, Long
|
|||||||
return detail;
|
return detail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addDetail(long resourceId, String key, String value, boolean display) {
|
||||||
|
super.addDetail(new ClusterDetailsVO(resourceId, key, value));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> findDetails(long clusterId) {
|
public Map<String, String> findDetails(long clusterId) {
|
||||||
SearchCriteria<ClusterDetailsVO> sc = ClusterSearch.create();
|
SearchCriteria<ClusterDetailsVO> sc = ClusterSearch.create();
|
||||||
@ -91,7 +97,7 @@ public class ClusterDetailsDaoImpl extends GenericDaoBase<ClusterDetailsVO, Long
|
|||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
}
|
}
|
||||||
SearchBuilder<ClusterDetailsVO> sb = createSearchBuilder();
|
SearchBuilder<ClusterDetailsVO> sb = createSearchBuilder();
|
||||||
sb.and("clusterId", sb.entity().getClusterId(), SearchCriteria.Op.EQ);
|
sb.and("clusterId", sb.entity().getResourceId(), SearchCriteria.Op.EQ);
|
||||||
sb.and("name", sb.entity().getName(), SearchCriteria.Op.IN);
|
sb.and("name", sb.entity().getName(), SearchCriteria.Op.IN);
|
||||||
sb.done();
|
sb.done();
|
||||||
SearchCriteria<ClusterDetailsVO> sc = sb.create();
|
SearchCriteria<ClusterDetailsVO> sc = sb.create();
|
||||||
|
|||||||
@ -23,11 +23,11 @@ import javax.persistence.GenerationType;
|
|||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.InternalIdentity;
|
import org.apache.cloudstack.api.ResourceDetail;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "cluster_details")
|
@Table(name = "cluster_details")
|
||||||
public class ClusterDetailsVO implements InternalIdentity {
|
public class ClusterDetailsVO implements ResourceDetail {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@ -35,7 +35,7 @@ public class ClusterDetailsVO implements InternalIdentity {
|
|||||||
private long id;
|
private long id;
|
||||||
|
|
||||||
@Column(name = "cluster_id")
|
@Column(name = "cluster_id")
|
||||||
private long clusterId;
|
private long resourceId;
|
||||||
|
|
||||||
@Column(name = "name")
|
@Column(name = "name")
|
||||||
private String name;
|
private String name;
|
||||||
@ -47,13 +47,14 @@ public class ClusterDetailsVO implements InternalIdentity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ClusterDetailsVO(long clusterId, String name, String value) {
|
public ClusterDetailsVO(long clusterId, String name, String value) {
|
||||||
this.clusterId = clusterId;
|
this.resourceId = clusterId;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getClusterId() {
|
@Override
|
||||||
return clusterId;
|
public long getResourceId() {
|
||||||
|
return resourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -64,6 +65,11 @@ public class ClusterDetailsVO implements InternalIdentity {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDisplay() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void setValue(String value) {
|
public void setValue(String value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,18 +23,18 @@ import javax.persistence.GenerationType;
|
|||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.InternalIdentity;
|
import org.apache.cloudstack.api.ResourceDetail;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "domain_details")
|
@Table(name = "domain_details")
|
||||||
public class DomainDetailVO implements InternalIdentity {
|
public class DomainDetailVO implements ResourceDetail {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "id")
|
@Column(name = "id")
|
||||||
private long id;
|
private long id;
|
||||||
|
|
||||||
@Column(name = "domain_id")
|
@Column(name = "domain_id")
|
||||||
private long domainId;
|
private long resourceId;
|
||||||
|
|
||||||
@Column(name = "name")
|
@Column(name = "name")
|
||||||
private String name;
|
private String name;
|
||||||
@ -46,13 +46,14 @@ public class DomainDetailVO implements InternalIdentity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DomainDetailVO(long domainId, String name, String value) {
|
public DomainDetailVO(long domainId, String name, String value) {
|
||||||
this.domainId = domainId;
|
this.resourceId = domainId;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getDomainId() {
|
@Override
|
||||||
return domainId;
|
public long getResourceId() {
|
||||||
|
return resourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -63,6 +64,11 @@ public class DomainDetailVO implements InternalIdentity {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDisplay() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void setValue(String value) {
|
public void setValue(String value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,8 +20,9 @@ import java.util.Map;
|
|||||||
|
|
||||||
import com.cloud.domain.DomainDetailVO;
|
import com.cloud.domain.DomainDetailVO;
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
|
||||||
|
|
||||||
public interface DomainDetailsDao extends GenericDao<DomainDetailVO, Long> {
|
public interface DomainDetailsDao extends GenericDao<DomainDetailVO, Long>, ResourceDetailsDao<DomainDetailVO> {
|
||||||
Map<String, String> findDetails(long domainId);
|
Map<String, String> findDetails(long domainId);
|
||||||
|
|
||||||
void persist(long domainId, Map<String, String> details);
|
void persist(long domainId, Map<String, String> details);
|
||||||
@ -31,6 +32,4 @@ public interface DomainDetailsDao extends GenericDao<DomainDetailVO, Long> {
|
|||||||
void deleteDetails(long domainId);
|
void deleteDetails(long domainId);
|
||||||
|
|
||||||
void update(long domainId, Map<String, String> details);
|
void update(long domainId, Map<String, String> details);
|
||||||
|
|
||||||
String getActualValue(DomainDetailVO domainDetailVO);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,19 +25,17 @@ import javax.inject.Inject;
|
|||||||
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
|
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
|
||||||
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
|
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
|
||||||
|
|
||||||
import com.cloud.domain.DomainDetailVO;
|
import com.cloud.domain.DomainDetailVO;
|
||||||
import com.cloud.domain.DomainVO;
|
import com.cloud.domain.DomainVO;
|
||||||
import com.cloud.utils.crypt.DBEncryptionUtil;
|
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
|
||||||
import com.cloud.utils.db.QueryBuilder;
|
import com.cloud.utils.db.QueryBuilder;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
import com.cloud.utils.db.SearchCriteria.Op;
|
import com.cloud.utils.db.SearchCriteria.Op;
|
||||||
import com.cloud.utils.db.TransactionLegacy;
|
import com.cloud.utils.db.TransactionLegacy;
|
||||||
|
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
|
||||||
|
|
||||||
public class DomainDetailsDaoImpl extends GenericDaoBase<DomainDetailVO, Long> implements DomainDetailsDao, ScopedConfigStorage {
|
public class DomainDetailsDaoImpl extends ResourceDetailsDaoBase<DomainDetailVO> implements DomainDetailsDao, ScopedConfigStorage {
|
||||||
protected final SearchBuilder<DomainDetailVO> domainSearch;
|
protected final SearchBuilder<DomainDetailVO> domainSearch;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ -47,14 +45,14 @@ public class DomainDetailsDaoImpl extends GenericDaoBase<DomainDetailVO, Long> i
|
|||||||
|
|
||||||
protected DomainDetailsDaoImpl() {
|
protected DomainDetailsDaoImpl() {
|
||||||
domainSearch = createSearchBuilder();
|
domainSearch = createSearchBuilder();
|
||||||
domainSearch.and("domainId", domainSearch.entity().getDomainId(), Op.EQ);
|
domainSearch.and("domainId", domainSearch.entity().getResourceId(), Op.EQ);
|
||||||
domainSearch.done();
|
domainSearch.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> findDetails(long domainId) {
|
public Map<String, String> findDetails(long domainId) {
|
||||||
QueryBuilder<DomainDetailVO> sc = QueryBuilder.create(DomainDetailVO.class);
|
QueryBuilder<DomainDetailVO> sc = QueryBuilder.create(DomainDetailVO.class);
|
||||||
sc.and(sc.entity().getDomainId(), Op.EQ, domainId);
|
sc.and(sc.entity().getResourceId(), Op.EQ, domainId);
|
||||||
List<DomainDetailVO> results = sc.list();
|
List<DomainDetailVO> results = sc.list();
|
||||||
Map<String, String> details = new HashMap<String, String>(results.size());
|
Map<String, String> details = new HashMap<String, String>(results.size());
|
||||||
for (DomainDetailVO r : results) {
|
for (DomainDetailVO r : results) {
|
||||||
@ -80,11 +78,16 @@ public class DomainDetailsDaoImpl extends GenericDaoBase<DomainDetailVO, Long> i
|
|||||||
@Override
|
@Override
|
||||||
public DomainDetailVO findDetail(long domainId, String name) {
|
public DomainDetailVO findDetail(long domainId, String name) {
|
||||||
QueryBuilder<DomainDetailVO> sc = QueryBuilder.create(DomainDetailVO.class);
|
QueryBuilder<DomainDetailVO> sc = QueryBuilder.create(DomainDetailVO.class);
|
||||||
sc.and(sc.entity().getDomainId(), Op.EQ, domainId);
|
sc.and(sc.entity().getResourceId(), Op.EQ, domainId);
|
||||||
sc.and(sc.entity().getName(), Op.EQ, name);
|
sc.and(sc.entity().getName(), Op.EQ, name);
|
||||||
return sc.find();
|
return sc.find();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addDetail(long resourceId, String key, String value, boolean display) {
|
||||||
|
super.addDetail(new DomainDetailVO(resourceId, key, value));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteDetails(long domainId) {
|
public void deleteDetails(long domainId) {
|
||||||
SearchCriteria<DomainDetailVO> sc = domainSearch.create();
|
SearchCriteria<DomainDetailVO> sc = domainSearch.create();
|
||||||
@ -129,13 +132,4 @@ public class DomainDetailsDaoImpl extends GenericDaoBase<DomainDetailVO, Long> i
|
|||||||
}
|
}
|
||||||
return vo == null ? null : getActualValue(vo);
|
return vo == null ? null : getActualValue(vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getActualValue(DomainDetailVO domainDetailVO) {
|
|
||||||
ConfigurationVO configurationVO = _configDao.findByName(domainDetailVO.getName());
|
|
||||||
if (configurationVO != null && configurationVO.isEncrypted()) {
|
|
||||||
return DBEncryptionUtil.decrypt(domainDetailVO.getValue());
|
|
||||||
}
|
|
||||||
return domainDetailVO.getValue();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,7 +46,7 @@ public class StoragePoolDetailsDaoImpl extends ResourceDetailsDaoBase<StoragePoo
|
|||||||
@Override
|
@Override
|
||||||
public String getConfigValue(long id, String key) {
|
public String getConfigValue(long id, String key) {
|
||||||
StoragePoolDetailVO vo = findDetail(id, key);
|
StoragePoolDetailVO vo = findDetail(id, key);
|
||||||
return vo == null ? null : vo.getValue();
|
return vo == null ? null : getActualValue(vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -334,7 +334,7 @@ public class SystemVmTemplateRegistration {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static boolean validateIfSeeded(String url, String path, String nfsVersion) {
|
public boolean validateIfSeeded(TemplateDataStoreVO templDataStoreVO, String url, String path, String nfsVersion) {
|
||||||
String filePath = null;
|
String filePath = null;
|
||||||
try {
|
try {
|
||||||
filePath = Files.createTempDirectory(TEMPORARY_SECONDARY_STORE).toString();
|
filePath = Files.createTempDirectory(TEMPORARY_SECONDARY_STORE).toString();
|
||||||
@ -347,6 +347,9 @@ public class SystemVmTemplateRegistration {
|
|||||||
String templatePath = filePath + File.separator + partialDirPath;
|
String templatePath = filePath + File.separator + partialDirPath;
|
||||||
File templateProps = new File(templatePath + "/template.properties");
|
File templateProps = new File(templatePath + "/template.properties");
|
||||||
if (templateProps.exists()) {
|
if (templateProps.exists()) {
|
||||||
|
Pair<Long, Long> templateSizes = readTemplatePropertiesSizes(templatePath + "/template.properties");
|
||||||
|
updateSeededTemplateDetails(templDataStoreVO.getTemplateId(), templDataStoreVO.getDataStoreId(),
|
||||||
|
templateSizes.first(), templateSizes.second());
|
||||||
LOGGER.info("SystemVM template already seeded, skipping registration");
|
LOGGER.info("SystemVM template already seeded, skipping registration");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -542,6 +545,21 @@ public class SystemVmTemplateRegistration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateSeededTemplateDetails(long templateId, long storeId, long size, long physicalSize) {
|
||||||
|
VMTemplateVO template = vmTemplateDao.findById(templateId);
|
||||||
|
template.setSize(size);
|
||||||
|
vmTemplateDao.update(template.getId(), template);
|
||||||
|
|
||||||
|
TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao.findByStoreTemplate(storeId, template.getId());
|
||||||
|
templateDataStoreVO.setSize(size);
|
||||||
|
templateDataStoreVO.setPhysicalSize(physicalSize);
|
||||||
|
templateDataStoreVO.setLastUpdated(new Date(DateUtil.currentGMTTime().getTime()));
|
||||||
|
boolean updated = templateDataStoreDao.update(templateDataStoreVO.getId(), templateDataStoreVO);
|
||||||
|
if (!updated) {
|
||||||
|
throw new CloudRuntimeException("Failed to update template_store_ref entry for seeded systemVM template");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void updateSystemVMEntries(Long templateId, Hypervisor.HypervisorType hypervisorType) {
|
public void updateSystemVMEntries(Long templateId, Hypervisor.HypervisorType hypervisorType) {
|
||||||
vmInstanceDao.updateSystemVmTemplateId(templateId, hypervisorType);
|
vmInstanceDao.updateSystemVmTemplateId(templateId, hypervisorType);
|
||||||
}
|
}
|
||||||
@ -555,7 +573,7 @@ public class SystemVmTemplateRegistration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void readTemplateProperties(String path, SystemVMTemplateDetails details) {
|
private static Pair<Long, Long> readTemplatePropertiesSizes(String path) {
|
||||||
File tmpFile = new File(path);
|
File tmpFile = new File(path);
|
||||||
Long size = null;
|
Long size = null;
|
||||||
Long physicalSize = 0L;
|
Long physicalSize = 0L;
|
||||||
@ -574,8 +592,13 @@ public class SystemVmTemplateRegistration {
|
|||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.warn("Failed to read from template.properties", ex);
|
LOGGER.warn("Failed to read from template.properties", ex);
|
||||||
}
|
}
|
||||||
details.setSize(size);
|
return new Pair<>(size, physicalSize);
|
||||||
details.setPhysicalSize(physicalSize);
|
}
|
||||||
|
|
||||||
|
public static void readTemplateProperties(String path, SystemVMTemplateDetails details) {
|
||||||
|
Pair<Long, Long> templateSizes = readTemplatePropertiesSizes(path);
|
||||||
|
details.setSize(templateSizes.first());
|
||||||
|
details.setPhysicalSize(templateSizes.second());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTemplateTablesOnFailure(long templateId) {
|
private void updateTemplateTablesOnFailure(long templateId) {
|
||||||
@ -799,7 +822,7 @@ public class SystemVmTemplateRegistration {
|
|||||||
TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao.findByStoreTemplate(storeUrlAndId.second(), templateId);
|
TemplateDataStoreVO templateDataStoreVO = templateDataStoreDao.findByStoreTemplate(storeUrlAndId.second(), templateId);
|
||||||
if (templateDataStoreVO != null) {
|
if (templateDataStoreVO != null) {
|
||||||
String installPath = templateDataStoreVO.getInstallPath();
|
String installPath = templateDataStoreVO.getInstallPath();
|
||||||
if (validateIfSeeded(storeUrlAndId.first(), installPath, nfsVersion)) {
|
if (validateIfSeeded(templateDataStoreVO, storeUrlAndId.first(), installPath, nfsVersion)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,18 +23,18 @@ import javax.persistence.GenerationType;
|
|||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.InternalIdentity;
|
import org.apache.cloudstack.api.ResourceDetail;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "account_details")
|
@Table(name = "account_details")
|
||||||
public class AccountDetailVO implements InternalIdentity {
|
public class AccountDetailVO implements ResourceDetail {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "id")
|
@Column(name = "id")
|
||||||
private long id;
|
private long id;
|
||||||
|
|
||||||
@Column(name = "account_id")
|
@Column(name = "account_id")
|
||||||
private long accountId;
|
private long resourceId;
|
||||||
|
|
||||||
@Column(name = "name")
|
@Column(name = "name")
|
||||||
private String name;
|
private String name;
|
||||||
@ -46,13 +46,14 @@ public class AccountDetailVO implements InternalIdentity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public AccountDetailVO(long accountId, String name, String value) {
|
public AccountDetailVO(long accountId, String name, String value) {
|
||||||
this.accountId = accountId;
|
this.resourceId = accountId;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getAccountId() {
|
@Override
|
||||||
return accountId;
|
public long getResourceId() {
|
||||||
|
return resourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -63,6 +64,11 @@ public class AccountDetailVO implements InternalIdentity {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDisplay() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void setValue(String value) {
|
public void setValue(String value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,8 +19,9 @@ package com.cloud.user;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
|
||||||
|
|
||||||
public interface AccountDetailsDao extends GenericDao<AccountDetailVO, Long> {
|
public interface AccountDetailsDao extends GenericDao<AccountDetailVO, Long>, ResourceDetailsDao<AccountDetailVO> {
|
||||||
Map<String, String> findDetails(long accountId);
|
Map<String, String> findDetails(long accountId);
|
||||||
|
|
||||||
void persist(long accountId, Map<String, String> details);
|
void persist(long accountId, Map<String, String> details);
|
||||||
@ -34,6 +35,4 @@ public interface AccountDetailsDao extends GenericDao<AccountDetailVO, Long> {
|
|||||||
* they will get created
|
* they will get created
|
||||||
*/
|
*/
|
||||||
void update(long accountId, Map<String, String> details);
|
void update(long accountId, Map<String, String> details);
|
||||||
|
|
||||||
String getActualValue(AccountDetailVO accountDetailVO);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,22 +27,20 @@ import org.apache.cloudstack.framework.config.ConfigKey;
|
|||||||
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
|
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
|
||||||
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
|
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
|
||||||
|
|
||||||
import com.cloud.domain.DomainDetailVO;
|
import com.cloud.domain.DomainDetailVO;
|
||||||
import com.cloud.domain.DomainVO;
|
import com.cloud.domain.DomainVO;
|
||||||
import com.cloud.domain.dao.DomainDao;
|
import com.cloud.domain.dao.DomainDao;
|
||||||
import com.cloud.domain.dao.DomainDetailsDao;
|
import com.cloud.domain.dao.DomainDetailsDao;
|
||||||
import com.cloud.user.dao.AccountDao;
|
import com.cloud.user.dao.AccountDao;
|
||||||
import com.cloud.utils.crypt.DBEncryptionUtil;
|
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
|
||||||
import com.cloud.utils.db.QueryBuilder;
|
import com.cloud.utils.db.QueryBuilder;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
import com.cloud.utils.db.SearchCriteria.Op;
|
import com.cloud.utils.db.SearchCriteria.Op;
|
||||||
import com.cloud.utils.db.TransactionLegacy;
|
import com.cloud.utils.db.TransactionLegacy;
|
||||||
|
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
|
||||||
|
|
||||||
public class AccountDetailsDaoImpl extends GenericDaoBase<AccountDetailVO, Long> implements AccountDetailsDao, ScopedConfigStorage {
|
public class AccountDetailsDaoImpl extends ResourceDetailsDaoBase<AccountDetailVO> implements AccountDetailsDao, ScopedConfigStorage {
|
||||||
protected final SearchBuilder<AccountDetailVO> accountSearch;
|
protected final SearchBuilder<AccountDetailVO> accountSearch;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ -56,16 +54,16 @@ public class AccountDetailsDaoImpl extends GenericDaoBase<AccountDetailVO, Long>
|
|||||||
|
|
||||||
protected AccountDetailsDaoImpl() {
|
protected AccountDetailsDaoImpl() {
|
||||||
accountSearch = createSearchBuilder();
|
accountSearch = createSearchBuilder();
|
||||||
accountSearch.and("accountId", accountSearch.entity().getAccountId(), Op.EQ);
|
accountSearch.and("accountId", accountSearch.entity().getResourceId(), Op.EQ);
|
||||||
accountSearch.done();
|
accountSearch.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> findDetails(long accountId) {
|
public Map<String, String> findDetails(long accountId) {
|
||||||
QueryBuilder<AccountDetailVO> sc = QueryBuilder.create(AccountDetailVO.class);
|
QueryBuilder<AccountDetailVO> sc = QueryBuilder.create(AccountDetailVO.class);
|
||||||
sc.and(sc.entity().getAccountId(), Op.EQ, accountId);
|
sc.and(sc.entity().getResourceId(), Op.EQ, accountId);
|
||||||
List<AccountDetailVO> results = sc.list();
|
List<AccountDetailVO> results = sc.list();
|
||||||
Map<String, String> details = new HashMap<String, String>(results.size());
|
Map<String, String> details = new HashMap<>(results.size());
|
||||||
for (AccountDetailVO r : results) {
|
for (AccountDetailVO r : results) {
|
||||||
details.put(r.getName(), r.getValue());
|
details.put(r.getName(), r.getValue());
|
||||||
}
|
}
|
||||||
@ -89,11 +87,16 @@ public class AccountDetailsDaoImpl extends GenericDaoBase<AccountDetailVO, Long>
|
|||||||
@Override
|
@Override
|
||||||
public AccountDetailVO findDetail(long accountId, String name) {
|
public AccountDetailVO findDetail(long accountId, String name) {
|
||||||
QueryBuilder<AccountDetailVO> sc = QueryBuilder.create(AccountDetailVO.class);
|
QueryBuilder<AccountDetailVO> sc = QueryBuilder.create(AccountDetailVO.class);
|
||||||
sc.and(sc.entity().getAccountId(), Op.EQ, accountId);
|
sc.and(sc.entity().getResourceId(), Op.EQ, accountId);
|
||||||
sc.and(sc.entity().getName(), Op.EQ, name);
|
sc.and(sc.entity().getName(), Op.EQ, name);
|
||||||
return sc.find();
|
return sc.find();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addDetail(long resourceId, String key, String value, boolean display) {
|
||||||
|
super.addDetail(new AccountDetailVO(resourceId, key, value));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteDetails(long accountId) {
|
public void deleteDetails(long accountId) {
|
||||||
SearchCriteria<AccountDetailVO> sc = accountSearch.create();
|
SearchCriteria<AccountDetailVO> sc = accountSearch.create();
|
||||||
@ -153,13 +156,4 @@ public class AccountDetailsDaoImpl extends GenericDaoBase<AccountDetailVO, Long>
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getActualValue(AccountDetailVO accountDetailVO) {
|
|
||||||
ConfigurationVO configurationVO = _configDao.findByName(accountDetailVO.getName());
|
|
||||||
if (configurationVO != null && configurationVO.isEncrypted()) {
|
|
||||||
return DBEncryptionUtil.decrypt(accountDetailVO.getValue());
|
|
||||||
}
|
|
||||||
return accountDetailVO.getValue();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,7 +53,7 @@ public interface ResourceDetailsDao<R extends ResourceDetail> extends GenericDao
|
|||||||
* Removes all details for the resource specified
|
* Removes all details for the resource specified
|
||||||
* @param resourceId
|
* @param resourceId
|
||||||
*/
|
*/
|
||||||
public void removeDetails(long resourceId);
|
void removeDetails(long resourceId);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,7 +76,7 @@ public interface ResourceDetailsDao<R extends ResourceDetail> extends GenericDao
|
|||||||
* @param resourceId
|
* @param resourceId
|
||||||
* @return list of details each implementing ResourceDetail interface
|
* @return list of details each implementing ResourceDetail interface
|
||||||
*/
|
*/
|
||||||
public List<R> listDetails(long resourceId);
|
List<R> listDetails(long resourceId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List details for resourceId having display field = forDisplay value passed in
|
* List details for resourceId having display field = forDisplay value passed in
|
||||||
@ -84,21 +84,23 @@ public interface ResourceDetailsDao<R extends ResourceDetail> extends GenericDao
|
|||||||
* @param forDisplay
|
* @param forDisplay
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<R> listDetails(long resourceId, boolean forDisplay);
|
List<R> listDetails(long resourceId, boolean forDisplay);
|
||||||
|
|
||||||
public Map<String, String> listDetailsKeyPairs(long resourceId);
|
Map<String, String> listDetailsKeyPairs(long resourceId);
|
||||||
|
|
||||||
Map<String, String> listDetailsKeyPairs(long resourceId, List<String> keys);
|
Map<String, String> listDetailsKeyPairs(long resourceId, List<String> keys);
|
||||||
|
|
||||||
public Map<String, String> listDetailsKeyPairs(long resourceId, boolean forDisplay);
|
Map<String, String> listDetailsKeyPairs(long resourceId, boolean forDisplay);
|
||||||
|
|
||||||
Map<String, Boolean> listDetailsVisibility(long resourceId);
|
Map<String, Boolean> listDetailsVisibility(long resourceId);
|
||||||
|
|
||||||
public void saveDetails(List<R> details);
|
void saveDetails(List<R> details);
|
||||||
|
|
||||||
public void addDetail(long resourceId, String key, String value, boolean display);
|
void addDetail(long resourceId, String key, String value, boolean display);
|
||||||
|
|
||||||
public List<Long> findResourceIdsByNameAndValueIn(String name, Object[] values);
|
List<Long> findResourceIdsByNameAndValueIn(String name, Object[] values);
|
||||||
|
|
||||||
public long batchExpungeForResources(List<Long> ids, Long batchSize);
|
long batchExpungeForResources(List<Long> ids, Long batchSize);
|
||||||
|
|
||||||
|
String getActualValue(ResourceDetail resourceDetail);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,9 +21,9 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.ResourceDetail;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
|
import com.cloud.utils.crypt.DBEncryptionUtil;
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
import com.cloud.utils.db.GenericDaoBase;
|
||||||
import com.cloud.utils.db.GenericSearchBuilder;
|
import com.cloud.utils.db.GenericSearchBuilder;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
@ -31,7 +31,17 @@ import com.cloud.utils.db.SearchCriteria;
|
|||||||
import com.cloud.utils.db.SearchCriteria.Op;
|
import com.cloud.utils.db.SearchCriteria.Op;
|
||||||
import com.cloud.utils.db.TransactionLegacy;
|
import com.cloud.utils.db.TransactionLegacy;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.ResourceDetail;
|
||||||
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
|
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
public abstract class ResourceDetailsDaoBase<R extends ResourceDetail> extends GenericDaoBase<R, Long> implements ResourceDetailsDao<R> {
|
public abstract class ResourceDetailsDaoBase<R extends ResourceDetail> extends GenericDaoBase<R, Long> implements ResourceDetailsDao<R> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ConfigurationDao configDao;
|
||||||
|
|
||||||
private SearchBuilder<R> AllFieldsSearch;
|
private SearchBuilder<R> AllFieldsSearch;
|
||||||
|
|
||||||
public ResourceDetailsDaoBase() {
|
public ResourceDetailsDaoBase() {
|
||||||
@ -76,8 +86,7 @@ public abstract class ResourceDetailsDaoBase<R extends ResourceDetail> extends G
|
|||||||
sc.setParameters("value", value);
|
sc.setParameters("value", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<R> results = search(sc, null);
|
return search(sc, null);
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> listDetailsKeyPairs(long resourceId) {
|
public Map<String, String> listDetailsKeyPairs(long resourceId) {
|
||||||
@ -85,7 +94,7 @@ public abstract class ResourceDetailsDaoBase<R extends ResourceDetail> extends G
|
|||||||
sc.setParameters("resourceId", resourceId);
|
sc.setParameters("resourceId", resourceId);
|
||||||
|
|
||||||
List<R> results = search(sc, null);
|
List<R> results = search(sc, null);
|
||||||
Map<String, String> details = new HashMap<String, String>(results.size());
|
Map<String, String> details = new HashMap<>(results.size());
|
||||||
for (R result : results) {
|
for (R result : results) {
|
||||||
details.put(result.getName(), result.getValue());
|
details.put(result.getName(), result.getValue());
|
||||||
}
|
}
|
||||||
@ -122,8 +131,7 @@ public abstract class ResourceDetailsDaoBase<R extends ResourceDetail> extends G
|
|||||||
SearchCriteria<R> sc = AllFieldsSearch.create();
|
SearchCriteria<R> sc = AllFieldsSearch.create();
|
||||||
sc.setParameters("resourceId", resourceId);
|
sc.setParameters("resourceId", resourceId);
|
||||||
|
|
||||||
List<R> results = search(sc, null);
|
return search(sc, null);
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeDetails(long resourceId) {
|
public void removeDetails(long resourceId) {
|
||||||
@ -185,7 +193,7 @@ public abstract class ResourceDetailsDaoBase<R extends ResourceDetail> extends G
|
|||||||
sc.setParameters("display", forDisplay);
|
sc.setParameters("display", forDisplay);
|
||||||
|
|
||||||
List<R> results = search(sc, null);
|
List<R> results = search(sc, null);
|
||||||
Map<String, String> details = new HashMap<String, String>(results.size());
|
Map<String, String> details = new HashMap<>(results.size());
|
||||||
for (R result : results) {
|
for (R result : results) {
|
||||||
details.put(result.getName(), result.getValue());
|
details.put(result.getName(), result.getValue());
|
||||||
}
|
}
|
||||||
@ -197,8 +205,7 @@ public abstract class ResourceDetailsDaoBase<R extends ResourceDetail> extends G
|
|||||||
sc.setParameters("resourceId", resourceId);
|
sc.setParameters("resourceId", resourceId);
|
||||||
sc.setParameters("display", forDisplay);
|
sc.setParameters("display", forDisplay);
|
||||||
|
|
||||||
List<R> results = search(sc, null);
|
return search(sc, null);
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -230,4 +237,13 @@ public abstract class ResourceDetailsDaoBase<R extends ResourceDetail> extends G
|
|||||||
sc.setParameters("ids", ids.toArray());
|
sc.setParameters("ids", ids.toArray());
|
||||||
return batchExpunge(sc, batchSize);
|
return batchExpunge(sc, batchSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getActualValue(ResourceDetail resourceDetail) {
|
||||||
|
ConfigurationVO configurationVO = configDao.findByName(resourceDetail.getName());
|
||||||
|
if (configurationVO != null && configurationVO.isEncrypted()) {
|
||||||
|
return DBEncryptionUtil.decrypt(resourceDetail.getValue());
|
||||||
|
}
|
||||||
|
return resourceDetail.getValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,6 @@ import com.cloud.utils.db.TransactionLegacy;
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class ImageStoreDetailsDaoImpl extends ResourceDetailsDaoBase<ImageStoreDetailVO> implements ImageStoreDetailsDao, ScopedConfigStorage {
|
public class ImageStoreDetailsDaoImpl extends ResourceDetailsDaoBase<ImageStoreDetailVO> implements ImageStoreDetailsDao, ScopedConfigStorage {
|
||||||
|
|
||||||
protected final SearchBuilder<ImageStoreDetailVO> storeSearch;
|
protected final SearchBuilder<ImageStoreDetailVO> storeSearch;
|
||||||
|
|
||||||
public ImageStoreDetailsDaoImpl() {
|
public ImageStoreDetailsDaoImpl() {
|
||||||
@ -67,7 +66,7 @@ public class ImageStoreDetailsDaoImpl extends ResourceDetailsDaoBase<ImageStoreD
|
|||||||
sc.setParameters("store", storeId);
|
sc.setParameters("store", storeId);
|
||||||
|
|
||||||
List<ImageStoreDetailVO> details = listBy(sc);
|
List<ImageStoreDetailVO> details = listBy(sc);
|
||||||
Map<String, String> detailsMap = new HashMap<String, String>();
|
Map<String, String> detailsMap = new HashMap<>();
|
||||||
for (ImageStoreDetailVO detail : details) {
|
for (ImageStoreDetailVO detail : details) {
|
||||||
String name = detail.getName();
|
String name = detail.getName();
|
||||||
String value = detail.getValue();
|
String value = detail.getValue();
|
||||||
@ -110,9 +109,14 @@ public class ImageStoreDetailsDaoImpl extends ResourceDetailsDaoBase<ImageStoreD
|
|||||||
return vo == null ? null : vo.getValue();
|
return vo == null ? null : vo.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getConfigValue(long id, ConfigKey<?> key) {
|
||||||
|
ImageStoreDetailVO vo = findDetail(id, key.key());
|
||||||
|
return vo == null ? null : getActualValue(vo);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addDetail(long resourceId, String key, String value, boolean display) {
|
public void addDetail(long resourceId, String key, String value, boolean display) {
|
||||||
super.addDetail(new ImageStoreDetailVO(resourceId, key, value, display));
|
super.addDetail(new ImageStoreDetailVO(resourceId, key, value, display));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -755,7 +755,7 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
|
|||||||
if (keyword != null) {
|
if (keyword != null) {
|
||||||
SearchCriteria<StoragePoolVO> ssc = createSearchCriteria();
|
SearchCriteria<StoragePoolVO> ssc = createSearchCriteria();
|
||||||
ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
||||||
ssc.addOr("poolType", SearchCriteria.Op.LIKE, new Storage.StoragePoolType("%" + keyword + "%"));
|
ssc.addOr("poolType", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
||||||
|
|
||||||
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
|
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,6 +40,7 @@ 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.DataObject;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
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.DataStoreCapabilities;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
|
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
|
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
|
||||||
@ -1534,6 +1535,16 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
|
|||||||
verifyFormat(templateInfo.getFormat());
|
verifyFormat(templateInfo.getFormat());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this blurb handles the case where the storage system can clone a volume from a template
|
||||||
|
String canCloneVolumeFromTemplate = templateInfo.getDataStore().getDriver().getCapabilities().get("CAN_CLONE_VOLUME_FROM_TEMPLATE");
|
||||||
|
if (canCloneVolumeFromTemplate != null && canCloneVolumeFromTemplate.toLowerCase().equals("true")) {
|
||||||
|
DataStoreDriver driver = templateInfo.getDataStore().getDriver();
|
||||||
|
driver.createAsync(volumeInfo.getDataStore(), volumeInfo, null);
|
||||||
|
volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
|
||||||
|
driver.copyAsync(templateInfo, volumeInfo, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
HostVO hostVO = null;
|
HostVO hostVO = null;
|
||||||
|
|
||||||
final boolean computeClusterSupportsVolumeClone;
|
final boolean computeClusterSupportsVolumeClone;
|
||||||
@ -1641,7 +1652,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
|
|||||||
errMsg = "Create volume from template failed: " + ex.getMessage();
|
errMsg = "Create volume from template failed: " + ex.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CloudRuntimeException(errMsg);
|
throw new CloudRuntimeException(errMsg, ex);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (copyCmdAnswer == null) {
|
if (copyCmdAnswer == null) {
|
||||||
@ -2634,7 +2645,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
|
|||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
errMsg = ex.getMessage();
|
errMsg = ex.getMessage();
|
||||||
|
|
||||||
throw new CloudRuntimeException(errMsg);
|
throw new CloudRuntimeException(errMsg, ex);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (copyCmdAnswer == null) {
|
if (copyCmdAnswer == null) {
|
||||||
|
|||||||
@ -622,7 +622,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
try {
|
try {
|
||||||
Thread.sleep(sleepTime * 1000);
|
Thread.sleep(sleepTime * 1000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
logger.debug("waiting for template download been interrupted: " + e.toString());
|
logger.debug("waiting for template download been interrupted: " + e);
|
||||||
}
|
}
|
||||||
tries--;
|
tries--;
|
||||||
}
|
}
|
||||||
@ -691,7 +691,6 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
}
|
}
|
||||||
_tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
|
_tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Void managedCopyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, ManagedCreateBaseImageContext<VolumeApiResult> context) {
|
protected Void managedCopyBaseImageCallback(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, ManagedCreateBaseImageContext<VolumeApiResult> context) {
|
||||||
@ -1039,7 +1038,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
try {
|
try {
|
||||||
grantAccess(templateOnPrimary, destHost, destPrimaryDataStore);
|
grantAccess(templateOnPrimary, destHost, destPrimaryDataStore);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new StorageAccessException(String.format("Unable to grant access to template: %s on host: %s", templateOnPrimary.getImage(), destHost));
|
throw new StorageAccessException(String.format("Unable to grant access to template: %s on host: %s", templateOnPrimary.getImage(), destHost), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
templateOnPrimary.processEvent(Event.CopyingRequested);
|
templateOnPrimary.processEvent(Event.CopyingRequested);
|
||||||
@ -1161,7 +1160,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
try {
|
try {
|
||||||
grantAccess(srcTemplateOnPrimary, destHost, destPrimaryDataStore);
|
grantAccess(srcTemplateOnPrimary, destHost, destPrimaryDataStore);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new StorageAccessException(String.format("Unable to grant access to src template: %s on host: %s", srcTemplateOnPrimary, destHost));
|
throw new StorageAccessException(String.format("Unable to grant access to src template: %s on host: %s", srcTemplateOnPrimary, destHost), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
_volumeDetailsDao.addDetail(volumeInfo.getId(), volumeDetailKey, String.valueOf(templatePoolRef.getId()), false);
|
_volumeDetailsDao.addDetail(volumeInfo.getId(), volumeDetailKey, String.valueOf(templatePoolRef.getId()), false);
|
||||||
@ -1408,7 +1407,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||||||
try {
|
try {
|
||||||
grantAccess(templateOnPrimary, destHost, destPrimaryDataStore);
|
grantAccess(templateOnPrimary, destHost, destPrimaryDataStore);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new StorageAccessException(String.format("Unable to grant access to template: %s on host: %s", templateOnPrimary, destHost));
|
throw new StorageAccessException(String.format("Unable to grant access to template: %s on host: %s", templateOnPrimary, destHost), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
templateOnPrimary.processEvent(Event.CopyingRequested);
|
templateOnPrimary.processEvent(Event.CopyingRequested);
|
||||||
|
|||||||
@ -39,7 +39,7 @@ import com.cloud.utils.mgmt.ManagementBean;
|
|||||||
public class CloudStackExtendedLifeCycle extends AbstractBeanCollector {
|
public class CloudStackExtendedLifeCycle extends AbstractBeanCollector {
|
||||||
|
|
||||||
|
|
||||||
Map<Integer, Set<ComponentLifecycle>> sorted = new TreeMap<Integer, Set<ComponentLifecycle>>();
|
Map<Integer, Set<ComponentLifecycle>> sorted = new TreeMap<>();
|
||||||
|
|
||||||
public CloudStackExtendedLifeCycle() {
|
public CloudStackExtendedLifeCycle() {
|
||||||
super();
|
super();
|
||||||
@ -80,13 +80,8 @@ public class CloudStackExtendedLifeCycle extends AbstractBeanCollector {
|
|||||||
ManagementBean mbean = (ManagementBean)lifecycle;
|
ManagementBean mbean = (ManagementBean)lifecycle;
|
||||||
try {
|
try {
|
||||||
JmxUtil.registerMBean(mbean);
|
JmxUtil.registerMBean(mbean);
|
||||||
} catch (MalformedObjectNameException e) {
|
} catch (MalformedObjectNameException | InstanceAlreadyExistsException |
|
||||||
logger.warn("Unable to register MBean: " + mbean.getName(), e);
|
MBeanRegistrationException | NotCompliantMBeanException e) {
|
||||||
} catch (InstanceAlreadyExistsException e) {
|
|
||||||
logger.warn("Unable to register MBean: " + mbean.getName(), e);
|
|
||||||
} catch (MBeanRegistrationException e) {
|
|
||||||
logger.warn("Unable to register MBean: " + mbean.getName(), e);
|
|
||||||
} catch (NotCompliantMBeanException e) {
|
|
||||||
logger.warn("Unable to register MBean: " + mbean.getName(), e);
|
logger.warn("Unable to register MBean: " + mbean.getName(), e);
|
||||||
}
|
}
|
||||||
logger.info("Registered MBean: " + mbean.getName());
|
logger.info("Registered MBean: " + mbean.getName());
|
||||||
@ -129,6 +124,7 @@ public class CloudStackExtendedLifeCycle extends AbstractBeanCollector {
|
|||||||
throw new CloudRuntimeException(e);
|
throw new CloudRuntimeException(e);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Error on configuring bean {} - {}", lifecycle.getName(), e.getMessage(), e);
|
logger.error("Error on configuring bean {} - {}", lifecycle.getName(), e.getMessage(), e);
|
||||||
|
throw new CloudRuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -141,7 +137,7 @@ public class CloudStackExtendedLifeCycle extends AbstractBeanCollector {
|
|||||||
Set<ComponentLifecycle> set = sorted.get(lifecycle.getRunLevel());
|
Set<ComponentLifecycle> set = sorted.get(lifecycle.getRunLevel());
|
||||||
|
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
set = new HashSet<ComponentLifecycle>();
|
set = new HashSet<>();
|
||||||
sorted.put(lifecycle.getRunLevel(), set);
|
sorted.put(lifecycle.getRunLevel(), set);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,12 +165,7 @@ public class CloudStackExtendedLifeCycle extends AbstractBeanCollector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private interface WithComponentLifeCycle {
|
||||||
public int getPhase() {
|
|
||||||
return 2000;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static interface WithComponentLifeCycle {
|
|
||||||
public void with(ComponentLifecycle lifecycle);
|
public void with(ComponentLifecycle lifecycle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,7 @@ public class RegistryLifecycle implements BeanPostProcessor, SmartLifecycle, App
|
|||||||
* can use this.
|
* can use this.
|
||||||
*/
|
*/
|
||||||
String registryBeanName;
|
String registryBeanName;
|
||||||
Set<Object> beans = new HashSet<Object>();
|
Set<Object> beans = new HashSet<>();
|
||||||
Class<?> typeClass;
|
Class<?> typeClass;
|
||||||
ApplicationContext applicationContext;
|
ApplicationContext applicationContext;
|
||||||
Set<String> excludes = null;
|
Set<String> excludes = null;
|
||||||
@ -79,7 +79,7 @@ public class RegistryLifecycle implements BeanPostProcessor, SmartLifecycle, App
|
|||||||
|
|
||||||
protected synchronized void loadExcluded() {
|
protected synchronized void loadExcluded() {
|
||||||
Properties props = applicationContext.getBean("DefaultConfigProperties", Properties.class);
|
Properties props = applicationContext.getBean("DefaultConfigProperties", Properties.class);
|
||||||
excludes = new HashSet<String>();
|
excludes = new HashSet<>();
|
||||||
for (String exclude : props.getProperty(EXTENSION_EXCLUDE, "").trim().split("\\s*,\\s*")) {
|
for (String exclude : props.getProperty(EXTENSION_EXCLUDE, "").trim().split("\\s*,\\s*")) {
|
||||||
if (StringUtils.hasText(exclude)) {
|
if (StringUtils.hasText(exclude)) {
|
||||||
excludes.add(exclude);
|
excludes.add(exclude);
|
||||||
@ -109,10 +109,15 @@ public class RegistryLifecycle implements BeanPostProcessor, SmartLifecycle, App
|
|||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Object next = iter.next();
|
Object next = iter.next();
|
||||||
if (registry.register(next)) {
|
try {
|
||||||
logger.debug("Registered " + next);
|
if (registry.register(next)) {
|
||||||
} else {
|
logger.debug("Registered " + next);
|
||||||
iter.remove();
|
} else {
|
||||||
|
logger.warn("Bean registration failed for " + next.toString());
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
logger.warn("Bean registration attempt resulted in an exception for " + next.toString(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,7 @@ public class DynamicRoleBasedAPIAccessChecker extends AdapterBase implements API
|
|||||||
private RoleService roleService;
|
private RoleService roleService;
|
||||||
|
|
||||||
private List<PluggableService> services;
|
private List<PluggableService> services;
|
||||||
private Map<RoleType, Set<String>> annotationRoleBasedApisMap = new HashMap<RoleType, Set<String>>();
|
private Map<RoleType, Set<String>> annotationRoleBasedApisMap = new HashMap<>();
|
||||||
|
|
||||||
private LazyCache<Long, Account> accountCache;
|
private LazyCache<Long, Account> accountCache;
|
||||||
private LazyCache<Long, Pair<Role, List<RolePermission>>> rolePermissionsCache;
|
private LazyCache<Long, Pair<Role, List<RolePermission>>> rolePermissionsCache;
|
||||||
@ -56,7 +56,7 @@ public class DynamicRoleBasedAPIAccessChecker extends AdapterBase implements API
|
|||||||
protected DynamicRoleBasedAPIAccessChecker() {
|
protected DynamicRoleBasedAPIAccessChecker() {
|
||||||
super();
|
super();
|
||||||
for (RoleType roleType : RoleType.values()) {
|
for (RoleType roleType : RoleType.values()) {
|
||||||
annotationRoleBasedApisMap.put(roleType, new HashSet<String>());
|
annotationRoleBasedApisMap.put(roleType, new HashSet<>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3133,7 +3133,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
disk.setLogicalBlockIOSize(pool.getSupportedLogicalBlockSize());
|
disk.setLogicalBlockIOSize(pool.getSupportedLogicalBlockSize());
|
||||||
disk.setPhysicalBlockIOSize(pool.getSupportedPhysicalBlockSize());
|
disk.setPhysicalBlockIOSize(pool.getSupportedPhysicalBlockSize());
|
||||||
|
|
||||||
if (diskBusType == DiskDef.DiskBus.SCSI ) {
|
if (diskBusType == DiskDef.DiskBus.SCSI || diskBusType == DiskDef.DiskBus.VIRTIOBLK) {
|
||||||
disk.setQemuDriver(true);
|
disk.setQemuDriver(true);
|
||||||
disk.setDiscard(DiscardType.UNMAP);
|
disk.setDiscard(DiscardType.UNMAP);
|
||||||
}
|
}
|
||||||
@ -3204,7 +3204,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
|||||||
disk.setCacheMode(DiskDef.DiskCacheMode.valueOf(volumeObjectTO.getCacheMode().toString().toUpperCase()));
|
disk.setCacheMode(DiskDef.DiskCacheMode.valueOf(volumeObjectTO.getCacheMode().toString().toUpperCase()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (volumeObjectTO.requiresEncryption()) {
|
if (volumeObjectTO.requiresEncryption() &&
|
||||||
|
pool.getType().encryptionSupportMode() == Storage.EncryptionSupport.Hypervisor ) {
|
||||||
String secretUuid = createLibvirtVolumeSecret(conn, volumeObjectTO.getPath(), volumeObjectTO.getPassphrase());
|
String secretUuid = createLibvirtVolumeSecret(conn, volumeObjectTO.getPath(), volumeObjectTO.getPassphrase());
|
||||||
DiskDef.LibvirtDiskEncryptDetails encryptDetails = new DiskDef.LibvirtDiskEncryptDetails(secretUuid, QemuObject.EncryptFormat.enumValue(volumeObjectTO.getEncryptFormat()));
|
DiskDef.LibvirtDiskEncryptDetails encryptDetails = new DiskDef.LibvirtDiskEncryptDetails(secretUuid, QemuObject.EncryptFormat.enumValue(volumeObjectTO.getEncryptFormat()));
|
||||||
disk.setLibvirtDiskEncryptDetails(encryptDetails);
|
disk.setLibvirtDiskEncryptDetails(encryptDetails);
|
||||||
|
|||||||
@ -248,7 +248,9 @@ public class LibvirtVMDef {
|
|||||||
guestDef.append("<boot dev='" + bo + "'/>\n");
|
guestDef.append("<boot dev='" + bo + "'/>\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
guestDef.append("<smbios mode='sysinfo'/>\n");
|
if (_arch == null || !_arch.equals("aarch64")) {
|
||||||
|
guestDef.append("<smbios mode='sysinfo'/>\n");
|
||||||
|
}
|
||||||
guestDef.append("</os>\n");
|
guestDef.append("</os>\n");
|
||||||
if (iothreads) {
|
if (iothreads) {
|
||||||
guestDef.append(String.format("<iothreads>%s</iothreads>", NUMBER_OF_IOTHREADS));
|
guestDef.append(String.format("<iothreads>%s</iothreads>", NUMBER_OF_IOTHREADS));
|
||||||
@ -678,7 +680,7 @@ public class LibvirtVMDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum DiskBus {
|
public enum DiskBus {
|
||||||
IDE("ide"), SCSI("scsi"), VIRTIO("virtio"), XEN("xen"), USB("usb"), UML("uml"), FDC("fdc"), SATA("sata");
|
IDE("ide"), SCSI("scsi"), VIRTIO("virtio"), XEN("xen"), USB("usb"), UML("uml"), FDC("fdc"), SATA("sata"), VIRTIOBLK("virtio-blk");
|
||||||
String _bus;
|
String _bus;
|
||||||
|
|
||||||
DiskBus(String bus) {
|
DiskBus(String bus) {
|
||||||
|
|||||||
@ -122,7 +122,10 @@ public final class LibvirtGetUnmanagedInstancesCommandWrapper extends CommandWra
|
|||||||
instance.setName(domain.getName());
|
instance.setName(domain.getName());
|
||||||
|
|
||||||
instance.setCpuCores((int) LibvirtComputingResource.countDomainRunningVcpus(domain));
|
instance.setCpuCores((int) LibvirtComputingResource.countDomainRunningVcpus(domain));
|
||||||
instance.setCpuSpeed(parser.getCpuTuneDef().getShares()/instance.getCpuCores());
|
|
||||||
|
if (parser.getCpuTuneDef() != null && instance.getCpuCores() != null) {
|
||||||
|
instance.setCpuSpeed(parser.getCpuTuneDef().getShares()/instance.getCpuCores());
|
||||||
|
}
|
||||||
|
|
||||||
if (parser.getCpuModeDef() != null) {
|
if (parser.getCpuModeDef() != null) {
|
||||||
instance.setCpuCoresPerSocket(parser.getCpuModeDef().getCoresPerSocket());
|
instance.setCpuCoresPerSocket(parser.getCpuModeDef().getCoresPerSocket());
|
||||||
|
|||||||
@ -125,6 +125,7 @@ import com.cloud.hypervisor.kvm.resource.wrapper.LibvirtUtilitiesHelper;
|
|||||||
import com.cloud.storage.JavaStorageLayer;
|
import com.cloud.storage.JavaStorageLayer;
|
||||||
import com.cloud.storage.MigrationOptions;
|
import com.cloud.storage.MigrationOptions;
|
||||||
import com.cloud.storage.ScopeType;
|
import com.cloud.storage.ScopeType;
|
||||||
|
import com.cloud.storage.Storage;
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
import com.cloud.storage.Storage.StoragePoolType;
|
import com.cloud.storage.Storage.StoragePoolType;
|
||||||
import com.cloud.storage.StorageLayer;
|
import com.cloud.storage.StorageLayer;
|
||||||
@ -161,7 +162,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
/**
|
/**
|
||||||
* Time interval before rechecking virsh commands
|
* Time interval before rechecking virsh commands
|
||||||
*/
|
*/
|
||||||
private long waitDelayForVirshCommands = 1000l;
|
private final long waitDelayForVirshCommands = 1000L;
|
||||||
|
|
||||||
public KVMStorageProcessor(final KVMStoragePoolManager storagePoolMgr, final LibvirtComputingResource resource) {
|
public KVMStorageProcessor(final KVMStoragePoolManager storagePoolMgr, final LibvirtComputingResource resource) {
|
||||||
this.storagePoolMgr = storagePoolMgr;
|
this.storagePoolMgr = storagePoolMgr;
|
||||||
@ -258,7 +259,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
logger.debug("Copying template to primary storage, template format is " + tmplVol.getFormat() );
|
logger.debug("Copying template to primary storage, template format is " + tmplVol.getFormat() );
|
||||||
final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
|
final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
|
||||||
|
|
||||||
KVMPhysicalDisk primaryVol = null;
|
KVMPhysicalDisk primaryVol;
|
||||||
if (destData instanceof VolumeObjectTO) {
|
if (destData instanceof VolumeObjectTO) {
|
||||||
final VolumeObjectTO volume = (VolumeObjectTO)destData;
|
final VolumeObjectTO volume = (VolumeObjectTO)destData;
|
||||||
// pass along volume's target size if it's bigger than template's size, for storage types that copy template rather than cloning on deploy
|
// pass along volume's target size if it's bigger than template's size, for storage types that copy template rather than cloning on deploy
|
||||||
@ -277,8 +278,13 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
|
|
||||||
String path = derivePath(primaryStore, destData, details);
|
String path = derivePath(primaryStore, destData, details);
|
||||||
|
|
||||||
if (!storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details)) {
|
if (path == null) {
|
||||||
|
path = destTempl.getUuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path != null && !storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details)) {
|
||||||
logger.warn("Failed to connect physical disk at path: {}, in storage pool [id: {}, name: {}]", path, primaryStore.getUuid(), primaryStore.getName());
|
logger.warn("Failed to connect physical disk at path: {}, in storage pool [id: {}, name: {}]", path, primaryStore.getUuid(), primaryStore.getName());
|
||||||
|
return new PrimaryStorageDownloadAnswer("Failed to spool template disk at path: " + path + ", in storage pool id: " + primaryStore.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, path != null ? path : destTempl.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
|
primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, path != null ? path : destTempl.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
|
||||||
@ -336,12 +342,13 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String derivePath(PrimaryDataStoreTO primaryStore, DataTO destData, Map<String, String> details) {
|
private String derivePath(PrimaryDataStoreTO primaryStore, DataTO destData, Map<String, String> details) {
|
||||||
String path = null;
|
String path;
|
||||||
if (primaryStore.getPoolType() == StoragePoolType.FiberChannel) {
|
if (primaryStore.getPoolType() == StoragePoolType.FiberChannel) {
|
||||||
path = destData.getPath();
|
path = destData.getPath();
|
||||||
} else {
|
} else {
|
||||||
path = details != null ? details.get("managedStoreTarget") : null;
|
path = details != null ? details.get("managedStoreTarget") : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,8 +397,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
logger.debug("Using templates disk size of " + toHumanReadableSize(templateVol.getVirtualSize()) + "since size passed was " + toHumanReadableSize(size));
|
logger.debug("Using templates disk size of " + toHumanReadableSize(templateVol.getVirtualSize()) + "since size passed was " + toHumanReadableSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
final KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(templateVol, volUuid, primaryPool, timeout);
|
return storagePoolMgr.copyPhysicalDisk(templateVol, volUuid, primaryPool, timeout);
|
||||||
return primaryVol;
|
|
||||||
} catch (final CloudRuntimeException e) {
|
} catch (final CloudRuntimeException e) {
|
||||||
logger.error("Failed to download template to primary storage", e);
|
logger.error("Failed to download template to primary storage", e);
|
||||||
return null;
|
return null;
|
||||||
@ -410,9 +416,9 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
final DataStoreTO imageStore = template.getDataStore();
|
final DataStoreTO imageStore = template.getDataStore();
|
||||||
final VolumeObjectTO volume = (VolumeObjectTO)destData;
|
final VolumeObjectTO volume = (VolumeObjectTO)destData;
|
||||||
final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore();
|
final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore();
|
||||||
KVMPhysicalDisk BaseVol = null;
|
KVMPhysicalDisk BaseVol;
|
||||||
KVMStoragePool primaryPool = null;
|
KVMStoragePool primaryPool;
|
||||||
KVMPhysicalDisk vol = null;
|
KVMPhysicalDisk vol;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
|
primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
|
||||||
@ -420,7 +426,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
String templatePath = template.getPath();
|
String templatePath = template.getPath();
|
||||||
|
|
||||||
if (primaryPool.getType() == StoragePoolType.CLVM) {
|
if (primaryPool.getType() == StoragePoolType.CLVM) {
|
||||||
templatePath = ((NfsTO)imageStore).getUrl() + File.separator + templatePath;
|
templatePath = imageStore.getUrl() + File.separator + templatePath;
|
||||||
vol = templateToPrimaryDownload(templatePath, primaryPool, volume.getUuid(), volume.getSize(), cmd.getWaitInMillSeconds());
|
vol = templateToPrimaryDownload(templatePath, primaryPool, volume.getUuid(), volume.getSize(), cmd.getWaitInMillSeconds());
|
||||||
} if (storagePoolMgr.supportsPhysicalDiskCopy(primaryPool.getType())) {
|
} if (storagePoolMgr.supportsPhysicalDiskCopy(primaryPool.getType())) {
|
||||||
Map<String, String> details = primaryStore.getDetails();
|
Map<String, String> details = primaryStore.getDetails();
|
||||||
@ -778,15 +784,19 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
|
|
||||||
KVMStoragePool secondaryStorage = null;
|
KVMStoragePool secondaryStorage = null;
|
||||||
|
|
||||||
|
String path = null;
|
||||||
try {
|
try {
|
||||||
// look for options indicating an overridden path or IQN. Used when snapshots have to be
|
// look for options indicating an overridden path or IQN. Used when snapshots have to be
|
||||||
// temporarily copied on the manaaged storage device before the actual copy to target object
|
// temporarily copied on the manaaged storage device before the actual copy to target object
|
||||||
Map<String, String> details = cmd.getOptions();
|
Map<String, String> details = cmd.getOptions();
|
||||||
String path = details != null ? details.get(DiskTO.PATH) : null;
|
path = details != null ? details.get(DiskTO.PATH) : null;
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
path = details != null ? details.get(DiskTO.IQN) : null;
|
path = details != null ? details.get(DiskTO.IQN) : null;
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
new CloudRuntimeException("The 'path' or 'iqn' field must be specified.");
|
path = srcData.getPath();
|
||||||
|
if (path == null) {
|
||||||
|
new CloudRuntimeException("The 'path' or 'iqn' field must be specified.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -849,8 +859,6 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
loc.addFormat(info);
|
loc.addFormat(info);
|
||||||
loc.save();
|
loc.save();
|
||||||
|
|
||||||
storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
|
|
||||||
|
|
||||||
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
||||||
|
|
||||||
newTemplate.setPath(templateFolder + File.separator + templateName + ".qcow2");
|
newTemplate.setPath(templateFolder + File.separator + templateName + ".qcow2");
|
||||||
@ -870,6 +878,10 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
|
|
||||||
return new CopyCmdAnswer(ex.toString());
|
return new CopyCmdAnswer(ex.toString());
|
||||||
} finally {
|
} finally {
|
||||||
|
if (path != null) {
|
||||||
|
storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path);
|
||||||
|
}
|
||||||
|
|
||||||
if (secondaryStorage != null) {
|
if (secondaryStorage != null) {
|
||||||
secondaryStorage.delete();
|
secondaryStorage.delete();
|
||||||
}
|
}
|
||||||
@ -1045,7 +1057,9 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
command.add(NAME_OPTION, snapshotName);
|
command.add(NAME_OPTION, snapshotName);
|
||||||
command.add("-p", snapshotDestPath);
|
command.add("-p", snapshotDestPath);
|
||||||
|
|
||||||
descName = UUID.randomUUID().toString();
|
if (isCreatedFromVmSnapshot) {
|
||||||
|
descName = UUID.randomUUID().toString();
|
||||||
|
}
|
||||||
|
|
||||||
command.add("-t", descName);
|
command.add("-t", descName);
|
||||||
final String result = command.execute();
|
final String result = command.execute();
|
||||||
@ -1415,12 +1429,14 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
if (disk.getDeviceType() == DeviceType.DISK) {
|
if (disk.getDeviceType() == DeviceType.DISK) {
|
||||||
if (disk.getBusType() == DiskDef.DiskBus.SCSI) {
|
if (disk.getBusType() == DiskDef.DiskBus.SCSI) {
|
||||||
busT = DiskDef.DiskBus.SCSI;
|
busT = DiskDef.DiskBus.SCSI;
|
||||||
|
} else if (disk.getBusType() == DiskDef.DiskBus.VIRTIOBLK) {
|
||||||
|
busT = DiskDef.DiskBus.VIRTIOBLK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
diskdef = new DiskDef();
|
diskdef = new DiskDef();
|
||||||
if (busT == DiskDef.DiskBus.SCSI) {
|
if (busT == DiskDef.DiskBus.SCSI || busT == DiskDef.DiskBus.VIRTIOBLK) {
|
||||||
diskdef.setQemuDriver(true);
|
diskdef.setQemuDriver(true);
|
||||||
diskdef.setDiscard(DiscardType.UNMAP);
|
diskdef.setDiscard(DiscardType.UNMAP);
|
||||||
}
|
}
|
||||||
@ -1459,7 +1475,8 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encryptDetails != null) {
|
if (encryptDetails != null &&
|
||||||
|
attachingPool.getType().encryptionSupportMode() == Storage.EncryptionSupport.Hypervisor) {
|
||||||
diskdef.setLibvirtDiskEncryptDetails(encryptDetails);
|
diskdef.setLibvirtDiskEncryptDetails(encryptDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -162,6 +162,13 @@ public abstract class MultipathSCSIAdapterBase implements StorageAdaptor {
|
|||||||
KVMPhysicalDisk disk = new KVMPhysicalDisk(address.getPath(), address.toString(), pool);
|
KVMPhysicalDisk disk = new KVMPhysicalDisk(address.getPath(), address.toString(), pool);
|
||||||
disk.setFormat(QemuImg.PhysicalDiskFormat.RAW);
|
disk.setFormat(QemuImg.PhysicalDiskFormat.RAW);
|
||||||
|
|
||||||
|
// validate we have a connection, if not we need to connect first.
|
||||||
|
if (!isConnected(address.getPath())) {
|
||||||
|
if (!connectPhysicalDisk(address, pool, null)) {
|
||||||
|
throw new CloudRuntimeException("Unable to connect to volume " + address.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
long diskSize = getPhysicalDiskSize(address.getPath());
|
long diskSize = getPhysicalDiskSize(address.getPath());
|
||||||
disk.setSize(diskSize);
|
disk.setSize(diskSize);
|
||||||
disk.setVirtualSize(diskSize);
|
disk.setVirtualSize(diskSize);
|
||||||
@ -199,6 +206,10 @@ public abstract class MultipathSCSIAdapterBase implements StorageAdaptor {
|
|||||||
// we expect WWN values in the volumePath so need to convert it to an actual physical path
|
// we expect WWN values in the volumePath so need to convert it to an actual physical path
|
||||||
AddressInfo address = this.parseAndValidatePath(volumePath);
|
AddressInfo address = this.parseAndValidatePath(volumePath);
|
||||||
|
|
||||||
|
return connectPhysicalDisk(address, pool, details);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean connectPhysicalDisk(AddressInfo address, KVMStoragePool pool, Map<String, String> details) {
|
||||||
// validate we have a connection id - we can't proceed without that
|
// validate we have a connection id - we can't proceed without that
|
||||||
if (address.getConnectionId() == null) {
|
if (address.getConnectionId() == null) {
|
||||||
LOGGER.error("Unable to connect volume with address [" + address.getPath() + "] of the storage pool: " + pool.getUuid() + " - connection id is not set in provided path");
|
LOGGER.error("Unable to connect volume with address [" + address.getPath() + "] of the storage pool: " + pool.getUuid() + " - connection id is not set in provided path");
|
||||||
@ -510,6 +521,18 @@ public abstract class MultipathSCSIAdapterBase implements StorageAdaptor {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isConnected(String path) {
|
||||||
|
// run a command to test if this is a binary device at this path
|
||||||
|
Script blockTest = new Script("/bin/test", LOGGER);
|
||||||
|
blockTest.add("-b", path);
|
||||||
|
blockTest.execute();
|
||||||
|
int rc = blockTest.getExitValue();
|
||||||
|
if (rc == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
long getPhysicalDiskSize(String diskPath) {
|
long getPhysicalDiskSize(String diskPath) {
|
||||||
if (StringUtils.isEmpty(diskPath)) {
|
if (StringUtils.isEmpty(diskPath)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -6531,4 +6531,14 @@ public class LibvirtComputingResourceTest {
|
|||||||
assertEquals(DiskDef.DiscardType.UNMAP, rootDisk.getDiscard());
|
assertEquals(DiskDef.DiscardType.UNMAP, rootDisk.getDiscard());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetDiskModelFromVMDetailVirtioBlk() {
|
||||||
|
VirtualMachineTO virtualMachineTO = Mockito.mock(VirtualMachineTO.class);
|
||||||
|
Map<String, String> details = new HashMap<>();
|
||||||
|
details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, "virtio-blk");
|
||||||
|
Mockito.when(virtualMachineTO.getDetails()).thenReturn(details);
|
||||||
|
DiskDef.DiskBus diskBus = libvirtComputingResourceSpy.getDiskModelFromVMDetail(virtualMachineTO);
|
||||||
|
assertEquals(DiskDef.DiskBus.VIRTIOBLK, diskBus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.CleanupVMCommand;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import com.cloud.agent.api.to.NfsTO;
|
import com.cloud.agent.api.to.NfsTO;
|
||||||
@ -370,6 +371,13 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
|
|||||||
return tokens[0] + "@" + vCenterIp;
|
return tokens[0] + "@" + vCenterIp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public List<Command> finalizeExpunge(VirtualMachine vm) {
|
||||||
|
List<Command> commands = new ArrayList<Command>();
|
||||||
|
final CleanupVMCommand cleanupVMCommand = new CleanupVMCommand(vm.getInstanceName(), true);
|
||||||
|
commands.add(cleanupVMCommand);
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
|
|
||||||
@Override public List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics) {
|
@Override public List<Command> finalizeExpungeNics(VirtualMachine vm, List<NicProfile> nics) {
|
||||||
List<Command> commands = new ArrayList<Command>();
|
List<Command> commands = new ArrayList<Command>();
|
||||||
List<NicVO> nicVOs = nicDao.listByVmId(vm.getId());
|
List<NicVO> nicVOs = nicDao.listByVmId(vm.getId());
|
||||||
|
|||||||
@ -22,12 +22,15 @@ import com.cloud.dc.VmwareDatacenterVO;
|
|||||||
import com.cloud.dc.VsphereStoragePolicy;
|
import com.cloud.dc.VsphereStoragePolicy;
|
||||||
import com.cloud.exception.DiscoveryException;
|
import com.cloud.exception.DiscoveryException;
|
||||||
import com.cloud.exception.ResourceInUseException;
|
import com.cloud.exception.ResourceInUseException;
|
||||||
|
import com.cloud.hypervisor.vmware.mo.HostMO;
|
||||||
import com.cloud.storage.StoragePool;
|
import com.cloud.storage.StoragePool;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.component.PluggableService;
|
import com.cloud.utils.component.PluggableService;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcVmsCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcVmsCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcHostsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
|
||||||
@ -53,5 +56,7 @@ public interface VmwareDatacenterService extends PluggableService {
|
|||||||
|
|
||||||
List<StoragePool> listVsphereStoragePolicyCompatibleStoragePools(ListVsphereStoragePolicyCompatiblePoolsCmd cmd);
|
List<StoragePool> listVsphereStoragePolicyCompatibleStoragePools(ListVsphereStoragePolicyCompatiblePoolsCmd cmd);
|
||||||
|
|
||||||
List<UnmanagedInstanceTO> listVMsInDatacenter(ListVmwareDcVmsCmd cmd);
|
List<HostMO> listHostsInDatacenter(ListVmwareDcHostsCmd cmd);
|
||||||
|
|
||||||
|
Pair<String, List<UnmanagedInstanceTO>> listVMsInDatacenter(ListVmwareDcVmsCmd cmd);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,10 +19,12 @@ package com.cloud.hypervisor.vmware.manager;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.rmi.RemoteException;
|
import java.rmi.RemoteException;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@ -43,10 +45,11 @@ import javax.inject.Inject;
|
|||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
import javax.persistence.EntityExistsException;
|
import javax.persistence.EntityExistsException;
|
||||||
|
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareClient;
|
|
||||||
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ImportVsphereStoragePoliciesCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcVmsCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcVmsCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcHostsCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcItems;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcsCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePoliciesCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
|
import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd;
|
||||||
@ -86,6 +89,7 @@ import com.cloud.dc.ClusterDetailsDao;
|
|||||||
import com.cloud.dc.ClusterVO;
|
import com.cloud.dc.ClusterVO;
|
||||||
import com.cloud.dc.ClusterVSMMapVO;
|
import com.cloud.dc.ClusterVSMMapVO;
|
||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
|
import com.cloud.dc.VmwareDatacenter;
|
||||||
import com.cloud.dc.VsphereStoragePolicy;
|
import com.cloud.dc.VsphereStoragePolicy;
|
||||||
import com.cloud.dc.VsphereStoragePolicyVO;
|
import com.cloud.dc.VsphereStoragePolicyVO;
|
||||||
import com.cloud.dc.dao.ClusterDao;
|
import com.cloud.dc.dao.ClusterDao;
|
||||||
@ -111,7 +115,8 @@ import com.cloud.hypervisor.HypervisorGuruManager;
|
|||||||
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
|
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
|
||||||
import com.cloud.hypervisor.vmware.LegacyZoneVO;
|
import com.cloud.hypervisor.vmware.LegacyZoneVO;
|
||||||
import com.cloud.hypervisor.vmware.VmwareCleanupMaid;
|
import com.cloud.hypervisor.vmware.VmwareCleanupMaid;
|
||||||
import com.cloud.dc.VmwareDatacenter;
|
import com.cloud.hypervisor.vmware.util.VmwareClient;
|
||||||
|
import com.cloud.hypervisor.vmware.util.VmwareClientException;
|
||||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||||
import com.cloud.dc.VmwareDatacenterVO;
|
import com.cloud.dc.VmwareDatacenterVO;
|
||||||
import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMap;
|
import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMap;
|
||||||
@ -168,9 +173,16 @@ import com.cloud.utils.ssh.SshHelper;
|
|||||||
import com.cloud.vm.DomainRouterVO;
|
import com.cloud.vm.DomainRouterVO;
|
||||||
import com.cloud.vm.dao.UserVmCloneSettingDao;
|
import com.cloud.vm.dao.UserVmCloneSettingDao;
|
||||||
import com.cloud.vm.dao.VMInstanceDao;
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
|
|
||||||
|
// TODO move these items upstream?
|
||||||
import com.vmware.pbm.PbmProfile;
|
import com.vmware.pbm.PbmProfile;
|
||||||
import com.vmware.vim25.AboutInfo;
|
import com.vmware.vim25.AboutInfo;
|
||||||
import com.vmware.vim25.ManagedObjectReference;
|
import com.vmware.vim25.ManagedObjectReference;
|
||||||
|
import com.vmware.vim25.InvalidLocaleFaultMsg;
|
||||||
|
import com.vmware.vim25.InvalidLoginFaultMsg;
|
||||||
|
import com.vmware.vim25.RuntimeFaultFaultMsg;
|
||||||
|
import com.vmware.vim25.InvalidPropertyFaultMsg;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService, Configurable {
|
public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService, Configurable {
|
||||||
|
|
||||||
@ -245,11 +257,11 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
private StorageLayer _storage;
|
private StorageLayer _storage;
|
||||||
private final String _privateNetworkVSwitchName = "vSwitch0";
|
private final String _privateNetworkVSwitchName = "vSwitch0";
|
||||||
|
|
||||||
private int _portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP;
|
private final int _portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP;
|
||||||
private boolean _fullCloneFlag;
|
private boolean _fullCloneFlag;
|
||||||
private boolean _instanceNameFlag;
|
private boolean _instanceNameFlag;
|
||||||
private String _serviceConsoleName;
|
private String _serviceConsoleName;
|
||||||
private String _managemetPortGroupName;
|
private String _managementPortGroupName;
|
||||||
private String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
|
private String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
|
||||||
private String _recycleHungWorker = "false";
|
private String _recycleHungWorker = "false";
|
||||||
private int _additionalPortRangeStart;
|
private int _additionalPortRangeStart;
|
||||||
@ -263,7 +275,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
private final Random _rand = new Random(System.currentTimeMillis());
|
private final Random _rand = new Random(System.currentTimeMillis());
|
||||||
|
|
||||||
private static ScheduledExecutorService templateCleanupScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-FullyClonedTemplateCheck"));;
|
private static final ScheduledExecutorService templateCleanupScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-FullyClonedTemplateCheck"));
|
||||||
|
|
||||||
private final VmwareStorageManager _storageMgr;
|
private final VmwareStorageManager _storageMgr;
|
||||||
private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
|
private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
|
||||||
@ -347,9 +359,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
_serviceConsoleName = "Service Console";
|
_serviceConsoleName = "Service Console";
|
||||||
}
|
}
|
||||||
|
|
||||||
_managemetPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key());
|
_managementPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key());
|
||||||
if (_managemetPortGroupName == null) {
|
if (_managementPortGroupName == null) {
|
||||||
_managemetPortGroupName = "Management Network";
|
_managementPortGroupName = "Management Network";
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaultSystemVmNicAdapterType = _configDao.getValue(Config.VmwareSystemVmNicDeviceType.key());
|
_defaultSystemVmNicAdapterType = _configDao.getValue(Config.VmwareSystemVmNicDeviceType.key());
|
||||||
@ -448,7 +460,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
logger.info("Preparing network on host " + hostMo.getContext().toString() + " for " + privateTrafficLabel);
|
logger.info("Preparing network on host " + hostMo.getContext().toString() + " for " + privateTrafficLabel);
|
||||||
VirtualSwitchType vsType = VirtualSwitchType.getType(vSwitchType);
|
VirtualSwitchType vsType = VirtualSwitchType.getType(vSwitchType);
|
||||||
//The management network is probably always going to be a physical network with islation type of vlans, so assume BroadcastDomainType VLAN
|
//The management network is probably always going to be a physical network with isolation type of vlans, so assume BroadcastDomainType VLAN
|
||||||
if (VirtualSwitchType.StandardVirtualSwitch == vsType) {
|
if (VirtualSwitchType.StandardVirtualSwitch == vsType) {
|
||||||
HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null, null);
|
HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null, null);
|
||||||
}
|
}
|
||||||
@ -457,7 +469,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
AboutInfo about = hostMo.getHostAboutInfo();
|
AboutInfo about = hostMo.getHostAboutInfo();
|
||||||
if (about != null) {
|
if (about != null) {
|
||||||
String version = about.getApiVersion();
|
String version = about.getApiVersion();
|
||||||
if (version != null && (version.equals("4.0") || version.equals("4.1")) && _portsPerDvPortGroup < DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x) {
|
if (version != null && (version.equals("4.0") || version.equals("4.1")) ) { // && _portsPerDvPortGroup < DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x)
|
||||||
portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x;
|
portsPerDvPortGroup = DEFAULT_PORTS_PER_DV_PORT_GROUP_VSPHERE4_x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -480,7 +492,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
}
|
}
|
||||||
|
|
||||||
URI uriForHost = new URI(UriUtils.encodeURIComponent(clusterDetails.get("url") + "/" + host.getName()));
|
URI uriForHost = new URI(UriUtils.encodeURIComponent(clusterDetails.get("url") + "/" + host.getName()));
|
||||||
morSrcHost = serviceContext.getHostMorByPath(URLDecoder.decode(uriForHost.getPath(), "UTF-8"));
|
morSrcHost = serviceContext.getHostMorByPath(URLDecoder.decode(uriForHost.getPath(), StandardCharsets.UTF_8));
|
||||||
if (morSrcHost == null) {
|
if (morSrcHost == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -496,19 +508,18 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
throw new CloudRuntimeException("Invalid serviceContext");
|
throw new CloudRuntimeException("Invalid serviceContext");
|
||||||
}
|
}
|
||||||
ManagedObjectReference mor = serviceContext.getHostMorByPath(hostInventoryPath);
|
ManagedObjectReference mor = serviceContext.getHostMorByPath(hostInventoryPath);
|
||||||
String privateTrafficLabel = null;
|
String privateTrafficLabel;
|
||||||
privateTrafficLabel = serviceContext.getStockObject("privateTrafficLabel");
|
privateTrafficLabel = serviceContext.getStockObject("privateTrafficLabel");
|
||||||
if (privateTrafficLabel == null) {
|
if (privateTrafficLabel == null) {
|
||||||
privateTrafficLabel = _privateNetworkVSwitchName;
|
privateTrafficLabel = _privateNetworkVSwitchName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mor != null) {
|
if (mor != null) {
|
||||||
List<ManagedObjectReference> returnedHostList = new ArrayList<ManagedObjectReference>();
|
List<ManagedObjectReference> returnedHostList = new ArrayList<>();
|
||||||
|
|
||||||
if (mor.getType().equals("ComputeResource")) {
|
if (mor.getType().equals("ComputeResource")) {
|
||||||
List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
|
List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
|
||||||
assert (hosts != null && hosts.size() > 0);
|
assert (CollectionUtils.isNullOrEmpty(hosts));
|
||||||
|
|
||||||
// For ESX host, we need to enable host firewall to allow VNC access
|
// For ESX host, we need to enable host firewall to allow VNC access
|
||||||
HostMO hostMo = new HostMO(serviceContext, hosts.get(0));
|
HostMO hostMo = new HostMO(serviceContext, hosts.get(0));
|
||||||
|
|
||||||
@ -519,8 +530,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
|
List<ManagedObjectReference> hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host");
|
||||||
assert (hosts != null);
|
assert (hosts != null);
|
||||||
|
|
||||||
if (hosts.size() > 0) {
|
if (!hosts.isEmpty()) {
|
||||||
AboutInfo about = (AboutInfo)(serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product"));
|
AboutInfo about = serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product");
|
||||||
String version = about.getApiVersion();
|
String version = about.getApiVersion();
|
||||||
int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(HypervisorType.VMware, version);
|
int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(HypervisorType.VMware, version);
|
||||||
if (hosts.size() > maxHostsPerCluster) {
|
if (hosts.size() > maxHostsPerCluster) {
|
||||||
@ -549,7 +560,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
returnedHostList.add(mor);
|
returnedHostList.add(mor);
|
||||||
return returnedHostList;
|
return returnedHostList;
|
||||||
} else {
|
} else {
|
||||||
logger.error("Unsupport host type " + mor.getType() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath);
|
logger.error("Unsupport host type {}:{} from inventory path: {}", mor.getType(), mor.getValue(), hostInventoryPath);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -614,13 +625,13 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getManagementPortGroupName() {
|
public String getManagementPortGroupName() {
|
||||||
return _managemetPortGroupName;
|
return _managementPortGroupName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getManagementPortGroupByHost(HostMO hostMo) throws Exception {
|
public String getManagementPortGroupByHost(HostMO hostMo) throws Exception {
|
||||||
if (hostMo.getHostType() == VmwareHostType.ESXi) {
|
if (hostMo.getHostType() == VmwareHostType.ESXi) {
|
||||||
return _managemetPortGroupName;
|
return _managementPortGroupName;
|
||||||
}
|
}
|
||||||
return _serviceConsoleName;
|
return _serviceConsoleName;
|
||||||
}
|
}
|
||||||
@ -630,7 +641,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
params.put("vmware.create.full.clone", _fullCloneFlag);
|
params.put("vmware.create.full.clone", _fullCloneFlag);
|
||||||
params.put("vm.instancename.flag", _instanceNameFlag);
|
params.put("vm.instancename.flag", _instanceNameFlag);
|
||||||
params.put("service.console.name", _serviceConsoleName);
|
params.put("service.console.name", _serviceConsoleName);
|
||||||
params.put("management.portgroup.name", _managemetPortGroupName);
|
params.put("management.portgroup.name", _managementPortGroupName);
|
||||||
params.put("vmware.root.disk.controller", _rootDiskController);
|
params.put("vmware.root.disk.controller", _rootDiskController);
|
||||||
params.put("vmware.data.disk.controller", _dataDiskController);
|
params.put("vmware.data.disk.controller", _dataDiskController);
|
||||||
params.put("vmware.recycle.hung.wokervm", _recycleHungWorker);
|
params.put("vmware.recycle.hung.wokervm", _recycleHungWorker);
|
||||||
@ -657,23 +668,23 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String tokens[] = workerTag.split("-");
|
String[] tokens = workerTag.split("-");
|
||||||
if (tokens.length != 3) {
|
if (tokens.length != 3) {
|
||||||
logger.error("Invalid worker VM tag " + workerTag);
|
logger.error("Invalid worker VM tag " + workerTag);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
long startTick = Long.parseLong(tokens[0]);
|
long startTick = Long.parseLong(tokens[0]);
|
||||||
long msid = Long.parseLong(tokens[1]);
|
long msId = Long.parseLong(tokens[1]);
|
||||||
long runid = Long.parseLong(tokens[2]);
|
long runId = Long.parseLong(tokens[2]);
|
||||||
|
|
||||||
if (msHostPeerDao.countStateSeenInPeers(msid, runid, ManagementServerHost.State.Down) > 0) {
|
if (msHostPeerDao.countStateSeenInPeers(msId, runId, ManagementServerHost.State.Down) > 0) {
|
||||||
if (logger.isInfoEnabled())
|
if (logger.isInfoEnabled())
|
||||||
logger.info("Worker VM's owner management server node has been detected down from peer nodes, recycle it");
|
logger.info("Worker VM's owner management server node has been detected down from peer nodes, recycle it");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runid != clusterManager.getManagementRunId(msid)) {
|
if (runId != clusterManager.getManagementRunId(msId)) {
|
||||||
if (logger.isInfoEnabled())
|
if (logger.isInfoEnabled())
|
||||||
logger.info("Worker VM's owner management server has changed runid, recycle it");
|
logger.info("Worker VM's owner management server has changed runid, recycle it");
|
||||||
return true;
|
return true;
|
||||||
@ -710,7 +721,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
File patchFolder = new File(mountPoint + "/systemvm");
|
File patchFolder = new File(mountPoint + "/systemvm");
|
||||||
if (!patchFolder.exists()) {
|
if (!patchFolder.exists()) {
|
||||||
if (!patchFolder.mkdirs()) {
|
if (!patchFolder.mkdirs()) {
|
||||||
String msg = "Unable to create systemvm folder on secondary storage. location: " + patchFolder.toString();
|
String msg = "Unable to create systemvm folder on secondary storage. location: " + patchFolder;
|
||||||
logger.error(msg);
|
logger.error(msg);
|
||||||
throw new CloudRuntimeException(msg);
|
throw new CloudRuntimeException(msg);
|
||||||
}
|
}
|
||||||
@ -729,7 +740,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.error("Unexpected exception ", e);
|
logger.error("Unexpected exception ", e);
|
||||||
|
|
||||||
String msg = "Unable to copy systemvm ISO on secondary storage. src location: " + srcIso.toString() + ", dest location: " + destIso;
|
String msg = "Unable to copy systemvm ISO on secondary storage. src location: " + srcIso + ", dest location: " + destIso;
|
||||||
logger.error(msg);
|
logger.error(msg);
|
||||||
throw new CloudRuntimeException(msg);
|
throw new CloudRuntimeException(msg);
|
||||||
}
|
}
|
||||||
@ -771,9 +782,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso");
|
isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso");
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (isoFile != null);
|
|
||||||
if (!isoFile.exists()) {
|
if (!isoFile.exists()) {
|
||||||
logger.error("Unable to locate systemvm.iso in your setup at " + isoFile.toString());
|
logger.error("Unable to locate systemvm.iso in your setup at " + isoFile);
|
||||||
}
|
}
|
||||||
return isoFile;
|
return isoFile;
|
||||||
}
|
}
|
||||||
@ -788,16 +798,16 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
if (keyFile == null || !keyFile.exists()) {
|
if (keyFile == null || !keyFile.exists()) {
|
||||||
keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
|
keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud");
|
||||||
}
|
}
|
||||||
assert (keyFile != null);
|
|
||||||
if (!keyFile.exists()) {
|
if (!keyFile.exists()) {
|
||||||
logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile.toString());
|
logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile);
|
||||||
}
|
}
|
||||||
return keyFile;
|
return keyFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMountPoint(String storageUrl, String nfsVersion) {
|
public String getMountPoint(String storageUrl, String nfsVersion) {
|
||||||
String mountPoint = null;
|
String mountPoint;
|
||||||
synchronized (_storageMounts) {
|
synchronized (_storageMounts) {
|
||||||
mountPoint = _storageMounts.get(storageUrl);
|
mountPoint = _storageMounts.get(storageUrl);
|
||||||
if (mountPoint != null) {
|
if (mountPoint != null) {
|
||||||
@ -827,7 +837,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
String mountPoint = null;
|
String mountPoint = null;
|
||||||
long mshostId = ManagementServerNode.getManagementServerId();
|
long mshostId = ManagementServerNode.getManagementServerId();
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
String mntPt = parent + File.separator + String.valueOf(mshostId) + "." + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
|
String mntPt = parent + File.separator + mshostId + "." + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
|
||||||
File file = new File(mntPt);
|
File file = new File(mntPt);
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
if (_storage.mkdir(mntPt)) {
|
if (_storage.mkdir(mntPt)) {
|
||||||
@ -852,10 +862,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
for (String mountPoint : mounts) {
|
for (String mountPoint : mounts) {
|
||||||
logger.info("umount NFS mount from previous session: " + mountPoint);
|
logger.info("umount NFS mount from previous session: " + mountPoint);
|
||||||
|
|
||||||
String result = null;
|
|
||||||
Script command = new Script(true, "umount", _timeout, logger);
|
Script command = new Script(true, "umount", _timeout, logger);
|
||||||
command.add(mountPoint);
|
command.add(mountPoint);
|
||||||
result = command.execute();
|
String result = command.execute();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
logger.warn("Unable to umount " + mountPoint + " due to " + result);
|
logger.warn("Unable to umount " + mountPoint + " due to " + result);
|
||||||
}
|
}
|
||||||
@ -873,10 +882,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
for (String mountPoint : _storageMounts.values()) {
|
for (String mountPoint : _storageMounts.values()) {
|
||||||
logger.info("umount NFS mount: " + mountPoint);
|
logger.info("umount NFS mount: " + mountPoint);
|
||||||
|
|
||||||
String result = null;
|
|
||||||
Script command = new Script(true, "umount", _timeout, logger);
|
Script command = new Script(true, "umount", _timeout, logger);
|
||||||
command.add(mountPoint);
|
command.add(mountPoint);
|
||||||
result = command.execute();
|
String result = command.execute();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
logger.warn("Unable to umount " + mountPoint + " due to " + result);
|
logger.warn("Unable to umount " + mountPoint + " due to " + result);
|
||||||
}
|
}
|
||||||
@ -894,8 +902,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Script script = null;
|
Script script;
|
||||||
String result = null;
|
String result;
|
||||||
Script command = new Script(true, "mount", _timeout, logger);
|
Script command = new Script(true, "mount", _timeout, logger);
|
||||||
command.add("-t", "nfs");
|
command.add("-t", "nfs");
|
||||||
if (nfsVersion != null){
|
if (nfsVersion != null){
|
||||||
@ -982,11 +990,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
|
public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) {
|
||||||
if (cmd instanceof StartupCommand) {
|
if (cmd != null) {
|
||||||
if (host.getHypervisorType() == HypervisorType.VMware) {
|
if (host.getHypervisorType() == HypervisorType.VMware) {
|
||||||
updateClusterNativeHAState(host, cmd);
|
updateClusterNativeHAState(host, cmd);
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1056,16 +1062,16 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<Integer, Integer> getAddiionalVncPortRange() {
|
public Pair<Integer, Integer> getAddiionalVncPortRange() {
|
||||||
return new Pair<Integer, Integer>(_additionalPortRangeStart, _additionalPortRangeSize);
|
return new Pair<>(_additionalPortRangeStart, _additionalPortRangeSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getNexusVSMCredentialsByClusterId(Long clusterId) {
|
public Map<String, String> getNexusVSMCredentialsByClusterId(Long clusterId) {
|
||||||
CiscoNexusVSMDeviceVO nexusVSM = null;
|
CiscoNexusVSMDeviceVO nexusVSM;
|
||||||
ClusterVSMMapVO vsmMapVO = null;
|
ClusterVSMMapVO vsmMapVO;
|
||||||
|
|
||||||
vsmMapVO = _vsmMapDao.findByClusterId(clusterId);
|
vsmMapVO = _vsmMapDao.findByClusterId(clusterId);
|
||||||
long vsmId = 0;
|
long vsmId;
|
||||||
if (vsmMapVO != null) {
|
if (vsmMapVO != null) {
|
||||||
vsmId = vsmMapVO.getVsmId();
|
vsmId = vsmMapVO.getVsmId();
|
||||||
logger.info("vsmId is " + vsmId);
|
logger.info("vsmId is " + vsmId);
|
||||||
@ -1076,7 +1082,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> nexusVSMCredentials = new HashMap<String, String>();
|
Map<String, String> nexusVSMCredentials = new HashMap<>();
|
||||||
if (nexusVSM != null) {
|
if (nexusVSM != null) {
|
||||||
nexusVSMCredentials.put("vsmip", nexusVSM.getipaddr());
|
nexusVSMCredentials.put("vsmip", nexusVSM.getipaddr());
|
||||||
nexusVSMCredentials.put("vsmusername", nexusVSM.getUserName());
|
nexusVSMCredentials.put("vsmusername", nexusVSM.getUserName());
|
||||||
@ -1103,7 +1109,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Class<?>> getCommands() {
|
public List<Class<?>> getCommands() {
|
||||||
List<Class<?>> cmdList = new ArrayList<Class<?>>();
|
List<Class<?>> cmdList = new ArrayList<>();
|
||||||
cmdList.add(AddVmwareDcCmd.class);
|
cmdList.add(AddVmwareDcCmd.class);
|
||||||
cmdList.add(UpdateVmwareDcCmd.class);
|
cmdList.add(UpdateVmwareDcCmd.class);
|
||||||
cmdList.add(RemoveVmwareDcCmd.class);
|
cmdList.add(RemoveVmwareDcCmd.class);
|
||||||
@ -1112,13 +1118,14 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
cmdList.add(ListVsphereStoragePoliciesCmd.class);
|
cmdList.add(ListVsphereStoragePoliciesCmd.class);
|
||||||
cmdList.add(ListVsphereStoragePolicyCompatiblePoolsCmd.class);
|
cmdList.add(ListVsphereStoragePolicyCompatiblePoolsCmd.class);
|
||||||
cmdList.add(ListVmwareDcVmsCmd.class);
|
cmdList.add(ListVmwareDcVmsCmd.class);
|
||||||
|
cmdList.add(ListVmwareDcHostsCmd.class);
|
||||||
return cmdList;
|
return cmdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DB
|
@DB
|
||||||
public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException {
|
public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException {
|
||||||
VmwareDatacenterVO vmwareDc = null;
|
VmwareDatacenterVO vmwareDc;
|
||||||
Long zoneId = cmd.getZoneId();
|
Long zoneId = cmd.getZoneId();
|
||||||
String userName = cmd.getUsername();
|
String userName = cmd.getUsername();
|
||||||
String password = cmd.getPassword();
|
String password = cmd.getPassword();
|
||||||
@ -1174,10 +1181,10 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
checkIfDcIsUsed(vCenterHost, vmwareDcName, zoneId);
|
checkIfDcIsUsed(vCenterHost, vmwareDcName, zoneId);
|
||||||
|
|
||||||
VmwareContext context = null;
|
VmwareContext context = null;
|
||||||
DatacenterMO dcMo = null;
|
DatacenterMO dcMo;
|
||||||
String dcCustomFieldValue;
|
String dcCustomFieldValue;
|
||||||
boolean addDcCustomFieldDef = false;
|
boolean addDcCustomFieldDef = false;
|
||||||
boolean dcInUse = false;
|
boolean dcInUse;
|
||||||
String guid;
|
String guid;
|
||||||
ManagedObjectReference dcMor;
|
ManagedObjectReference dcMor;
|
||||||
try {
|
try {
|
||||||
@ -1210,7 +1217,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
// Map zone with vmware datacenter
|
// Map zone with vmware datacenter
|
||||||
vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId());
|
vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId());
|
||||||
|
|
||||||
vmwareDcZoneMap = vmwareDatacenterZoneMapDao.persist(vmwareDcZoneMap);
|
vmwareDatacenterZoneMapDao.persist(vmwareDcZoneMap);
|
||||||
|
|
||||||
// Set custom field for this DC
|
// Set custom field for this DC
|
||||||
if (addDcCustomFieldDef) {
|
if (addDcCustomFieldDef) {
|
||||||
@ -1230,7 +1237,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
if (context != null) {
|
if (context != null) {
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
context = null;
|
|
||||||
}
|
}
|
||||||
importVsphereStoragePoliciesInternal(zoneId, vmwareDc.getId());
|
importVsphereStoragePoliciesInternal(zoneId, vmwareDc.getId());
|
||||||
return vmwareDc;
|
return vmwareDc;
|
||||||
@ -1255,9 +1261,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
* Check if DC is already part of zone
|
* Check if DC is already part of zone
|
||||||
* In that case vmware_data_center table should have the DC and a dc zone mapping should exist
|
* In that case vmware_data_center table should have the DC and a dc zone mapping should exist
|
||||||
*
|
*
|
||||||
* @param vCenterHost
|
* @param vCenterHost the vcenter appliance hostname
|
||||||
* @param vmwareDcName
|
* @param vmwareDcName the name of the vmware DC
|
||||||
* @param zoneId
|
* @param zoneId zone that the DC should be connected to
|
||||||
* @throws ResourceInUseException if the DC can not be used.
|
* @throws ResourceInUseException if the DC can not be used.
|
||||||
*/
|
*/
|
||||||
private void checkIfDcIsUsed(String vCenterHost, String vmwareDcName, Long zoneId) throws ResourceInUseException {
|
private void checkIfDcIsUsed(String vCenterHost, String vmwareDcName, Long zoneId) throws ResourceInUseException {
|
||||||
@ -1265,7 +1271,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
vmwareDc = vmwareDcDao.getVmwareDatacenterByGuid(vmwareDcName + "@" + vCenterHost);
|
vmwareDc = vmwareDcDao.getVmwareDatacenterByGuid(vmwareDcName + "@" + vCenterHost);
|
||||||
if (vmwareDc != null) {
|
if (vmwareDc != null) {
|
||||||
VmwareDatacenterZoneMapVO mapping = vmwareDatacenterZoneMapDao.findByVmwareDcId(vmwareDc.getId());
|
VmwareDatacenterZoneMapVO mapping = vmwareDatacenterZoneMapDao.findByVmwareDcId(vmwareDc.getId());
|
||||||
if (mapping != null && Long.compare(zoneId, mapping.getZoneId()) == 0) {
|
if (mapping != null && zoneId == mapping.getZoneId()) {
|
||||||
throw new ResourceInUseException(String.format("This DC (%s) is already part of other CloudStack zone (%d). Cannot add this DC to more zones.", vmwareDc.getUuid(), zoneId));
|
throw new ResourceInUseException(String.format("This DC (%s) is already part of other CloudStack zone (%d). Cannot add this DC to more zones.", vmwareDc.getUuid(), zoneId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1274,7 +1280,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "updating VMware datacenter")
|
@ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "updating VMware datacenter")
|
||||||
public VmwareDatacenter updateVmwareDatacenter(UpdateVmwareDcCmd cmd) {
|
public VmwareDatacenter updateVmwareDatacenter(UpdateVmwareDcCmd cmd) {
|
||||||
final Long zoneId = cmd.getZoneId();
|
final long zoneId = cmd.getZoneId();
|
||||||
final String userName = cmd.getUsername();
|
final String userName = cmd.getUsername();
|
||||||
final String password = cmd.getPassword();
|
final String password = cmd.getPassword();
|
||||||
final String vCenterHost = cmd.getVcenter();
|
final String vCenterHost = cmd.getVcenter();
|
||||||
@ -1302,7 +1308,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
}
|
}
|
||||||
vmwareDc.setGuid(String.format("%s@%s", vmwareDc.getVmwareDatacenterName(), vmwareDc.getVcenterHost()));
|
vmwareDc.setGuid(String.format("%s@%s", vmwareDc.getVmwareDatacenterName(), vmwareDc.getVcenterHost()));
|
||||||
|
|
||||||
return Transaction.execute(new TransactionCallback<VmwareDatacenter>() {
|
return Transaction.execute(new TransactionCallback<>() {
|
||||||
@Override
|
@Override
|
||||||
public VmwareDatacenter doInTransaction(TransactionStatus status) {
|
public VmwareDatacenter doInTransaction(TransactionStatus status) {
|
||||||
if (vmwareDcDao.update(vmwareDc.getId(), vmwareDc)) {
|
if (vmwareDcDao.update(vmwareDc.getId(), vmwareDc)) {
|
||||||
@ -1351,7 +1357,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
String vCenterHost;
|
String vCenterHost;
|
||||||
String userName;
|
String userName;
|
||||||
String password;
|
String password;
|
||||||
DatacenterMO dcMo = null;
|
DatacenterMO dcMo;
|
||||||
final VmwareDatacenterZoneMapVO vmwareDcZoneMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId);
|
final VmwareDatacenterZoneMapVO vmwareDcZoneMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId);
|
||||||
// Check if zone is associated with VMware DC
|
// Check if zone is associated with VMware DC
|
||||||
if (vmwareDcZoneMap == null) {
|
if (vmwareDcZoneMap == null) {
|
||||||
@ -1388,11 +1394,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
throw new DiscoveryException(msg);
|
throw new DiscoveryException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (dcMo != null);
|
|
||||||
|
|
||||||
// Reset custom field property cloud.zone over this DC
|
// Reset custom field property cloud.zone over this DC
|
||||||
dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "false");
|
dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "false");
|
||||||
logger.info("Sucessfully reset custom field property cloud.zone over DC " + vmwareDcName);
|
logger.info("Sucessfully reset custom field property cloud.zone over DC {}", vmwareDcName);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String msg = "Unable to reset custom field property cloud.zone over DC " + vmwareDcName + " due to : " + VmwareHelper.getExceptionMessage(e);
|
String msg = "Unable to reset custom field property cloud.zone over DC " + vmwareDcName + " due to : " + VmwareHelper.getExceptionMessage(e);
|
||||||
logger.error(msg);
|
logger.error(msg);
|
||||||
@ -1401,7 +1405,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
if (context != null) {
|
if (context != null) {
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
context = null;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1422,7 +1425,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
private void validateZoneWithResources(Long zoneId, String errStr) throws ResourceInUseException {
|
private void validateZoneWithResources(Long zoneId, String errStr) throws ResourceInUseException {
|
||||||
// Check if zone has resources? - For now look for clusters
|
// Check if zone has resources? - For now look for clusters
|
||||||
List<ClusterVO> clusters = clusterDao.listByZoneId(zoneId);
|
List<ClusterVO> clusters = clusterDao.listByZoneId(zoneId);
|
||||||
if (clusters != null && clusters.size() > 0) {
|
if (!CollectionUtils.isNullOrEmpty(clusters)) {
|
||||||
// Look for VMware hypervisor.
|
// Look for VMware hypervisor.
|
||||||
for (ClusterVO cluster : clusters) {
|
for (ClusterVO cluster : clusters) {
|
||||||
if (cluster.getHypervisorType().equals(HypervisorType.VMware)) {
|
if (cluster.getHypervisorType().equals(HypervisorType.VMware)) {
|
||||||
@ -1443,9 +1446,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException, InvalidParameterValueException {
|
public List<? extends VmwareDatacenter> listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException {
|
||||||
Long zoneId = cmd.getZoneId();
|
Long zoneId = cmd.getZoneId();
|
||||||
List<VmwareDatacenterVO> vmwareDcList = new ArrayList<VmwareDatacenterVO>();
|
List<VmwareDatacenterVO> vmwareDcList = new ArrayList<>();
|
||||||
VmwareDatacenterZoneMapVO vmwareDcZoneMap;
|
VmwareDatacenterZoneMapVO vmwareDcZoneMap;
|
||||||
VmwareDatacenterVO vmwareDatacenter;
|
VmwareDatacenterVO vmwareDatacenter;
|
||||||
long vmwareDcId;
|
long vmwareDcId;
|
||||||
@ -1503,7 +1506,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
String vCenterHost = vmwareDatacenter.getVcenterHost();
|
String vCenterHost = vmwareDatacenter.getVcenterHost();
|
||||||
String userName = vmwareDatacenter.getUser();
|
String userName = vmwareDatacenter.getUser();
|
||||||
String password = vmwareDatacenter.getPassword();
|
String password = vmwareDatacenter.getPassword();
|
||||||
List<PbmProfile> storageProfiles = null;
|
List<PbmProfile> storageProfiles;
|
||||||
try {
|
try {
|
||||||
logger.debug(String.format("Importing vSphere Storage Policies for the vmware DC %d in zone %d", vmwareDcId, zoneId));
|
logger.debug(String.format("Importing vSphere Storage Policies for the vmware DC %d in zone %d", vmwareDcId, zoneId));
|
||||||
VmwareContext context = VmwareContextFactory.getContext(vCenterHost, userName, password);
|
VmwareContext context = VmwareContextFactory.getContext(vCenterHost, userName, password);
|
||||||
@ -1531,16 +1534,15 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
List<VsphereStoragePolicyVO> allStoragePolicies = vsphereStoragePolicyDao.listAll();
|
List<VsphereStoragePolicyVO> allStoragePolicies = vsphereStoragePolicyDao.listAll();
|
||||||
List<PbmProfile> finalStorageProfiles = storageProfiles;
|
List<PbmProfile> finalStorageProfiles = storageProfiles;
|
||||||
List<VsphereStoragePolicyVO> needToMarkRemoved = allStoragePolicies.stream()
|
List<VsphereStoragePolicyVO> needToMarkRemoved = allStoragePolicies.stream()
|
||||||
.filter(existingPolicy -> !finalStorageProfiles.stream()
|
.filter(existingPolicy -> finalStorageProfiles.stream()
|
||||||
.anyMatch(storageProfile -> storageProfile.getProfileId().getUniqueId().equals(existingPolicy.getPolicyId())))
|
.noneMatch(storageProfile -> storageProfile.getProfileId().getUniqueId().equals(existingPolicy.getPolicyId())))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
for (VsphereStoragePolicyVO storagePolicy : needToMarkRemoved) {
|
for (VsphereStoragePolicyVO storagePolicy : needToMarkRemoved) {
|
||||||
vsphereStoragePolicyDao.remove(storagePolicy.getId());
|
vsphereStoragePolicyDao.remove(storagePolicy.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<VsphereStoragePolicyVO> storagePolicies = vsphereStoragePolicyDao.listAll();
|
return vsphereStoragePolicyDao.listAll();
|
||||||
return storagePolicies;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1586,13 +1588,87 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<UnmanagedInstanceTO> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) {
|
public List<HostMO> listHostsInDatacenter(ListVmwareDcHostsCmd cmd) {
|
||||||
|
VcenterData vmwaredc = getVcenterData(cmd);
|
||||||
|
|
||||||
|
try {
|
||||||
|
VmwareContext context = getVmwareContext(vmwaredc);
|
||||||
|
DatacenterMO dcMo = getDatacenterMO(context, vmwaredc);
|
||||||
|
return dcMo.getAllHostsOnDatacenter();
|
||||||
|
} catch (RuntimeFaultFaultMsg | URISyntaxException | VmwareClientException | InvalidLocaleFaultMsg |
|
||||||
|
InvalidLoginFaultMsg | InvalidPropertyFaultMsg e) {
|
||||||
|
String errorMsg = String.format("Error retrieving stopped VMs from the VMware VC %s datacenter %s: %s",
|
||||||
|
vmwaredc.vcenter, vmwaredc.datacenterName, e.getMessage());
|
||||||
|
logger.error(errorMsg, e);
|
||||||
|
throw new CloudRuntimeException(errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pair<String, List<UnmanagedInstanceTO>> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) {
|
||||||
|
Integer maxObjects = cmd.getBatchSize();
|
||||||
|
String token = cmd.getToken();
|
||||||
|
String host = cmd.getHost();
|
||||||
|
|
||||||
|
VcenterData vmwaredc = getVcenterData(cmd);
|
||||||
|
|
||||||
|
try {
|
||||||
|
VmwareContext context = getVmwareContext(vmwaredc);
|
||||||
|
|
||||||
|
DatacenterMO dcMo = getDatacenterMO(context, vmwaredc);
|
||||||
|
|
||||||
|
if (com.cloud.utils.StringUtils.isNotBlank(host)) {
|
||||||
|
ManagedObjectReference hostMor = dcMo.findHost(host);
|
||||||
|
if (hostMor == null) {
|
||||||
|
throw new VmwareClientException(String.format("No host '%s' found on DC: %s.", host, dcMo.getName()));
|
||||||
|
}
|
||||||
|
HostMO hostMo = new HostMO(context, hostMor);
|
||||||
|
return hostMo.getVms(maxObjects, token);
|
||||||
|
} else {
|
||||||
|
return dcMo.getVms(maxObjects, token);
|
||||||
|
}
|
||||||
|
} catch (InvalidParameterValueException | VmwareClientException | InvalidLocaleFaultMsg | InvalidLoginFaultMsg |
|
||||||
|
RuntimeFaultFaultMsg | URISyntaxException | InvalidPropertyFaultMsg | InvocationTargetException |
|
||||||
|
NoSuchMethodException | IllegalAccessException e) {
|
||||||
|
String errorMsg = String.format("Error retrieving stopped VMs from the VMware VC %s datacenter %s: %s",
|
||||||
|
vmwaredc.vcenter, vmwaredc.datacenterName, e.getMessage());
|
||||||
|
logger.error(errorMsg, e);
|
||||||
|
throw new CloudRuntimeException(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private DatacenterMO getDatacenterMO(VmwareContext context, VcenterData vmwaredc) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
|
DatacenterMO dcMo = new DatacenterMO(context, vmwaredc.datacenterName);
|
||||||
|
ManagedObjectReference dcMor = dcMo.getMor();
|
||||||
|
if (dcMor == null) {
|
||||||
|
String msg = String.format("Unable to find VMware datacenter %s in vCenter %s",
|
||||||
|
vmwaredc.datacenterName, vmwaredc.vcenter);
|
||||||
|
logger.error(msg);
|
||||||
|
throw new InvalidParameterValueException(msg);
|
||||||
|
}
|
||||||
|
return dcMo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private VmwareContext getVmwareContext(VcenterData vmwaredc) throws RuntimeFaultFaultMsg, URISyntaxException, VmwareClientException, InvalidLocaleFaultMsg, InvalidLoginFaultMsg {
|
||||||
|
logger.debug(String.format("Connecting to the VMware datacenter %s at vCenter %s to retrieve VMs",
|
||||||
|
vmwaredc.datacenterName, vmwaredc.vcenter));
|
||||||
|
String serviceUrl = String.format("https://%s/sdk/vimService", vmwaredc.vcenter);
|
||||||
|
VmwareClient vimClient = new VmwareClient(vmwaredc.vcenter);
|
||||||
|
vimClient.connect(serviceUrl, vmwaredc.username, vmwaredc.password);
|
||||||
|
VmwareContext context = new VmwareContext(vimClient, vmwaredc.vcenter);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private VcenterData getVcenterData(ListVmwareDcItems cmd) {
|
||||||
String vcenter = cmd.getVcenter();
|
String vcenter = cmd.getVcenter();
|
||||||
String datacenterName = cmd.getDatacenterName();
|
String datacenterName = cmd.getDatacenterName();
|
||||||
String username = cmd.getUsername();
|
String username = cmd.getUsername();
|
||||||
String password = cmd.getPassword();
|
String password = cmd.getPassword();
|
||||||
Long existingVcenterId = cmd.getExistingVcenterId();
|
Long existingVcenterId = cmd.getExistingVcenterId();
|
||||||
String keyword = cmd.getKeyword();
|
|
||||||
|
|
||||||
if ((existingVcenterId == null && StringUtils.isBlank(vcenter)) ||
|
if ((existingVcenterId == null && StringUtils.isBlank(vcenter)) ||
|
||||||
(existingVcenterId != null && StringUtils.isNotBlank(vcenter))) {
|
(existingVcenterId != null && StringUtils.isNotBlank(vcenter))) {
|
||||||
@ -1613,37 +1689,27 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
username = vmwareDc.getUser();
|
username = vmwareDc.getUser();
|
||||||
password = vmwareDc.getPassword();
|
password = vmwareDc.getPassword();
|
||||||
}
|
}
|
||||||
|
VcenterData vmwaredc = new VcenterData(vcenter, datacenterName, username, password);
|
||||||
|
return vmwaredc;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
private static class VcenterData {
|
||||||
logger.debug(String.format("Connecting to the VMware datacenter %s at vCenter %s to retrieve VMs",
|
public final String vcenter;
|
||||||
datacenterName, vcenter));
|
public final String datacenterName;
|
||||||
String serviceUrl = String.format("https://%s/sdk/vimService", vcenter);
|
public final String username;
|
||||||
VmwareClient vimClient = new VmwareClient(vcenter);
|
public final String password;
|
||||||
vimClient.connect(serviceUrl, username, password);
|
|
||||||
VmwareContext context = new VmwareContext(vimClient, vcenter);
|
|
||||||
|
|
||||||
DatacenterMO dcMo = new DatacenterMO(context, datacenterName);
|
public VcenterData(String vcenter, String datacenterName, String username, String password) {
|
||||||
ManagedObjectReference dcMor = dcMo.getMor();
|
this.vcenter = vcenter;
|
||||||
if (dcMor == null) {
|
this.datacenterName = datacenterName;
|
||||||
String msg = String.format("Unable to find VMware datacenter %s in vCenter %s",
|
this.username = username;
|
||||||
datacenterName, vcenter);
|
this.password = password;
|
||||||
logger.error(msg);
|
|
||||||
throw new InvalidParameterValueException(msg);
|
|
||||||
}
|
|
||||||
List<UnmanagedInstanceTO> instances = dcMo.getAllVmsOnDatacenter();
|
|
||||||
return StringUtils.isBlank(keyword) ? instances :
|
|
||||||
instances.stream().filter(x -> x.getName().toLowerCase().contains(keyword.toLowerCase())).collect(Collectors.toList());
|
|
||||||
} catch (Exception e) {
|
|
||||||
String errorMsg = String.format("Error retrieving stopped VMs from the VMware VC %s datacenter %s: %s",
|
|
||||||
vcenter, datacenterName, e.getMessage());
|
|
||||||
logger.error(errorMsg, e);
|
|
||||||
throw new CloudRuntimeException(errorMsg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNexusVSM(Long clusterId) {
|
public boolean hasNexusVSM(Long clusterId) {
|
||||||
ClusterVSMMapVO vsmMapVo = null;
|
ClusterVSMMapVO vsmMapVo;
|
||||||
|
|
||||||
vsmMapVo = _vsmMapDao.findByClusterId(clusterId);
|
vsmMapVo = _vsmMapDao.findByClusterId(clusterId);
|
||||||
if (vsmMapVo == null) {
|
if (vsmMapVo == null) {
|
||||||
@ -1693,7 +1759,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This task is to cleanup templates from primary storage that are otherwise not cleaned by the {@link com.cloud.storage.StorageManagerImpl.StorageGarbageCollector}.
|
* This task is to clean-up templates from primary storage that are otherwise not cleaned by the {@see com.cloud.storage.StorageManagerImpl.StorageGarbageCollector}.
|
||||||
* it is called at regular intervals when storage.template.cleanup.enabled == true
|
* it is called at regular intervals when storage.template.cleanup.enabled == true
|
||||||
* It collect all templates that
|
* It collect all templates that
|
||||||
* - are deleted from cloudstack
|
* - are deleted from cloudstack
|
||||||
|
|||||||
@ -45,6 +45,7 @@ import java.util.TimeZone;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.CleanupVMCommand;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
|
|
||||||
@ -583,6 +584,8 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
|||||||
return execute((ResizeVolumeCommand) cmd);
|
return execute((ResizeVolumeCommand) cmd);
|
||||||
} else if (clz == UnregisterVMCommand.class) {
|
} else if (clz == UnregisterVMCommand.class) {
|
||||||
return execute((UnregisterVMCommand) cmd);
|
return execute((UnregisterVMCommand) cmd);
|
||||||
|
} else if (clz == CleanupVMCommand.class) {
|
||||||
|
return execute((CleanupVMCommand) cmd);
|
||||||
} else if (cmd instanceof StorageSubSystemCommand) {
|
} else if (cmd instanceof StorageSubSystemCommand) {
|
||||||
checkStorageProcessorAndHandlerNfsVersionAttribute((StorageSubSystemCommand) cmd);
|
checkStorageProcessorAndHandlerNfsVersionAttribute((StorageSubSystemCommand) cmd);
|
||||||
return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd);
|
return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd);
|
||||||
@ -5796,6 +5799,26 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
|
|||||||
return new Answer(cmd, true, "success");
|
return new Answer(cmd, true, "success");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Answer execute(CleanupVMCommand cmd) {
|
||||||
|
VmwareContext context = getServiceContext();
|
||||||
|
VmwareHypervisorHost hyperHost = getHyperHost(context);
|
||||||
|
|
||||||
|
try {
|
||||||
|
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
|
||||||
|
if (vmMo == null) {
|
||||||
|
String msg = String.format("VM [%s] not found on vCenter, cleanup not needed.", cmd.getVmName());
|
||||||
|
logger.debug(msg);
|
||||||
|
return new Answer(cmd, true, msg);
|
||||||
|
}
|
||||||
|
vmMo.destroy();
|
||||||
|
String msg = String.format("VM [%s] remnants on vCenter cleaned up.", cmd.getVmName());
|
||||||
|
logger.debug(msg);
|
||||||
|
return new Answer(cmd, true, msg);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return new Answer(cmd, false, createLogMessageException(e, cmd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected Answer execute(UnregisterVMCommand cmd) {
|
protected Answer execute(UnregisterVMCommand cmd) {
|
||||||
VmwareContext context = getServiceContext();
|
VmwareContext context = getServiceContext();
|
||||||
VmwareHypervisorHost hyperHost = getHyperHost(context);
|
VmwareHypervisorHost hyperHost = getHyperHost(context);
|
||||||
|
|||||||
@ -36,8 +36,8 @@ import com.cloud.dc.VmwareDatacenterVO;
|
|||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
@APICommand(name = "addVmwareDc", description = "Adds a VMware datacenter to specified zone", responseObject = VmwareDatacenterResponse.class,
|
@APICommand(name = "addVmwareDc", description = "Adds a Vmware datacenter to specified zone",
|
||||||
requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
|
responseObject = VmwareDatacenterResponse.class, responseHasSensitiveInfo = false)
|
||||||
public class AddVmwareDcCmd extends BaseCmd {
|
public class AddVmwareDcCmd extends BaseCmd {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ -45,7 +45,7 @@ public class AddVmwareDcCmd extends BaseCmd {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of VMware datacenter to be added to specified zone.")
|
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "Name of Vmware datacenter to be added to specified zone.")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.VCENTER,
|
@Parameter(name = ApiConstants.VCENTER,
|
||||||
@ -54,10 +54,10 @@ public class AddVmwareDcCmd extends BaseCmd {
|
|||||||
description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
|
description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
|
||||||
private String vCenter;
|
private String vCenter;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = false, description = "The Username required to connect to resource.")
|
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The Username required to connect to resource.")
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, required = false, description = "The password for specified username.")
|
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "The Zone ID.")
|
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "The Zone ID.")
|
||||||
@ -99,7 +99,7 @@ public class AddVmwareDcCmd extends BaseCmd {
|
|||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
response.setObjectName("vmwaredc");
|
response.setObjectName("vmwaredc");
|
||||||
} else {
|
} else {
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add VMware Datacenter to zone.");
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add Vmware Datacenter to zone.");
|
||||||
}
|
}
|
||||||
this.setResponseObject(response);
|
this.setResponseObject(response);
|
||||||
} catch (DiscoveryException ex) {
|
} catch (DiscoveryException ex) {
|
||||||
|
|||||||
@ -48,8 +48,6 @@ import java.util.List;
|
|||||||
authorized = {RoleType.Admin})
|
authorized = {RoleType.Admin})
|
||||||
public class ImportVsphereStoragePoliciesCmd extends BaseCmd {
|
public class ImportVsphereStoragePoliciesCmd extends BaseCmd {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public VmwareDatacenterService _vmwareDatacenterService;
|
public VmwareDatacenterService _vmwareDatacenterService;
|
||||||
|
|
||||||
@ -74,6 +72,13 @@ public class ImportVsphereStoragePoliciesCmd extends BaseCmd {
|
|||||||
|
|
||||||
List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.importVsphereStoragePolicies(this);
|
List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.importVsphereStoragePolicies(this);
|
||||||
final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
|
final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
|
||||||
|
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = getVsphereStoragePoliciesResponses(storagePolicies, dataCenter);
|
||||||
|
responseList.setResponses(storagePoliciesResponseList);
|
||||||
|
responseList.setResponseName(getCommandName());
|
||||||
|
setResponseObject(responseList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<VsphereStoragePoliciesResponse> getVsphereStoragePoliciesResponses(List<? extends VsphereStoragePolicy> storagePolicies, DataCenter dataCenter) {
|
||||||
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
|
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
|
||||||
for (VsphereStoragePolicy storagePolicy : storagePolicies) {
|
for (VsphereStoragePolicy storagePolicy : storagePolicies) {
|
||||||
final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
|
final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
|
||||||
@ -86,9 +91,7 @@ public class ImportVsphereStoragePoliciesCmd extends BaseCmd {
|
|||||||
|
|
||||||
storagePoliciesResponseList.add(storagePoliciesResponse);
|
storagePoliciesResponseList.add(storagePoliciesResponse);
|
||||||
}
|
}
|
||||||
responseList.setResponses(storagePoliciesResponseList);
|
return storagePoliciesResponseList;
|
||||||
responseList.setResponseName(getCommandName());
|
|
||||||
setResponseObject(responseList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -0,0 +1,144 @@
|
|||||||
|
// 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 org.apache.cloudstack.api.command.admin.zone;
|
||||||
|
|
||||||
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
|
import com.cloud.exception.InsufficientCapacityException;
|
||||||
|
import com.cloud.exception.NetworkRuleConflictException;
|
||||||
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
|
import com.cloud.exception.ResourceUnavailableException;
|
||||||
|
import com.cloud.hypervisor.Hypervisor;
|
||||||
|
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||||
|
import com.cloud.hypervisor.vmware.mo.HostMO;
|
||||||
|
import com.cloud.user.Account;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
|
import com.vmware.vim25.InvalidPropertyFaultMsg;
|
||||||
|
import com.vmware.vim25.RuntimeFaultFaultMsg;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
|
import org.apache.cloudstack.api.BaseResponse;
|
||||||
|
import org.apache.cloudstack.api.Parameter;
|
||||||
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.response.HostResponse;
|
||||||
|
import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@APICommand(name = "listVmwareDcHosts", responseObject = VmwareRequestResponse.class,
|
||||||
|
description = "Lists the VMs in a Vmware Datacenter",
|
||||||
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
|
public class ListVmwareDcHostsCmd extends BaseCmd implements ListVmwareDcItems {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public VmwareDatacenterService _vmwareDatacenterService;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.EXISTING_VCENTER_ID,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
entityType = VmwareDatacenterResponse.class,
|
||||||
|
description = "UUID of a linked existing vCenter")
|
||||||
|
private Long existingVcenterId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.VCENTER,
|
||||||
|
type = CommandType.STRING,
|
||||||
|
description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
|
||||||
|
private String vcenter;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.DATACENTER_NAME, type = CommandType.STRING, description = "Name of Vmware datacenter.")
|
||||||
|
private String datacenterName;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The Username required to connect to resource.")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
public String getVcenter() {
|
||||||
|
return vcenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatacenterName() {
|
||||||
|
return datacenterName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getExistingVcenterId() {
|
||||||
|
return existingVcenterId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||||
|
checkParameters();
|
||||||
|
try {
|
||||||
|
List<HostMO> hosts = _vmwareDatacenterService.listHostsInDatacenter(this);
|
||||||
|
List<BaseResponse> baseResponseList = new ArrayList<>();
|
||||||
|
if (CollectionUtils.isNotEmpty(hosts)) {
|
||||||
|
for (HostMO vmwareHost : hosts) {
|
||||||
|
HostResponse resp = createHostResponse(vmwareHost);
|
||||||
|
baseResponseList.add(resp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VmwareRequestResponse<BaseResponse> response = new VmwareRequestResponse<>();
|
||||||
|
response.setResponses(baseResponseList, baseResponseList.size());
|
||||||
|
response.setResponseName(getCommandName());
|
||||||
|
setResponseObject(response);
|
||||||
|
} catch (CloudRuntimeException | InvalidPropertyFaultMsg | RuntimeFaultFaultMsg | InvocationTargetException |
|
||||||
|
NoSuchMethodException | IllegalAccessException e) {
|
||||||
|
String errorMsg = String.format("Error retrieving VMs from Vmware VC: %s", e.getMessage());
|
||||||
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HostResponse createHostResponse(HostMO hostInstance) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
|
HostResponse response = new HostResponse();
|
||||||
|
response.setHypervisor(Hypervisor.HypervisorType.VMware.toString());
|
||||||
|
response.setName(hostInstance.getHostName());
|
||||||
|
response.setObjectName("host");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkParameters() {
|
||||||
|
if ((existingVcenterId == null && vcenter == null) || (existingVcenterId != null && vcenter != null)) {
|
||||||
|
throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
|
||||||
|
"Please provide an existing vCenter ID or a vCenter IP/Name, parameters are mutually exclusive");
|
||||||
|
}
|
||||||
|
if (existingVcenterId == null && StringUtils.isAnyBlank(vcenter, datacenterName, username, password)) {
|
||||||
|
throw new ServerApiException(ApiErrorCode.PARAM_ERROR,
|
||||||
|
"Please set all the information for a vCenter IP/Name, datacenter, username and password");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getEntityOwnerId() {
|
||||||
|
return Account.ACCOUNT_ID_SYSTEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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.
|
||||||
|
package org.apache.cloudstack.api.command.admin.zone;
|
||||||
|
|
||||||
|
public interface ListVmwareDcItems {
|
||||||
|
String getVcenter();
|
||||||
|
|
||||||
|
String getDatacenterName();
|
||||||
|
|
||||||
|
String getUsername();
|
||||||
|
|
||||||
|
String getPassword();
|
||||||
|
|
||||||
|
Long getExistingVcenterId();
|
||||||
|
}
|
||||||
@ -23,15 +23,15 @@ import com.cloud.exception.ResourceAllocationException;
|
|||||||
import com.cloud.exception.ResourceUnavailableException;
|
import com.cloud.exception.ResourceUnavailableException;
|
||||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.ApiErrorCode;
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
import org.apache.cloudstack.api.BaseListCmd;
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
import org.apache.cloudstack.api.BaseResponse;
|
import org.apache.cloudstack.api.BaseResponse;
|
||||||
import org.apache.cloudstack.api.Parameter;
|
import org.apache.cloudstack.api.Parameter;
|
||||||
import org.apache.cloudstack.api.ServerApiException;
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
import org.apache.cloudstack.api.response.ListResponse;
|
|
||||||
import org.apache.cloudstack.api.response.UnmanagedInstanceResponse;
|
import org.apache.cloudstack.api.response.UnmanagedInstanceResponse;
|
||||||
import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
|
import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
|
||||||
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
||||||
@ -42,10 +42,10 @@ import javax.inject.Inject;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@APICommand(name = "listVmwareDcVms", responseObject = UnmanagedInstanceResponse.class,
|
@APICommand(name = "listVmwareDcVms", responseObject = VmwareRequestResponse.class,
|
||||||
description = "Lists the VMs in a VMware Datacenter",
|
description = "Lists the VMs in a Vmware Datacenter",
|
||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
public class ListVmwareDcVmsCmd extends BaseListCmd {
|
public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public VmwareDatacenterService _vmwareDatacenterService;
|
public VmwareDatacenterService _vmwareDatacenterService;
|
||||||
@ -61,7 +61,7 @@ public class ListVmwareDcVmsCmd extends BaseListCmd {
|
|||||||
description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
|
description = "The name/ip of vCenter. Make sure it is IP address or full qualified domain name for host running vCenter server.")
|
||||||
private String vcenter;
|
private String vcenter;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.DATACENTER_NAME, type = CommandType.STRING, description = "Name of VMware datacenter.")
|
@Parameter(name = ApiConstants.DATACENTER_NAME, type = CommandType.STRING, description = "Name of Vmware datacenter.")
|
||||||
private String datacenterName;
|
private String datacenterName;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The Username required to connect to resource.")
|
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "The Username required to connect to resource.")
|
||||||
@ -70,6 +70,18 @@ public class ListVmwareDcVmsCmd extends BaseListCmd {
|
|||||||
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
|
@Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.HOST, type = CommandType.STRING, description = "get only the VMs from the specified host.")
|
||||||
|
private String host;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.BATCH_SIZE, type = CommandType.INTEGER, description = "The maximum number of results to return.")
|
||||||
|
private Integer batchSize;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.TOKEN, type = CommandType.STRING,
|
||||||
|
description = "For listVmwareDcVms, if the maximum number of results (the `batchsize`) is exceeded, " +
|
||||||
|
" a token is returned. This token can be used in subsequent calls to retrieve more results." +
|
||||||
|
" As long as a token is returned, more results can be retrieved.")
|
||||||
|
private String token;
|
||||||
|
|
||||||
public String getVcenter() {
|
public String getVcenter() {
|
||||||
return vcenter;
|
return vcenter;
|
||||||
}
|
}
|
||||||
@ -82,6 +94,18 @@ public class ListVmwareDcVmsCmd extends BaseListCmd {
|
|||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getBatchSize() {
|
||||||
|
return batchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
public String getDatacenterName() {
|
public String getDatacenterName() {
|
||||||
return datacenterName;
|
return datacenterName;
|
||||||
}
|
}
|
||||||
@ -94,7 +118,8 @@ public class ListVmwareDcVmsCmd extends BaseListCmd {
|
|||||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||||
checkParameters();
|
checkParameters();
|
||||||
try {
|
try {
|
||||||
List<UnmanagedInstanceTO> vms = _vmwareDatacenterService.listVMsInDatacenter(this);
|
Pair<String, List<UnmanagedInstanceTO>> results = _vmwareDatacenterService.listVMsInDatacenter(this);
|
||||||
|
List<UnmanagedInstanceTO> vms = results.second();
|
||||||
List<BaseResponse> baseResponseList = new ArrayList<>();
|
List<BaseResponse> baseResponseList = new ArrayList<>();
|
||||||
if (CollectionUtils.isNotEmpty(vms)) {
|
if (CollectionUtils.isNotEmpty(vms)) {
|
||||||
for (UnmanagedInstanceTO vmwareVm : vms) {
|
for (UnmanagedInstanceTO vmwareVm : vms) {
|
||||||
@ -102,16 +127,13 @@ public class ListVmwareDcVmsCmd extends BaseListCmd {
|
|||||||
baseResponseList.add(resp);
|
baseResponseList.add(resp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<BaseResponse> pagingList = com.cloud.utils.StringUtils.applyPagination(baseResponseList, this.getStartIndex(), this.getPageSizeVal());
|
VmwareRequestResponse<BaseResponse> response = new VmwareRequestResponse<>();
|
||||||
if (CollectionUtils.isEmpty(pagingList)) {
|
response.setResponses(baseResponseList, baseResponseList.size());
|
||||||
pagingList = baseResponseList;
|
|
||||||
}
|
|
||||||
ListResponse<BaseResponse> response = new ListResponse<>();
|
|
||||||
response.setResponses(pagingList, baseResponseList.size());
|
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
|
response.setToken(results.first());
|
||||||
setResponseObject(response);
|
setResponseObject(response);
|
||||||
} catch (CloudRuntimeException e) {
|
} catch (CloudRuntimeException e) {
|
||||||
String errorMsg = String.format("Error retrieving VMs from VMware VC: %s", e.getMessage());
|
String errorMsg = String.format("Error retrieving VMs from Vmware VC: %s", e.getMessage());
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,6 +156,6 @@ public class ListVmwareDcVmsCmd extends BaseListCmd {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCommandName() {
|
public String getCommandName() {
|
||||||
return "listvmwaredcvmsresponse";
|
return "listVmwareDcVmsResponse".toLowerCase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ import com.cloud.dc.VmwareDatacenter;
|
|||||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
|
|
||||||
@APICommand(name = "listVmwareDcs", responseObject = VmwareDatacenterResponse.class, description = "Retrieves VMware DC(s) associated with a zone.",
|
@APICommand(name = "listVmwareDcs", responseObject = VmwareDatacenterResponse.class, description = "Retrieves Vmware DC(s) associated with a zone.",
|
||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
public class ListVmwareDcsCmd extends BaseListCmd {
|
public class ListVmwareDcsCmd extends BaseListCmd {
|
||||||
|
|
||||||
@ -50,7 +50,6 @@ public class ListVmwareDcsCmd extends BaseListCmd {
|
|||||||
public VmwareDatacenterService _vmwareDatacenterService;
|
public VmwareDatacenterService _vmwareDatacenterService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
//////////////// API parameters /////////////////////
|
//////////////// API parameters /////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -73,20 +72,27 @@ public class ListVmwareDcsCmd extends BaseListCmd {
|
|||||||
@Override
|
@Override
|
||||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
||||||
ResourceAllocationException {
|
ResourceAllocationException {
|
||||||
List<? extends VmwareDatacenter> vmwareDcList = null;
|
List<? extends VmwareDatacenter> vmwareDcList;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
vmwareDcList = _vmwareDatacenterService.listVmwareDatacenters(this);
|
vmwareDcList = _vmwareDatacenterService.listVmwareDatacenters(this);
|
||||||
} catch (InvalidParameterValueException ie) {
|
} catch (InvalidParameterValueException ie) {
|
||||||
throw new InvalidParameterValueException("Invalid zone id " + getZoneId());
|
throw new InvalidParameterValueException("Invalid zone id " + getZoneId());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find associated VMware DCs associated with zone " + getZoneId());
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to find associated Vmware DCs associated with zone " + getZoneId());
|
||||||
}
|
}
|
||||||
|
|
||||||
ListResponse<VmwareDatacenterResponse> response = new ListResponse<VmwareDatacenterResponse>();
|
ListResponse<VmwareDatacenterResponse> response = new ListResponse<>();
|
||||||
List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<VmwareDatacenterResponse>();
|
List<VmwareDatacenterResponse> vmwareDcResponses = getVmwareDatacenterResponses(vmwareDcList);
|
||||||
|
response.setResponses(vmwareDcResponses);
|
||||||
|
response.setResponseName(getCommandName());
|
||||||
|
setResponseObject(response);
|
||||||
|
}
|
||||||
|
|
||||||
if (vmwareDcList != null && vmwareDcList.size() > 0) {
|
private List<VmwareDatacenterResponse> getVmwareDatacenterResponses(List<? extends VmwareDatacenter> vmwareDcList) {
|
||||||
|
List<VmwareDatacenterResponse> vmwareDcResponses = new ArrayList<>();
|
||||||
|
|
||||||
|
if (vmwareDcList != null && !vmwareDcList.isEmpty()) {
|
||||||
for (VmwareDatacenter vmwareDc : vmwareDcList) {
|
for (VmwareDatacenter vmwareDc : vmwareDcList) {
|
||||||
VmwareDatacenterResponse vmwareDcResponse = new VmwareDatacenterResponse();
|
VmwareDatacenterResponse vmwareDcResponse = new VmwareDatacenterResponse();
|
||||||
|
|
||||||
@ -94,14 +100,12 @@ public class ListVmwareDcsCmd extends BaseListCmd {
|
|||||||
vmwareDcResponse.setVcenter(vmwareDc.getVcenterHost());
|
vmwareDcResponse.setVcenter(vmwareDc.getVcenterHost());
|
||||||
vmwareDcResponse.setName(vmwareDc.getVmwareDatacenterName());
|
vmwareDcResponse.setName(vmwareDc.getVmwareDatacenterName());
|
||||||
vmwareDcResponse.setZoneId(getZoneId());
|
vmwareDcResponse.setZoneId(getZoneId());
|
||||||
vmwareDcResponse.setObjectName("VMwareDC");
|
vmwareDcResponse.setObjectName(ApiConstants.VMWARE_DC);
|
||||||
|
|
||||||
vmwareDcResponses.add(vmwareDcResponse);
|
vmwareDcResponses.add(vmwareDcResponse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response.setResponses(vmwareDcResponses);
|
return vmwareDcResponses;
|
||||||
response.setResponseName(getCommandName());
|
|
||||||
setResponseObject(response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -47,8 +47,6 @@ import java.util.List;
|
|||||||
authorized = {RoleType.Admin})
|
authorized = {RoleType.Admin})
|
||||||
public class ListVsphereStoragePoliciesCmd extends BaseCmd {
|
public class ListVsphereStoragePoliciesCmd extends BaseCmd {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public VmwareDatacenterService _vmwareDatacenterService;
|
public VmwareDatacenterService _vmwareDatacenterService;
|
||||||
|
|
||||||
@ -73,6 +71,13 @@ public class ListVsphereStoragePoliciesCmd extends BaseCmd {
|
|||||||
|
|
||||||
List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.listVsphereStoragePolicies(this);
|
List<? extends VsphereStoragePolicy> storagePolicies = _vmwareDatacenterService.listVsphereStoragePolicies(this);
|
||||||
final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
|
final ListResponse<VsphereStoragePoliciesResponse> responseList = new ListResponse<>();
|
||||||
|
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = getVsphereStoragePoliciesResponses(storagePolicies, dataCenter);
|
||||||
|
responseList.setResponses(storagePoliciesResponseList);
|
||||||
|
responseList.setResponseName(getCommandName());
|
||||||
|
setResponseObject(responseList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<VsphereStoragePoliciesResponse> getVsphereStoragePoliciesResponses(List<? extends VsphereStoragePolicy> storagePolicies, DataCenter dataCenter) {
|
||||||
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
|
final List<VsphereStoragePoliciesResponse> storagePoliciesResponseList = new ArrayList<>();
|
||||||
for (VsphereStoragePolicy storagePolicy : storagePolicies) {
|
for (VsphereStoragePolicy storagePolicy : storagePolicies) {
|
||||||
final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
|
final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse();
|
||||||
@ -81,13 +86,11 @@ public class ListVsphereStoragePoliciesCmd extends BaseCmd {
|
|||||||
storagePoliciesResponse.setName(storagePolicy.getName());
|
storagePoliciesResponse.setName(storagePolicy.getName());
|
||||||
storagePoliciesResponse.setPolicyId(storagePolicy.getPolicyId());
|
storagePoliciesResponse.setPolicyId(storagePolicy.getPolicyId());
|
||||||
storagePoliciesResponse.setDescription(storagePolicy.getDescription());
|
storagePoliciesResponse.setDescription(storagePolicy.getDescription());
|
||||||
storagePoliciesResponse.setObjectName("StoragePolicy");
|
storagePoliciesResponse.setObjectName(ApiConstants.STORAGE_POLICY);
|
||||||
|
|
||||||
storagePoliciesResponseList.add(storagePoliciesResponse);
|
storagePoliciesResponseList.add(storagePoliciesResponse);
|
||||||
}
|
}
|
||||||
responseList.setResponses(storagePoliciesResponseList);
|
return storagePoliciesResponseList;
|
||||||
responseList.setResponseName(getCommandName());
|
|
||||||
setResponseObject(responseList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -68,7 +68,7 @@ public class ListVsphereStoragePolicyCompatiblePoolsCmd extends BaseListCmd {
|
|||||||
List<StoragePoolResponse> poolResponses = new ArrayList<>();
|
List<StoragePoolResponse> poolResponses = new ArrayList<>();
|
||||||
for (StoragePool pool : pools) {
|
for (StoragePool pool : pools) {
|
||||||
StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
|
StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool);
|
||||||
poolResponse.setObjectName("storagepool");
|
poolResponse.setObjectName(ApiConstants.STORAGE_POOL);
|
||||||
poolResponses.add(poolResponse);
|
poolResponses.add(poolResponse);
|
||||||
}
|
}
|
||||||
response.setResponses(poolResponses);
|
response.setResponses(poolResponses);
|
||||||
|
|||||||
@ -34,7 +34,7 @@ import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
|||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
@APICommand(name = "removeVmwareDc", responseObject = SuccessResponse.class, description = "Remove a VMware datacenter from a zone.",
|
@APICommand(name = "removeVmwareDc", responseObject = SuccessResponse.class, description = "Remove a Vmware datacenter from a zone.",
|
||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
public class RemoveVmwareDcCmd extends BaseCmd {
|
public class RemoveVmwareDcCmd extends BaseCmd {
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ public class RemoveVmwareDcCmd extends BaseCmd {
|
|||||||
type = CommandType.UUID,
|
type = CommandType.UUID,
|
||||||
entityType = ZoneResponse.class,
|
entityType = ZoneResponse.class,
|
||||||
required = true,
|
required = true,
|
||||||
description = "The id of Zone from which VMware datacenter has to be removed.")
|
description = "The id of Zone from which Vmware datacenter has to be removed.")
|
||||||
private Long zoneId;
|
private Long zoneId;
|
||||||
|
|
||||||
public Long getZoneId() {
|
public Long getZoneId() {
|
||||||
@ -63,7 +63,7 @@ public class RemoveVmwareDcCmd extends BaseCmd {
|
|||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
setResponseObject(response);
|
setResponseObject(response);
|
||||||
} else {
|
} else {
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove VMware datacenter from zone");
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove Vmware datacenter from zone");
|
||||||
}
|
}
|
||||||
} catch (ResourceInUseException ex) {
|
} catch (ResourceInUseException ex) {
|
||||||
logger.warn("The zone has one or more resources (like cluster), hence not able to remove VMware datacenter from zone."
|
logger.warn("The zone has one or more resources (like cluster), hence not able to remove VMware datacenter from zone."
|
||||||
|
|||||||
@ -33,12 +33,11 @@ import com.cloud.dc.VmwareDatacenter;
|
|||||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
|
|
||||||
@APICommand(name = "updateVmwareDc", description = "Updates a VMware datacenter details for a zone",
|
@APICommand(name = "updateVmwareDc", description = "Updates a Vmware datacenter details for a zone",
|
||||||
responseObject = VmwareDatacenterResponse.class, responseHasSensitiveInfo = false,
|
responseObject = VmwareDatacenterResponse.class, responseHasSensitiveInfo = false,
|
||||||
since = "4.12.0", authorized = {RoleType.Admin})
|
since = "4.12.0", authorized = {RoleType.Admin})
|
||||||
public class UpdateVmwareDcCmd extends BaseCmd {
|
public class UpdateVmwareDcCmd extends BaseCmd {
|
||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public VmwareDatacenterService vmwareDatacenterService;
|
public VmwareDatacenterService vmwareDatacenterService;
|
||||||
|
|
||||||
@ -51,7 +50,7 @@ public class UpdateVmwareDcCmd extends BaseCmd {
|
|||||||
private Long zoneId;
|
private Long zoneId;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
|
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
|
||||||
description = "VMware datacenter name.")
|
description = "Vmware datacenter name.")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.VCENTER, type = CommandType.STRING,
|
@Parameter(name = ApiConstants.VCENTER, type = CommandType.STRING,
|
||||||
@ -106,13 +105,13 @@ public class UpdateVmwareDcCmd extends BaseCmd {
|
|||||||
public void execute() {
|
public void execute() {
|
||||||
final VmwareDatacenter vmwareDatacenter = vmwareDatacenterService.updateVmwareDatacenter(this);
|
final VmwareDatacenter vmwareDatacenter = vmwareDatacenterService.updateVmwareDatacenter(this);
|
||||||
if (vmwareDatacenter == null) {
|
if (vmwareDatacenter == null) {
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update VMware datacenter");
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update Vmware datacenter");
|
||||||
}
|
}
|
||||||
final VmwareDatacenterResponse response = new VmwareDatacenterResponse();
|
final VmwareDatacenterResponse response = new VmwareDatacenterResponse();
|
||||||
response.setId(vmwareDatacenter.getUuid());
|
response.setId(vmwareDatacenter.getUuid());
|
||||||
response.setName(vmwareDatacenter.getVmwareDatacenterName());
|
response.setName(vmwareDatacenter.getVmwareDatacenterName());
|
||||||
response.setResponseName(getCommandName());
|
response.setResponseName(getCommandName());
|
||||||
response.setObjectName("vmwaredc");
|
response.setObjectName(ApiConstants.VMWARE_DC);
|
||||||
setResponseObject(response);
|
setResponseObject(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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 org.apache.cloudstack.api.command.admin.zone;
|
||||||
|
|
||||||
|
import com.cloud.serializer.Param;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.api.ResponseObject;
|
||||||
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
|
|
||||||
|
public class VmwareRequestResponse<T extends ResponseObject> extends ListResponse<T> {
|
||||||
|
@SerializedName(ApiConstants.TOKEN)
|
||||||
|
@Param(description = "The Vmware API token to use for retrieving further responses with")
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(String token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -23,10 +23,8 @@ import java.io.FileWriter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -206,14 +204,12 @@ public class KubernetesClusterActionWorker {
|
|||||||
|
|
||||||
protected String getControlNodeLoginUser() {
|
protected String getControlNodeLoginUser() {
|
||||||
List<KubernetesClusterVmMapVO> vmMapVOList = getKubernetesClusterVMMaps();
|
List<KubernetesClusterVmMapVO> vmMapVOList = getKubernetesClusterVMMaps();
|
||||||
if (vmMapVOList.size() > 0) {
|
if (!vmMapVOList.isEmpty()) {
|
||||||
long vmId = vmMapVOList.get(0).getVmId();
|
long vmId = vmMapVOList.get(0).getVmId();
|
||||||
UserVmVO userVM = userVmDao.findById(vmId);
|
UserVmVO userVM = userVmDao.findById(vmId);
|
||||||
if (userVM == null) {
|
if (userVM == null) {
|
||||||
throw new CloudRuntimeException("Failed to find login user, Unable to log in to node to fetch details");
|
throw new CloudRuntimeException("Failed to find login user, Unable to log in to node to fetch details");
|
||||||
}
|
}
|
||||||
Set<String> vm = new HashSet<>();
|
|
||||||
vm.add(userVM.getName());
|
|
||||||
UserVmDetailVO vmDetail = userVmDetailsDao.findDetail(vmId, VmDetailConstants.CKS_CONTROL_NODE_LOGIN_USER);
|
UserVmDetailVO vmDetail = userVmDetailsDao.findDetail(vmId, VmDetailConstants.CKS_CONTROL_NODE_LOGIN_USER);
|
||||||
if (vmDetail != null && !org.apache.commons.lang3.StringUtils.isEmpty(vmDetail.getValue())) {
|
if (vmDetail != null && !org.apache.commons.lang3.StringUtils.isEmpty(vmDetail.getValue())) {
|
||||||
return vmDetail.getValue();
|
return vmDetail.getValue();
|
||||||
@ -309,7 +305,7 @@ public class KubernetesClusterActionWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected KubernetesClusterVmMapVO addKubernetesClusterVm(final long kubernetesClusterId, final long vmId, boolean isControlNode) {
|
protected KubernetesClusterVmMapVO addKubernetesClusterVm(final long kubernetesClusterId, final long vmId, boolean isControlNode) {
|
||||||
return Transaction.execute(new TransactionCallback<KubernetesClusterVmMapVO>() {
|
return Transaction.execute(new TransactionCallback<>() {
|
||||||
@Override
|
@Override
|
||||||
public KubernetesClusterVmMapVO doInTransaction(TransactionStatus status) {
|
public KubernetesClusterVmMapVO doInTransaction(TransactionStatus status) {
|
||||||
KubernetesClusterVmMapVO newClusterVmMap = new KubernetesClusterVmMapVO(kubernetesClusterId, vmId, isControlNode);
|
KubernetesClusterVmMapVO newClusterVmMap = new KubernetesClusterVmMapVO(kubernetesClusterId, vmId, isControlNode);
|
||||||
@ -361,7 +357,12 @@ public class KubernetesClusterActionWorker {
|
|||||||
}
|
}
|
||||||
IpAddress address = ipAddressDao.findByUuid(detailsVO.getValue());
|
IpAddress address = ipAddressDao.findByUuid(detailsVO.getValue());
|
||||||
if (address == null || !Objects.equals(network.getVpcId(), address.getVpcId())) {
|
if (address == null || !Objects.equals(network.getVpcId(), address.getVpcId())) {
|
||||||
logger.warn(String.format("Public IP with ID: %s linked to the Kubernetes cluster: %s is not usable", detailsVO.getValue(), kubernetesCluster.getName()));
|
logger.warn("Public IP with ID: {} linked to the Kubernetes cluster: {} is not usable", detailsVO.getValue(), kubernetesCluster.getName());
|
||||||
|
if (address == null) {
|
||||||
|
logger.warn("Public IP with ID: {} was not found by uuid", detailsVO.getValue());
|
||||||
|
} else {
|
||||||
|
logger.warn("Public IP with ID: {} was associated with vpc {} instead of {}", detailsVO.getValue(), address.getVpcId(), network.getVpcId());
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return address;
|
return address;
|
||||||
@ -517,8 +518,7 @@ public class KubernetesClusterActionWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected List<KubernetesClusterVmMapVO> getKubernetesClusterVMMaps() {
|
protected List<KubernetesClusterVmMapVO> getKubernetesClusterVMMaps() {
|
||||||
List<KubernetesClusterVmMapVO> clusterVMs = kubernetesClusterVmMapDao.listByClusterId(kubernetesCluster.getId());
|
return kubernetesClusterVmMapDao.listByClusterId(kubernetesCluster.getId());
|
||||||
return clusterVMs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<KubernetesClusterVmMapVO> getKubernetesClusterVMMapsForNodes(List<Long> nodeIds) {
|
protected List<KubernetesClusterVmMapVO> getKubernetesClusterVMMapsForNodes(List<Long> nodeIds) {
|
||||||
|
|||||||
@ -193,7 +193,7 @@ public class KubernetesClusterUtil {
|
|||||||
while (System.currentTimeMillis() < timeoutTime) {
|
while (System.currentTimeMillis() < timeoutTime) {
|
||||||
try {
|
try {
|
||||||
Pair<Boolean, String> result = SshHelper.sshExecute(ipAddress, port, user,
|
Pair<Boolean, String> result = SshHelper.sshExecute(ipAddress, port, user,
|
||||||
sshKeyFile, null, "sudo cat /etc/kubernetes/admin.conf",
|
sshKeyFile, null, "sudo cat /etc/kubernetes/user.conf 2>/dev/null || sudo cat /etc/kubernetes/admin.conf",
|
||||||
10000, 10000, 10000);
|
10000, 10000, 10000);
|
||||||
|
|
||||||
if (result.first() && StringUtils.isNotEmpty(result.second())) {
|
if (result.first() && StringUtils.isNotEmpty(result.second())) {
|
||||||
|
|||||||
@ -5,12 +5,23 @@ All notable changes to Linstor CloudStack plugin will be documented in this file
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [2025-01-27]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Use of multiple primary storages on the same linstor controller
|
||||||
|
|
||||||
## [2025-01-20]
|
## [2025-01-20]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Volume snapshots on zfs used the wrong dataset path to hide/unhide snapdev
|
- Volume snapshots on zfs used the wrong dataset path to hide/unhide snapdev
|
||||||
|
|
||||||
|
## [2024-12-19]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Native CloudStack encryption support
|
||||||
|
|
||||||
## [2024-12-13]
|
## [2024-12-13]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@ -97,18 +97,23 @@ public final class LinstorBackupSnapshotCommandWrapper
|
|||||||
// NOTE: the qemu img will also contain the drbd metadata at the end
|
// NOTE: the qemu img will also contain the drbd metadata at the end
|
||||||
final QemuImg qemu = new QemuImg(waitMilliSeconds);
|
final QemuImg qemu = new QemuImg(waitMilliSeconds);
|
||||||
qemu.convert(srcFile, dstFile);
|
qemu.convert(srcFile, dstFile);
|
||||||
LOGGER.info("Backup snapshot " + srcFile + " to " + dstPath);
|
LOGGER.info("Backup snapshot '{}' to '{}'", srcPath, dstPath);
|
||||||
return dstPath;
|
return dstPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SnapshotObjectTO setCorrectSnapshotSize(final SnapshotObjectTO dst, final String dstPath) {
|
private SnapshotObjectTO setCorrectSnapshotSize(final SnapshotObjectTO dst, final String dstPath) {
|
||||||
final File snapFile = new File(dstPath);
|
final File snapFile = new File(dstPath);
|
||||||
final long size = snapFile.exists() ? snapFile.length() : 0;
|
long size;
|
||||||
|
if (snapFile.exists()) {
|
||||||
|
size = snapFile.length();
|
||||||
|
} else {
|
||||||
|
LOGGER.warn("Snapshot file {} does not exist. Reporting size 0", dstPath);
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
final SnapshotObjectTO snapshot = new SnapshotObjectTO();
|
dst.setPath(dst.getPath() + File.separator + dst.getName());
|
||||||
snapshot.setPath(dst.getPath() + File.separator + dst.getName());
|
dst.setPhysicalSize(size);
|
||||||
snapshot.setPhysicalSize(size);
|
return dst;
|
||||||
return snapshot;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -158,6 +163,7 @@ public final class LinstorBackupSnapshotCommandWrapper
|
|||||||
LOGGER.info("Backup shrunk " + dstPath + " to actual size " + src.getVolume().getSize());
|
LOGGER.info("Backup shrunk " + dstPath + " to actual size " + src.getVolume().getSize());
|
||||||
|
|
||||||
SnapshotObjectTO snapshot = setCorrectSnapshotSize(dst, dstPath);
|
SnapshotObjectTO snapshot = setCorrectSnapshotSize(dst, dstPath);
|
||||||
|
LOGGER.info("Actual file size for '{}' is {}", dstPath, snapshot.getPhysicalSize());
|
||||||
return new CopyCmdAnswer(snapshot);
|
return new CopyCmdAnswer(snapshot);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
final String error = String.format("Failed to backup snapshot with id [%s] with a pool %s, due to %s",
|
final String error = String.format("Failed to backup snapshot with id [%s] with a pool %s, due to %s",
|
||||||
|
|||||||
@ -61,6 +61,11 @@ import com.linbit.linstor.api.model.Volume;
|
|||||||
import com.linbit.linstor.api.model.VolumeDefinition;
|
import com.linbit.linstor.api.model.VolumeDefinition;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
public class LinstorStorageAdaptor implements StorageAdaptor {
|
public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||||
protected Logger logger = LogManager.getLogger(getClass());
|
protected Logger logger = LogManager.getLogger(getClass());
|
||||||
@ -202,10 +207,10 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
|||||||
final DevelopersApi api = getLinstorAPI(pool);
|
final DevelopersApi api = getLinstorAPI(pool);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<ResourceDefinition> definitionList = api.resourceDefinitionList(
|
ResourceDefinition resourceDefinition = LinstorUtil.findResourceDefinition(
|
||||||
Collections.singletonList(rscName), null, null, null);
|
api, rscName, lpool.getResourceGroup());
|
||||||
|
|
||||||
if (definitionList.isEmpty()) {
|
if (resourceDefinition == null) {
|
||||||
ResourceGroupSpawn rgSpawn = new ResourceGroupSpawn();
|
ResourceGroupSpawn rgSpawn = new ResourceGroupSpawn();
|
||||||
rgSpawn.setResourceDefinitionName(rscName);
|
rgSpawn.setResourceDefinitionName(rscName);
|
||||||
rgSpawn.addVolumeSizesItem(size / 1024); // linstor uses KiB
|
rgSpawn.addVolumeSizesItem(size / 1024); // linstor uses KiB
|
||||||
@ -215,22 +220,28 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
|||||||
handleLinstorApiAnswers(answers, "Linstor: Unable to spawn resource.");
|
handleLinstorApiAnswers(answers, "Linstor: Unable to spawn resource.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String foundRscName = resourceDefinition != null ? resourceDefinition.getName() : rscName;
|
||||||
|
|
||||||
// query linstor for the device path
|
// query linstor for the device path
|
||||||
List<ResourceWithVolumes> resources = api.viewResources(
|
List<ResourceWithVolumes> resources = api.viewResources(
|
||||||
Collections.emptyList(),
|
Collections.emptyList(),
|
||||||
Collections.singletonList(rscName),
|
Collections.singletonList(foundRscName),
|
||||||
Collections.emptyList(),
|
Collections.emptyList(),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null);
|
null);
|
||||||
|
|
||||||
makeResourceAvailable(api, rscName, false);
|
makeResourceAvailable(api, foundRscName, false);
|
||||||
|
|
||||||
if (!resources.isEmpty() && !resources.get(0).getVolumes().isEmpty()) {
|
if (!resources.isEmpty() && !resources.get(0).getVolumes().isEmpty()) {
|
||||||
final String devPath = resources.get(0).getVolumes().get(0).getDevicePath();
|
final String devPath = resources.get(0).getVolumes().get(0).getDevicePath();
|
||||||
logger.info("Linstor: Created drbd device: " + devPath);
|
logger.info("Linstor: Created drbd device: " + devPath);
|
||||||
final KVMPhysicalDisk kvmDisk = new KVMPhysicalDisk(devPath, name, pool);
|
final KVMPhysicalDisk kvmDisk = new KVMPhysicalDisk(devPath, name, pool);
|
||||||
kvmDisk.setFormat(QemuImg.PhysicalDiskFormat.RAW);
|
kvmDisk.setFormat(QemuImg.PhysicalDiskFormat.RAW);
|
||||||
|
long allocatedKib = resources.get(0).getVolumes().get(0).getAllocatedSizeKib() != null ?
|
||||||
|
resources.get(0).getVolumes().get(0).getAllocatedSizeKib() : 0;
|
||||||
|
kvmDisk.setSize(allocatedKib >= 0 ? allocatedKib * 1024 : 0);
|
||||||
|
kvmDisk.setVirtualSize(size);
|
||||||
return kvmDisk;
|
return kvmDisk;
|
||||||
} else {
|
} else {
|
||||||
logger.error("Linstor: viewResources didn't return resources or volumes.");
|
logger.error("Linstor: viewResources didn't return resources or volumes.");
|
||||||
@ -410,7 +421,7 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
|||||||
if (rsc.getFlags() != null &&
|
if (rsc.getFlags() != null &&
|
||||||
rsc.getFlags().contains(ApiConsts.FLAG_DRBD_DISKLESS) &&
|
rsc.getFlags().contains(ApiConsts.FLAG_DRBD_DISKLESS) &&
|
||||||
!rsc.getFlags().contains(ApiConsts.FLAG_TIE_BREAKER)) {
|
!rsc.getFlags().contains(ApiConsts.FLAG_TIE_BREAKER)) {
|
||||||
ApiCallRcList delAnswers = api.resourceDelete(rsc.getName(), localNodeName);
|
ApiCallRcList delAnswers = api.resourceDelete(rsc.getName(), localNodeName, true);
|
||||||
logLinstorAnswers(delAnswers);
|
logLinstorAnswers(delAnswers);
|
||||||
}
|
}
|
||||||
} catch (ApiException apiEx) {
|
} catch (ApiException apiEx) {
|
||||||
@ -473,21 +484,56 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrements the aux property key for template resource and deletes or just deletes if not template resource.
|
||||||
|
* @param api
|
||||||
|
* @param rscName
|
||||||
|
* @param rscGrpName
|
||||||
|
* @return
|
||||||
|
* @throws ApiException
|
||||||
|
*/
|
||||||
|
private boolean deRefOrDeleteResource(DevelopersApi api, String rscName, String rscGrpName) throws ApiException {
|
||||||
|
boolean deleted = false;
|
||||||
|
List<ResourceDefinition> existingRDs = LinstorUtil.getRDListStartingWith(api, rscName);
|
||||||
|
for (ResourceDefinition rd : existingRDs) {
|
||||||
|
int expectedProps = 0; // if it is a non template resource, we don't expect any _cs-template-for- prop
|
||||||
|
String propKey = LinstorUtil.getTemplateForAuxPropKey(rscGrpName);
|
||||||
|
if (rd.getProps().containsKey(propKey)) {
|
||||||
|
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
|
||||||
|
rdm.deleteProps(Collections.singletonList(propKey));
|
||||||
|
api.resourceDefinitionModify(rd.getName(), rdm);
|
||||||
|
expectedProps = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there is only one template-for property left for templates, the template isn't needed anymore
|
||||||
|
// or if it isn't a template anyway, it will not have this Aux property
|
||||||
|
// _cs-template-for- poperties work like a ref-count.
|
||||||
|
if (rd.getProps().keySet().stream()
|
||||||
|
.filter(key -> key.startsWith("Aux/" + LinstorUtil.CS_TEMPLATE_FOR_PREFIX))
|
||||||
|
.count() == expectedProps) {
|
||||||
|
ApiCallRcList answers = api.resourceDefinitionDelete(rd.getName());
|
||||||
|
checkLinstorAnswersThrow(answers);
|
||||||
|
deleted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deletePhysicalDisk(String name, KVMStoragePool pool, Storage.ImageFormat format)
|
public boolean deletePhysicalDisk(String name, KVMStoragePool pool, Storage.ImageFormat format)
|
||||||
{
|
{
|
||||||
logger.debug("Linstor: deletePhysicalDisk " + name);
|
logger.debug("Linstor: deletePhysicalDisk " + name);
|
||||||
final DevelopersApi api = getLinstorAPI(pool);
|
final DevelopersApi api = getLinstorAPI(pool);
|
||||||
|
final String rscName = getLinstorRscName(name);
|
||||||
|
final LinstorStoragePool linstorPool = (LinstorStoragePool) pool;
|
||||||
|
String rscGrpName = linstorPool.getResourceGroup();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final String rscName = getLinstorRscName(name);
|
return deRefOrDeleteResource(api, rscName, rscGrpName);
|
||||||
logger.debug("Linstor: delete resource definition " + rscName);
|
|
||||||
ApiCallRcList answers = api.resourceDefinitionDelete(rscName);
|
|
||||||
handleLinstorApiAnswers(answers, "Linstor: Unable to delete resource definition " + rscName);
|
|
||||||
} catch (ApiException apiEx) {
|
} catch (ApiException apiEx) {
|
||||||
|
logger.error("Linstor: ApiEx - " + apiEx.getMessage());
|
||||||
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
|
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -561,6 +607,56 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given disk is the SystemVM template, by checking its properties file in the same directory.
|
||||||
|
* The initial systemvm template resource isn't created on the management server, but
|
||||||
|
* we now need to know if the systemvm template is used, while copying.
|
||||||
|
* @param disk
|
||||||
|
* @return True if it is the systemvm template disk, else false.
|
||||||
|
*/
|
||||||
|
private static boolean isSystemTemplate(KVMPhysicalDisk disk) {
|
||||||
|
Path diskPath = Paths.get(disk.getPath());
|
||||||
|
Path propFile = diskPath.getParent().resolve("template.properties");
|
||||||
|
if (Files.exists(propFile)) {
|
||||||
|
java.util.Properties templateProps = new java.util.Properties();
|
||||||
|
try {
|
||||||
|
templateProps.load(new FileInputStream(propFile.toFile()));
|
||||||
|
String desc = templateProps.getProperty("description");
|
||||||
|
if (desc.startsWith("SystemVM Template")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conditionally sets the correct aux properties for templates or basic resources.
|
||||||
|
* @param api
|
||||||
|
* @param srcDisk
|
||||||
|
* @param destPool
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
private void setRscDfnAuxProperties(
|
||||||
|
DevelopersApi api, KVMPhysicalDisk srcDisk, KVMStoragePool destPool, String name) {
|
||||||
|
// if it is the initial systemvm disk copy, we need to apply the _cs-template-for property.
|
||||||
|
if (isSystemTemplate(srcDisk)) {
|
||||||
|
applyAuxProps(api, name, "SystemVM Template", null);
|
||||||
|
LinstorStoragePool linPool = (LinstorStoragePool) destPool;
|
||||||
|
final String rscName = getLinstorRscName(name);
|
||||||
|
try {
|
||||||
|
LinstorUtil.setAuxTemplateForProperty(api, rscName, linPool.getResourceGroup());
|
||||||
|
} catch (ApiException apiExc) {
|
||||||
|
logger.error("Error setting aux template for property for {}", rscName);
|
||||||
|
logLinstorAnswers(apiExc.getApiCallRcList());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
applyAuxProps(api, name, srcDisk.getDispName(), srcDisk.getVmName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMStoragePool destPools, int timeout, byte[] srcPassphrase, byte[] destPassphrase, Storage.ProvisioningType provisioningType)
|
public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMStoragePool destPools, int timeout, byte[] srcPassphrase, byte[] destPassphrase, Storage.ProvisioningType provisioningType)
|
||||||
{
|
{
|
||||||
@ -574,15 +670,14 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
|||||||
name, QemuImg.PhysicalDiskFormat.RAW, provisioningType, disk.getVirtualSize(), null);
|
name, QemuImg.PhysicalDiskFormat.RAW, provisioningType, disk.getVirtualSize(), null);
|
||||||
|
|
||||||
final DevelopersApi api = getLinstorAPI(destPools);
|
final DevelopersApi api = getLinstorAPI(destPools);
|
||||||
applyAuxProps(api, name, disk.getDispName(), disk.getVmName());
|
setRscDfnAuxProperties(api, disk, destPools, name);
|
||||||
|
|
||||||
logger.debug("Linstor.copyPhysicalDisk: dstPath: {}", dstDisk.getPath());
|
logger.debug("Linstor.copyPhysicalDisk: dstPath: {}", dstDisk.getPath());
|
||||||
final QemuImgFile destFile = new QemuImgFile(dstDisk.getPath());
|
final QemuImgFile destFile = new QemuImgFile(dstDisk.getPath());
|
||||||
destFile.setFormat(dstDisk.getFormat());
|
destFile.setFormat(dstDisk.getFormat());
|
||||||
destFile.setSize(disk.getVirtualSize());
|
destFile.setSize(disk.getVirtualSize());
|
||||||
|
|
||||||
boolean zeroedDevice = resourceSupportZeroBlocks(destPools, LinstorUtil.RSC_PREFIX + name);
|
boolean zeroedDevice = resourceSupportZeroBlocks(destPools, getLinstorRscName(name));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final QemuImg qemu = new QemuImg(timeout, zeroedDevice, true);
|
final QemuImg qemu = new QemuImg(timeout, zeroedDevice, true);
|
||||||
qemu.convert(srcFile, destFile);
|
qemu.convert(srcFile, destFile);
|
||||||
|
|||||||
@ -21,11 +21,16 @@ import com.linbit.linstor.api.CloneWaiter;
|
|||||||
import com.linbit.linstor.api.DevelopersApi;
|
import com.linbit.linstor.api.DevelopersApi;
|
||||||
import com.linbit.linstor.api.model.ApiCallRc;
|
import com.linbit.linstor.api.model.ApiCallRc;
|
||||||
import com.linbit.linstor.api.model.ApiCallRcList;
|
import com.linbit.linstor.api.model.ApiCallRcList;
|
||||||
|
import com.linbit.linstor.api.model.AutoSelectFilter;
|
||||||
|
import com.linbit.linstor.api.model.LayerType;
|
||||||
import com.linbit.linstor.api.model.Properties;
|
import com.linbit.linstor.api.model.Properties;
|
||||||
import com.linbit.linstor.api.model.ResourceDefinition;
|
import com.linbit.linstor.api.model.ResourceDefinition;
|
||||||
import com.linbit.linstor.api.model.ResourceDefinitionCloneRequest;
|
import com.linbit.linstor.api.model.ResourceDefinitionCloneRequest;
|
||||||
import com.linbit.linstor.api.model.ResourceDefinitionCloneStarted;
|
import com.linbit.linstor.api.model.ResourceDefinitionCloneStarted;
|
||||||
import com.linbit.linstor.api.model.ResourceDefinitionCreate;
|
import com.linbit.linstor.api.model.ResourceDefinitionCreate;
|
||||||
|
|
||||||
|
import com.linbit.linstor.api.model.ResourceDefinitionModify;
|
||||||
|
import com.linbit.linstor.api.model.ResourceGroup;
|
||||||
import com.linbit.linstor.api.model.ResourceGroupSpawn;
|
import com.linbit.linstor.api.model.ResourceGroupSpawn;
|
||||||
import com.linbit.linstor.api.model.ResourceMakeAvailable;
|
import com.linbit.linstor.api.model.ResourceMakeAvailable;
|
||||||
import com.linbit.linstor.api.model.Snapshot;
|
import com.linbit.linstor.api.model.Snapshot;
|
||||||
@ -34,6 +39,7 @@ import com.linbit.linstor.api.model.VolumeDefinition;
|
|||||||
import com.linbit.linstor.api.model.VolumeDefinitionModify;
|
import com.linbit.linstor.api.model.VolumeDefinitionModify;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -43,6 +49,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.storage.ResizeVolumeAnswer;
|
import com.cloud.agent.api.storage.ResizeVolumeAnswer;
|
||||||
@ -66,6 +73,7 @@ import com.cloud.storage.Storage.StoragePoolType;
|
|||||||
import com.cloud.storage.StorageManager;
|
import com.cloud.storage.StorageManager;
|
||||||
import com.cloud.storage.StoragePool;
|
import com.cloud.storage.StoragePool;
|
||||||
import com.cloud.storage.VMTemplateStoragePoolVO;
|
import com.cloud.storage.VMTemplateStoragePoolVO;
|
||||||
|
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
import com.cloud.storage.VolumeDetailVO;
|
import com.cloud.storage.VolumeDetailVO;
|
||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
@ -85,6 +93,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
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.DataStore;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
|
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||||
@ -93,6 +102,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
|||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
import org.apache.cloudstack.storage.RemoteHostEndPoint;
|
import org.apache.cloudstack.storage.RemoteHostEndPoint;
|
||||||
import org.apache.cloudstack.storage.command.CommandResult;
|
import org.apache.cloudstack.storage.command.CommandResult;
|
||||||
|
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
|
||||||
import org.apache.cloudstack.storage.command.CopyCommand;
|
import org.apache.cloudstack.storage.command.CopyCommand;
|
||||||
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
|
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
@ -103,8 +113,12 @@ import org.apache.cloudstack.storage.snapshot.SnapshotObject;
|
|||||||
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
import org.apache.cloudstack.storage.to.SnapshotObjectTO;
|
||||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||||
import org.apache.cloudstack.storage.volume.VolumeObject;
|
import org.apache.cloudstack.storage.volume.VolumeObject;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
|
public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver {
|
||||||
protected Logger logger = LogManager.getLogger(getClass());
|
protected Logger logger = LogManager.getLogger(getClass());
|
||||||
@ -216,7 +230,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
}
|
}
|
||||||
throw new CloudRuntimeException("Linstor: Unable to delete resource definition: " + rscDefName);
|
throw new CloudRuntimeException("Linstor: Unable to delete resource definition: " + rscDefName);
|
||||||
}
|
}
|
||||||
logger.info(String.format("Linstor: Deleted resource %s", rscDefName));
|
logger.info("Linstor: Deleted resource {}", rscDefName);
|
||||||
} catch (ApiException apiEx)
|
} catch (ApiException apiEx)
|
||||||
{
|
{
|
||||||
logger.error("Linstor: ApiEx - " + apiEx.getMessage());
|
logger.error("Linstor: ApiEx - " + apiEx.getMessage());
|
||||||
@ -394,22 +408,166 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
storagePoolVO.getUserInfo() : "DfltRscGrp";
|
storagePoolVO.getUserInfo() : "DfltRscGrp";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createResourceBase(
|
/**
|
||||||
String rscName, long sizeInBytes, String volName, String vmName, DevelopersApi api, String rscGrp) {
|
* Returns the layerlist of the resourceGroup with encryption(LUKS) added above STORAGE.
|
||||||
ResourceGroupSpawn rscGrpSpawn = new ResourceGroupSpawn();
|
* If the resourceGroup layer list already contains LUKS this layer list will be returned.
|
||||||
rscGrpSpawn.setResourceDefinitionName(rscName);
|
* @param api Linstor developers API
|
||||||
rscGrpSpawn.addVolumeSizesItem(sizeInBytes / 1024);
|
* @param resourceGroup Resource group to get the encryption layer list
|
||||||
|
* @return layer list with LUKS added
|
||||||
|
*/
|
||||||
|
public List<LayerType> getEncryptedLayerList(DevelopersApi api, String resourceGroup) {
|
||||||
|
try {
|
||||||
|
List<ResourceGroup> rscGrps = api.resourceGroupList(
|
||||||
|
Collections.singletonList(resourceGroup), Collections.emptyList(), null, null);
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(rscGrps)) {
|
||||||
|
throw new CloudRuntimeException(
|
||||||
|
String.format("Resource Group %s not found on Linstor cluster.", resourceGroup));
|
||||||
|
}
|
||||||
|
|
||||||
|
final ResourceGroup rscGrp = rscGrps.get(0);
|
||||||
|
List<LayerType> layers = Arrays.asList(LayerType.DRBD, LayerType.LUKS, LayerType.STORAGE);
|
||||||
|
List<String> curLayerStack = rscGrp.getSelectFilter() != null ?
|
||||||
|
rscGrp.getSelectFilter().getLayerStack() : Collections.emptyList();
|
||||||
|
if (CollectionUtils.isNotEmpty(curLayerStack)) {
|
||||||
|
layers = curLayerStack.stream().map(LayerType::valueOf).collect(Collectors.toList());
|
||||||
|
if (!layers.contains(LayerType.LUKS)) {
|
||||||
|
layers.add(layers.size() - 1, LayerType.LUKS); // lowest layer is STORAGE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return layers;
|
||||||
|
} catch (ApiException e) {
|
||||||
|
throw new CloudRuntimeException(
|
||||||
|
String.format("Resource Group %s not found on Linstor cluster.", resourceGroup));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns a new Linstor resource with the given arguments.
|
||||||
|
* @param api
|
||||||
|
* @param newRscName
|
||||||
|
* @param sizeInBytes
|
||||||
|
* @param isTemplate
|
||||||
|
* @param rscGrpName
|
||||||
|
* @param volName
|
||||||
|
* @param vmName
|
||||||
|
* @throws ApiException
|
||||||
|
*/
|
||||||
|
private void spawnResource(
|
||||||
|
DevelopersApi api, String newRscName, long sizeInBytes, boolean isTemplate, String rscGrpName,
|
||||||
|
String volName, String vmName, @Nullable Long passPhraseId, @Nullable byte[] passPhrase) throws ApiException
|
||||||
|
{
|
||||||
|
ResourceGroupSpawn rscGrpSpawn = new ResourceGroupSpawn();
|
||||||
|
rscGrpSpawn.setResourceDefinitionName(newRscName);
|
||||||
|
rscGrpSpawn.addVolumeSizesItem(sizeInBytes / 1024);
|
||||||
|
if (passPhraseId != null) {
|
||||||
|
AutoSelectFilter asf = new AutoSelectFilter();
|
||||||
|
List<LayerType> luksLayers = getEncryptedLayerList(api, rscGrpName);
|
||||||
|
asf.setLayerStack(luksLayers.stream().map(LayerType::toString).collect(Collectors.toList()));
|
||||||
|
rscGrpSpawn.setSelectFilter(asf);
|
||||||
|
if (passPhrase != null) {
|
||||||
|
String utf8Passphrase = new String(passPhrase, StandardCharsets.UTF_8);
|
||||||
|
rscGrpSpawn.setVolumePassphrases(Collections.singletonList(utf8Passphrase));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTemplate) {
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put(LinstorUtil.getTemplateForAuxPropKey(rscGrpName), "true");
|
||||||
|
rscGrpSpawn.setResourceDefinitionProps(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Linstor: Spawn resource " + newRscName);
|
||||||
|
ApiCallRcList answers = api.resourceGroupSpawn(rscGrpName, rscGrpSpawn);
|
||||||
|
checkLinstorAnswersThrow(answers);
|
||||||
|
|
||||||
|
answers = LinstorUtil.applyAuxProps(api, newRscName, volName, vmName);
|
||||||
|
checkLinstorAnswersThrow(answers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Condition if a template resource can be shared with the given resource group.
|
||||||
|
* @param tgtRscGrp
|
||||||
|
* @param tgtLayerStack
|
||||||
|
* @param rg
|
||||||
|
* @return True if the template resource can be shared, else false.
|
||||||
|
*/
|
||||||
|
private boolean canShareTemplateForResourceGroup(
|
||||||
|
ResourceGroup tgtRscGrp, List<String> tgtLayerStack, ResourceGroup rg) {
|
||||||
|
List<String> rgLayerStack = rg.getSelectFilter() != null ?
|
||||||
|
rg.getSelectFilter().getLayerStack() : null;
|
||||||
|
return Objects.equals(tgtLayerStack, rgLayerStack) &&
|
||||||
|
Objects.equals(tgtRscGrp.getSelectFilter().getStoragePoolList(),
|
||||||
|
rg.getSelectFilter().getStoragePoolList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for a shareable template for this rscGrpName and sets the aux template property.
|
||||||
|
* @param api
|
||||||
|
* @param rscName
|
||||||
|
* @param rscGrpName
|
||||||
|
* @param existingRDs
|
||||||
|
* @return
|
||||||
|
* @throws ApiException
|
||||||
|
*/
|
||||||
|
private boolean foundShareableTemplate(
|
||||||
|
DevelopersApi api, String rscName, String rscGrpName,
|
||||||
|
List<Pair<ResourceDefinition, ResourceGroup>> existingRDs) throws ApiException {
|
||||||
|
if (!existingRDs.isEmpty()) {
|
||||||
|
ResourceGroup tgtRscGrp = api.resourceGroupList(
|
||||||
|
Collections.singletonList(rscGrpName), null, null, null).get(0);
|
||||||
|
List<String> tgtLayerStack = tgtRscGrp.getSelectFilter() != null ?
|
||||||
|
tgtRscGrp.getSelectFilter().getLayerStack() : null;
|
||||||
|
|
||||||
|
// check if there is already a template copy, that we could reuse
|
||||||
|
// this means if select filters are similar enough to allow cloning from
|
||||||
|
for (Pair<ResourceDefinition, ResourceGroup> rdPair : existingRDs) {
|
||||||
|
ResourceGroup rg = rdPair.second();
|
||||||
|
if (canShareTemplateForResourceGroup(tgtRscGrp, tgtLayerStack, rg)) {
|
||||||
|
LinstorUtil.setAuxTemplateForProperty(api, rscName, rscGrpName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Linstor resource.
|
||||||
|
* @param rscName
|
||||||
|
* @param sizeInBytes
|
||||||
|
* @param volName
|
||||||
|
* @param vmName
|
||||||
|
* @param api
|
||||||
|
* @param rscGrp
|
||||||
|
* @param poolId
|
||||||
|
* @param isTemplate indicates if the resource is a template
|
||||||
|
* @return true if a new resource was created, false if it already existed or was reused.
|
||||||
|
*/
|
||||||
|
private boolean createResourceBase(
|
||||||
|
String rscName, long sizeInBytes, String volName, String vmName,
|
||||||
|
@Nullable Long passPhraseId, @Nullable byte[] passPhrase, DevelopersApi api,
|
||||||
|
String rscGrp, long poolId, boolean isTemplate)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
logger.info("Linstor: Spawn resource " + rscName);
|
logger.debug("createRscBase: {} :: {} :: {}", rscName, rscGrp, isTemplate);
|
||||||
ApiCallRcList answers = api.resourceGroupSpawn(rscGrp, rscGrpSpawn);
|
List<Pair<ResourceDefinition, ResourceGroup>> existingRDs = LinstorUtil.getRDAndRGListStartingWith(api, rscName);
|
||||||
checkLinstorAnswersThrow(answers);
|
|
||||||
|
|
||||||
answers = LinstorUtil.applyAuxProps(api, rscName, volName, vmName);
|
String fullRscName = String.format("%s-%d", rscName, poolId);
|
||||||
checkLinstorAnswersThrow(answers);
|
boolean alreadyCreated = existingRDs.stream()
|
||||||
|
.anyMatch(p -> p.first().getName().equalsIgnoreCase(fullRscName)) ||
|
||||||
return LinstorUtil.getDevicePath(api, rscName);
|
existingRDs.stream().anyMatch(p -> p.first().getProps().containsKey(LinstorUtil.getTemplateForAuxPropKey(rscGrp)));
|
||||||
|
if (!alreadyCreated) {
|
||||||
|
boolean createNewRsc = !foundShareableTemplate(api, rscName, rscGrp, existingRDs);
|
||||||
|
if (createNewRsc) {
|
||||||
|
String newRscName = existingRDs.isEmpty() ? rscName : fullRscName;
|
||||||
|
spawnResource(api, newRscName, sizeInBytes, isTemplate, rscGrp,
|
||||||
|
volName, vmName, passPhraseId, passPhrase);
|
||||||
|
}
|
||||||
|
return createNewRsc;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
} catch (ApiException apiEx)
|
} catch (ApiException apiEx)
|
||||||
{
|
{
|
||||||
logger.error("Linstor: ApiEx - " + apiEx.getMessage());
|
logger.error("Linstor: ApiEx - " + apiEx.getMessage());
|
||||||
@ -422,8 +580,9 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
final String rscGrp = getRscGrp(storagePoolVO);
|
final String rscGrp = getRscGrp(storagePoolVO);
|
||||||
|
|
||||||
final String rscName = LinstorUtil.RSC_PREFIX + vol.getUuid();
|
final String rscName = LinstorUtil.RSC_PREFIX + vol.getUuid();
|
||||||
String deviceName = createResourceBase(
|
createResourceBase(
|
||||||
rscName, vol.getSize(), vol.getName(), vol.getAttachedVmName(), linstorApi, rscGrp);
|
rscName, vol.getSize(), vol.getName(), vol.getAttachedVmName(), vol.getPassphraseId(), vol.getPassphrase(),
|
||||||
|
linstorApi, rscGrp, storagePoolVO.getId(), false);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -450,20 +609,83 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update resource-definitions resource-group to the correct one if it isn't already the intended.
|
||||||
|
* @param api Linstor api
|
||||||
|
* @param rscName resource name to check the resource group
|
||||||
|
* @param tgtRscGrp resource group name to set
|
||||||
|
* @throws ApiException exception if any api error occurred
|
||||||
|
*/
|
||||||
|
private void updateRscGrpIfNecessary(DevelopersApi api, String rscName, String tgtRscGrp) throws ApiException {
|
||||||
|
List<ResourceDefinition> rscDfns = api.resourceDefinitionList(
|
||||||
|
Collections.singletonList(rscName), null, null, null);
|
||||||
|
if (rscDfns != null && !rscDfns.isEmpty()) {
|
||||||
|
ResourceDefinition rscDfn = rscDfns.get(0);
|
||||||
|
|
||||||
|
if (!rscDfn.getResourceGroupName().equalsIgnoreCase(tgtRscGrp)) {
|
||||||
|
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
|
||||||
|
rdm.setResourceGroup(tgtRscGrp);
|
||||||
|
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
|
||||||
|
|
||||||
|
if (answers.hasError()) {
|
||||||
|
String bestError = LinstorUtil.getBestErrorMessage(answers);
|
||||||
|
logger.error("Update resource group on {} error: {}", rscName, bestError);
|
||||||
|
throw new CloudRuntimeException(bestError);
|
||||||
|
} else {
|
||||||
|
logger.info("Successfully changed resource group to {} on {}", tgtRscGrp, rscName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a resource is cloned, all properties are cloned too, but the _cs-template-for properties,
|
||||||
|
* should only stay on the template resource, so delete them in this method.
|
||||||
|
* @param api
|
||||||
|
* @param rscName
|
||||||
|
* @throws ApiException
|
||||||
|
*/
|
||||||
|
private void deleteTemplateForProps(
|
||||||
|
DevelopersApi api, String rscName) throws ApiException {
|
||||||
|
List<ResourceDefinition> rdList = api.resourceDefinitionList(
|
||||||
|
Collections.singletonList(rscName), null, null, null);
|
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(rdList)) {
|
||||||
|
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
|
||||||
|
List<String> deleteProps = rdList.get(0).getProps().keySet().stream()
|
||||||
|
.filter(key -> key.startsWith("Aux/" + LinstorUtil.CS_TEMPLATE_FOR_PREFIX))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
rdm.deleteProps(deleteProps);
|
||||||
|
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
|
||||||
|
checkLinstorAnswers(answers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String cloneResource(long csCloneId, VolumeInfo volumeInfo, StoragePoolVO storagePoolVO) {
|
private String cloneResource(long csCloneId, VolumeInfo volumeInfo, StoragePoolVO storagePoolVO) {
|
||||||
// get the cached template on this storage
|
// get the cached template on this storage
|
||||||
VMTemplateStoragePoolVO tmplPoolRef = _vmTemplatePoolDao.findByPoolTemplate(
|
VMTemplateStoragePoolVO tmplPoolRef = _vmTemplatePoolDao.findByPoolTemplate(
|
||||||
storagePoolVO.getId(), csCloneId, null);
|
storagePoolVO.getId(), csCloneId, null);
|
||||||
|
|
||||||
if (tmplPoolRef != null) {
|
if (tmplPoolRef != null) {
|
||||||
final String cloneRes = LinstorUtil.RSC_PREFIX + tmplPoolRef.getLocalDownloadPath();
|
final String templateRscName = LinstorUtil.RSC_PREFIX + tmplPoolRef.getLocalDownloadPath();
|
||||||
final String rscName = LinstorUtil.RSC_PREFIX + volumeInfo.getUuid();
|
final String rscName = LinstorUtil.RSC_PREFIX + volumeInfo.getUuid();
|
||||||
final DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePoolVO.getHostAddress());
|
final DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePoolVO.getHostAddress());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.info("Clone resource definition " + cloneRes + " to " + rscName);
|
ResourceDefinition templateRD = LinstorUtil.findResourceDefinition(
|
||||||
|
linstorApi, templateRscName, getRscGrp(storagePoolVO));
|
||||||
|
final String cloneRes = templateRD != null ? templateRD.getName() : templateRscName;
|
||||||
|
logger.info("Clone resource definition {} to {}", cloneRes, rscName);
|
||||||
ResourceDefinitionCloneRequest cloneRequest = new ResourceDefinitionCloneRequest();
|
ResourceDefinitionCloneRequest cloneRequest = new ResourceDefinitionCloneRequest();
|
||||||
cloneRequest.setName(rscName);
|
cloneRequest.setName(rscName);
|
||||||
|
if (volumeInfo.getPassphraseId() != null) {
|
||||||
|
List<LayerType> encryptionLayer = getEncryptedLayerList(linstorApi, getRscGrp(storagePoolVO));
|
||||||
|
cloneRequest.setLayerList(encryptionLayer);
|
||||||
|
if (volumeInfo.getPassphrase() != null) {
|
||||||
|
String utf8Passphrase = new String(volumeInfo.getPassphrase(), StandardCharsets.UTF_8);
|
||||||
|
cloneRequest.setVolumePassphrases(Collections.singletonList(utf8Passphrase));
|
||||||
|
}
|
||||||
|
}
|
||||||
ResourceDefinitionCloneStarted cloneStarted = linstorApi.resourceDefinitionClone(
|
ResourceDefinitionCloneStarted cloneStarted = linstorApi.resourceDefinitionClone(
|
||||||
cloneRes, cloneRequest);
|
cloneRes, cloneRequest);
|
||||||
|
|
||||||
@ -479,6 +701,9 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
resizeResource(linstorApi, rscName, volumeInfo.getSize());
|
resizeResource(linstorApi, rscName, volumeInfo.getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateRscGrpIfNecessary(linstorApi, rscName, getRscGrp(storagePoolVO));
|
||||||
|
|
||||||
|
deleteTemplateForProps(linstorApi, rscName);
|
||||||
LinstorUtil.applyAuxProps(linstorApi, rscName, volumeInfo.getName(), volumeInfo.getAttachedVmName());
|
LinstorUtil.applyAuxProps(linstorApi, rscName, volumeInfo.getName(), volumeInfo.getAttachedVmName());
|
||||||
applyQoSSettings(storagePoolVO, linstorApi, rscName, volumeInfo.getMaxIops());
|
applyQoSSettings(storagePoolVO, linstorApi, rscName, volumeInfo.getMaxIops());
|
||||||
|
|
||||||
@ -906,41 +1131,74 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
|||||||
return LinstorUtil.getDevicePath(api, restoredName);
|
return LinstorUtil.getDevicePath(api, restoredName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the template_spool_ref DB entry to indicate that this template was fully downloaded and is ready.
|
||||||
|
* @param templateId
|
||||||
|
* @param destTemplateInfoUuid
|
||||||
|
* @param destDataStoreId
|
||||||
|
* @param templateSize
|
||||||
|
*/
|
||||||
|
private void updateTemplateSpoolRef(
|
||||||
|
long templateId, String destTemplateInfoUuid, long destDataStoreId, long templateSize) {
|
||||||
|
VMTemplateStoragePoolVO destVolumeTemplateStoragePoolVO = _vmTemplatePoolDao.findByPoolTemplate(
|
||||||
|
destDataStoreId, templateId, null);
|
||||||
|
if (destVolumeTemplateStoragePoolVO == null) {
|
||||||
|
throw new CloudRuntimeException(
|
||||||
|
String.format("Unable to find template_spool_ref entry for pool_id %d and template_id %d",
|
||||||
|
destDataStoreId, templateId));
|
||||||
|
}
|
||||||
|
destVolumeTemplateStoragePoolVO.setDownloadPercent(100);
|
||||||
|
destVolumeTemplateStoragePoolVO.setDownloadState(VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
|
||||||
|
destVolumeTemplateStoragePoolVO.setState(ObjectInDataStoreStateMachine.State.Ready);
|
||||||
|
destVolumeTemplateStoragePoolVO.setTemplateSize(templateSize);
|
||||||
|
destVolumeTemplateStoragePoolVO.setLocalDownloadPath(destTemplateInfoUuid);
|
||||||
|
destVolumeTemplateStoragePoolVO.setInstallPath(destTemplateInfoUuid);
|
||||||
|
_vmTemplatePoolDao.persist(destVolumeTemplateStoragePoolVO);
|
||||||
|
}
|
||||||
|
|
||||||
private Answer copyTemplate(DataObject srcData, DataObject dstData) {
|
private Answer copyTemplate(DataObject srcData, DataObject dstData) {
|
||||||
TemplateInfo tInfo = (TemplateInfo) dstData;
|
TemplateInfo tInfo = (TemplateInfo) dstData;
|
||||||
final StoragePoolVO pool = _storagePoolDao.findById(dstData.getDataStore().getId());
|
final StoragePoolVO pool = _storagePoolDao.findById(dstData.getDataStore().getId());
|
||||||
final DevelopersApi api = LinstorUtil.getLinstorAPI(pool.getHostAddress());
|
final DevelopersApi api = LinstorUtil.getLinstorAPI(pool.getHostAddress());
|
||||||
final String rscName = LinstorUtil.RSC_PREFIX + dstData.getUuid();
|
final String rscName = LinstorUtil.RSC_PREFIX + dstData.getUuid();
|
||||||
createResourceBase(
|
boolean newCreated = createResourceBase(
|
||||||
LinstorUtil.RSC_PREFIX + dstData.getUuid(),
|
LinstorUtil.RSC_PREFIX + dstData.getUuid(),
|
||||||
tInfo.getSize(),
|
tInfo.getSize(),
|
||||||
tInfo.getName(),
|
tInfo.getName(),
|
||||||
"",
|
"",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
api,
|
api,
|
||||||
getRscGrp(pool));
|
getRscGrp(pool),
|
||||||
|
pool.getId(),
|
||||||
|
true);
|
||||||
|
|
||||||
int nMaxExecutionMinutes = NumbersUtil.parseInt(
|
|
||||||
_configDao.getValue(Config.SecStorageCmdExecutionTimeMax.key()), 30);
|
|
||||||
CopyCommand cmd = new CopyCommand(
|
|
||||||
srcData.getTO(),
|
|
||||||
dstData.getTO(),
|
|
||||||
nMaxExecutionMinutes * 60 * 1000,
|
|
||||||
VirtualMachineManager.ExecuteInSequence.value());
|
|
||||||
Answer answer;
|
Answer answer;
|
||||||
|
if (newCreated) {
|
||||||
|
int nMaxExecutionMinutes = NumbersUtil.parseInt(
|
||||||
|
_configDao.getValue(Config.SecStorageCmdExecutionTimeMax.key()), 30);
|
||||||
|
CopyCommand cmd = new CopyCommand(
|
||||||
|
srcData.getTO(),
|
||||||
|
dstData.getTO(),
|
||||||
|
nMaxExecutionMinutes * 60 * 1000,
|
||||||
|
VirtualMachineManager.ExecuteInSequence.value());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Optional<RemoteHostEndPoint> optEP = getLinstorEP(api, rscName);
|
Optional<RemoteHostEndPoint> optEP = getLinstorEP(api, rscName);
|
||||||
if (optEP.isPresent()) {
|
if (optEP.isPresent()) {
|
||||||
answer = optEP.get().sendMessage(cmd);
|
answer = optEP.get().sendMessage(cmd);
|
||||||
}
|
} else {
|
||||||
else {
|
answer = new Answer(cmd, false, "Unable to get matching Linstor endpoint.");
|
||||||
answer = new Answer(cmd, false, "Unable to get matching Linstor endpoint.");
|
deleteResourceDefinition(pool, rscName);
|
||||||
|
}
|
||||||
|
} catch (ApiException exc) {
|
||||||
|
logger.error("copy template failed: ", exc);
|
||||||
deleteResourceDefinition(pool, rscName);
|
deleteResourceDefinition(pool, rscName);
|
||||||
|
throw new CloudRuntimeException(exc.getBestMessage());
|
||||||
}
|
}
|
||||||
} catch (ApiException exc) {
|
} else {
|
||||||
logger.error("copy template failed: ", exc);
|
updateTemplateSpoolRef(dstData.getId(), tInfo.getUuid(), dstData.getDataStore().getId(), srcData.getSize());
|
||||||
deleteResourceDefinition(pool, rscName);
|
answer = new Answer(new CopyCmdAnswer(dstData.getTO()));
|
||||||
throw new CloudRuntimeException(exc.getBestMessage());
|
|
||||||
}
|
}
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import com.linbit.linstor.api.model.Node;
|
|||||||
import com.linbit.linstor.api.model.Properties;
|
import com.linbit.linstor.api.model.Properties;
|
||||||
import com.linbit.linstor.api.model.ProviderKind;
|
import com.linbit.linstor.api.model.ProviderKind;
|
||||||
import com.linbit.linstor.api.model.Resource;
|
import com.linbit.linstor.api.model.Resource;
|
||||||
|
import com.linbit.linstor.api.model.ResourceDefinition;
|
||||||
import com.linbit.linstor.api.model.ResourceDefinitionModify;
|
import com.linbit.linstor.api.model.ResourceDefinitionModify;
|
||||||
import com.linbit.linstor.api.model.ResourceGroup;
|
import com.linbit.linstor.api.model.ResourceGroup;
|
||||||
import com.linbit.linstor.api.model.ResourceWithVolumes;
|
import com.linbit.linstor.api.model.ResourceWithVolumes;
|
||||||
@ -37,8 +38,11 @@ import javax.annotation.Nonnull;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@ -49,6 +53,7 @@ public class LinstorUtil {
|
|||||||
public final static String PROVIDER_NAME = "Linstor";
|
public final static String PROVIDER_NAME = "Linstor";
|
||||||
public static final String RSC_PREFIX = "cs-";
|
public static final String RSC_PREFIX = "cs-";
|
||||||
public static final String RSC_GROUP = "resourceGroup";
|
public static final String RSC_GROUP = "resourceGroup";
|
||||||
|
public static final String CS_TEMPLATE_FOR_PREFIX = "_cs-template-for-";
|
||||||
|
|
||||||
public static final String TEMP_VOLUME_ID = "tempVolumeId";
|
public static final String TEMP_VOLUME_ID = "tempVolumeId";
|
||||||
|
|
||||||
@ -288,4 +293,114 @@ public class LinstorUtil {
|
|||||||
}
|
}
|
||||||
return answers;
|
return answers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all resource definitions that start with the given `startWith` name.
|
||||||
|
* @param api
|
||||||
|
* @param startWith startWith String
|
||||||
|
* @return a List with all ResourceDefinition starting with `startWith`
|
||||||
|
* @throws ApiException
|
||||||
|
*/
|
||||||
|
public static List<ResourceDefinition> getRDListStartingWith(DevelopersApi api, String startWith)
|
||||||
|
throws ApiException
|
||||||
|
{
|
||||||
|
List<ResourceDefinition> rscDfns = api.resourceDefinitionList(null, null, null, null);
|
||||||
|
|
||||||
|
return rscDfns.stream()
|
||||||
|
.filter(rscDfn -> rscDfn.getName().toLowerCase().startsWith(startWith.toLowerCase()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a pair list of resource-definitions with ther 1:1 mapped resource-group objects that start with the
|
||||||
|
* resource name `startWith`
|
||||||
|
* @param api
|
||||||
|
* @param startWith
|
||||||
|
* @return
|
||||||
|
* @throws ApiException
|
||||||
|
*/
|
||||||
|
public static List<Pair<ResourceDefinition, ResourceGroup>> getRDAndRGListStartingWith(DevelopersApi api, String startWith)
|
||||||
|
throws ApiException
|
||||||
|
{
|
||||||
|
List<ResourceDefinition> foundRDs = getRDListStartingWith(api, startWith);
|
||||||
|
|
||||||
|
List<String> rscGrpStrings = foundRDs.stream()
|
||||||
|
.map(ResourceDefinition::getResourceGroupName)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
Map<String, ResourceGroup> rscGrps = api.resourceGroupList(rscGrpStrings, null, null, null).stream()
|
||||||
|
.collect(Collectors.toMap(ResourceGroup::getName, rscGrp -> rscGrp));
|
||||||
|
|
||||||
|
return foundRDs.stream()
|
||||||
|
.map(rd -> new Pair<>(rd, rscGrps.get(rd.getResourceGroupName())))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The full name of template-for aux property key.
|
||||||
|
* @param rscGrpName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getTemplateForAuxPropKey(String rscGrpName) {
|
||||||
|
return String.format("Aux/%s%s", CS_TEMPLATE_FOR_PREFIX, rscGrpName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template resource should have a _cs-template-for-... property, that indicates to which resource-group
|
||||||
|
* this template belongs, it works like a refcount to keep it alive if there are still such properties on the
|
||||||
|
* template resource. That methods set the correct property on the given resource.
|
||||||
|
* @param api
|
||||||
|
* @param rscName Resource name to set the property.
|
||||||
|
* @param rscGrpName Resource group this template should belong too.
|
||||||
|
* @throws ApiException
|
||||||
|
*/
|
||||||
|
public static void setAuxTemplateForProperty(DevelopersApi api, String rscName, String rscGrpName)
|
||||||
|
throws ApiException
|
||||||
|
{
|
||||||
|
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
|
||||||
|
Properties props = new Properties();
|
||||||
|
String propKey = LinstorUtil.getTemplateForAuxPropKey(rscGrpName);
|
||||||
|
props.put(propKey, "true");
|
||||||
|
rdm.setOverrideProps(props);
|
||||||
|
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
|
||||||
|
|
||||||
|
if (answers.hasError()) {
|
||||||
|
String bestError = LinstorUtil.getBestErrorMessage(answers);
|
||||||
|
LOGGER.error("Set {} on {} error: {}", propKey, rscName, bestError);
|
||||||
|
throw new CloudRuntimeException(bestError);
|
||||||
|
} else {
|
||||||
|
LOGGER.info("Set {} property on {}", propKey, rscName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the correct resource definition to clone from.
|
||||||
|
* There could be multiple resource definitions for the same template, with the same prefix.
|
||||||
|
* This method searches for which resource group the resource definition was intended and returns that.
|
||||||
|
* If no exact resource definition could be found, we return the first with a similar name as a fallback.
|
||||||
|
* If there is not even one with the correct prefix, we return null.
|
||||||
|
* @param api
|
||||||
|
* @param rscName
|
||||||
|
* @param rscGrpName
|
||||||
|
* @return The resource-definition to clone from, if no template and no match, return null.
|
||||||
|
* @throws ApiException
|
||||||
|
*/
|
||||||
|
public static ResourceDefinition findResourceDefinition(DevelopersApi api, String rscName, String rscGrpName)
|
||||||
|
throws ApiException {
|
||||||
|
List<ResourceDefinition> rscDfns = api.resourceDefinitionList(null, null, null, null);
|
||||||
|
|
||||||
|
List<ResourceDefinition> rdsStartingWith = rscDfns.stream()
|
||||||
|
.filter(rscDfn -> rscDfn.getName().toLowerCase().startsWith(rscName.toLowerCase()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (rdsStartingWith.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<ResourceDefinition> rd = rdsStartingWith.stream()
|
||||||
|
.filter(rscDfn -> rscDfn.getProps().containsKey(LinstorUtil.getTemplateForAuxPropKey(rscGrpName)))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
return rd.orElseGet(() -> rdsStartingWith.get(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,87 @@
|
|||||||
|
// 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 org.apache.cloudstack.storage.datastore.driver;
|
||||||
|
|
||||||
|
import com.linbit.linstor.api.ApiException;
|
||||||
|
import com.linbit.linstor.api.DevelopersApi;
|
||||||
|
import com.linbit.linstor.api.model.AutoSelectFilter;
|
||||||
|
import com.linbit.linstor.api.model.LayerType;
|
||||||
|
import com.linbit.linstor.api.model.ResourceGroup;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class LinstorPrimaryDataStoreDriverImplTest {
|
||||||
|
|
||||||
|
private DevelopersApi api;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private LinstorPrimaryDataStoreDriverImpl linstorPrimaryDataStoreDriver;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
api = mock(DevelopersApi.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEncryptedLayerList() throws ApiException {
|
||||||
|
ResourceGroup dfltRscGrp = new ResourceGroup();
|
||||||
|
dfltRscGrp.setName("DfltRscGrp");
|
||||||
|
|
||||||
|
ResourceGroup bCacheRscGrp = new ResourceGroup();
|
||||||
|
bCacheRscGrp.setName("BcacheGrp");
|
||||||
|
AutoSelectFilter asf = new AutoSelectFilter();
|
||||||
|
asf.setLayerStack(Arrays.asList(LayerType.DRBD.name(), LayerType.BCACHE.name(), LayerType.STORAGE.name()));
|
||||||
|
asf.setStoragePool("nvmePool");
|
||||||
|
bCacheRscGrp.setSelectFilter(asf);
|
||||||
|
|
||||||
|
ResourceGroup encryptedGrp = new ResourceGroup();
|
||||||
|
encryptedGrp.setName("EncryptedGrp");
|
||||||
|
AutoSelectFilter asf2 = new AutoSelectFilter();
|
||||||
|
asf2.setLayerStack(Arrays.asList(LayerType.DRBD.name(), LayerType.LUKS.name(), LayerType.STORAGE.name()));
|
||||||
|
asf2.setStoragePool("ssdPool");
|
||||||
|
encryptedGrp.setSelectFilter(asf2);
|
||||||
|
|
||||||
|
when(api.resourceGroupList(Collections.singletonList("DfltRscGrp"), Collections.emptyList(), null, null))
|
||||||
|
.thenReturn(Collections.singletonList(dfltRscGrp));
|
||||||
|
when(api.resourceGroupList(Collections.singletonList("BcacheGrp"), Collections.emptyList(), null, null))
|
||||||
|
.thenReturn(Collections.singletonList(bCacheRscGrp));
|
||||||
|
when(api.resourceGroupList(Collections.singletonList("EncryptedGrp"), Collections.emptyList(), null, null))
|
||||||
|
.thenReturn(Collections.singletonList(encryptedGrp));
|
||||||
|
|
||||||
|
List<LayerType> layers = linstorPrimaryDataStoreDriver.getEncryptedLayerList(api, "DfltRscGrp");
|
||||||
|
Assert.assertEquals(Arrays.asList(LayerType.DRBD, LayerType.LUKS, LayerType.STORAGE), layers);
|
||||||
|
|
||||||
|
layers = linstorPrimaryDataStoreDriver.getEncryptedLayerList(api, "BcacheGrp");
|
||||||
|
Assert.assertEquals(Arrays.asList(LayerType.DRBD, LayerType.BCACHE, LayerType.LUKS, LayerType.STORAGE), layers);
|
||||||
|
|
||||||
|
layers = linstorPrimaryDataStoreDriver.getEncryptedLayerList(api, "EncryptedGrp");
|
||||||
|
Assert.assertEquals(Arrays.asList(LayerType.DRBD, LayerType.LUKS, LayerType.STORAGE), layers);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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.
|
||||||
|
package org.apache.cloudstack.storage.datastore.util;
|
||||||
|
|
||||||
|
import com.linbit.linstor.api.ApiException;
|
||||||
|
import com.linbit.linstor.api.DevelopersApi;
|
||||||
|
import com.linbit.linstor.api.model.AutoSelectFilter;
|
||||||
|
import com.linbit.linstor.api.model.Node;
|
||||||
|
import com.linbit.linstor.api.model.Properties;
|
||||||
|
import com.linbit.linstor.api.model.ProviderKind;
|
||||||
|
import com.linbit.linstor.api.model.ResourceGroup;
|
||||||
|
import com.linbit.linstor.api.model.StoragePool;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class LinstorUtilTest {
|
||||||
|
|
||||||
|
private static final String LINSTOR_URL_TEST = "devnull.com:3370";
|
||||||
|
private DevelopersApi api;
|
||||||
|
|
||||||
|
private Node mockNode(String name) {
|
||||||
|
Node nodeMock = new Node();
|
||||||
|
nodeMock.setName(name);
|
||||||
|
|
||||||
|
return nodeMock;
|
||||||
|
}
|
||||||
|
|
||||||
|
private StoragePool mockStoragePool(String name, String node, ProviderKind kind) {
|
||||||
|
StoragePool sp = new StoragePool();
|
||||||
|
sp.setStoragePoolName(name);
|
||||||
|
sp.setNodeName(node);
|
||||||
|
sp.setProviderKind(kind);
|
||||||
|
return sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws ApiException {
|
||||||
|
api = mock(DevelopersApi.class);
|
||||||
|
|
||||||
|
when(api.nodeList(Collections.emptyList(), Collections.emptyList(), null, null))
|
||||||
|
.thenReturn(Arrays.asList(mockNode("nodeA"), mockNode("nodeB"), mockNode("nodeC")));
|
||||||
|
|
||||||
|
ResourceGroup csGroup = new ResourceGroup();
|
||||||
|
csGroup.setName("cloudstack");
|
||||||
|
AutoSelectFilter asf = new AutoSelectFilter();
|
||||||
|
asf.setPlaceCount(2);
|
||||||
|
csGroup.setSelectFilter(asf);
|
||||||
|
when(api.resourceGroupList(Collections.singletonList("cloudstack"), null, null, null))
|
||||||
|
.thenReturn(Collections.singletonList(csGroup));
|
||||||
|
|
||||||
|
when(api.viewStoragePools(Collections.emptyList(), null, null, null, null, true))
|
||||||
|
.thenReturn(Arrays.asList(
|
||||||
|
mockStoragePool("thinpool", "nodeA", ProviderKind.LVM_THIN),
|
||||||
|
mockStoragePool("thinpool", "nodeB", ProviderKind.LVM_THIN),
|
||||||
|
mockStoragePool("thinpool", "nodeC", ProviderKind.LVM_THIN)
|
||||||
|
));
|
||||||
|
|
||||||
|
// when(LinstorUtil.getLinstorAPI(LINSTOR_URL_TEST)).thenReturn(api);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetLinstorNodeNames() throws ApiException {
|
||||||
|
List<String> linstorNodes = LinstorUtil.getLinstorNodeNames(api);
|
||||||
|
Assert.assertEquals(Arrays.asList("nodeA", "nodeB", "nodeC"), linstorNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSnapshotPath() {
|
||||||
|
{
|
||||||
|
StoragePool spLVMThin = new StoragePool();
|
||||||
|
Properties lvmThinProps = new Properties();
|
||||||
|
lvmThinProps.put("StorDriver/StorPoolName", "storage/storage-thin");
|
||||||
|
spLVMThin.setProps(lvmThinProps);
|
||||||
|
spLVMThin.setProviderKind(ProviderKind.LVM_THIN);
|
||||||
|
String snapPath = LinstorUtil.getSnapshotPath(spLVMThin, "cs-cb32532a-dd8f-47e0-a81c-8a75573d3545", "snap3");
|
||||||
|
Assert.assertEquals("/dev/mapper/storage-cs--cb32532a--dd8f--47e0--a81c--8a75573d3545_00000_snap3", snapPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
StoragePool spZFS = new StoragePool();
|
||||||
|
Properties zfsProps = new Properties();
|
||||||
|
zfsProps.put("StorDriver/StorPoolName", "linstorPool");
|
||||||
|
spZFS.setProps(zfsProps);
|
||||||
|
spZFS.setProviderKind(ProviderKind.ZFS);
|
||||||
|
|
||||||
|
String snapPath = LinstorUtil.getSnapshotPath(spZFS, "cs-cb32532a-dd8f-47e0-a81c-8a75573d3545", "snap2");
|
||||||
|
Assert.assertEquals("zfs://linstorPool/cs-cb32532a-dd8f-47e0-a81c-8a75573d3545_00000@snap2", snapPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetRscGroupStoragePools() throws ApiException {
|
||||||
|
List<StoragePool> storagePools = LinstorUtil.getRscGroupStoragePools(api, "cloudstack");
|
||||||
|
|
||||||
|
List<String> names = storagePools.stream()
|
||||||
|
.map(sp -> String.format("%s::%s", sp.getNodeName(), sp.getStoragePoolName()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
Assert.assertEquals(names, Arrays.asList("nodeA::thinpool", "nodeB::thinpool", "nodeC::thinpool"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -146,16 +146,18 @@ public class PrimeraAdapter implements ProviderAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// determine volume type based on offering
|
// determine volume type based on offering
|
||||||
// THIN: tpvv=true, reduce=false
|
// tpvv -- thin provisioned virtual volume (no deduplication)
|
||||||
// SPARSE: tpvv=true, reduce=true
|
// reduce -- thin provisioned virtual volume (with duplication and compression, also known as DECO)
|
||||||
// THICK: tpvv=false, tpZeroFill=true (not supported)
|
// these are the only choices with newer Primera devices
|
||||||
|
// we will use THIN for the deduplicated/compressed type and SPARSE for thin-only without dedup/compress
|
||||||
|
// note: DECO/reduce type must be at least 16GB in size
|
||||||
if (diskOffering != null) {
|
if (diskOffering != null) {
|
||||||
if (diskOffering.getType() == ProvisioningType.THIN) {
|
if (diskOffering.getType() == ProvisioningType.THIN) {
|
||||||
request.setTpvv(true);
|
|
||||||
request.setReduce(false);
|
|
||||||
} else if (diskOffering.getType() == ProvisioningType.SPARSE) {
|
|
||||||
request.setTpvv(false);
|
request.setTpvv(false);
|
||||||
request.setReduce(true);
|
request.setReduce(true);
|
||||||
|
} else if (diskOffering.getType() == ProvisioningType.SPARSE) {
|
||||||
|
request.setTpvv(true);
|
||||||
|
request.setReduce(false);
|
||||||
} else if (diskOffering.getType() == ProvisioningType.FAT) {
|
} else if (diskOffering.getType() == ProvisioningType.FAT) {
|
||||||
throw new RuntimeException("This storage provider does not support FAT provisioned volumes");
|
throw new RuntimeException("This storage provider does not support FAT provisioned volumes");
|
||||||
}
|
}
|
||||||
@ -166,8 +168,16 @@ public class PrimeraAdapter implements ProviderAdapter {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// default to deduplicated volume
|
// default to deduplicated volume
|
||||||
request.setReduce(true);
|
|
||||||
request.setTpvv(false);
|
request.setTpvv(false);
|
||||||
|
request.setReduce(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getReduce() == true) {
|
||||||
|
// check if sizeMiB is less than 16GB adjust up to 16GB. The AdaptiveDatastoreDriver will automatically
|
||||||
|
// update this on the cloudstack side to match
|
||||||
|
if (request.getSizeMiB() < 16 * 1024) {
|
||||||
|
request.setSizeMiB(16 * 1024);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
request.setComment(ProviderVolumeNamer.generateObjectComment(context, dataIn));
|
request.setComment(ProviderVolumeNamer.generateObjectComment(context, dataIn));
|
||||||
@ -185,8 +195,11 @@ public class PrimeraAdapter implements ProviderAdapter {
|
|||||||
if (host == null) {
|
if (host == null) {
|
||||||
throw new RuntimeException("Unable to find host " + hostname + " on storage provider");
|
throw new RuntimeException("Unable to find host " + hostname + " on storage provider");
|
||||||
}
|
}
|
||||||
request.setHostname(host.getName());
|
|
||||||
|
|
||||||
|
// check if we already have a vlun for requested host
|
||||||
|
Integer vlun = hasVlun(hostname, hostname);
|
||||||
|
if (vlun == null) {
|
||||||
|
request.setHostname(host.getName());
|
||||||
request.setVolumeName(dataIn.getExternalName());
|
request.setVolumeName(dataIn.getExternalName());
|
||||||
request.setAutoLun(true);
|
request.setAutoLun(true);
|
||||||
// auto-lun returned here: Location: /api/v1/vluns/test_vv02,252,mysystem,2:2:4
|
// auto-lun returned here: Location: /api/v1/vluns/test_vv02,252,mysystem,2:2:4
|
||||||
@ -198,7 +211,13 @@ public class PrimeraAdapter implements ProviderAdapter {
|
|||||||
if (toks.length <2) {
|
if (toks.length <2) {
|
||||||
throw new RuntimeException("Attach volume failed with invalid location response to vlun add command on storage provider. Provided location: " + location);
|
throw new RuntimeException("Attach volume failed with invalid location response to vlun add command on storage provider. Provided location: " + location);
|
||||||
}
|
}
|
||||||
return toks[1];
|
try {
|
||||||
|
vlun = Integer.parseInt(toks[1]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new RuntimeException("VLUN attach request succeeded but the VLUN value is not a valid number: " + toks[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vlun.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -233,6 +252,20 @@ public class PrimeraAdapter implements ProviderAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Integer hasVlun(String externalName, String hostname) {
|
||||||
|
PrimeraVlunList list = getVluns(externalName);
|
||||||
|
if (list != null && list.getMembers().size() > 0) {
|
||||||
|
for (PrimeraVlun vlun: list.getMembers()) {
|
||||||
|
if (hostname != null) {
|
||||||
|
if (vlun.getHostname().equals(hostname) || vlun.getHostname().equals(hostname.split("\\.")[0])) {
|
||||||
|
return vlun.getLun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public void removeVlun(String name, Integer lunid, String hostString) {
|
public void removeVlun(String name, Integer lunid, String hostString) {
|
||||||
// hostString can be a hostname OR "set:<hostsetname>". It is stored this way
|
// hostString can be a hostname OR "set:<hostsetname>". It is stored this way
|
||||||
// in the appliance and returned as the vlun's name/string.
|
// in the appliance and returned as the vlun's name/string.
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@ -175,7 +175,7 @@
|
|||||||
<cs.nitro.version>10.1</cs.nitro.version>
|
<cs.nitro.version>10.1</cs.nitro.version>
|
||||||
<cs.opensaml.version>2.6.6</cs.opensaml.version>
|
<cs.opensaml.version>2.6.6</cs.opensaml.version>
|
||||||
<cs.rados-java.version>0.6.0</cs.rados-java.version>
|
<cs.rados-java.version>0.6.0</cs.rados-java.version>
|
||||||
<cs.java-linstor.version>0.5.2</cs.java-linstor.version>
|
<cs.java-linstor.version>0.6.0</cs.java-linstor.version>
|
||||||
<cs.reflections.version>0.10.2</cs.reflections.version>
|
<cs.reflections.version>0.10.2</cs.reflections.version>
|
||||||
<cs.servicemix.version>3.4.4_1</cs.servicemix.version>
|
<cs.servicemix.version>3.4.4_1</cs.servicemix.version>
|
||||||
<cs.servlet.version>4.0.1</cs.servlet.version>
|
<cs.servlet.version>4.0.1</cs.servlet.version>
|
||||||
|
|||||||
@ -22,10 +22,18 @@
|
|||||||
#
|
#
|
||||||
#############################################################################################
|
#############################################################################################
|
||||||
|
|
||||||
|
SCRIPT_NAME=$(basename "$0")
|
||||||
|
|
||||||
|
if [[ $(pgrep -f ${SCRIPT_NAME}) != "$$" ]]; then
|
||||||
|
echo "Another instance of ${SCRIPT_NAME} is already running! Exiting"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
|
|
||||||
for WWID in $(multipathd list maps status | awk '{ if ($4 == 0) { print substr($1,2); }}'); do
|
for WWID in $(multipathd list maps status | awk '{ if ($4 == 0) { print substr($1,2); }}'); do
|
||||||
./removeVolume.sh ${WWID}
|
./disconnectVolume.sh ${WWID}
|
||||||
done
|
done
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@ -66,6 +66,9 @@ fi
|
|||||||
|
|
||||||
logger -t CS_SCSI_VOL_REMOVE "${WWID} successfully purged from multipath along with slave devices"
|
logger -t CS_SCSI_VOL_REMOVE "${WWID} successfully purged from multipath along with slave devices"
|
||||||
|
|
||||||
|
# Added to give time for the event to be fired to the server
|
||||||
|
sleep 10
|
||||||
|
|
||||||
echo "$(date): ${WWID} removed"
|
echo "$(date): ${WWID} removed"
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@ -355,263 +355,263 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
private static final String ID_FIELD = "id";
|
private static final String ID_FIELD = "id";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AccountManager accountMgr;
|
AccountManager accountMgr;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ProjectManager _projectMgr;
|
ProjectManager _projectMgr;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DomainDao _domainDao;
|
DomainDao _domainDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DomainJoinDao _domainJoinDao;
|
DomainJoinDao _domainJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private UserAccountJoinDao _userAccountJoinDao;
|
UserAccountJoinDao _userAccountJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private EventDao eventDao;
|
EventDao eventDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private EventJoinDao _eventJoinDao;
|
EventJoinDao _eventJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ResourceTagJoinDao _resourceTagJoinDao;
|
ResourceTagJoinDao _resourceTagJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private InstanceGroupJoinDao _vmGroupJoinDao;
|
InstanceGroupJoinDao _vmGroupJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private UserVmJoinDao _userVmJoinDao;
|
UserVmJoinDao _userVmJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private UserVmDao userVmDao;
|
UserVmDao userVmDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private VMInstanceDao _vmInstanceDao;
|
VMInstanceDao _vmInstanceDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SecurityGroupJoinDao _securityGroupJoinDao;
|
SecurityGroupJoinDao _securityGroupJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SecurityGroupVMMapDao securityGroupVMMapDao;
|
SecurityGroupVMMapDao securityGroupVMMapDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DomainRouterJoinDao _routerJoinDao;
|
DomainRouterJoinDao _routerJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ProjectInvitationJoinDao _projectInvitationJoinDao;
|
ProjectInvitationJoinDao _projectInvitationJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ProjectJoinDao _projectJoinDao;
|
ProjectJoinDao _projectJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ProjectDao _projectDao;
|
ProjectDao _projectDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ProjectAccountDao _projectAccountDao;
|
ProjectAccountDao _projectAccountDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ProjectAccountJoinDao _projectAccountJoinDao;
|
ProjectAccountJoinDao _projectAccountJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private HostJoinDao hostJoinDao;
|
HostJoinDao hostJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private VolumeJoinDao _volumeJoinDao;
|
VolumeJoinDao _volumeJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AccountDao _accountDao;
|
AccountDao _accountDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AccountJoinDao _accountJoinDao;
|
AccountJoinDao _accountJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AsyncJobJoinDao _jobJoinDao;
|
AsyncJobJoinDao _jobJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private StoragePoolJoinDao _poolJoinDao;
|
StoragePoolJoinDao _poolJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private StoragePoolTagsDao _storageTagDao;
|
StoragePoolTagsDao _storageTagDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private HostTagsDao _hostTagDao;
|
HostTagsDao _hostTagDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ImageStoreJoinDao _imageStoreJoinDao;
|
ImageStoreJoinDao _imageStoreJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DiskOfferingJoinDao _diskOfferingJoinDao;
|
DiskOfferingJoinDao _diskOfferingJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DiskOfferingDetailsDao _diskOfferingDetailsDao;
|
DiskOfferingDetailsDao _diskOfferingDetailsDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ServiceOfferingJoinDao _srvOfferingJoinDao;
|
ServiceOfferingJoinDao _srvOfferingJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ServiceOfferingDao _srvOfferingDao;
|
ServiceOfferingDao _srvOfferingDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ServiceOfferingDetailsDao _srvOfferingDetailsDao;
|
ServiceOfferingDetailsDao _srvOfferingDetailsDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DiskOfferingDao _diskOfferingDao;
|
DiskOfferingDao _diskOfferingDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DataCenterJoinDao _dcJoinDao;
|
DataCenterJoinDao _dcJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DomainRouterDao _routerDao;
|
DomainRouterDao _routerDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private HighAvailabilityManager _haMgr;
|
HighAvailabilityManager _haMgr;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private VMTemplateDao _templateDao;
|
VMTemplateDao _templateDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TemplateJoinDao _templateJoinDao;
|
TemplateJoinDao _templateJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ResourceManager _resourceMgr;
|
ResourceManager _resourceMgr;
|
||||||
@Inject
|
@Inject
|
||||||
private ResourceMetaDataService _resourceMetaDataMgr;
|
ResourceMetaDataService _resourceMetaDataMgr;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ResourceManagerUtil resourceManagerUtil;
|
ResourceManagerUtil resourceManagerUtil;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AffinityGroupVMMapDao _affinityGroupVMMapDao;
|
AffinityGroupVMMapDao _affinityGroupVMMapDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AffinityGroupJoinDao _affinityGroupJoinDao;
|
AffinityGroupJoinDao _affinityGroupJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DedicatedResourceDao _dedicatedDao;
|
DedicatedResourceDao _dedicatedDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DomainManager _domainMgr;
|
DomainManager _domainMgr;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AffinityGroupDomainMapDao _affinityGroupDomainMapDao;
|
AffinityGroupDomainMapDao _affinityGroupDomainMapDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ResourceTagDao resourceTagDao;
|
ResourceTagDao resourceTagDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DataStoreManager dataStoreManager;
|
DataStoreManager dataStoreManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ManagementServerJoinDao managementServerJoinDao;
|
ManagementServerJoinDao managementServerJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public VpcVirtualNetworkApplianceService routerService;
|
VpcVirtualNetworkApplianceService routerService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ResponseGenerator responseGenerator;
|
ResponseGenerator responseGenerator;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private RouterHealthCheckResultDao routerHealthCheckResultDao;
|
RouterHealthCheckResultDao routerHealthCheckResultDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private PrimaryDataStoreDao storagePoolDao;
|
PrimaryDataStoreDao storagePoolDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private StoragePoolDetailsDao _storagePoolDetailsDao;
|
StoragePoolDetailsDao _storagePoolDetailsDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ProjectInvitationDao projectInvitationDao;
|
ProjectInvitationDao projectInvitationDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TemplateDataStoreDao templateDataStoreDao;
|
TemplateDataStoreDao templateDataStoreDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private VMTemplatePoolDao templatePoolDao;
|
VMTemplatePoolDao templatePoolDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SnapshotDataStoreDao snapshotDataStoreDao;
|
SnapshotDataStoreDao snapshotDataStoreDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private UserDao userDao;
|
UserDao userDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private VirtualMachineManager virtualMachineManager;
|
VirtualMachineManager virtualMachineManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private VolumeDao volumeDao;
|
VolumeDao volumeDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ResourceIconDao resourceIconDao;
|
ResourceIconDao resourceIconDao;
|
||||||
@Inject
|
@Inject
|
||||||
StorageManager storageManager;
|
StorageManager storageManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ManagementServerHostDao msHostDao;
|
ManagementServerHostDao msHostDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SecondaryStorageHeuristicDao secondaryStorageHeuristicDao;
|
SecondaryStorageHeuristicDao secondaryStorageHeuristicDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private NetworkDao networkDao;
|
NetworkDao networkDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private IPAddressDao ipAddressDao;
|
IPAddressDao ipAddressDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private NicDao nicDao;
|
NicDao nicDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private HostDao hostDao;
|
HostDao hostDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private OutOfBandManagementDao outOfBandManagementDao;
|
OutOfBandManagementDao outOfBandManagementDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private InstanceGroupVMMapDao instanceGroupVMMapDao;
|
InstanceGroupVMMapDao instanceGroupVMMapDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AffinityGroupVMMapDao affinityGroupVMMapDao;
|
AffinityGroupVMMapDao affinityGroupVMMapDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private UserVmDetailsDao userVmDetailsDao;
|
UserVmDetailsDao userVmDetailsDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SSHKeyPairDao sshKeyPairDao;
|
SSHKeyPairDao sshKeyPairDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private BackupOfferingDao backupOfferingDao;
|
BackupOfferingDao backupOfferingDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AutoScaleVmGroupDao autoScaleVmGroupDao;
|
AutoScaleVmGroupDao autoScaleVmGroupDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AutoScaleVmGroupVmMapDao autoScaleVmGroupVmMapDao;
|
AutoScaleVmGroupVmMapDao autoScaleVmGroupVmMapDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SnapshotJoinDao snapshotJoinDao;
|
SnapshotJoinDao snapshotJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ObjectStoreDao objectStoreDao;
|
ObjectStoreDao objectStoreDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private BucketDao bucketDao;
|
BucketDao bucketDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
EntityManager entityManager;
|
EntityManager entityManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private PublicIpQuarantineDao publicIpQuarantineDao;
|
PublicIpQuarantineDao publicIpQuarantineDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private StoragePoolHostDao storagePoolHostDao;
|
StoragePoolHostDao storagePoolHostDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ClusterDao clusterDao;
|
ClusterDao clusterDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ManagementServerHostPeerJoinDao mshostPeerJoinDao;
|
ManagementServerHostPeerJoinDao mshostPeerJoinDao;
|
||||||
|
|
||||||
|
|
||||||
private SearchCriteria<ServiceOfferingJoinVO> getMinimumCpuServiceOfferingJoinSearchCriteria(int cpu) {
|
private SearchCriteria<ServiceOfferingJoinVO> getMinimumCpuServiceOfferingJoinSearchCriteria(int cpu) {
|
||||||
@ -663,7 +663,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<UserResponse> searchForUsers(ResponseView responseView, ListUsersCmd cmd) throws PermissionDeniedException {
|
public ListResponse<UserResponse> searchForUsers(ResponseView responseView, ListUsersCmd cmd) throws PermissionDeniedException {
|
||||||
Pair<List<UserAccountJoinVO>, Integer> result = searchForUsersInternal(cmd);
|
Pair<List<UserAccountJoinVO>, Integer> result = searchForUsersInternal(cmd);
|
||||||
ListResponse<UserResponse> response = new ListResponse<UserResponse>();
|
ListResponse<UserResponse> response = new ListResponse<>();
|
||||||
if (CallContext.current().getCallingAccount().getType() == Account.Type.ADMIN) {
|
if (CallContext.current().getCallingAccount().getType() == Account.Type.ADMIN) {
|
||||||
responseView = ResponseView.Full;
|
responseView = ResponseView.Full;
|
||||||
}
|
}
|
||||||
@ -833,7 +833,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<EventResponse> searchForEvents(ListEventsCmd cmd) {
|
public ListResponse<EventResponse> searchForEvents(ListEventsCmd cmd) {
|
||||||
Pair<List<EventJoinVO>, Integer> result = searchForEventsInternal(cmd);
|
Pair<List<EventJoinVO>, Integer> result = searchForEventsInternal(cmd);
|
||||||
ListResponse<EventResponse> response = new ListResponse<EventResponse>();
|
ListResponse<EventResponse> response = new ListResponse<>();
|
||||||
List<EventResponse> eventResponses = ViewResponseHelper.createEventResponse(result.first().toArray(new EventJoinVO[result.first().size()]));
|
List<EventResponse> eventResponses = ViewResponseHelper.createEventResponse(result.first().toArray(new EventJoinVO[result.first().size()]));
|
||||||
response.setResponses(eventResponses, result.second());
|
response.setResponses(eventResponses, result.second());
|
||||||
return response;
|
return response;
|
||||||
@ -905,7 +905,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(cmd.getDomainId(), cmd.isRecursive(), null);
|
||||||
accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
||||||
Long domainId = domainIdRecursiveListProject.first();
|
Long domainId = domainIdRecursiveListProject.first();
|
||||||
Boolean isRecursive = domainIdRecursiveListProject.second();
|
Boolean isRecursive = domainIdRecursiveListProject.second();
|
||||||
@ -996,7 +996,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sc.setParameters("archived", cmd.getArchived());
|
sc.setParameters("archived", cmd.getArchived());
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair<List<Long>, Integer> eventPair = null;
|
Pair<List<Long>, Integer> eventPair;
|
||||||
// event_view will not have duplicate rows for each event, so
|
// event_view will not have duplicate rows for each event, so
|
||||||
// searchAndCount should be good enough.
|
// searchAndCount should be good enough.
|
||||||
if ((entryTime != null) && (duration != null)) {
|
if ((entryTime != null) && (duration != null)) {
|
||||||
@ -1033,7 +1033,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<ResourceTagResponse> listTags(ListTagsCmd cmd) {
|
public ListResponse<ResourceTagResponse> listTags(ListTagsCmd cmd) {
|
||||||
Pair<List<ResourceTagJoinVO>, Integer> tags = listTagsInternal(cmd);
|
Pair<List<ResourceTagJoinVO>, Integer> tags = listTagsInternal(cmd);
|
||||||
ListResponse<ResourceTagResponse> response = new ListResponse<ResourceTagResponse>();
|
ListResponse<ResourceTagResponse> response = new ListResponse<>();
|
||||||
List<ResourceTagResponse> tagResponses = ViewResponseHelper.createResourceTagResponse(false, tags.first().toArray(new ResourceTagJoinVO[tags.first().size()]));
|
List<ResourceTagResponse> tagResponses = ViewResponseHelper.createResourceTagResponse(false, tags.first().toArray(new ResourceTagJoinVO[tags.first().size()]));
|
||||||
response.setResponses(tagResponses, tags.second());
|
response.setResponses(tagResponses, tags.second());
|
||||||
return response;
|
return response;
|
||||||
@ -1041,7 +1041,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
private Pair<List<ResourceTagJoinVO>, Integer> listTagsInternal(ListTagsCmd cmd) {
|
private Pair<List<ResourceTagJoinVO>, Integer> listTagsInternal(ListTagsCmd cmd) {
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
List<Long> permittedAccounts = new ArrayList<>();
|
||||||
String key = cmd.getKey();
|
String key = cmd.getKey();
|
||||||
String value = cmd.getValue();
|
String value = cmd.getValue();
|
||||||
String resourceId = cmd.getResourceId();
|
String resourceId = cmd.getResourceId();
|
||||||
@ -1061,7 +1061,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(cmd.getDomainId(), cmd.isRecursive(), null);
|
||||||
|
|
||||||
accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
|
accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), projectId, permittedAccounts, domainIdRecursiveListProject, listAll, false);
|
||||||
Long domainId = domainIdRecursiveListProject.first();
|
Long domainId = domainIdRecursiveListProject.first();
|
||||||
@ -1113,14 +1113,13 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sc.setParameters("customer", customerName);
|
sc.setParameters("customer", customerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pair<List<ResourceTagJoinVO>, Integer> result = _resourceTagJoinDao.searchAndCount(sc, searchFilter);
|
return _resourceTagJoinDao.searchAndCount(sc, searchFilter);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListResponse<InstanceGroupResponse> searchForVmGroups(ListVMGroupsCmd cmd) {
|
public ListResponse<InstanceGroupResponse> searchForVmGroups(ListVMGroupsCmd cmd) {
|
||||||
Pair<List<InstanceGroupJoinVO>, Integer> groups = searchForVmGroupsInternal(cmd);
|
Pair<List<InstanceGroupJoinVO>, Integer> groups = searchForVmGroupsInternal(cmd);
|
||||||
ListResponse<InstanceGroupResponse> response = new ListResponse<InstanceGroupResponse>();
|
ListResponse<InstanceGroupResponse> response = new ListResponse<>();
|
||||||
List<InstanceGroupResponse> grpResponses = ViewResponseHelper.createInstanceGroupResponse(groups.first().toArray(new InstanceGroupJoinVO[groups.first().size()]));
|
List<InstanceGroupResponse> grpResponses = ViewResponseHelper.createInstanceGroupResponse(groups.first().toArray(new InstanceGroupJoinVO[groups.first().size()]));
|
||||||
response.setResponses(grpResponses, groups.second());
|
response.setResponses(grpResponses, groups.second());
|
||||||
return response;
|
return response;
|
||||||
@ -1132,9 +1131,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
String keyword = cmd.getKeyword();
|
String keyword = cmd.getKeyword();
|
||||||
|
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
List<Long> permittedAccounts = new ArrayList<>();
|
||||||
|
|
||||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(cmd.getDomainId(), cmd.isRecursive(), null);
|
||||||
accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
||||||
Long domainId = domainIdRecursiveListProject.first();
|
Long domainId = domainIdRecursiveListProject.first();
|
||||||
Boolean isRecursive = domainIdRecursiveListProject.second();
|
Boolean isRecursive = domainIdRecursiveListProject.second();
|
||||||
@ -1328,7 +1327,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
Filter searchFilter = new Filter(UserVmVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
|
Filter searchFilter = new Filter(UserVmVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||||
|
|
||||||
List<Long> ids = null;
|
List<Long> ids;
|
||||||
if (cmd.getId() != null) {
|
if (cmd.getId() != null) {
|
||||||
if (cmd.getIds() != null && !cmd.getIds().isEmpty()) {
|
if (cmd.getIds() != null && !cmd.getIds().isEmpty()) {
|
||||||
throw new InvalidParameterValueException("Specify either id or ids but not both parameters");
|
throw new InvalidParameterValueException("Specify either id or ids but not both parameters");
|
||||||
@ -1694,7 +1693,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<SecurityGroupResponse> searchForSecurityGroups(ListSecurityGroupsCmd cmd) {
|
public ListResponse<SecurityGroupResponse> searchForSecurityGroups(ListSecurityGroupsCmd cmd) {
|
||||||
Pair<List<SecurityGroupJoinVO>, Integer> result = searchForSecurityGroupsInternal(cmd);
|
Pair<List<SecurityGroupJoinVO>, Integer> result = searchForSecurityGroupsInternal(cmd);
|
||||||
ListResponse<SecurityGroupResponse> response = new ListResponse<SecurityGroupResponse>();
|
ListResponse<SecurityGroupResponse> response = new ListResponse<>();
|
||||||
List<SecurityGroupResponse> routerResponses = ViewResponseHelper.createSecurityGroupResponses(result.first());
|
List<SecurityGroupResponse> routerResponses = ViewResponseHelper.createSecurityGroupResponses(result.first());
|
||||||
response.setResponses(routerResponses, result.second());
|
response.setResponses(routerResponses, result.second());
|
||||||
return response;
|
return response;
|
||||||
@ -1706,7 +1705,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
String securityGroup = cmd.getSecurityGroupName();
|
String securityGroup = cmd.getSecurityGroupName();
|
||||||
Long id = cmd.getId();
|
Long id = cmd.getId();
|
||||||
Object keyword = cmd.getKeyword();
|
Object keyword = cmd.getKeyword();
|
||||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
List<Long> permittedAccounts = new ArrayList<>();
|
||||||
Map<String, String> tags = cmd.getTags();
|
Map<String, String> tags = cmd.getTags();
|
||||||
|
|
||||||
if (instanceId != null) {
|
if (instanceId != null) {
|
||||||
@ -1718,7 +1717,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
return listSecurityGroupRulesByVM(instanceId.longValue(), cmd.getStartIndex(), cmd.getPageSizeVal());
|
return listSecurityGroupRulesByVM(instanceId.longValue(), cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(cmd.getDomainId(), cmd.isRecursive(), null);
|
||||||
accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
||||||
Long domainId = domainIdRecursiveListProject.first();
|
Long domainId = domainIdRecursiveListProject.first();
|
||||||
Boolean isRecursive = domainIdRecursiveListProject.second();
|
Boolean isRecursive = domainIdRecursiveListProject.second();
|
||||||
@ -1777,7 +1776,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sgIds[i++] = v.getId();
|
sgIds[i++] = v.getId();
|
||||||
}
|
}
|
||||||
List<SecurityGroupJoinVO> sgs = _securityGroupJoinDao.searchByIds(sgIds);
|
List<SecurityGroupJoinVO> sgs = _securityGroupJoinDao.searchByIds(sgIds);
|
||||||
return new Pair<List<SecurityGroupJoinVO>, Integer>(sgs, count);
|
return new Pair<>(sgs, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<List<SecurityGroupJoinVO>, Integer> listSecurityGroupRulesByVM(long vmId, long pageInd, long pageSize) {
|
private Pair<List<SecurityGroupJoinVO>, Integer> listSecurityGroupRulesByVM(long vmId, long pageInd, long pageSize) {
|
||||||
@ -1786,7 +1785,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Integer count = sgVmMappingPair.second();
|
Integer count = sgVmMappingPair.second();
|
||||||
if (count.intValue() == 0) {
|
if (count.intValue() == 0) {
|
||||||
// handle empty result cases
|
// handle empty result cases
|
||||||
return new Pair<List<SecurityGroupJoinVO>, Integer>(new ArrayList<SecurityGroupJoinVO>(), count);
|
return new Pair<>(new ArrayList<>(), count);
|
||||||
}
|
}
|
||||||
List<SecurityGroupVMMapVO> sgVmMappings = sgVmMappingPair.first();
|
List<SecurityGroupVMMapVO> sgVmMappings = sgVmMappingPair.first();
|
||||||
Long[] sgIds = new Long[sgVmMappings.size()];
|
Long[] sgIds = new Long[sgVmMappings.size()];
|
||||||
@ -1795,14 +1794,14 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sgIds[i++] = sgVm.getSecurityGroupId();
|
sgIds[i++] = sgVm.getSecurityGroupId();
|
||||||
}
|
}
|
||||||
List<SecurityGroupJoinVO> sgs = _securityGroupJoinDao.searchByIds(sgIds);
|
List<SecurityGroupJoinVO> sgs = _securityGroupJoinDao.searchByIds(sgIds);
|
||||||
return new Pair<List<SecurityGroupJoinVO>, Integer>(sgs, count);
|
return new Pair<>(sgs, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListResponse<DomainRouterResponse> searchForRouters(ListRoutersCmd cmd) {
|
public ListResponse<DomainRouterResponse> searchForRouters(ListRoutersCmd cmd) {
|
||||||
Pair<List<DomainRouterJoinVO>, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getClusterId(),
|
Pair<List<DomainRouterJoinVO>, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), cmd.getClusterId(),
|
||||||
cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getVersion(), cmd.isHealthCheckFailed());
|
cmd.getHostId(), cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), cmd.getVersion(), cmd.isHealthCheckFailed());
|
||||||
ListResponse<DomainRouterResponse> response = new ListResponse<DomainRouterResponse>();
|
ListResponse<DomainRouterResponse> response = new ListResponse<>();
|
||||||
List<DomainRouterResponse> routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()]));
|
List<DomainRouterResponse> routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()]));
|
||||||
if (VirtualNetworkApplianceManager.RouterHealthChecksEnabled.value()) {
|
if (VirtualNetworkApplianceManager.RouterHealthChecksEnabled.value()) {
|
||||||
for (DomainRouterResponse res : routerResponses) {
|
for (DomainRouterResponse res : routerResponses) {
|
||||||
@ -1822,7 +1821,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
public ListResponse<DomainRouterResponse> searchForInternalLbVms(ListInternalLBVMsCmd cmd) {
|
public ListResponse<DomainRouterResponse> searchForInternalLbVms(ListInternalLBVMsCmd cmd) {
|
||||||
Pair<List<DomainRouterJoinVO>, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), null, cmd.getHostId(),
|
Pair<List<DomainRouterJoinVO>, Integer> result = searchForRoutersInternal(cmd, cmd.getId(), cmd.getRouterName(), cmd.getState(), cmd.getZoneId(), cmd.getPodId(), null, cmd.getHostId(),
|
||||||
cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), null, null);
|
cmd.getKeyword(), cmd.getNetworkId(), cmd.getVpcId(), cmd.getForVpc(), cmd.getRole(), null, null);
|
||||||
ListResponse<DomainRouterResponse> response = new ListResponse<DomainRouterResponse>();
|
ListResponse<DomainRouterResponse> response = new ListResponse<>();
|
||||||
List<DomainRouterResponse> routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()]));
|
List<DomainRouterResponse> routerResponses = ViewResponseHelper.createDomainRouterResponse(result.first().toArray(new DomainRouterJoinVO[result.first().size()]));
|
||||||
if (VirtualNetworkApplianceManager.RouterHealthChecksEnabled.value()) {
|
if (VirtualNetworkApplianceManager.RouterHealthChecksEnabled.value()) {
|
||||||
for (DomainRouterResponse res : routerResponses) {
|
for (DomainRouterResponse res : routerResponses) {
|
||||||
@ -1843,9 +1842,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role, String version, Boolean isHealthCheckFailed) {
|
Long hostId, String keyword, Long networkId, Long vpcId, Boolean forVpc, String role, String version, Boolean isHealthCheckFailed) {
|
||||||
|
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
List<Long> permittedAccounts = new ArrayList<>();
|
||||||
|
|
||||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(cmd.getDomainId(), cmd.isRecursive(), null);
|
||||||
accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
||||||
Long domainId = domainIdRecursiveListProject.first();
|
Long domainId = domainIdRecursiveListProject.first();
|
||||||
Boolean isRecursive = domainIdRecursiveListProject.second();
|
Boolean isRecursive = domainIdRecursiveListProject.second();
|
||||||
@ -1901,7 +1900,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sb.and("routerId", sb.entity().getId(), SearchCriteria.Op.NIN);
|
sb.and("routerId", sb.entity().getId(), SearchCriteria.Op.NIN);
|
||||||
}
|
}
|
||||||
} else if (isHealthCheckFailed) {
|
} else if (isHealthCheckFailed) {
|
||||||
return new Pair<List<DomainRouterJoinVO>, Integer>(Collections.emptyList(), 0);
|
return new Pair<>(Collections.emptyList(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1981,13 +1980,13 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
vrIds[i++] = v.getId();
|
vrIds[i++] = v.getId();
|
||||||
}
|
}
|
||||||
List<DomainRouterJoinVO> vrs = _routerJoinDao.searchByIds(vrIds);
|
List<DomainRouterJoinVO> vrs = _routerJoinDao.searchByIds(vrIds);
|
||||||
return new Pair<List<DomainRouterJoinVO>, Integer>(vrs, count);
|
return new Pair<>(vrs, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListResponse<ProjectResponse> listProjects(ListProjectsCmd cmd) {
|
public ListResponse<ProjectResponse> listProjects(ListProjectsCmd cmd) {
|
||||||
Pair<List<ProjectJoinVO>, Integer> projects = listProjectsInternal(cmd);
|
Pair<List<ProjectJoinVO>, Integer> projects = listProjectsInternal(cmd);
|
||||||
ListResponse<ProjectResponse> response = new ListResponse<ProjectResponse>();
|
ListResponse<ProjectResponse> response = new ListResponse<>();
|
||||||
List<ProjectResponse> projectResponses = ViewResponseHelper.createProjectResponse(cmd.getDetails(), projects.first().toArray(new ProjectJoinVO[projects.first().size()]));
|
List<ProjectResponse> projectResponses = ViewResponseHelper.createProjectResponse(cmd.getDetails(), projects.first().toArray(new ProjectJoinVO[projects.first().size()]));
|
||||||
response.setResponses(projectResponses, projects.second());
|
response.setResponses(projectResponses, projects.second());
|
||||||
return response;
|
return response;
|
||||||
@ -2155,13 +2154,13 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
prjIds[i++] = v.getId();
|
prjIds[i++] = v.getId();
|
||||||
}
|
}
|
||||||
List<ProjectJoinVO> prjs = _projectJoinDao.searchByIds(prjIds);
|
List<ProjectJoinVO> prjs = _projectJoinDao.searchByIds(prjIds);
|
||||||
return new Pair<List<ProjectJoinVO>, Integer>(prjs, count);
|
return new Pair<>(prjs, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListResponse<ProjectInvitationResponse> listProjectInvitations(ListProjectInvitationsCmd cmd) {
|
public ListResponse<ProjectInvitationResponse> listProjectInvitations(ListProjectInvitationsCmd cmd) {
|
||||||
Pair<List<ProjectInvitationJoinVO>, Integer> invites = listProjectInvitationsInternal(cmd);
|
Pair<List<ProjectInvitationJoinVO>, Integer> invites = listProjectInvitationsInternal(cmd);
|
||||||
ListResponse<ProjectInvitationResponse> response = new ListResponse<ProjectInvitationResponse>();
|
ListResponse<ProjectInvitationResponse> response = new ListResponse<>();
|
||||||
List<ProjectInvitationResponse> projectInvitationResponses = ViewResponseHelper.createProjectInvitationResponse(invites.first().toArray(new ProjectInvitationJoinVO[invites.first().size()]));
|
List<ProjectInvitationResponse> projectInvitationResponses = ViewResponseHelper.createProjectInvitationResponse(invites.first().toArray(new ProjectInvitationJoinVO[invites.first().size()]));
|
||||||
|
|
||||||
response.setResponses(projectInvitationResponses, invites.second());
|
response.setResponses(projectInvitationResponses, invites.second());
|
||||||
@ -2183,9 +2182,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
User callingUser = CallContext.current().getCallingUser();
|
User callingUser = CallContext.current().getCallingUser();
|
||||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
List<Long> permittedAccounts = new ArrayList<>();
|
||||||
|
|
||||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null);
|
||||||
accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, true);
|
accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccounts, domainIdRecursiveListProject, listAll, true);
|
||||||
domainId = domainIdRecursiveListProject.first();
|
domainId = domainIdRecursiveListProject.first();
|
||||||
isRecursive = domainIdRecursiveListProject.second();
|
isRecursive = domainIdRecursiveListProject.second();
|
||||||
@ -2237,7 +2236,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<ProjectAccountResponse> listProjectAccounts(ListProjectAccountsCmd cmd) {
|
public ListResponse<ProjectAccountResponse> listProjectAccounts(ListProjectAccountsCmd cmd) {
|
||||||
Pair<List<ProjectAccountJoinVO>, Integer> projectAccounts = listProjectAccountsInternal(cmd);
|
Pair<List<ProjectAccountJoinVO>, Integer> projectAccounts = listProjectAccountsInternal(cmd);
|
||||||
ListResponse<ProjectAccountResponse> response = new ListResponse<ProjectAccountResponse>();
|
ListResponse<ProjectAccountResponse> response = new ListResponse<>();
|
||||||
List<ProjectAccountResponse> projectResponses = ViewResponseHelper.createProjectAccountResponse(projectAccounts.first().toArray(new ProjectAccountJoinVO[projectAccounts.first().size()]));
|
List<ProjectAccountResponse> projectResponses = ViewResponseHelper.createProjectAccountResponse(projectAccounts.first().toArray(new ProjectAccountJoinVO[projectAccounts.first().size()]));
|
||||||
response.setResponses(projectResponses, projectAccounts.second());
|
response.setResponses(projectResponses, projectAccounts.second());
|
||||||
return response;
|
return response;
|
||||||
@ -2311,7 +2310,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
// Right now it is handled separately outside this QueryService
|
// Right now it is handled separately outside this QueryService
|
||||||
logger.debug(">>>Searching for hosts>>>");
|
logger.debug(">>>Searching for hosts>>>");
|
||||||
Pair<List<HostJoinVO>, Integer> hosts = searchForServersInternal(cmd);
|
Pair<List<HostJoinVO>, Integer> hosts = searchForServersInternal(cmd);
|
||||||
ListResponse<HostResponse> response = new ListResponse<HostResponse>();
|
ListResponse<HostResponse> response = new ListResponse<>();
|
||||||
logger.debug(">>>Generating Response>>>");
|
logger.debug(">>>Generating Response>>>");
|
||||||
List<HostResponse> hostResponses = ViewResponseHelper.createHostResponse(cmd.getDetails(), hosts.first().toArray(new HostJoinVO[hosts.first().size()]));
|
List<HostResponse> hostResponses = ViewResponseHelper.createHostResponse(cmd.getDetails(), hosts.first().toArray(new HostJoinVO[hosts.first().size()]));
|
||||||
response.setResponses(hostResponses, hosts.second());
|
response.setResponses(hostResponses, hosts.second());
|
||||||
@ -2723,7 +2722,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<DomainResponse> searchForDomains(ListDomainsCmd cmd) {
|
public ListResponse<DomainResponse> searchForDomains(ListDomainsCmd cmd) {
|
||||||
Pair<List<DomainJoinVO>, Integer> result = searchForDomainsInternal(cmd);
|
Pair<List<DomainJoinVO>, Integer> result = searchForDomainsInternal(cmd);
|
||||||
ListResponse<DomainResponse> response = new ListResponse<DomainResponse>();
|
ListResponse<DomainResponse> response = new ListResponse<>();
|
||||||
|
|
||||||
ResponseView respView = ResponseView.Restricted;
|
ResponseView respView = ResponseView.Restricted;
|
||||||
if (cmd instanceof ListDomainsCmdByAdmin) {
|
if (cmd instanceof ListDomainsCmdByAdmin) {
|
||||||
@ -2825,7 +2824,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<AccountResponse> searchForAccounts(ListAccountsCmd cmd) {
|
public ListResponse<AccountResponse> searchForAccounts(ListAccountsCmd cmd) {
|
||||||
Pair<List<AccountJoinVO>, Integer> result = searchForAccountsInternal(cmd);
|
Pair<List<AccountJoinVO>, Integer> result = searchForAccountsInternal(cmd);
|
||||||
ListResponse<AccountResponse> response = new ListResponse<AccountResponse>();
|
ListResponse<AccountResponse> response = new ListResponse<>();
|
||||||
|
|
||||||
ResponseView respView = ResponseView.Restricted;
|
ResponseView respView = ResponseView.Restricted;
|
||||||
if (cmd instanceof ListAccountsCmdByAdmin) {
|
if (cmd instanceof ListAccountsCmdByAdmin) {
|
||||||
@ -3011,7 +3010,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<AsyncJobResponse> searchForAsyncJobs(ListAsyncJobsCmd cmd) {
|
public ListResponse<AsyncJobResponse> searchForAsyncJobs(ListAsyncJobsCmd cmd) {
|
||||||
Pair<List<AsyncJobJoinVO>, Integer> result = searchForAsyncJobsInternal(cmd);
|
Pair<List<AsyncJobJoinVO>, Integer> result = searchForAsyncJobsInternal(cmd);
|
||||||
ListResponse<AsyncJobResponse> response = new ListResponse<AsyncJobResponse>();
|
ListResponse<AsyncJobResponse> response = new ListResponse<>();
|
||||||
List<AsyncJobResponse> jobResponses = ViewResponseHelper.createAsyncJobResponse(result.first().toArray(new AsyncJobJoinVO[result.first().size()]));
|
List<AsyncJobResponse> jobResponses = ViewResponseHelper.createAsyncJobResponse(result.first().toArray(new AsyncJobJoinVO[result.first().size()]));
|
||||||
response.setResponses(jobResponses, result.second());
|
response.setResponses(jobResponses, result.second());
|
||||||
return response;
|
return response;
|
||||||
@ -3021,9 +3020,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
|
|
||||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
List<Long> permittedAccounts = new ArrayList<>();
|
||||||
|
|
||||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(), cmd.isRecursive(), null);
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(cmd.getDomainId(), cmd.isRecursive(), null);
|
||||||
accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), null, permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
accountMgr.buildACLSearchParameters(caller, null, cmd.getAccountName(), null, permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
||||||
Long domainId = domainIdRecursiveListProject.first();
|
Long domainId = domainIdRecursiveListProject.first();
|
||||||
Boolean isRecursive = domainIdRecursiveListProject.second();
|
Boolean isRecursive = domainIdRecursiveListProject.second();
|
||||||
@ -3183,7 +3182,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<StorageTagResponse> searchForStorageTags(ListStorageTagsCmd cmd) {
|
public ListResponse<StorageTagResponse> searchForStorageTags(ListStorageTagsCmd cmd) {
|
||||||
Pair<List<StoragePoolTagVO>, Integer> result = searchForStorageTagsInternal(cmd);
|
Pair<List<StoragePoolTagVO>, Integer> result = searchForStorageTagsInternal(cmd);
|
||||||
ListResponse<StorageTagResponse> response = new ListResponse<StorageTagResponse>();
|
ListResponse<StorageTagResponse> response = new ListResponse<>();
|
||||||
List<StorageTagResponse> tagResponses = ViewResponseHelper.createStorageTagResponse(result.first().toArray(new StoragePoolTagVO[result.first().size()]));
|
List<StorageTagResponse> tagResponses = ViewResponseHelper.createStorageTagResponse(result.first().toArray(new StoragePoolTagVO[result.first().size()]));
|
||||||
|
|
||||||
response.setResponses(tagResponses, result.second());
|
response.setResponses(tagResponses, result.second());
|
||||||
@ -3218,13 +3217,13 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
List<StoragePoolTagVO> vrs = _storageTagDao.searchByIds(vrIds);
|
List<StoragePoolTagVO> vrs = _storageTagDao.searchByIds(vrIds);
|
||||||
|
|
||||||
return new Pair<List<StoragePoolTagVO>, Integer>(vrs, count);
|
return new Pair<>(vrs, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListResponse<HostTagResponse> searchForHostTags(ListHostTagsCmd cmd) {
|
public ListResponse<HostTagResponse> searchForHostTags(ListHostTagsCmd cmd) {
|
||||||
Pair<List<HostTagVO>, Integer> result = searchForHostTagsInternal(cmd);
|
Pair<List<HostTagVO>, Integer> result = searchForHostTagsInternal(cmd);
|
||||||
ListResponse<HostTagResponse> response = new ListResponse<HostTagResponse>();
|
ListResponse<HostTagResponse> response = new ListResponse<>();
|
||||||
List<HostTagResponse> tagResponses = ViewResponseHelper.createHostTagResponse(result.first().toArray(new HostTagVO[result.first().size()]));
|
List<HostTagResponse> tagResponses = ViewResponseHelper.createHostTagResponse(result.first().toArray(new HostTagVO[result.first().size()]));
|
||||||
|
|
||||||
response.setResponses(tagResponses, result.second());
|
response.setResponses(tagResponses, result.second());
|
||||||
@ -3259,7 +3258,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
List<HostTagVO> vrs = _hostTagDao.searchByIds(vrIds);
|
List<HostTagVO> vrs = _hostTagDao.searchByIds(vrIds);
|
||||||
|
|
||||||
return new Pair<List<HostTagVO>, Integer>(vrs, count);
|
return new Pair<>(vrs, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -3342,14 +3341,14 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
vrIds[i++] = v.getId();
|
vrIds[i++] = v.getId();
|
||||||
}
|
}
|
||||||
List<ImageStoreJoinVO> vrs = _imageStoreJoinDao.searchByIds(vrIds);
|
List<ImageStoreJoinVO> vrs = _imageStoreJoinDao.searchByIds(vrIds);
|
||||||
return new Pair<List<ImageStoreJoinVO>, Integer>(vrs, count);
|
return new Pair<>(vrs, count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListResponse<ImageStoreResponse> searchForSecondaryStagingStores(ListSecondaryStagingStoresCmd cmd) {
|
public ListResponse<ImageStoreResponse> searchForSecondaryStagingStores(ListSecondaryStagingStoresCmd cmd) {
|
||||||
Pair<List<ImageStoreJoinVO>, Integer> result = searchForCacheStoresInternal(cmd);
|
Pair<List<ImageStoreJoinVO>, Integer> result = searchForCacheStoresInternal(cmd);
|
||||||
ListResponse<ImageStoreResponse> response = new ListResponse<ImageStoreResponse>();
|
ListResponse<ImageStoreResponse> response = new ListResponse<>();
|
||||||
|
|
||||||
List<ImageStoreResponse> poolResponses = ViewResponseHelper.createImageStoreResponse(result.first().toArray(new ImageStoreJoinVO[result.first().size()]));
|
List<ImageStoreResponse> poolResponses = ViewResponseHelper.createImageStoreResponse(result.first().toArray(new ImageStoreJoinVO[result.first().size()]));
|
||||||
response.setResponses(poolResponses, result.second());
|
response.setResponses(poolResponses, result.second());
|
||||||
@ -3421,7 +3420,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
vrIds[i++] = v.getId();
|
vrIds[i++] = v.getId();
|
||||||
}
|
}
|
||||||
List<ImageStoreJoinVO> vrs = _imageStoreJoinDao.searchByIds(vrIds);
|
List<ImageStoreJoinVO> vrs = _imageStoreJoinDao.searchByIds(vrIds);
|
||||||
return new Pair<List<ImageStoreJoinVO>, Integer>(vrs, count);
|
return new Pair<>(vrs, count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4245,7 +4244,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<ZoneResponse> listDataCenters(ListZonesCmd cmd) {
|
public ListResponse<ZoneResponse> listDataCenters(ListZonesCmd cmd) {
|
||||||
Pair<List<DataCenterJoinVO>, Integer> result = listDataCentersInternal(cmd);
|
Pair<List<DataCenterJoinVO>, Integer> result = listDataCentersInternal(cmd);
|
||||||
ListResponse<ZoneResponse> response = new ListResponse<ZoneResponse>();
|
ListResponse<ZoneResponse> response = new ListResponse<>();
|
||||||
|
|
||||||
ResponseView respView = ResponseView.Restricted;
|
ResponseView respView = ResponseView.Restricted;
|
||||||
if (cmd instanceof ListZonesCmdByAdmin || CallContext.current().getCallingAccount().getType() == Account.Type.ADMIN) {
|
if (cmd instanceof ListZonesCmdByAdmin || CallContext.current().getCallingAccount().getType() == Account.Type.ADMIN) {
|
||||||
@ -4332,7 +4331,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
// list
|
// list
|
||||||
|
|
||||||
// find all domain Id up to root domain for this account
|
// find all domain Id up to root domain for this account
|
||||||
List<Long> domainIds = new ArrayList<Long>();
|
List<Long> domainIds = new ArrayList<>();
|
||||||
DomainVO domainRecord = _domainDao.findById(account.getDomainId());
|
DomainVO domainRecord = _domainDao.findById(account.getDomainId());
|
||||||
if (domainRecord == null) {
|
if (domainRecord == null) {
|
||||||
logger.error("Could not find the domainId for account: {}", account);
|
logger.error("Could not find the domainId for account: {}", account);
|
||||||
@ -4372,7 +4371,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
// it was decided to return all zones for the domain admin, and
|
// it was decided to return all zones for the domain admin, and
|
||||||
// everything above till root, as well as zones till the domain
|
// everything above till root, as well as zones till the domain
|
||||||
// leaf
|
// leaf
|
||||||
List<Long> domainIds = new ArrayList<Long>();
|
List<Long> domainIds = new ArrayList<>();
|
||||||
DomainVO domainRecord = _domainDao.findById(account.getDomainId());
|
DomainVO domainRecord = _domainDao.findById(account.getDomainId());
|
||||||
if (domainRecord == null) {
|
if (domainRecord == null) {
|
||||||
logger.error("Could not find the domainId for account: {}", account);
|
logger.error("Could not find the domainId for account: {}", account);
|
||||||
@ -4412,8 +4411,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
// one VM running there
|
// one VM running there
|
||||||
Boolean available = cmd.isAvailable();
|
Boolean available = cmd.isAvailable();
|
||||||
if (account != null) {
|
if (account != null) {
|
||||||
if ((available != null) && Boolean.FALSE.equals(available)) {
|
if (Boolean.FALSE.equals(available)) {
|
||||||
Set<Long> dcIds = new HashSet<Long>(); // data centers with
|
Set<Long> dcIds = new HashSet<>(); // data centers with
|
||||||
// at least one VM
|
// at least one VM
|
||||||
// running
|
// running
|
||||||
List<DomainRouterVO> routers = _routerDao.listBy(account.getId());
|
List<DomainRouterVO> routers = _routerDao.listBy(account.getId());
|
||||||
@ -4421,7 +4420,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
dcIds.add(router.getDataCenterId());
|
dcIds.add(router.getDataCenterId());
|
||||||
}
|
}
|
||||||
if (dcIds.size() == 0) {
|
if (dcIds.size() == 0) {
|
||||||
return new Pair<List<DataCenterJoinVO>, Integer>(new ArrayList<DataCenterJoinVO>(), 0);
|
return new Pair<>(new ArrayList<>(), 0);
|
||||||
} else {
|
} else {
|
||||||
sc.addAnd("id", SearchCriteria.Op.IN, dcIds.toArray());
|
sc.addAnd("id", SearchCriteria.Op.IN, dcIds.toArray());
|
||||||
}
|
}
|
||||||
@ -4445,7 +4444,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
private List<Long> removeDedicatedZoneNotSuitabe(List<Long> domainIds) {
|
private List<Long> removeDedicatedZoneNotSuitabe(List<Long> domainIds) {
|
||||||
// remove dedicated zone of other domain
|
// remove dedicated zone of other domain
|
||||||
List<Long> dedicatedZoneIds = new ArrayList<Long>();
|
List<Long> dedicatedZoneIds = new ArrayList<>();
|
||||||
List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listZonesNotInDomainIds(domainIds);
|
List<DedicatedResourceVO> dedicatedResources = _dedicatedDao.listZonesNotInDomainIds(domainIds);
|
||||||
for (DedicatedResourceVO dr : dedicatedResources) {
|
for (DedicatedResourceVO dr : dedicatedResources) {
|
||||||
if (dr != null) {
|
if (dr != null) {
|
||||||
@ -4486,7 +4485,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
@Override
|
@Override
|
||||||
public ListResponse<TemplateResponse> listTemplates(ListTemplatesCmd cmd) {
|
public ListResponse<TemplateResponse> listTemplates(ListTemplatesCmd cmd) {
|
||||||
Pair<List<TemplateJoinVO>, Integer> result = searchForTemplatesInternal(cmd);
|
Pair<List<TemplateJoinVO>, Integer> result = searchForTemplatesInternal(cmd);
|
||||||
ListResponse<TemplateResponse> response = new ListResponse<TemplateResponse>();
|
ListResponse<TemplateResponse> response = new ListResponse<>();
|
||||||
|
|
||||||
ResponseView respView = ResponseView.Restricted;
|
ResponseView respView = ResponseView.Restricted;
|
||||||
if (cmd instanceof ListTemplatesCmdByAdmin) {
|
if (cmd instanceof ListTemplatesCmdByAdmin) {
|
||||||
@ -4514,14 +4513,14 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
listAll = true;
|
listAll = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Long> permittedAccountIds = new ArrayList<Long>();
|
List<Long> permittedAccountIds = new ArrayList<>();
|
||||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(cmd.getDomainId(), cmd.isRecursive(), null);
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(cmd.getDomainId(), cmd.isRecursive(), null);
|
||||||
accountMgr.buildACLSearchParameters(
|
accountMgr.buildACLSearchParameters(
|
||||||
caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds,
|
caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds,
|
||||||
domainIdRecursiveListProject, listAll, false
|
domainIdRecursiveListProject, listAll, false
|
||||||
);
|
);
|
||||||
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
|
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
|
||||||
List<Account> permittedAccounts = new ArrayList<Account>();
|
List<Account> permittedAccounts = new ArrayList<>();
|
||||||
for (Long accountId : permittedAccountIds) {
|
for (Long accountId : permittedAccountIds) {
|
||||||
permittedAccounts.add(accountMgr.getAccount(accountId));
|
permittedAccounts.add(accountMgr.getAccount(accountId));
|
||||||
}
|
}
|
||||||
@ -4559,11 +4558,11 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
if (!isIso) {
|
if (!isIso) {
|
||||||
hypers = _resourceMgr.listAvailHypervisorInZone(null);
|
hypers = _resourceMgr.listAvailHypervisorInZone(null);
|
||||||
if (hypers == null || hypers.isEmpty()) {
|
if (hypers == null || hypers.isEmpty()) {
|
||||||
return new Pair<List<TemplateJoinVO>, Integer>(new ArrayList<TemplateJoinVO>(), 0);
|
return new Pair<>(new ArrayList<>(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VMTemplateVO template = null;
|
VMTemplateVO template;
|
||||||
|
|
||||||
Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", SortKeyAscending.value(), startIndex, pageSize);
|
Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", SortKeyAscending.value(), startIndex, pageSize);
|
||||||
searchFilter.addOrderBy(TemplateJoinVO.class, "tempZonePair", SortKeyAscending.value());
|
searchFilter.addOrderBy(TemplateJoinVO.class, "tempZonePair", SortKeyAscending.value());
|
||||||
@ -4634,7 +4633,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sc.addAnd("id", SearchCriteria.Op.EQ, templateId);
|
sc.addAnd("id", SearchCriteria.Op.EQ, templateId);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
DomainVO domain = null;
|
DomainVO domain;
|
||||||
if (!permittedAccounts.isEmpty()) {
|
if (!permittedAccounts.isEmpty()) {
|
||||||
domain = _domainDao.findById(permittedAccounts.get(0).getDomainId());
|
domain = _domainDao.findById(permittedAccounts.get(0).getDomainId());
|
||||||
} else {
|
} else {
|
||||||
@ -4656,15 +4655,15 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%");
|
sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Long> relatedDomainIds = new ArrayList<Long>();
|
List<Long> relatedDomainIds = new ArrayList<>();
|
||||||
List<Long> permittedAccountIds = new ArrayList<Long>();
|
List<Long> permittedAccountIds = new ArrayList<>();
|
||||||
if (!permittedAccounts.isEmpty()) {
|
if (!permittedAccounts.isEmpty()) {
|
||||||
for (Account account : permittedAccounts) {
|
for (Account account : permittedAccounts) {
|
||||||
permittedAccountIds.add(account.getId());
|
permittedAccountIds.add(account.getId());
|
||||||
boolean publicTemplates = (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community);
|
boolean publicTemplates = (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community);
|
||||||
|
|
||||||
// get all parent domain ID's all the way till root domain
|
// get all parent domain ID's all the way till root domain
|
||||||
DomainVO domainTreeNode = null;
|
DomainVO domainTreeNode;
|
||||||
//if template filter is featured, or community, all child domains should be included in search
|
//if template filter is featured, or community, all child domains should be included in search
|
||||||
if (publicTemplates) {
|
if (publicTemplates) {
|
||||||
domainTreeNode = _domainDao.findById(Domain.ROOT_DOMAIN);
|
domainTreeNode = _domainDao.findById(Domain.ROOT_DOMAIN);
|
||||||
@ -4895,7 +4894,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
// sc.addAnd("removed", SearchCriteria.Op.NULL);
|
// sc.addAnd("removed", SearchCriteria.Op.NULL);
|
||||||
|
|
||||||
// search unique templates and find details by Ids
|
// search unique templates and find details by Ids
|
||||||
Pair<List<TemplateJoinVO>, Integer> uniqueTmplPair = null;
|
Pair<List<TemplateJoinVO>, Integer> uniqueTmplPair;
|
||||||
if (showRemovedTmpl) {
|
if (showRemovedTmpl) {
|
||||||
uniqueTmplPair = _templateJoinDao.searchIncludingRemovedAndCount(sc, searchFilter);
|
uniqueTmplPair = _templateJoinDao.searchIncludingRemovedAndCount(sc, searchFilter);
|
||||||
} else {
|
} else {
|
||||||
@ -4926,7 +4925,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
return templateDataPair;
|
return templateDataPair;
|
||||||
}
|
}
|
||||||
List<TemplateJoinVO> templateData = templateDataPair.first();
|
List<TemplateJoinVO> templateData = templateDataPair.first();
|
||||||
List<TemplateJoinVO> templates = null;
|
List<TemplateJoinVO> templates;
|
||||||
if (showUnique) {
|
if (showUnique) {
|
||||||
Long[] templateIds = templateData.stream().map(template -> template.getId()).toArray(Long[]::new);
|
Long[] templateIds = templateData.stream().map(template -> template.getId()).toArray(Long[]::new);
|
||||||
templates = _templateJoinDao.findByDistinctIds(templateIds);
|
templates = _templateJoinDao.findByDistinctIds(templateIds);
|
||||||
@ -4935,7 +4934,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
templates = _templateJoinDao.searchByTemplateZonePair(showRemoved, templateZonePairs);
|
templates = _templateJoinDao.searchByTemplateZonePair(showRemoved, templateZonePairs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Pair<List<TemplateJoinVO>, Integer>(templates, count);
|
return new Pair<>(templates, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -5056,7 +5055,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
if (HypervisorType.KVM.equals(hypervisorType)) {
|
if (HypervisorType.KVM.equals(hypervisorType)) {
|
||||||
options.put(VmDetailConstants.CPU_THREAD_PER_CORE, Collections.emptyList());
|
options.put(VmDetailConstants.CPU_THREAD_PER_CORE, Collections.emptyList());
|
||||||
options.put(VmDetailConstants.NIC_ADAPTER, Arrays.asList("e1000", "virtio", "rtl8139", "vmxnet3", "ne2k_pci"));
|
options.put(VmDetailConstants.NIC_ADAPTER, Arrays.asList("e1000", "virtio", "rtl8139", "vmxnet3", "ne2k_pci"));
|
||||||
options.put(VmDetailConstants.ROOT_DISK_CONTROLLER, Arrays.asList("osdefault", "ide", "scsi", "virtio"));
|
options.put(VmDetailConstants.ROOT_DISK_CONTROLLER, Arrays.asList("osdefault", "ide", "scsi", "virtio", "virtio-blk"));
|
||||||
options.put(VmDetailConstants.VIDEO_HARDWARE, Arrays.asList("cirrus", "vga", "qxl", "virtio"));
|
options.put(VmDetailConstants.VIDEO_HARDWARE, Arrays.asList("cirrus", "vga", "qxl", "virtio"));
|
||||||
options.put(VmDetailConstants.VIDEO_RAM, Collections.emptyList());
|
options.put(VmDetailConstants.VIDEO_RAM, Collections.emptyList());
|
||||||
options.put(VmDetailConstants.IO_POLICY, Arrays.asList("threads", "native", "io_uring", "storage_specific"));
|
options.put(VmDetailConstants.IO_POLICY, Arrays.asList("threads", "native", "io_uring", "storage_specific"));
|
||||||
@ -5110,8 +5109,8 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
return listAffinityGroupsByVM(vmId.longValue(), startIndex, pageSize);
|
return listAffinityGroupsByVM(vmId.longValue(), startIndex, pageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
List<Long> permittedAccounts = new ArrayList<>();
|
||||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> ternary = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> ternary = new Ternary<>(domainId, isRecursive, null);
|
||||||
|
|
||||||
accountMgr.buildACLSearchParameters(caller, affinityGroupId, accountName, projectId, permittedAccounts, ternary, listAll, false);
|
accountMgr.buildACLSearchParameters(caller, affinityGroupId, accountName, projectId, permittedAccounts, ternary, listAll, false);
|
||||||
|
|
||||||
@ -5127,7 +5126,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Pair<List<AffinityGroupJoinVO>, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, searchFilter);
|
Pair<List<AffinityGroupJoinVO>, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, searchFilter);
|
||||||
|
|
||||||
// search group details by ids
|
// search group details by ids
|
||||||
List<AffinityGroupJoinVO> affinityGroups = new ArrayList<AffinityGroupJoinVO>();
|
List<AffinityGroupJoinVO> affinityGroups = new ArrayList<>();
|
||||||
|
|
||||||
Integer count = uniqueGroupsPair.second();
|
Integer count = uniqueGroupsPair.second();
|
||||||
if (count.intValue() != 0) {
|
if (count.intValue() != 0) {
|
||||||
@ -5143,7 +5142,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
if (!permittedAccounts.isEmpty()) {
|
if (!permittedAccounts.isEmpty()) {
|
||||||
// add domain level affinity groups
|
// add domain level affinity groups
|
||||||
if (domainId != null) {
|
if (domainId != null) {
|
||||||
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria, affinityGroupId,
|
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<>(), listProjectResourcesCriteria, affinityGroupId,
|
||||||
affinityGroupName, affinityGroupType, keyword);
|
affinityGroupName, affinityGroupType, keyword);
|
||||||
Pair<List<AffinityGroupJoinVO>, Integer> groupsPair = listDomainLevelAffinityGroups(scDomain, searchFilter, domainId);
|
Pair<List<AffinityGroupJoinVO>, Integer> groupsPair = listDomainLevelAffinityGroups(scDomain, searchFilter, domainId);
|
||||||
affinityGroups.addAll(groupsPair.first());
|
affinityGroups.addAll(groupsPair.first());
|
||||||
@ -5152,7 +5151,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
for (Long permAcctId : permittedAccounts) {
|
for (Long permAcctId : permittedAccounts) {
|
||||||
Account permittedAcct = _accountDao.findById(permAcctId);
|
Account permittedAcct = _accountDao.findById(permAcctId);
|
||||||
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria, affinityGroupId,
|
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<>(), listProjectResourcesCriteria, affinityGroupId,
|
||||||
affinityGroupName, affinityGroupType, keyword);
|
affinityGroupName, affinityGroupType, keyword);
|
||||||
Pair<List<AffinityGroupJoinVO>, Integer> groupsPair = listDomainLevelAffinityGroups(scDomain, searchFilter, permittedAcct.getDomainId());
|
Pair<List<AffinityGroupJoinVO>, Integer> groupsPair = listDomainLevelAffinityGroups(scDomain, searchFilter, permittedAcct.getDomainId());
|
||||||
affinityGroups.addAll(groupsPair.first());
|
affinityGroups.addAll(groupsPair.first());
|
||||||
@ -5161,14 +5160,14 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
}
|
}
|
||||||
} else if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
|
} else if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
|
||||||
// list all domain level affinity groups for the domain admin case
|
// list all domain level affinity groups for the domain admin case
|
||||||
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria, affinityGroupId, affinityGroupName,
|
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<>(), listProjectResourcesCriteria, affinityGroupId, affinityGroupName,
|
||||||
affinityGroupType, keyword);
|
affinityGroupType, keyword);
|
||||||
Pair<List<AffinityGroupJoinVO>, Integer> groupsPair = listDomainLevelAffinityGroups(scDomain, searchFilter, domainId);
|
Pair<List<AffinityGroupJoinVO>, Integer> groupsPair = listDomainLevelAffinityGroups(scDomain, searchFilter, domainId);
|
||||||
affinityGroups.addAll(groupsPair.first());
|
affinityGroups.addAll(groupsPair.first());
|
||||||
count += groupsPair.second();
|
count += groupsPair.second();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Pair<List<AffinityGroupJoinVO>, Integer>(affinityGroups, count);
|
return new Pair<>(affinityGroups, count);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5254,7 +5253,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Integer count = agVmMappingPair.second();
|
Integer count = agVmMappingPair.second();
|
||||||
if (count.intValue() == 0) {
|
if (count.intValue() == 0) {
|
||||||
// handle empty result cases
|
// handle empty result cases
|
||||||
return new Pair<List<AffinityGroupJoinVO>, Integer>(new ArrayList<AffinityGroupJoinVO>(), count);
|
return new Pair<>(new ArrayList<>(), count);
|
||||||
}
|
}
|
||||||
List<AffinityGroupVMMapVO> agVmMappings = agVmMappingPair.first();
|
List<AffinityGroupVMMapVO> agVmMappings = agVmMappingPair.first();
|
||||||
Long[] agIds = new Long[agVmMappings.size()];
|
Long[] agIds = new Long[agVmMappings.size()];
|
||||||
@ -5263,11 +5262,11 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
agIds[i++] = agVm.getAffinityGroupId();
|
agIds[i++] = agVm.getAffinityGroupId();
|
||||||
}
|
}
|
||||||
List<AffinityGroupJoinVO> ags = _affinityGroupJoinDao.searchByIds(agIds);
|
List<AffinityGroupJoinVO> ags = _affinityGroupJoinDao.searchByIds(agIds);
|
||||||
return new Pair<List<AffinityGroupJoinVO>, Integer>(ags, count);
|
return new Pair<>(ags, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<List<AffinityGroupJoinVO>, Integer> listDomainLevelAffinityGroups(SearchCriteria<AffinityGroupJoinVO> sc, Filter searchFilter, long domainId) {
|
private Pair<List<AffinityGroupJoinVO>, Integer> listDomainLevelAffinityGroups(SearchCriteria<AffinityGroupJoinVO> sc, Filter searchFilter, long domainId) {
|
||||||
List<Long> affinityGroupIds = new ArrayList<Long>();
|
List<Long> affinityGroupIds = new ArrayList<>();
|
||||||
Set<Long> allowedDomains = _domainMgr.getDomainParentIds(domainId);
|
Set<Long> allowedDomains = _domainMgr.getDomainParentIds(domainId);
|
||||||
List<AffinityGroupDomainMapVO> maps = _affinityGroupDomainMapDao.listByDomain(allowedDomains.toArray());
|
List<AffinityGroupDomainMapVO> maps = _affinityGroupDomainMapDao.listByDomain(allowedDomains.toArray());
|
||||||
|
|
||||||
@ -5290,7 +5289,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Integer count = uniqueGroupsPair.second();
|
Integer count = uniqueGroupsPair.second();
|
||||||
if (count.intValue() == 0) {
|
if (count.intValue() == 0) {
|
||||||
// empty result
|
// empty result
|
||||||
return new Pair<>(new ArrayList<AffinityGroupJoinVO>(), 0);
|
return new Pair<>(new ArrayList<>(), 0);
|
||||||
}
|
}
|
||||||
List<AffinityGroupJoinVO> uniqueGroups = uniqueGroupsPair.first();
|
List<AffinityGroupJoinVO> uniqueGroups = uniqueGroupsPair.first();
|
||||||
Long[] vrIds = new Long[uniqueGroups.size()];
|
Long[] vrIds = new Long[uniqueGroups.size()];
|
||||||
@ -5301,7 +5300,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
List<AffinityGroupJoinVO> vrs = _affinityGroupJoinDao.searchByIds(vrIds);
|
List<AffinityGroupJoinVO> vrs = _affinityGroupJoinDao.searchByIds(vrIds);
|
||||||
return new Pair<>(vrs, count);
|
return new Pair<>(vrs, count);
|
||||||
} else {
|
} else {
|
||||||
return new Pair<>(new ArrayList<AffinityGroupJoinVO>(), 0);
|
return new Pair<>(new ArrayList<>(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5332,7 +5331,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<? extends ResourceDetail> detailList = new ArrayList<ResourceDetail>();
|
List<? extends ResourceDetail> detailList = new ArrayList<>();
|
||||||
ResourceDetail requestedDetail = null;
|
ResourceDetail requestedDetail = null;
|
||||||
|
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
@ -5346,7 +5345,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
detailList = _resourceMetaDataMgr.getDetails(resourceType, key, value, forDisplay);
|
detailList = _resourceMetaDataMgr.getDetails(resourceType, key, value, forDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ResourceDetailResponse> responseList = new ArrayList<ResourceDetailResponse>();
|
List<ResourceDetailResponse> responseList = new ArrayList<>();
|
||||||
if (requestedDetail != null) {
|
if (requestedDetail != null) {
|
||||||
ResourceDetailResponse detailResponse = createResourceDetailsResponse(requestedDetail, resourceType);
|
ResourceDetailResponse detailResponse = createResourceDetailsResponse(requestedDetail, resourceType);
|
||||||
responseList.add(detailResponse);
|
responseList.add(detailResponse);
|
||||||
@ -5596,7 +5595,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Filter searchFilter = new Filter(SnapshotJoinVO.class, "snapshotStorePair", SortKeyAscending.value(), startIndex, pageSize);
|
Filter searchFilter = new Filter(SnapshotJoinVO.class, "snapshotStorePair", SortKeyAscending.value(), startIndex, pageSize);
|
||||||
|
|
||||||
List<Long> permittedAccountIds = new ArrayList<>();
|
List<Long> permittedAccountIds = new ArrayList<>();
|
||||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(domainId, isRecursive, null);
|
||||||
accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccountIds, domainIdRecursiveListProject, listAll, false);
|
accountMgr.buildACLSearchParameters(caller, id, accountName, projectId, permittedAccountIds, domainIdRecursiveListProject, listAll, false);
|
||||||
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
|
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
|
||||||
domainId = domainIdRecursiveListProject.first();
|
domainId = domainIdRecursiveListProject.first();
|
||||||
@ -5729,7 +5728,6 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
Integer count = snapshotDataPair.second();
|
Integer count = snapshotDataPair.second();
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
// empty result
|
|
||||||
return snapshotDataPair;
|
return snapshotDataPair;
|
||||||
}
|
}
|
||||||
List<SnapshotJoinVO> snapshotData = snapshotDataPair.first();
|
List<SnapshotJoinVO> snapshotData = snapshotDataPair.first();
|
||||||
@ -5739,13 +5737,12 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
} else {
|
} else {
|
||||||
snapshots = snapshotJoinDao.searchBySnapshotStorePair(snapshotData.stream().map(SnapshotJoinVO::getSnapshotStorePair).toArray(String[]::new));
|
snapshots = snapshotJoinDao.searchBySnapshotStorePair(snapshotData.stream().map(SnapshotJoinVO::getSnapshotStorePair).toArray(String[]::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Pair<>(snapshots, count);
|
return new Pair<>(snapshots, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListResponse<ObjectStoreResponse> searchForObjectStores(ListObjectStoragePoolsCmd cmd) {
|
public ListResponse<ObjectStoreResponse> searchForObjectStores(ListObjectStoragePoolsCmd cmd) {
|
||||||
Pair<List<ObjectStoreVO>, Integer> result = searchForObjectStoresInternal(cmd);
|
Pair<List<ObjectStoreVO>, Integer> result = searchForObjectStoresInternal(cmd);
|
||||||
ListResponse<ObjectStoreResponse> response = new ListResponse<ObjectStoreResponse>();
|
ListResponse<ObjectStoreResponse> response = new ListResponse<>();
|
||||||
|
|
||||||
List<ObjectStoreResponse> poolResponses = ViewResponseHelper.createObjectStoreResponse(result.first().toArray(new ObjectStoreVO[result.first().size()]));
|
List<ObjectStoreResponse> poolResponses = ViewResponseHelper.createObjectStoreResponse(result.first().toArray(new ObjectStoreVO[result.first().size()]));
|
||||||
response.setResponses(poolResponses, result.second());
|
response.setResponses(poolResponses, result.second());
|
||||||
@ -5830,7 +5827,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
Long startIndex = cmd.getStartIndex();
|
Long startIndex = cmd.getStartIndex();
|
||||||
Long pageSize = cmd.getPageSizeVal();
|
Long pageSize = cmd.getPageSizeVal();
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = CallContext.current().getCallingAccount();
|
||||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
List<Long> permittedAccounts = new ArrayList<>();
|
||||||
|
|
||||||
// Verify parameters
|
// Verify parameters
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
@ -5842,7 +5839,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||||||
|
|
||||||
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
|
List<Long> ids = getIdsListFromCmd(cmd.getId(), cmd.getIds());
|
||||||
|
|
||||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(),
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<>(cmd.getDomainId(),
|
||||||
cmd.isRecursive(), null);
|
cmd.isRecursive(), null);
|
||||||
accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false);
|
||||||
Long domainId = domainIdRecursiveListProject.first();
|
Long domainId = domainIdRecursiveListProject.first();
|
||||||
|
|||||||
@ -23,10 +23,7 @@ import org.apache.cloudstack.api.ResponseObject;
|
|||||||
import org.apache.cloudstack.api.response.SnapshotResponse;
|
import org.apache.cloudstack.api.response.SnapshotResponse;
|
||||||
|
|
||||||
import com.cloud.api.query.vo.SnapshotJoinVO;
|
import com.cloud.api.query.vo.SnapshotJoinVO;
|
||||||
import com.cloud.utils.Pair;
|
|
||||||
import com.cloud.utils.db.Filter;
|
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
|
||||||
|
|
||||||
public interface SnapshotJoinDao extends GenericDao<SnapshotJoinVO, Long> {
|
public interface SnapshotJoinDao extends GenericDao<SnapshotJoinVO, Long> {
|
||||||
|
|
||||||
@ -34,8 +31,7 @@ public interface SnapshotJoinDao extends GenericDao<SnapshotJoinVO, Long> {
|
|||||||
|
|
||||||
SnapshotResponse setSnapshotResponse(SnapshotResponse snapshotResponse, SnapshotJoinVO snapshot);
|
SnapshotResponse setSnapshotResponse(SnapshotResponse snapshotResponse, SnapshotJoinVO snapshot);
|
||||||
|
|
||||||
Pair<List<SnapshotJoinVO>, Integer> searchIncludingRemovedAndCount(final SearchCriteria<SnapshotJoinVO> sc, final Filter filter);
|
|
||||||
|
|
||||||
List<SnapshotJoinVO> searchBySnapshotStorePair(String... pairs);
|
List<SnapshotJoinVO> searchBySnapshotStorePair(String... pairs);
|
||||||
|
|
||||||
List<SnapshotJoinVO> findByDistinctIds(Long zoneId, Long... ids);
|
List<SnapshotJoinVO> findByDistinctIds(Long zoneId, Long... ids);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,8 @@
|
|||||||
package com.cloud.api.query.dao;
|
package com.cloud.api.query.dao;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -34,6 +36,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
|||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
import org.apache.cloudstack.query.QueryService;
|
import org.apache.cloudstack.query.QueryService;
|
||||||
|
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
import com.cloud.api.ApiDBUtils;
|
import com.cloud.api.ApiDBUtils;
|
||||||
import com.cloud.api.ApiResponseHelper;
|
import com.cloud.api.ApiResponseHelper;
|
||||||
import com.cloud.api.query.vo.SnapshotJoinVO;
|
import com.cloud.api.query.vo.SnapshotJoinVO;
|
||||||
@ -44,7 +48,6 @@ import com.cloud.storage.Volume.Type;
|
|||||||
import com.cloud.storage.VolumeVO;
|
import com.cloud.storage.VolumeVO;
|
||||||
import com.cloud.user.Account;
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.AccountService;
|
import com.cloud.user.AccountService;
|
||||||
import com.cloud.utils.Pair;
|
|
||||||
import com.cloud.utils.db.Filter;
|
import com.cloud.utils.db.Filter;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
@ -53,11 +56,11 @@ import com.cloud.vm.VMInstanceVO;
|
|||||||
public class SnapshotJoinDaoImpl extends GenericDaoBaseWithTagInformation<SnapshotJoinVO, SnapshotResponse> implements SnapshotJoinDao {
|
public class SnapshotJoinDaoImpl extends GenericDaoBaseWithTagInformation<SnapshotJoinVO, SnapshotResponse> implements SnapshotJoinDao {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private AccountService accountService;
|
AccountService accountService;
|
||||||
@Inject
|
@Inject
|
||||||
private AnnotationDao annotationDao;
|
AnnotationDao annotationDao;
|
||||||
@Inject
|
@Inject
|
||||||
private ConfigurationDao configDao;
|
ConfigurationDao configDao;
|
||||||
@Inject
|
@Inject
|
||||||
SnapshotDataFactory snapshotDataFactory;
|
SnapshotDataFactory snapshotDataFactory;
|
||||||
|
|
||||||
@ -85,7 +88,7 @@ public class SnapshotJoinDaoImpl extends GenericDaoBaseWithTagInformation<Snapsh
|
|||||||
if (snapshot.getDataCenterId() == null) {
|
if (snapshot.getDataCenterId() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SnapshotInfo snapshotInfo = null;
|
SnapshotInfo snapshotInfo;
|
||||||
snapshotInfo = snapshotDataFactory.getSnapshotWithRoleAndZone(snapshot.getId(), snapshot.getStoreRole(), snapshot.getDataCenterId());
|
snapshotInfo = snapshotDataFactory.getSnapshotWithRoleAndZone(snapshot.getId(), snapshot.getStoreRole(), snapshot.getDataCenterId());
|
||||||
if (snapshotInfo == null) {
|
if (snapshotInfo == null) {
|
||||||
logger.debug("Unable to find info for image store snapshot {}", snapshot);
|
logger.debug("Unable to find info for image store snapshot {}", snapshot);
|
||||||
@ -192,13 +195,6 @@ public class SnapshotJoinDaoImpl extends GenericDaoBaseWithTagInformation<Snapsh
|
|||||||
return snapshotResponse;
|
return snapshotResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Pair<List<SnapshotJoinVO>, Integer> searchIncludingRemovedAndCount(final SearchCriteria<SnapshotJoinVO> sc, final Filter filter) {
|
|
||||||
List<SnapshotJoinVO> objects = searchIncludingRemoved(sc, filter, null, false);
|
|
||||||
Integer count = getDistinctCount(sc);
|
|
||||||
return new Pair<>(objects, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<SnapshotJoinVO> searchBySnapshotStorePair(String... pairs) {
|
public List<SnapshotJoinVO> searchBySnapshotStorePair(String... pairs) {
|
||||||
// set detail batch query size
|
// set detail batch query size
|
||||||
@ -243,14 +239,33 @@ public class SnapshotJoinDaoImpl extends GenericDaoBaseWithTagInformation<Snapsh
|
|||||||
return uvList;
|
return uvList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected List<SnapshotJoinVO> findById(Long zoneId, long id) {
|
||||||
|
SearchBuilder<SnapshotJoinVO> sb = createSearchBuilder();
|
||||||
|
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
|
||||||
|
sb.and("zoneId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||||
|
sb.done();
|
||||||
|
SearchCriteria<SnapshotJoinVO> sc = sb.create();
|
||||||
|
sc.setParameters("id", id);
|
||||||
|
if (zoneId != null) {
|
||||||
|
sc.setParameters("zoneId", zoneId);
|
||||||
|
}
|
||||||
|
List<SnapshotJoinVO> snapshotJoinVOS = search(sc, null);
|
||||||
|
if (CollectionUtils.isEmpty(snapshotJoinVOS)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
snapshotJoinVOS.sort(Comparator.comparing(SnapshotJoinVO::getSnapshotStorePair));
|
||||||
|
return Collections.singletonList(snapshotJoinVOS.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<SnapshotJoinVO> findByDistinctIds(Long zoneId, Long... ids) {
|
public List<SnapshotJoinVO> findByDistinctIds(Long zoneId, Long... ids) {
|
||||||
if (ids == null || ids.length == 0) {
|
if (ids == null || ids.length == 0) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
if (ids.length == 1) {
|
||||||
|
return findById(zoneId, ids[0]);
|
||||||
|
}
|
||||||
Filter searchFilter = new Filter(SnapshotJoinVO.class, "snapshotStorePair", QueryService.SortKeyAscending.value(), null, null);
|
Filter searchFilter = new Filter(SnapshotJoinVO.class, "snapshotStorePair", QueryService.SortKeyAscending.value(), null, null);
|
||||||
|
|
||||||
SearchCriteria<SnapshotJoinVO> sc = snapshotIdsSearch.create();
|
SearchCriteria<SnapshotJoinVO> sc = snapshotIdsSearch.create();
|
||||||
if (zoneId != null) {
|
if (zoneId != null) {
|
||||||
sc.setParameters("zoneId", zoneId);
|
sc.setParameters("zoneId", zoneId);
|
||||||
|
|||||||
@ -7225,10 +7225,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
sc.addAnd("id", SearchCriteria.Op.EQ, id);
|
sc.addAnd("id", SearchCriteria.Op.EQ, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tags != null) {
|
|
||||||
sc.addAnd("tags", SearchCriteria.Op.EQ, tags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isTagged != null) {
|
if (isTagged != null) {
|
||||||
if (isTagged) {
|
if (isTagged) {
|
||||||
sc.addAnd("tags", SearchCriteria.Op.NNULL);
|
sc.addAnd("tags", SearchCriteria.Op.NNULL);
|
||||||
@ -7237,6 +7233,17 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tags != null) {
|
||||||
|
if (GuestType.Shared.name().equalsIgnoreCase(guestIpType)) {
|
||||||
|
SearchCriteria<NetworkOfferingJoinVO> tagsSc = networkOfferingJoinDao.createSearchCriteria();
|
||||||
|
tagsSc.addAnd("tags", SearchCriteria.Op.EQ, tags);
|
||||||
|
tagsSc.addOr("isDefault", SearchCriteria.Op.EQ, true);
|
||||||
|
sc.addAnd("tags", SearchCriteria.Op.SC, tagsSc);
|
||||||
|
} else {
|
||||||
|
sc.addAnd("tags", SearchCriteria.Op.EQ, tags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (zoneId != null) {
|
if (zoneId != null) {
|
||||||
SearchBuilder<NetworkOfferingJoinVO> sb = networkOfferingJoinDao.createSearchBuilder();
|
SearchBuilder<NetworkOfferingJoinVO> sb = networkOfferingJoinDao.createSearchBuilder();
|
||||||
sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.FIND_IN_SET);
|
sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.FIND_IN_SET);
|
||||||
@ -7297,7 +7304,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
boolean addOffering = true;
|
boolean addOffering = true;
|
||||||
List<Service> checkForProviders = new ArrayList<Service>();
|
List<Service> checkForProviders = new ArrayList<Service>();
|
||||||
|
|
||||||
if (checkForTags && ! checkNetworkOfferingTags(pNtwkTags, allowNullTag, offering.getTags())) {
|
if (checkForTags && !checkNetworkOfferingTags(pNtwkTags, allowNullTag, offering.getTags())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -934,8 +934,12 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserDataServiceProvider getUserDataUpdateProvider(Network network) {
|
public UserDataServiceProvider getUserDataUpdateProvider(Network network) {
|
||||||
String userDataProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.UserData);
|
if (network == null) {
|
||||||
|
logger.warn("No network details, can't fetch user data provider");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String userDataProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.UserData);
|
||||||
if (userDataProvider == null) {
|
if (userDataProvider == null) {
|
||||||
logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName());
|
logger.debug("Network " + network + " doesn't support service " + Service.UserData.getName());
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -325,8 +325,12 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
|
|||||||
try {
|
try {
|
||||||
final Network network = _networkMgr.getNetwork(nic.getNetworkId());
|
final Network network = _networkMgr.getNetwork(nic.getNetworkId());
|
||||||
final UserDataServiceProvider userDataUpdateProvider = _networkModel.getUserDataUpdateProvider(network);
|
final UserDataServiceProvider userDataUpdateProvider = _networkModel.getUserDataUpdateProvider(network);
|
||||||
|
if (userDataUpdateProvider == null) {
|
||||||
|
logger.warn("Failed to get user data provider");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
final Provider provider = userDataUpdateProvider.getProvider();
|
final Provider provider = userDataUpdateProvider.getProvider();
|
||||||
if (provider.equals(Provider.ConfigDrive)) {
|
if (Provider.ConfigDrive.equals(provider)) {
|
||||||
try {
|
try {
|
||||||
return deleteConfigDriveIso(vm);
|
return deleteConfigDriveIso(vm);
|
||||||
} catch (ResourceUnavailableException e) {
|
} catch (ResourceUnavailableException e) {
|
||||||
@ -341,8 +345,13 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean prepareMigration(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) {
|
public boolean prepareMigration(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) {
|
||||||
if (_networkModel.getUserDataUpdateProvider(network).getProvider().equals(Provider.ConfigDrive)) {
|
final UserDataServiceProvider userDataUpdateProvider = _networkModel.getUserDataUpdateProvider(network);
|
||||||
logger.trace(String.format("[prepareMigration] for vm: %s", vm));
|
if (userDataUpdateProvider == null) {
|
||||||
|
logger.warn("Failed to prepare for migration, can't get user data provider");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Provider.ConfigDrive.equals(userDataUpdateProvider.getProvider())) {
|
||||||
|
logger.trace(String.format("[prepareMigration] for vm: %s", vm.getInstanceName()));
|
||||||
try {
|
try {
|
||||||
if (isConfigDriveIsoOnHostCache(vm.getId())) {
|
if (isConfigDriveIsoOnHostCache(vm.getId())) {
|
||||||
vm.setConfigDriveLocation(Location.HOST);
|
vm.setConfigDriveLocation(Location.HOST);
|
||||||
@ -392,7 +401,11 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void recreateConfigDriveIso(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest) throws ResourceUnavailableException {
|
private void recreateConfigDriveIso(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest) throws ResourceUnavailableException {
|
||||||
if (nic.isDefaultNic() && _networkModel.getUserDataUpdateProvider(network).getProvider().equals(Provider.ConfigDrive)) {
|
final UserDataServiceProvider userDataUpdateProvider = _networkModel.getUserDataUpdateProvider(network);
|
||||||
|
if (userDataUpdateProvider == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (nic.isDefaultNic() && Provider.ConfigDrive.equals(userDataUpdateProvider.getProvider())) {
|
||||||
DiskTO diskToUse = null;
|
DiskTO diskToUse = null;
|
||||||
for (DiskTO disk : vm.getDisks()) {
|
for (DiskTO disk : vm.getDisks()) {
|
||||||
if (disk.getType() == Volume.Type.ISO && disk.getPath() != null && disk.getPath().contains("configdrive")) {
|
if (disk.getType() == Volume.Type.ISO && disk.getPath() != null && disk.getPath().contains("configdrive")) {
|
||||||
|
|||||||
@ -769,7 +769,12 @@ NetworkMigrationResponder, AggregatedCommandExecutor, RedundantResource, DnsServ
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean saveHypervisorHostname(NicProfile nicProfile, Network network, VirtualMachineProfile vm, DeployDestination dest) throws ResourceUnavailableException {
|
public boolean saveHypervisorHostname(NicProfile nicProfile, Network network, VirtualMachineProfile vm, DeployDestination dest) throws ResourceUnavailableException {
|
||||||
if (_networkModel.getUserDataUpdateProvider(network).getProvider().equals(Provider.VirtualRouter) && vm.getVirtualMachine().getType() == VirtualMachine.Type.User) {
|
final UserDataServiceProvider userDataUpdateProvider = _networkModel.getUserDataUpdateProvider(network);
|
||||||
|
if (userDataUpdateProvider == null) {
|
||||||
|
logger.warn("Failed to update hypervisor host details, can't get user data provider");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Provider.VirtualRouter.equals(userDataUpdateProvider.getProvider()) && vm.getVirtualMachine().getType() == VirtualMachine.Type.User) {
|
||||||
VirtualMachine uvm = vm.getVirtualMachine();
|
VirtualMachine uvm = vm.getVirtualMachine();
|
||||||
UserVmVO destVm = _userVmDao.findById(uvm.getId());
|
UserVmVO destVm = _userVmDao.findById(uvm.getId());
|
||||||
VirtualMachineProfile profile = null;
|
VirtualMachineProfile profile = null;
|
||||||
|
|||||||
@ -3622,8 +3622,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
templateVO = _templateStoreDao.findByStoreTemplate(store.getId(), templateId);
|
templateVO = _templateStoreDao.findByStoreTemplate(store.getId(), templateId);
|
||||||
if (templateVO != null) {
|
if (templateVO != null) {
|
||||||
try {
|
try {
|
||||||
if (SystemVmTemplateRegistration.validateIfSeeded(
|
if (systemVmTemplateRegistration.validateIfSeeded(
|
||||||
url, templateVO.getInstallPath(), nfsVersion)) {
|
templateVO, url, templateVO.getInstallPath(), nfsVersion)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@ -2482,10 +2482,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
return existingVolumeOfVm;
|
return existingVolumeOfVm;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected StoragePool getPoolForAllocatedOrUploadedVolumeForAttach(final VolumeInfo volumeToAttach, final UserVmVO vm) {
|
protected StoragePool getSuitablePoolForAllocatedOrUploadedVolumeForAttach(final VolumeInfo volumeToAttach, final UserVmVO vm) {
|
||||||
DataCenter zone = _dcDao.findById(vm.getDataCenterId());
|
DataCenter zone = _dcDao.findById(vm.getDataCenterId());
|
||||||
Pair<Long, Long> clusterHostId = virtualMachineManager.findClusterAndHostIdForVm(vm, false);
|
Pair<Long, Long> clusterHostId = virtualMachineManager.findClusterAndHostIdForVm(vm, false);
|
||||||
long podId = vm.getPodIdToDeployIn();
|
Long podId = vm.getPodIdToDeployIn();
|
||||||
if (clusterHostId.first() != null) {
|
if (clusterHostId.first() != null) {
|
||||||
Cluster cluster = clusterDao.findById(clusterHostId.first());
|
Cluster cluster = clusterDao.findById(clusterHostId.first());
|
||||||
podId = cluster.getPodId();
|
podId = cluster.getPodId();
|
||||||
@ -2497,12 +2497,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
offering.isUseLocalStorage(), offering.isRecreatable(),
|
offering.isUseLocalStorage(), offering.isRecreatable(),
|
||||||
volumeToAttach.getTemplateId());
|
volumeToAttach.getTemplateId());
|
||||||
diskProfile.setHyperType(vm.getHypervisorType());
|
diskProfile.setHyperType(vm.getHypervisorType());
|
||||||
StoragePool pool = _volumeMgr.findStoragePool(diskProfile, zone, pod, clusterHostId.first(),
|
return _volumeMgr.findStoragePool(diskProfile, zone, pod, clusterHostId.first(),
|
||||||
clusterHostId.second(), vm, Collections.emptySet());
|
clusterHostId.second(), vm, Collections.emptySet());
|
||||||
if (pool == null) {
|
|
||||||
throw new CloudRuntimeException(String.format("Failed to find a primary storage for volume in state: %s", volumeToAttach.getState()));
|
|
||||||
}
|
|
||||||
return pool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected VolumeInfo createVolumeOnPrimaryForAttachIfNeeded(final VolumeInfo volumeToAttach, final UserVmVO vm, VolumeVO existingVolumeOfVm) {
|
protected VolumeInfo createVolumeOnPrimaryForAttachIfNeeded(final VolumeInfo volumeToAttach, final UserVmVO vm, VolumeVO existingVolumeOfVm) {
|
||||||
@ -2520,7 +2516,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (destPrimaryStorage == null) {
|
if (destPrimaryStorage == null) {
|
||||||
destPrimaryStorage = getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
destPrimaryStorage = getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
||||||
|
if (destPrimaryStorage == null) {
|
||||||
|
if (Volume.State.Allocated.equals(volumeToAttach.getState()) && State.Stopped.equals(vm.getState())) {
|
||||||
|
return newVolumeOnPrimaryStorage;
|
||||||
|
}
|
||||||
|
throw new CloudRuntimeException(String.format("Failed to find a primary storage for volume in state: %s", volumeToAttach.getState()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (volumeOnSecondary && Storage.StoragePoolType.PowerFlex.equals(destPrimaryStorage.getPoolType())) {
|
if (volumeOnSecondary && Storage.StoragePoolType.PowerFlex.equals(destPrimaryStorage.getPoolType())) {
|
||||||
|
|||||||
@ -498,8 +498,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
|
|
||||||
if (apiNameList == null) {
|
if (apiNameList == null) {
|
||||||
long startTime = System.nanoTime();
|
long startTime = System.nanoTime();
|
||||||
apiNameList = new ArrayList<String>();
|
apiNameList = new ArrayList<>();
|
||||||
Set<Class<?>> cmdClasses = new LinkedHashSet<Class<?>>();
|
Set<Class<?>> cmdClasses = new LinkedHashSet<>();
|
||||||
for (PluggableService service : services) {
|
for (PluggableService service : services) {
|
||||||
logger.debug(String.format("getting api commands of service: %s", service.getClass().getName()));
|
logger.debug(String.format("getting api commands of service: %s", service.getClass().getName()));
|
||||||
cmdClasses.addAll(service.getCommands());
|
cmdClasses.addAll(service.getCommands());
|
||||||
@ -513,7 +513,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected List<String> createApiNameList(Set<Class<?>> cmdClasses) {
|
protected List<String> createApiNameList(Set<Class<?>> cmdClasses) {
|
||||||
List<String> apiNameList = new ArrayList<String>();
|
List<String> apiNameList = new ArrayList<>();
|
||||||
|
|
||||||
for (Class<?> cmdClass : cmdClasses) {
|
for (Class<?> cmdClass : cmdClasses) {
|
||||||
APICommand apiCmdAnnotation = cmdClass.getAnnotation(APICommand.class);
|
APICommand apiCmdAnnotation = cmdClass.getAnnotation(APICommand.class);
|
||||||
@ -698,7 +698,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap<Long, List<ControlledEntity>> domains = new HashMap<Long, List<ControlledEntity>>();
|
HashMap<Long, List<ControlledEntity>> domains = new HashMap<>();
|
||||||
|
|
||||||
for (ControlledEntity entity : entities) {
|
for (ControlledEntity entity : entities) {
|
||||||
long domainId = entity.getDomainId();
|
long domainId = entity.getDomainId();
|
||||||
@ -713,7 +713,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
List<ControlledEntity> toBeChecked = domains.get(entity.getDomainId());
|
List<ControlledEntity> toBeChecked = domains.get(entity.getDomainId());
|
||||||
// for templates, we don't have to do cross domains check
|
// for templates, we don't have to do cross domains check
|
||||||
if (toBeChecked == null) {
|
if (toBeChecked == null) {
|
||||||
toBeChecked = new ArrayList<ControlledEntity>();
|
toBeChecked = new ArrayList<>();
|
||||||
domains.put(domainId, toBeChecked);
|
domains.put(domainId, toBeChecked);
|
||||||
}
|
}
|
||||||
toBeChecked.add(entity);
|
toBeChecked.add(entity);
|
||||||
@ -722,7 +722,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
for (SecurityChecker checker : _securityCheckers) {
|
for (SecurityChecker checker : _securityCheckers) {
|
||||||
if (checker.checkAccess(caller, entity, accessType, apiName)) {
|
if (checker.checkAccess(caller, entity, accessType, apiName)) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Access to " + entity + " granted to " + caller + " by " + checker.getName());
|
User user = CallContext.current().getCallingUser();
|
||||||
|
String userName = "";
|
||||||
|
if (user != null)
|
||||||
|
userName = user.getUsername();
|
||||||
|
logger.debug("Access to {} granted to {} by {} on behalf of user {}", entity, caller, checker.getName(), userName);
|
||||||
}
|
}
|
||||||
granted = true;
|
granted = true;
|
||||||
break;
|
break;
|
||||||
@ -1023,12 +1027,12 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
logger.debug("Deleting networks for account {}", account);
|
logger.debug("Deleting networks for account {}", account);
|
||||||
List<NetworkVO> networks = _networkDao.listByOwner(accountId);
|
List<NetworkVO> networks = _networkDao.listByOwner(accountId);
|
||||||
if (networks != null) {
|
if (networks != null) {
|
||||||
Collections.sort(networks, new Comparator<NetworkVO>() {
|
Collections.sort(networks, new Comparator<>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(NetworkVO network1, NetworkVO network2) {
|
public int compare(NetworkVO network1, NetworkVO network2) {
|
||||||
if (network1.getGuestType() != network2.getGuestType() && Network.GuestType.Isolated.equals(network2.getGuestType())) {
|
if (network1.getGuestType() != network2.getGuestType() && Network.GuestType.Isolated.equals(network2.getGuestType())) {
|
||||||
return -1;
|
return -1;
|
||||||
};
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1300,7 +1304,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
final String accountNameFinal = accountName;
|
final String accountNameFinal = accountName;
|
||||||
final Long domainIdFinal = domainId;
|
final Long domainIdFinal = domainId;
|
||||||
final String accountUUIDFinal = accountUUID;
|
final String accountUUIDFinal = accountUUID;
|
||||||
Pair<Long, Account> pair = Transaction.execute(new TransactionCallback<Pair<Long, Account>>() {
|
Pair<Long, Account> pair = Transaction.execute(new TransactionCallback<>() {
|
||||||
@Override
|
@Override
|
||||||
public Pair<Long, Account> doInTransaction(TransactionStatus status) {
|
public Pair<Long, Account> doInTransaction(TransactionStatus status) {
|
||||||
// create account
|
// create account
|
||||||
@ -1323,7 +1327,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
user.setRegistrationToken(registrationToken);
|
user.setRegistrationToken(registrationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Pair<Long, Account>(user.getId(), account);
|
return new Pair<>(user.getId(), account);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1332,7 +1336,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
|
|
||||||
// create correct account and group association based on accountType
|
// create correct account and group association based on accountType
|
||||||
if (accountType != Account.Type.PROJECT) {
|
if (accountType != Account.Type.PROJECT) {
|
||||||
Map<Long, Long> accountGroupMap = new HashMap<Long, Long>();
|
Map<Long, Long> accountGroupMap = new HashMap<>();
|
||||||
accountGroupMap.put(account.getId(), (long) (accountType.ordinal() + 1));
|
accountGroupMap.put(account.getId(), (long) (accountType.ordinal() + 1));
|
||||||
_messageBus.publish(_name, MESSAGE_ADD_ACCOUNT_EVENT, PublishScope.LOCAL, accountGroupMap);
|
_messageBus.publish(_name, MESSAGE_ADD_ACCOUNT_EVENT, PublishScope.LOCAL, accountGroupMap);
|
||||||
}
|
}
|
||||||
@ -1476,7 +1480,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) {
|
if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) {
|
||||||
throw new CloudRuntimeException(String.format("The user %s already exists in domain %s", userName, domain));
|
throw new CloudRuntimeException(String.format("The user %s already exists in domain %s", userName, domain));
|
||||||
}
|
}
|
||||||
UserVO user = null;
|
UserVO user;
|
||||||
user = createUser(account.getId(), userName, password, firstName, lastName, email, timeZone, userUUID, source);
|
user = createUser(account.getId(), userName, password, firstName, lastName, email, timeZone, userUUID, source);
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
@ -1731,7 +1735,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
Long callingUserId = CallContext.current().getCallingUserId();
|
Long callingUserId = CallContext.current().getCallingUserId();
|
||||||
Account callingAccount = CallContext.current().getCallingAccount();
|
Account callingAccount = CallContext.current().getCallingAccount();
|
||||||
ActionEventUtils.onActionEvent(callingUserId, callingAccount.getAccountId(), callingAccount.getDomainId(),
|
ActionEventUtils.onActionEvent(callingUserId, callingAccount.getAccountId(), callingAccount.getDomainId(),
|
||||||
EventTypes.API_KEY_ACCESS_UPDATE, "Api key access was changed for the User to " + access.toString(),
|
EventTypes.API_KEY_ACCESS_UPDATE, "Api key access was changed for the User to " + access,
|
||||||
user.getId(), ApiCommandResourceType.User.toString());
|
user.getId(), ApiCommandResourceType.User.toString());
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
throw new InvalidParameterValueException("ApiKeyAccess value can only be Enabled/Disabled/Inherit");
|
throw new InvalidParameterValueException("ApiKeyAccess value can only be Enabled/Disabled/Inherit");
|
||||||
@ -1747,7 +1751,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
Long callingUserId = CallContext.current().getCallingUserId();
|
Long callingUserId = CallContext.current().getCallingUserId();
|
||||||
Account callingAccount = CallContext.current().getCallingAccount();
|
Account callingAccount = CallContext.current().getCallingAccount();
|
||||||
ActionEventUtils.onActionEvent(callingUserId, callingAccount.getAccountId(), callingAccount.getDomainId(),
|
ActionEventUtils.onActionEvent(callingUserId, callingAccount.getAccountId(), callingAccount.getDomainId(),
|
||||||
EventTypes.API_KEY_ACCESS_UPDATE, "Api key access was changed for the Account to " + access.toString(),
|
EventTypes.API_KEY_ACCESS_UPDATE, "Api key access was changed for the Account to " + access,
|
||||||
account.getId(), ApiCommandResourceType.Account.toString());
|
account.getId(), ApiCommandResourceType.Account.toString());
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
throw new InvalidParameterValueException("ApiKeyAccess value can only be Enabled/Disabled/Inherit");
|
throw new InvalidParameterValueException("ApiKeyAccess value can only be Enabled/Disabled/Inherit");
|
||||||
@ -1837,7 +1841,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
|
|
||||||
checkAccess(caller, AccessType.OperateEntry, true, account);
|
checkAccess(caller, AccessType.OperateEntry, true, account);
|
||||||
|
|
||||||
boolean success = Transaction.execute(new TransactionCallback<Boolean>() {
|
boolean success = Transaction.execute(new TransactionCallback<>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean doInTransaction(TransactionStatus status) {
|
public Boolean doInTransaction(TransactionStatus status) {
|
||||||
boolean success = doSetUserStatus(userId, State.ENABLED);
|
boolean success = doSetUserStatus(userId, State.ENABLED);
|
||||||
@ -1892,7 +1896,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
// make sure the account is enabled too
|
// make sure the account is enabled too
|
||||||
// if the user is either locked already or disabled already, don't change state...only lock currently enabled
|
// if the user is either locked already or disabled already, don't change state...only lock currently enabled
|
||||||
// users
|
// users
|
||||||
boolean success = true;
|
boolean success;
|
||||||
if (user.getState().equals(State.LOCKED)) {
|
if (user.getState().equals(State.LOCKED)) {
|
||||||
// already locked...no-op
|
// already locked...no-op
|
||||||
return _userAccountDao.findById(userId);
|
return _userAccountDao.findById(userId);
|
||||||
@ -1995,7 +1999,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
public AccountVO enableAccount(String accountName, Long domainId, Long accountId) {
|
public AccountVO enableAccount(String accountName, Long domainId, Long accountId) {
|
||||||
|
|
||||||
// Check if account exists
|
// Check if account exists
|
||||||
Account account = null;
|
Account account;
|
||||||
if (accountId != null) {
|
if (accountId != null) {
|
||||||
account = _accountDao.findById(accountId);
|
account = _accountDao.findById(accountId);
|
||||||
} else {
|
} else {
|
||||||
@ -2021,7 +2025,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
|
|
||||||
return _accountDao.findById(account.getId());
|
return _accountDao.findById(account.getId());
|
||||||
} else {
|
} else {
|
||||||
throw new CloudRuntimeException(String.format("Unable to enable account %s in domain %s", account, accountName, _domainMgr.getDomain(domainId)));
|
throw new CloudRuntimeException(String.format("Unable to enable account %s[%s] in domain %s", accountName, account.getUuid(), _domainMgr.getDomain(domainId)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2030,7 +2034,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
public AccountVO lockAccount(String accountName, Long domainId, Long accountId) {
|
public AccountVO lockAccount(String accountName, Long domainId, Long accountId) {
|
||||||
Account caller = getCurrentCallingAccount();
|
Account caller = getCurrentCallingAccount();
|
||||||
|
|
||||||
Account account = null;
|
Account account;
|
||||||
if (accountId != null) {
|
if (accountId != null) {
|
||||||
account = _accountDao.findById(accountId);
|
account = _accountDao.findById(accountId);
|
||||||
} else {
|
} else {
|
||||||
@ -2051,7 +2055,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
CallContext.current().putContextParameter(Account.class, account.getUuid());
|
CallContext.current().putContextParameter(Account.class, account.getUuid());
|
||||||
return _accountDao.findById(account.getId());
|
return _accountDao.findById(account.getId());
|
||||||
} else {
|
} else {
|
||||||
throw new CloudRuntimeException(String.format("Unable to lock account %s by accountId: %d OR by name: %s in domain %d", account, accountId, accountName, _domainMgr.getDomain(domainId)));
|
throw new CloudRuntimeException(String.format("Unable to lock account %s by accountId: %d OR by name: %s in domain %s", account, accountId, accountName, _domainMgr.getDomain(domainId)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2060,7 +2064,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
public AccountVO disableAccount(String accountName, Long domainId, Long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
|
public AccountVO disableAccount(String accountName, Long domainId, Long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||||
Account caller = getCurrentCallingAccount();
|
Account caller = getCurrentCallingAccount();
|
||||||
|
|
||||||
Account account = null;
|
Account account;
|
||||||
if (accountId != null) {
|
if (accountId != null) {
|
||||||
account = _accountDao.findById(accountId);
|
account = _accountDao.findById(accountId);
|
||||||
} else {
|
} else {
|
||||||
@ -2097,8 +2101,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
String networkDomain = cmd.getNetworkDomain();
|
String networkDomain = cmd.getNetworkDomain();
|
||||||
final Map<String, String> details = cmd.getDetails();
|
final Map<String, String> details = cmd.getDetails();
|
||||||
|
|
||||||
boolean success = false;
|
boolean success;
|
||||||
Account account = null;
|
Account account;
|
||||||
if (accountId != null) {
|
if (accountId != null) {
|
||||||
account = _accountDao.findById(accountId);
|
account = _accountDao.findById(accountId);
|
||||||
} else {
|
} else {
|
||||||
@ -2159,7 +2163,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
if (roleNotFound) {
|
if (roleNotFound) {
|
||||||
throw new InvalidParameterValueException(String.format("Role with ID '%s' is not " +
|
throw new InvalidParameterValueException(String.format("Role with ID '%s' is not " +
|
||||||
"found or not available for the account '%s' in the domain '%s'.",
|
"found or not available for the account '%s' in the domain '%s'.",
|
||||||
roleId.toString(), account, _domainMgr.getDomain(domainId)));
|
roleId, account, _domainMgr.getDomain(domainId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Role role = roleService.findRole(roleId);
|
Role role = roleService.findRole(roleId);
|
||||||
@ -2244,7 +2248,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
return true; // no need to create a new user object for this user
|
return true; // no need to create a new user object for this user
|
||||||
}
|
}
|
||||||
|
|
||||||
return Transaction.execute(new TransactionCallback<Boolean>() {
|
return Transaction.execute(new TransactionCallback<>() {
|
||||||
@Override
|
@Override
|
||||||
public Boolean doInTransaction(TransactionStatus status) {
|
public Boolean doInTransaction(TransactionStatus status) {
|
||||||
UserVO newUser = new UserVO(user);
|
UserVO newUser = new UserVO(user);
|
||||||
@ -2560,7 +2564,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the account
|
// Create the account
|
||||||
return Transaction.execute(new TransactionCallback<AccountVO>() {
|
return Transaction.execute(new TransactionCallback<>() {
|
||||||
@Override
|
@Override
|
||||||
public AccountVO doInTransaction(TransactionStatus status) {
|
public AccountVO doInTransaction(TransactionStatus status) {
|
||||||
AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, roleId, uuid));
|
AccountVO account = _accountDao.persist(new AccountVO(accountName, domainId, networkDomain, accountType, roleId, uuid));
|
||||||
@ -2650,12 +2654,12 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
long tolerance = Long.parseLong(singleSignOnTolerance);
|
long tolerance = Long.parseLong(singleSignOnTolerance);
|
||||||
String signature = null;
|
String signature = null;
|
||||||
long timestamp = 0L;
|
long timestamp = 0L;
|
||||||
String unsignedRequest = null;
|
String unsignedRequest;
|
||||||
StringBuffer unsignedRequestBuffer = new StringBuffer();
|
StringBuffer unsignedRequestBuffer = new StringBuffer();
|
||||||
|
|
||||||
// - build a request string with sorted params, make sure it's all lowercase
|
// - build a request string with sorted params, make sure it's all lowercase
|
||||||
// - sign the request, verify the signature is the same
|
// - sign the request, verify the signature is the same
|
||||||
List<String> parameterNames = new ArrayList<String>();
|
List<String> parameterNames = new ArrayList<>();
|
||||||
|
|
||||||
for (Object paramNameObj : requestParameters.keySet()) {
|
for (Object paramNameObj : requestParameters.keySet()) {
|
||||||
parameterNames.add((String)paramNameObj); // put the name in a list that we'll sort later
|
parameterNames.add((String)paramNameObj); // put the name in a list that we'll sort later
|
||||||
@ -2780,7 +2784,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId);
|
UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId);
|
||||||
|
|
||||||
boolean authenticated = false;
|
boolean authenticated = false;
|
||||||
HashSet<ActionOnFailedAuthentication> actionsOnFailedAuthenticaion = new HashSet<ActionOnFailedAuthentication>();
|
HashSet<ActionOnFailedAuthentication> actionsOnFailedAuthenticaion = new HashSet<>();
|
||||||
User.Source userSource = userAccount != null ? userAccount.getSource() : User.Source.UNKNOWN;
|
User.Source userSource = userAccount != null ? userAccount.getSource() : User.Source.UNKNOWN;
|
||||||
for (UserAuthenticator authenticator : _userAuthenticators) {
|
for (UserAuthenticator authenticator : _userAuthenticators) {
|
||||||
final String[] secretCodeArray = (String[])requestParameters.get(ApiConstants.SECRET_CODE);
|
final String[] secretCodeArray = (String[])requestParameters.get(ApiConstants.SECRET_CODE);
|
||||||
@ -2886,7 +2890,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
preventRootDomainAdminAccessToRootAdminKeys(caller, account);
|
preventRootDomainAdminAccessToRootAdminKeys(caller, account);
|
||||||
checkAccess(caller, account);
|
checkAccess(caller, account);
|
||||||
|
|
||||||
Map<String, String> keys = new HashMap<String, String>();
|
Map<String, String> keys = new HashMap<>();
|
||||||
keys.put("apikey", user.getApiKey());
|
keys.put("apikey", user.getApiKey());
|
||||||
keys.put("secretkey", user.getSecretKey());
|
keys.put("secretkey", user.getSecretKey());
|
||||||
|
|
||||||
@ -2898,7 +2902,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Pair<Boolean, Map<String, String>>(apiKeyAccess, keys);
|
return new Pair<>(apiKeyAccess, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void preventRootDomainAdminAccessToRootAdminKeys(User caller, ControlledEntity account) {
|
protected void preventRootDomainAdminAccessToRootAdminKeys(User caller, ControlledEntity account) {
|
||||||
@ -2999,8 +3003,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
try {
|
try {
|
||||||
UserVO updatedUser = _userDao.createForUpdate();
|
UserVO updatedUser = _userDao.createForUpdate();
|
||||||
|
|
||||||
String encodedKey = null;
|
String encodedKey;
|
||||||
Pair<User, Account> userAcct = null;
|
Pair<User, Account> userAcct;
|
||||||
int retryLimit = 10;
|
int retryLimit = 10;
|
||||||
do {
|
do {
|
||||||
// FIXME: what algorithm should we use for API keys?
|
// FIXME: what algorithm should we use for API keys?
|
||||||
@ -3026,9 +3030,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
private String createUserSecretKey(long userId) {
|
private String createUserSecretKey(long userId) {
|
||||||
try {
|
try {
|
||||||
UserVO updatedUser = _userDao.createForUpdate();
|
UserVO updatedUser = _userDao.createForUpdate();
|
||||||
String encodedKey = null;
|
String encodedKey;
|
||||||
int retryLimit = 10;
|
int retryLimit = 10;
|
||||||
UserVO userBySecretKey = null;
|
UserVO userBySecretKey;
|
||||||
do {
|
do {
|
||||||
KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");
|
KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");
|
||||||
SecretKey key = generator.generateKey();
|
SecretKey key = generator.generateKey();
|
||||||
@ -3136,8 +3140,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
throw new InvalidParameterValueException("Account and projectId can't be specified together");
|
throw new InvalidParameterValueException("Account and projectId can't be specified together");
|
||||||
}
|
}
|
||||||
|
|
||||||
Account userAccount = null;
|
Account userAccount;
|
||||||
Domain domain = null;
|
Domain domain;
|
||||||
if (domainId != null) {
|
if (domainId != null) {
|
||||||
userAccount = _accountDao.findActiveAccount(accountName, domainId);
|
userAccount = _accountDao.findActiveAccount(accountName, domainId);
|
||||||
domain = _domainDao.findById(domainId);
|
domain = _domainDao.findById(domainId);
|
||||||
@ -3262,7 +3266,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
@Override
|
@Override
|
||||||
public List<String> listAclGroupsByAccount(Long accountId) {
|
public List<String> listAclGroupsByAccount(Long accountId) {
|
||||||
if (_querySelectors == null || _querySelectors.size() == 0) {
|
if (_querySelectors == null || _querySelectors.size() == 0) {
|
||||||
return new ArrayList<String>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
QuerySelector qs = _querySelectors.get(0);
|
QuerySelector qs = _querySelectors.get(0);
|
||||||
@ -3522,7 +3526,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected UserTwoFactorAuthenticationSetupResponse disableTwoFactorAuthentication(Long userId, Account caller, Account owner) {
|
protected UserTwoFactorAuthenticationSetupResponse disableTwoFactorAuthentication(Long userId, Account caller, Account owner) {
|
||||||
UserVO userVO = null;
|
UserVO userVO;
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
userVO = validateUser(userId);
|
userVO = validateUser(userId);
|
||||||
owner = _accountService.getActiveAccountById(userVO.getAccountId());
|
owner = _accountService.getActiveAccountById(userVO.getAccountId());
|
||||||
|
|||||||
@ -134,8 +134,8 @@ import org.apache.cloudstack.storage.template.VnfTemplateManager;
|
|||||||
import org.apache.cloudstack.userdata.UserDataManager;
|
import org.apache.cloudstack.userdata.UserDataManager;
|
||||||
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
|
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
|
||||||
import org.apache.cloudstack.utils.security.ParserUtils;
|
import org.apache.cloudstack.utils.security.ParserUtils;
|
||||||
import org.apache.cloudstack.vm.UnmanagedVMsManager;
|
|
||||||
import org.apache.cloudstack.vm.schedule.VMScheduleManager;
|
import org.apache.cloudstack.vm.schedule.VMScheduleManager;
|
||||||
|
import org.apache.cloudstack.vm.UnmanagedVMsManager;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections.MapUtils;
|
import org.apache.commons.collections.MapUtils;
|
||||||
import org.apache.commons.lang.math.NumberUtils;
|
import org.apache.commons.lang.math.NumberUtils;
|
||||||
@ -2140,7 +2140,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
throw new InvalidParameterValueException("Unable to Scale VM, since disk offering strictness flag is not same for new service offering and old service offering");
|
throw new InvalidParameterValueException("Unable to Scale VM, since disk offering strictness flag is not same for new service offering and old service offering");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentServiceOffering.getDiskOfferingStrictness() && currentServiceOffering.getDiskOfferingId() != newServiceOffering.getDiskOfferingId()) {
|
if (currentServiceOffering.getDiskOfferingStrictness() && !currentServiceOffering.getDiskOfferingId().equals(newServiceOffering.getDiskOfferingId())) {
|
||||||
throw new InvalidParameterValueException("Unable to Scale VM, since disk offering id associated with the old service offering is not same for new service offering");
|
throw new InvalidParameterValueException("Unable to Scale VM, since disk offering id associated with the old service offering is not same for new service offering");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4526,7 +4526,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) {
|
if (customParameters.containsKey(VmDetailConstants.ROOT_DISK_SIZE)) {
|
||||||
Long rootDiskSize = rootDiskSizeCustomParam * GiB_TO_BYTES;
|
Long rootDiskSize = NumbersUtil.parseLong(customParameters.get(VmDetailConstants.ROOT_DISK_SIZE), -1);
|
||||||
|
if (rootDiskSize <= 0) {
|
||||||
|
throw new InvalidParameterValueException("Root disk size should be a positive number.");
|
||||||
|
}
|
||||||
|
rootDiskSize = rootDiskSizeCustomParam * GiB_TO_BYTES;
|
||||||
_volumeService.validateVolumeSizeInBytes(rootDiskSize);
|
_volumeService.validateVolumeSizeInBytes(rootDiskSize);
|
||||||
return rootDiskSize;
|
return rootDiskSize;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -0,0 +1,109 @@
|
|||||||
|
// 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.api.query.dao;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Spy;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import com.cloud.api.query.vo.SnapshotJoinVO;
|
||||||
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class SnapshotJoinDaoImplTest {
|
||||||
|
|
||||||
|
@Spy
|
||||||
|
@InjectMocks
|
||||||
|
SnapshotJoinDaoImpl snapshotJoinDao = new SnapshotJoinDaoImpl();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
SearchCriteria<SnapshotJoinVO> mockSearchCriteria;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
SnapshotJoinVO mockSnap = mock(SnapshotJoinVO.class);
|
||||||
|
SearchBuilder<SnapshotJoinVO> mockSearchBuilder = mock(SearchBuilder.class);
|
||||||
|
when(mockSearchBuilder.entity()).thenReturn(mockSnap);
|
||||||
|
doReturn(mockSearchBuilder).when(snapshotJoinDao).createSearchBuilder();
|
||||||
|
when(mockSearchBuilder.create()).thenReturn(mockSearchCriteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindById_WithNullZoneId_EmptyResult() {
|
||||||
|
Long zoneId = null;
|
||||||
|
long id = 1L;
|
||||||
|
doReturn(Collections.emptyList()).when(snapshotJoinDao).search(mockSearchCriteria, null);
|
||||||
|
List<SnapshotJoinVO> result = snapshotJoinDao.findById(zoneId, id);
|
||||||
|
assertNull(result);
|
||||||
|
verify(mockSearchCriteria).setParameters("id", id);
|
||||||
|
verify(mockSearchCriteria, never()).setParameters("zoneId", zoneId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindById_WithValidZoneId_EmptyResult() {
|
||||||
|
Long zoneId = 1L;
|
||||||
|
long id = 1L;
|
||||||
|
doReturn(Collections.emptyList()).when(snapshotJoinDao).search(mockSearchCriteria, null);
|
||||||
|
List<SnapshotJoinVO> result = snapshotJoinDao.findById(zoneId, id);
|
||||||
|
assertNull(result);
|
||||||
|
verify(mockSearchCriteria).setParameters("id", id);
|
||||||
|
verify(mockSearchCriteria).setParameters("zoneId", zoneId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindById_WithValidResults() {
|
||||||
|
Long zoneId = 1L;
|
||||||
|
long id = 1L;
|
||||||
|
SnapshotJoinVO snapshot1 = mock(SnapshotJoinVO.class);
|
||||||
|
when(snapshot1.getSnapshotStorePair()).thenReturn("Primary_1");
|
||||||
|
SnapshotJoinVO snapshot2 = mock(SnapshotJoinVO.class);
|
||||||
|
when(snapshot2.getSnapshotStorePair()).thenReturn("Image_1");
|
||||||
|
doReturn(Arrays.asList(snapshot1, snapshot2)).when(snapshotJoinDao).search(mockSearchCriteria, null);
|
||||||
|
List<SnapshotJoinVO> result = snapshotJoinDao.findById(zoneId, id);
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(1, result.size());
|
||||||
|
assertEquals("Image_1", result.get(0).getSnapshotStorePair());
|
||||||
|
verify(mockSearchCriteria).setParameters("id", id);
|
||||||
|
verify(mockSearchCriteria).setParameters("zoneId", zoneId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindById_WithNullResults() {
|
||||||
|
long id = 1L;
|
||||||
|
doReturn(null).when(snapshotJoinDao).search(mockSearchCriteria, null);
|
||||||
|
List<SnapshotJoinVO> result = snapshotJoinDao.findById(null, id);
|
||||||
|
assertNull(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2038,13 +2038,13 @@ public class VolumeApiServiceImplTest {
|
|||||||
when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
|
when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
|
||||||
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class), eq(zone), eq(pod), eq(1L), eq(2L), eq(vm), eq(Collections.emptySet())))
|
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class), eq(zone), eq(pod), eq(1L), eq(2L), eq(vm), eq(Collections.emptySet())))
|
||||||
.thenReturn(pool);
|
.thenReturn(pool);
|
||||||
StoragePool result = volumeApiServiceImpl.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
StoragePool result = volumeApiServiceImpl.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
||||||
Assert.assertNotNull(result);
|
Assert.assertNotNull(result);
|
||||||
Assert.assertEquals(pool, result);
|
Assert.assertEquals(pool, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = CloudRuntimeException.class)
|
@Test
|
||||||
public void testGetPoolForAllocatedOrUploadedVolumeForAttach_NoPoolFound_ThrowsException() {
|
public void testGetPoolForAllocatedOrUploadedVolumeForAttach_NoSuitablePoolFound_ReturnsNull() {
|
||||||
VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
|
VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
|
||||||
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||||
DataCenterVO zone = mockZone();
|
DataCenterVO zone = mockZone();
|
||||||
@ -2059,11 +2059,11 @@ public class VolumeApiServiceImplTest {
|
|||||||
when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
|
when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
|
||||||
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class), eq(zone), eq(pod), eq(1L), eq(2L), eq(vm), eq(Collections.emptySet())))
|
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class), eq(zone), eq(pod), eq(1L), eq(2L), eq(vm), eq(Collections.emptySet())))
|
||||||
.thenReturn(null);
|
.thenReturn(null);
|
||||||
volumeApiServiceImpl.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
Assert.assertNull(volumeApiServiceImpl.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetPoolForAllocatedOrUploadedVolumeForAttach_NoCluster() {
|
public void testGetSuitablePoolForAllocatedOrUploadedVolumeForAttach_NoCluster() {
|
||||||
VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
|
VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
|
||||||
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||||
DataCenterVO zone = mockZone();
|
DataCenterVO zone = mockZone();
|
||||||
@ -2077,7 +2077,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
|
when(volumeToAttach.getDiskOfferingId()).thenReturn(1L);
|
||||||
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class), eq(zone), eq(pod), eq(null), eq(2L), eq(vm), eq(Collections.emptySet())))
|
when(volumeOrchestrationService.findStoragePool(any(DiskProfile.class), eq(zone), eq(pod), eq(null), eq(2L), eq(vm), eq(Collections.emptySet())))
|
||||||
.thenReturn(pool);
|
.thenReturn(pool);
|
||||||
StoragePool result = volumeApiServiceImpl.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
StoragePool result = volumeApiServiceImpl.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
||||||
Assert.assertNotNull(result);
|
Assert.assertNotNull(result);
|
||||||
Assert.assertEquals(pool, result);
|
Assert.assertEquals(pool, result);
|
||||||
}
|
}
|
||||||
@ -2123,7 +2123,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||||
StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
|
StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
|
||||||
Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
|
Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
|
||||||
.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
||||||
VolumeInfo newVolumeOnPrimaryStorage = Mockito.mock(VolumeInfo.class);
|
VolumeInfo newVolumeOnPrimaryStorage = Mockito.mock(VolumeInfo.class);
|
||||||
try {
|
try {
|
||||||
Mockito.when(volumeOrchestrationService.createVolumeOnPrimaryStorage(
|
Mockito.when(volumeOrchestrationService.createVolumeOnPrimaryStorage(
|
||||||
@ -2134,7 +2134,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
}
|
}
|
||||||
VolumeInfo result = volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, null);
|
VolumeInfo result = volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, null);
|
||||||
Assert.assertSame(newVolumeOnPrimaryStorage, result);
|
Assert.assertSame(newVolumeOnPrimaryStorage, result);
|
||||||
verify(volumeApiServiceImpl).getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
verify(volumeApiServiceImpl).getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = InvalidParameterValueException.class)
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
@ -2145,7 +2145,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
|
StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
|
||||||
when(destPrimaryStorage.getPoolType()).thenReturn(Storage.StoragePoolType.PowerFlex);
|
when(destPrimaryStorage.getPoolType()).thenReturn(Storage.StoragePoolType.PowerFlex);
|
||||||
Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
|
Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
|
||||||
.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
||||||
volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, null);
|
volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2157,7 +2157,7 @@ public class VolumeApiServiceImplTest {
|
|||||||
StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
|
StoragePool destPrimaryStorage = Mockito.mock(StoragePool.class);
|
||||||
Mockito.when(destPrimaryStorage.getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem);
|
Mockito.when(destPrimaryStorage.getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem);
|
||||||
Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
|
Mockito.doReturn(destPrimaryStorage).when(volumeApiServiceImpl)
|
||||||
.getPoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
||||||
try {
|
try {
|
||||||
Mockito.when(volumeOrchestrationService.createVolumeOnPrimaryStorage(vm, volumeToAttach, vm.getHypervisorType(), destPrimaryStorage))
|
Mockito.when(volumeOrchestrationService.createVolumeOnPrimaryStorage(vm, volumeToAttach, vm.getHypervisorType(), destPrimaryStorage))
|
||||||
.thenThrow(new NoTransitionException("Mocked exception"));
|
.thenThrow(new NoTransitionException("Mocked exception"));
|
||||||
@ -2169,4 +2169,35 @@ public class VolumeApiServiceImplTest {
|
|||||||
);
|
);
|
||||||
Assert.assertTrue(exception.getMessage().contains("Failed to create volume on primary storage"));
|
Assert.assertTrue(exception.getMessage().contains("Failed to create volume on primary storage"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateVolumeOnSecondaryForAttachIfNeeded_NoSuitablePool_ThrowsException() {
|
||||||
|
VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
|
||||||
|
Mockito.when(volumeToAttach.getState()).thenReturn(Volume.State.Uploaded);
|
||||||
|
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||||
|
Mockito.doReturn(null).when(volumeApiServiceImpl)
|
||||||
|
.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
||||||
|
CloudRuntimeException exception = Assert.assertThrows(CloudRuntimeException.class, () ->
|
||||||
|
volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, null)
|
||||||
|
);
|
||||||
|
Assert.assertTrue(exception.getMessage().startsWith("Failed to find a primary storage for volume"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateVolumeOnSecondaryForAttachIfNeeded_NoSuitablePool_ReturnSameVolumeInfo() {
|
||||||
|
VolumeInfo volumeToAttach = Mockito.mock(VolumeInfo.class);
|
||||||
|
Mockito.when(volumeToAttach.getState()).thenReturn(Volume.State.Allocated);
|
||||||
|
UserVmVO vm = Mockito.mock(UserVmVO.class);
|
||||||
|
Mockito.when(vm.getState()).thenReturn(State.Stopped);
|
||||||
|
Mockito.doReturn(null).when(volumeApiServiceImpl)
|
||||||
|
.getSuitablePoolForAllocatedOrUploadedVolumeForAttach(volumeToAttach, vm);
|
||||||
|
VolumeInfo result = volumeApiServiceImpl.createVolumeOnPrimaryForAttachIfNeeded(volumeToAttach, vm, null);
|
||||||
|
Assert.assertSame(volumeToAttach, result);
|
||||||
|
try {
|
||||||
|
Mockito.verify(volumeOrchestrationService, Mockito.never()).createVolumeOnPrimaryStorage(Mockito.any(),
|
||||||
|
Mockito.any(), Mockito.any(), Mockito.any());
|
||||||
|
} catch (NoTransitionException e) {
|
||||||
|
Assert.fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,11 +40,6 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc
|
|||||||
this._inSystemVM = false;
|
this._inSystemVM = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setParentPath(String path) {
|
|
||||||
this._parent = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Answer executeRequest(Command cmd) {
|
public Answer executeRequest(Command cmd) {
|
||||||
return super.executeRequest(cmd);
|
return super.executeRequest(cmd);
|
||||||
@ -57,7 +52,7 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc
|
|||||||
String dir = mountUri(uri, nfsVersion);
|
String dir = mountUri(uri, nfsVersion);
|
||||||
return _parent + "/" + dir;
|
return _parent + "/" + dir;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
|
String msg = "GetRootDir for " + secUrl + " failed due to " + e;
|
||||||
logger.error(msg, e);
|
logger.error(msg, e);
|
||||||
throw new CloudRuntimeException(msg);
|
throw new CloudRuntimeException(msg);
|
||||||
}
|
}
|
||||||
@ -75,14 +70,14 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc
|
|||||||
|
|
||||||
// Change permissions for the mountpoint - seems to bypass authentication
|
// Change permissions for the mountpoint - seems to bypass authentication
|
||||||
Script script = new Script(true, "chmod", _timeout, logger);
|
Script script = new Script(true, "chmod", _timeout, logger);
|
||||||
script.add("777", localRootPath);
|
script.add("1777", localRootPath);
|
||||||
String result = script.execute();
|
String result = script.execute();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
String errMsg = "Unable to set permissions for " + localRootPath + " due to " + result;
|
String errMsg = "Unable to set permissions for " + localRootPath + " due to " + result;
|
||||||
logger.error(errMsg);
|
logger.error(errMsg);
|
||||||
throw new CloudRuntimeException(errMsg);
|
throw new CloudRuntimeException(errMsg);
|
||||||
}
|
}
|
||||||
logger.debug("Successfully set 777 permission for " + localRootPath);
|
logger.debug("Successfully set 1777 permission for " + localRootPath);
|
||||||
|
|
||||||
// XXX: Adding the check for creation of snapshots dir here. Might have
|
// XXX: Adding the check for creation of snapshots dir here. Might have
|
||||||
// to move it somewhere more logical later.
|
// to move it somewhere more logical later.
|
||||||
|
|||||||
@ -19,15 +19,16 @@ import logging
|
|||||||
from netaddr import IPAddress, IPNetwork
|
from netaddr import IPAddress, IPNetwork
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from . import CsHelper
|
from . import CsHelper
|
||||||
from .CsDatabag import CsDataBag
|
from .CsDatabag import CsDataBag
|
||||||
from .CsApp import CsApache, CsDnsmasq, CsPasswdSvc
|
from .CsApp import CsApache, CsDnsmasq, CsPasswdSvc
|
||||||
from .CsRoute import CsRoute
|
from .CsRoute import CsRoute
|
||||||
from .CsRule import CsRule
|
from .CsRule import CsRule
|
||||||
|
from .CsStaticRoutes import CsStaticRoutes
|
||||||
|
|
||||||
VRRP_TYPES = ['guest']
|
VRRP_TYPES = ['guest']
|
||||||
|
|
||||||
|
|
||||||
class CsAddress(CsDataBag):
|
class CsAddress(CsDataBag):
|
||||||
|
|
||||||
def compare(self):
|
def compare(self):
|
||||||
@ -556,8 +557,10 @@ class CsIP:
|
|||||||
(self.dev, guestNetworkCidr, self.address['gateway'], self.dev)])
|
(self.dev, guestNetworkCidr, self.address['gateway'], self.dev)])
|
||||||
|
|
||||||
if self.is_private_gateway():
|
if self.is_private_gateway():
|
||||||
self.fw.append(["filter", "", "-A FORWARD -d %s -o %s -j ACL_INBOUND_%s" %
|
self.fw.append(["filter", "front", "-A FORWARD -d %s -o %s -j ACL_INBOUND_%s" %
|
||||||
(self.address['network'], self.dev, self.dev)])
|
(self.address['network'], self.dev, self.dev)])
|
||||||
|
self.fw.append(["filter", "front", "-A FORWARD -d %s -o %s -m state --state RELATED,ESTABLISHED -j ACCEPT" %
|
||||||
|
(self.address['network'], self.dev)])
|
||||||
self.fw.append(["filter", "", "-A ACL_INBOUND_%s -j DROP" % self.dev])
|
self.fw.append(["filter", "", "-A ACL_INBOUND_%s -j DROP" % self.dev])
|
||||||
self.fw.append(["mangle", "",
|
self.fw.append(["mangle", "",
|
||||||
"-A PREROUTING -m state --state NEW -i %s -s %s ! -d %s/32 -j ACL_OUTBOUND_%s" %
|
"-A PREROUTING -m state --state NEW -i %s -s %s ! -d %s/32 -j ACL_OUTBOUND_%s" %
|
||||||
@ -565,6 +568,23 @@ class CsIP:
|
|||||||
self.fw.append(["mangle", "front",
|
self.fw.append(["mangle", "front",
|
||||||
"-A PREROUTING -s %s -d %s -m state --state NEW -j MARK --set-xmark %s/0xffffffff" %
|
"-A PREROUTING -s %s -d %s -m state --state NEW -j MARK --set-xmark %s/0xffffffff" %
|
||||||
(self.cl.get_vpccidr(), self.address['network'], hex(100 + int(self.dev[3:])))])
|
(self.cl.get_vpccidr(), self.address['network'], hex(100 + int(self.dev[3:])))])
|
||||||
|
|
||||||
|
static_routes = CsStaticRoutes("staticroutes", self.config)
|
||||||
|
if static_routes:
|
||||||
|
for item in static_routes.get_bag():
|
||||||
|
if item == "id":
|
||||||
|
continue
|
||||||
|
static_route = static_routes.get_bag()[item]
|
||||||
|
if static_route['ip_address'] == self.address['public_ip'] and not static_route['revoke']:
|
||||||
|
self.fw.append(["mangle", "",
|
||||||
|
"-A PREROUTING -m state --state NEW -i %s -s %s ! -d %s/32 -j ACL_OUTBOUND_%s" %
|
||||||
|
(self.dev, static_route['network'], static_route['ip_address'], self.dev)])
|
||||||
|
self.fw.append(["filter", "front", "-A FORWARD -d %s -o %s -j ACL_INBOUND_%s" %
|
||||||
|
(static_route['network'], self.dev, self.dev)])
|
||||||
|
self.fw.append(["filter", "front",
|
||||||
|
"-A FORWARD -d %s -o %s -m state --state RELATED,ESTABLISHED -j ACCEPT" %
|
||||||
|
(static_route['network'], self.dev)])
|
||||||
|
|
||||||
if self.address["source_nat"]:
|
if self.address["source_nat"]:
|
||||||
self.fw.append(["nat", "front",
|
self.fw.append(["nat", "front",
|
||||||
"-A POSTROUTING -o %s -j SNAT --to-source %s" %
|
"-A POSTROUTING -o %s -j SNAT --to-source %s" %
|
||||||
|
|||||||
@ -139,8 +139,7 @@ class CsDhcp(CsDataBag):
|
|||||||
# Listen Address
|
# Listen Address
|
||||||
if self.cl.is_redundant():
|
if self.cl.is_redundant():
|
||||||
listen_address.append(gateway)
|
listen_address.append(gateway)
|
||||||
else:
|
listen_address.append(ip)
|
||||||
listen_address.append(ip)
|
|
||||||
# Add localized "data-server" records in /etc/hosts for VPC routers
|
# Add localized "data-server" records in /etc/hosts for VPC routers
|
||||||
if self.config.is_vpc() or self.config.is_router():
|
if self.config.is_vpc() or self.config.is_router():
|
||||||
self.add_host(gateway, "%s data-server" % CsHelper.get_hostname())
|
self.add_host(gateway, "%s data-server" % CsHelper.get_hostname())
|
||||||
|
|||||||
@ -74,6 +74,7 @@ class TestData(object):
|
|||||||
"listApis": "allow",
|
"listApis": "allow",
|
||||||
"listAccounts": "allow",
|
"listAccounts": "allow",
|
||||||
"listClusters": "deny",
|
"listClusters": "deny",
|
||||||
|
"*VmwareDc*": "allow",
|
||||||
"*VM*": "allow",
|
"*VM*": "allow",
|
||||||
"*Host*": "deny"
|
"*Host*": "deny"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3263,6 +3263,7 @@
|
|||||||
"message.license.agreements.not.accepted": "License agreements not accepted.",
|
"message.license.agreements.not.accepted": "License agreements not accepted.",
|
||||||
"message.linstor.resourcegroup.description": "Linstor resource group to use for primary storage.",
|
"message.linstor.resourcegroup.description": "Linstor resource group to use for primary storage.",
|
||||||
"message.list.zone.vmware.datacenter.empty": "No VMware Datacenter exists in the selected Zone",
|
"message.list.zone.vmware.datacenter.empty": "No VMware Datacenter exists in the selected Zone",
|
||||||
|
"message.list.zone.vmware.hosts.empty": "No VMware hosts were found in the selected Datacenter",
|
||||||
"message.listnsp.not.return.providerid": "error: listNetworkServiceProviders API doesn't return VirtualRouter provider ID.",
|
"message.listnsp.not.return.providerid": "error: listNetworkServiceProviders API doesn't return VirtualRouter provider ID.",
|
||||||
"message.load.host.failed": "Failed to load hosts.",
|
"message.load.host.failed": "Failed to load hosts.",
|
||||||
"message.loadbalancer.stickypolicy.configuration": "Customize the load balancer stickiness policy:",
|
"message.loadbalancer.stickypolicy.configuration": "Customize the load balancer stickiness policy:",
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
import { shallowRef, defineAsyncComponent } from 'vue'
|
import { shallowRef, defineAsyncComponent } from 'vue'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
|
import { isZoneCreated } from '@/utils/zone'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'compute',
|
name: 'compute',
|
||||||
@ -100,6 +101,7 @@ export default {
|
|||||||
label: 'label.vm.add',
|
label: 'label.vm.add',
|
||||||
docHelp: 'adminguide/virtual_machines.html#creating-vms',
|
docHelp: 'adminguide/virtual_machines.html#creating-vms',
|
||||||
listView: true,
|
listView: true,
|
||||||
|
show: isZoneCreated,
|
||||||
component: () => import('@/views/compute/DeployVM.vue')
|
component: () => import('@/views/compute/DeployVM.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -225,6 +227,10 @@ export default {
|
|||||||
args: ['virtualmachineid', 'backupofferingid'],
|
args: ['virtualmachineid', 'backupofferingid'],
|
||||||
show: (record) => { return !record.backupofferingid },
|
show: (record) => { return !record.backupofferingid },
|
||||||
mapping: {
|
mapping: {
|
||||||
|
backupofferingid: {
|
||||||
|
api: 'listBackupOfferings',
|
||||||
|
params: (record) => { return { zoneid: record.zoneid } }
|
||||||
|
},
|
||||||
virtualmachineid: {
|
virtualmachineid: {
|
||||||
value: (record, params) => { return record.id }
|
value: (record, params) => { return record.id }
|
||||||
}
|
}
|
||||||
@ -569,6 +575,7 @@ export default {
|
|||||||
docHelp: 'plugins/cloudstack-kubernetes-service.html#creating-a-new-kubernetes-cluster',
|
docHelp: 'plugins/cloudstack-kubernetes-service.html#creating-a-new-kubernetes-cluster',
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
|
show: isZoneCreated,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/CreateKubernetesCluster.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/compute/CreateKubernetesCluster.vue')))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -697,6 +704,7 @@ export default {
|
|||||||
icon: 'plus-outlined',
|
icon: 'plus-outlined',
|
||||||
label: 'label.new.autoscale.vmgroup',
|
label: 'label.new.autoscale.vmgroup',
|
||||||
listView: true,
|
listView: true,
|
||||||
|
show: isZoneCreated,
|
||||||
component: () => import('@/views/compute/CreateAutoScaleVmGroup.vue')
|
component: () => import('@/views/compute/CreateAutoScaleVmGroup.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -787,6 +795,7 @@ export default {
|
|||||||
icon: 'plus-outlined',
|
icon: 'plus-outlined',
|
||||||
label: 'label.new.instance.group',
|
label: 'label.new.instance.group',
|
||||||
listView: true,
|
listView: true,
|
||||||
|
show: isZoneCreated,
|
||||||
args: ['name']
|
args: ['name']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
import { shallowRef, defineAsyncComponent } from 'vue'
|
import { shallowRef, defineAsyncComponent } from 'vue'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
|
import { isZoneCreated } from '@/utils/zone'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'image',
|
name: 'image',
|
||||||
@ -110,16 +111,17 @@ export default {
|
|||||||
docHelp: 'adminguide/templates.html#uploading-templates-from-a-remote-http-server',
|
docHelp: 'adminguide/templates.html#uploading-templates-from-a-remote-http-server',
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
|
show: isZoneCreated,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/image/RegisterOrUploadTemplate.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/image/RegisterOrUploadTemplate.vue')))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
api: 'registerTemplate',
|
api: 'registerTemplate',
|
||||||
icon: 'cloud-upload-outlined',
|
icon: 'cloud-upload-outlined',
|
||||||
label: 'label.upload.template.from.local',
|
label: 'label.upload.template.from.local',
|
||||||
show: () => { return 'getUploadParamsForTemplate' in store.getters.apis },
|
|
||||||
docHelp: 'adminguide/templates.html#uploading-templates-and-isos-from-a-local-computer',
|
docHelp: 'adminguide/templates.html#uploading-templates-and-isos-from-a-local-computer',
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
|
show: () => { return isZoneCreated() && 'getUploadParamsForTemplate' in store.getters.apis },
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/image/RegisterOrUploadTemplate.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/image/RegisterOrUploadTemplate.vue')))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -270,13 +272,14 @@ export default {
|
|||||||
docHelp: 'adminguide/templates.html#id10',
|
docHelp: 'adminguide/templates.html#id10',
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
|
show: isZoneCreated,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/image/RegisterOrUploadIso.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/image/RegisterOrUploadIso.vue')))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
api: 'registerIso',
|
api: 'registerIso',
|
||||||
icon: 'cloud-upload-outlined',
|
icon: 'cloud-upload-outlined',
|
||||||
label: 'label.upload.iso.from.local',
|
label: 'label.upload.iso.from.local',
|
||||||
show: () => { return 'getUploadParamsForIso' in store.getters.apis },
|
show: () => { return isZoneCreated() && 'getUploadParamsForIso' in store.getters.apis },
|
||||||
docHelp: 'adminguide/templates.html#id10',
|
docHelp: 'adminguide/templates.html#id10',
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
@ -389,6 +392,7 @@ export default {
|
|||||||
label: 'label.kubernetes.version.add',
|
label: 'label.kubernetes.version.add',
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
|
show: isZoneCreated,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/image/AddKubernetesSupportedVersion.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/image/AddKubernetesSupportedVersion.vue')))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import { shallowRef, defineAsyncComponent } from 'vue'
|
|||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import tungsten from '@/assets/icons/tungsten.svg?inline'
|
import tungsten from '@/assets/icons/tungsten.svg?inline'
|
||||||
import { isAdmin } from '@/role'
|
import { isAdmin } from '@/role'
|
||||||
|
import { isZoneCreated } from '@/utils/zone'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'network',
|
name: 'network',
|
||||||
@ -123,7 +124,7 @@ export default {
|
|||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
show: () => {
|
show: () => {
|
||||||
if (!store.getters.zones || store.getters.zones.length === 0) {
|
if (!isZoneCreated()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
const AdvancedZones = store.getters.zones.filter(zone => zone.networktype === 'Advanced')
|
const AdvancedZones = store.getters.zones.filter(zone => zone.networktype === 'Advanced')
|
||||||
@ -245,6 +246,7 @@ export default {
|
|||||||
icon: 'plus-outlined',
|
icon: 'plus-outlined',
|
||||||
label: 'label.add.vpc',
|
label: 'label.add.vpc',
|
||||||
docHelp: 'adminguide/networking_and_traffic.html#adding-a-virtual-private-cloud',
|
docHelp: 'adminguide/networking_and_traffic.html#adding-a-virtual-private-cloud',
|
||||||
|
show: isZoneCreated,
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/CreateVpc.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/network/CreateVpc.vue')))
|
||||||
@ -306,7 +308,7 @@ export default {
|
|||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/IngressEgressRuleConfigure.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/network/IngressEgressRuleConfigure.vue')))
|
||||||
}],
|
}],
|
||||||
show: () => {
|
show: () => {
|
||||||
if (!store.getters.zones || store.getters.zones.length === 0) {
|
if (!isZoneCreated()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
const listZoneHaveSGEnabled = store.getters.zones.filter(zone => zone.securitygroupsenabled === true)
|
const listZoneHaveSGEnabled = store.getters.zones.filter(zone => zone.securitygroupsenabled === true)
|
||||||
@ -394,6 +396,7 @@ export default {
|
|||||||
label: 'label.vnf.appliance.add',
|
label: 'label.vnf.appliance.add',
|
||||||
docHelp: 'adminguide/networking/vnf_templates_appliances.html#deploying-vnf-appliances',
|
docHelp: 'adminguide/networking/vnf_templates_appliances.html#deploying-vnf-appliances',
|
||||||
listView: true,
|
listView: true,
|
||||||
|
show: isZoneCreated,
|
||||||
component: () => import('@/views/compute/DeployVnfAppliance.vue')
|
component: () => import('@/views/compute/DeployVnfAppliance.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -941,6 +944,7 @@ export default {
|
|||||||
label: 'label.add.vpn.gateway',
|
label: 'label.add.vpn.gateway',
|
||||||
docHelp: 'adminguide/networking_and_traffic.html#creating-a-vpn-gateway-for-the-vpc',
|
docHelp: 'adminguide/networking_and_traffic.html#creating-a-vpn-gateway-for-the-vpc',
|
||||||
listView: true,
|
listView: true,
|
||||||
|
show: isZoneCreated,
|
||||||
args: ['vpcid']
|
args: ['vpcid']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1116,6 +1120,7 @@ export default {
|
|||||||
icon: 'plus-outlined',
|
icon: 'plus-outlined',
|
||||||
label: 'label.add.vpn.user',
|
label: 'label.add.vpn.user',
|
||||||
listView: true,
|
listView: true,
|
||||||
|
show: isZoneCreated,
|
||||||
args: (record, store) => {
|
args: (record, store) => {
|
||||||
if (store.userInfo.roletype === 'User') {
|
if (store.userInfo.roletype === 'User') {
|
||||||
return ['username', 'password']
|
return ['username', 'password']
|
||||||
@ -1195,6 +1200,7 @@ export default {
|
|||||||
docHelp: 'adminguide/networking_and_traffic.html#creating-and-updating-a-vpn-customer-gateway',
|
docHelp: 'adminguide/networking_and_traffic.html#creating-and-updating-a-vpn-customer-gateway',
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
|
show: isZoneCreated,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/CreateVpnCustomerGateway.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/network/CreateVpnCustomerGateway.vue')))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1384,12 +1390,7 @@ export default {
|
|||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/network/GuestVlanNetworksTab.vue'))),
|
component: shallowRef(defineAsyncComponent(() => import('@/views/network/GuestVlanNetworksTab.vue'))),
|
||||||
show: (record) => { return (record.allocationstate === 'Allocated') }
|
show: (record) => { return (record.allocationstate === 'Allocated') }
|
||||||
}],
|
}],
|
||||||
show: () => {
|
show: isZoneCreated
|
||||||
if (!store.getters.zones || store.getters.zones.length === 0) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
import { shallowRef, defineAsyncComponent } from 'vue'
|
import { shallowRef, defineAsyncComponent } from 'vue'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
|
import { isZoneCreated } from '@/utils/zone'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'storage',
|
name: 'storage',
|
||||||
@ -103,6 +104,7 @@ export default {
|
|||||||
icon: 'plus-outlined',
|
icon: 'plus-outlined',
|
||||||
docHelp: 'adminguide/storage.html#creating-a-new-volume',
|
docHelp: 'adminguide/storage.html#creating-a-new-volume',
|
||||||
label: 'label.action.create.volume',
|
label: 'label.action.create.volume',
|
||||||
|
show: isZoneCreated,
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/storage/CreateVolume.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/storage/CreateVolume.vue')))
|
||||||
@ -112,7 +114,7 @@ export default {
|
|||||||
icon: 'cloud-upload-outlined',
|
icon: 'cloud-upload-outlined',
|
||||||
docHelp: 'adminguide/storage.html#uploading-an-existing-volume-to-a-virtual-machine',
|
docHelp: 'adminguide/storage.html#uploading-an-existing-volume-to-a-virtual-machine',
|
||||||
label: 'label.upload.volume.from.local',
|
label: 'label.upload.volume.from.local',
|
||||||
show: () => { return 'getUploadParamsForVolume' in store.getters.apis },
|
show: () => { return isZoneCreated() && 'getUploadParamsForVolume' in store.getters.apis },
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/storage/UploadLocalVolume.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/storage/UploadLocalVolume.vue')))
|
||||||
@ -122,6 +124,7 @@ export default {
|
|||||||
icon: 'link-outlined',
|
icon: 'link-outlined',
|
||||||
docHelp: 'adminguide/storage.html#uploading-an-existing-volume-to-a-virtual-machine',
|
docHelp: 'adminguide/storage.html#uploading-an-existing-volume-to-a-virtual-machine',
|
||||||
label: 'label.upload.volume.from.url',
|
label: 'label.upload.volume.from.url',
|
||||||
|
show: isZoneCreated,
|
||||||
listView: true,
|
listView: true,
|
||||||
popup: true,
|
popup: true,
|
||||||
component: shallowRef(defineAsyncComponent(() => import('@/views/storage/UploadVolume.vue')))
|
component: shallowRef(defineAsyncComponent(() => import('@/views/storage/UploadVolume.vue')))
|
||||||
|
|||||||
25
ui/src/utils/zone.js
Normal file
25
ui/src/utils/zone.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
import store from '@/store'
|
||||||
|
|
||||||
|
export function isZoneCreated () {
|
||||||
|
if (!store.getters.zones || store.getters.zones.length === 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
@ -793,6 +793,10 @@ export default {
|
|||||||
if (this.scopeType === 'domain') {
|
if (this.scopeType === 'domain') {
|
||||||
params.domainid = this.selectedDomain.id
|
params.domainid = this.selectedDomain.id
|
||||||
}
|
}
|
||||||
|
console.log(params?.tags?.length === 0)
|
||||||
|
if (!params?.tags || params.tags.length === 0) {
|
||||||
|
params.istagged = false
|
||||||
|
}
|
||||||
this.handleNetworkOfferingChange(null)
|
this.handleNetworkOfferingChange(null)
|
||||||
this.networkOfferings = []
|
this.networkOfferings = []
|
||||||
api('listNetworkOfferings', params).then(json => {
|
api('listNetworkOfferings', params).then(json => {
|
||||||
|
|||||||
@ -1198,6 +1198,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
params.existingvcenterid = this.selectedVmwareVcenter.existingvcenterid
|
params.existingvcenterid = this.selectedVmwareVcenter.existingvcenterid
|
||||||
}
|
}
|
||||||
|
params.host = this.selectedVmwareVcenter.host
|
||||||
}
|
}
|
||||||
|
|
||||||
api(apiName, params).then(json => {
|
api(apiName, params).then(json => {
|
||||||
|
|||||||
@ -89,6 +89,7 @@
|
|||||||
<a-input
|
<a-input
|
||||||
v-model:value="vcenter"
|
v-model:value="vcenter"
|
||||||
:placeholder="apiParams.vcenter.description"
|
:placeholder="apiParams.vcenter.description"
|
||||||
|
@change="onSelectExternalVmwareDatacenter"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item ref="datacenter" name="datacenter">
|
<a-form-item ref="datacenter" name="datacenter">
|
||||||
@ -98,6 +99,7 @@
|
|||||||
<a-input
|
<a-input
|
||||||
v-model:value="datacenter"
|
v-model:value="datacenter"
|
||||||
:placeholder="apiParams.datacentername.description"
|
:placeholder="apiParams.datacentername.description"
|
||||||
|
@change="onSelectExternalVmwareDatacenter"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item ref="username" name="username">
|
<a-form-item ref="username" name="username">
|
||||||
@ -107,6 +109,7 @@
|
|||||||
<a-input
|
<a-input
|
||||||
v-model:value="username"
|
v-model:value="username"
|
||||||
:placeholder="apiParams.username.description"
|
:placeholder="apiParams.username.description"
|
||||||
|
@change="onSelectExternalVmwareDatacenter"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item ref="password" name="password">
|
<a-form-item ref="password" name="password">
|
||||||
@ -116,14 +119,36 @@
|
|||||||
<a-input-password
|
<a-input-password
|
||||||
v-model:value="password"
|
v-model:value="password"
|
||||||
:placeholder="apiParams.password.description"
|
:placeholder="apiParams.password.description"
|
||||||
|
@change="onSelectExternalVmwareDatacenter"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="selectedExistingVcenterId || (vcenterSelectedOption === 'new')">
|
||||||
|
<a-form-item :label="$t('label.vcenter.host')" ref="host" name="host" v-if="hosts.length > 0">
|
||||||
|
<a-select
|
||||||
|
v-model:value="form.host"
|
||||||
|
:loading="loading"
|
||||||
|
optionFilterProp="label"
|
||||||
|
:filterOption="(input, option) => {
|
||||||
|
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||||
|
}"
|
||||||
|
:placeholder="$t('label.vcenter.host')"
|
||||||
|
@change="onSelectExistingVmwareHost">
|
||||||
|
<a-select-option v-for="opt in hosts" :key="opt.name">
|
||||||
|
{{ 'ESXi: ' + opt.name }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<div v-else>
|
||||||
|
{{ $t('message.list.zone.vmware.hosts.empty') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<a-button
|
<a-button
|
||||||
v-if="vcenterSelectedOption == 'existing' || vcenterSelectedOption == 'new'"
|
v-if="vcenterSelectedOption == 'existing' || vcenterSelectedOption == 'new'"
|
||||||
:disabled="(vcenterSelectedOption === 'new' && (vcenter === '' || datacentername === '' || username === '' || password === '')) ||
|
:disabled="(vcenterSelectedOption === 'new' && (vcenter === '' || datacentername === '' || username === '' || password === '')) ||
|
||||||
(vcenterSelectedOption === 'existing' && selectedExistingVcenterId === '')"
|
(vcenterSelectedOption === 'existing' && selectedExistingVcenterId === '') && host === ''"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="listVmwareDatacenterVms">{{ $t('label.list.vmware.vcenter.vms') }}</a-button>
|
@click="listVmwareDatacenterVms">{{ $t('label.list.vmware.vcenter.vms') }}</a-button>
|
||||||
@ -154,6 +179,8 @@ export default {
|
|||||||
zones: {},
|
zones: {},
|
||||||
vcenterSelectedOption: '',
|
vcenterSelectedOption: '',
|
||||||
existingvcenter: [],
|
existingvcenter: [],
|
||||||
|
hosts: [],
|
||||||
|
selectedHost: '',
|
||||||
selectedExistingVcenterId: '',
|
selectedExistingVcenterId: '',
|
||||||
selectedPoweredOnVm: false,
|
selectedPoweredOnVm: false,
|
||||||
vmwareDcVms: [],
|
vmwareDcVms: [],
|
||||||
@ -217,6 +244,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
params.existingvcenterid = this.selectedExistingVcenterId
|
params.existingvcenterid = this.selectedExistingVcenterId
|
||||||
}
|
}
|
||||||
|
params.host = this.selectedHost
|
||||||
api('listVmwareDcVms', params).then(json => {
|
api('listVmwareDcVms', params).then(json => {
|
||||||
const obj = {
|
const obj = {
|
||||||
params: params,
|
params: params,
|
||||||
@ -246,8 +274,29 @@ export default {
|
|||||||
listZoneVmwareDcs () {
|
listZoneVmwareDcs () {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
api('listVmwareDcs', { zoneid: this.sourcezoneid }).then(response => {
|
api('listVmwareDcs', { zoneid: this.sourcezoneid }).then(response => {
|
||||||
if (response.listvmwaredcsresponse.VMwareDC && response.listvmwaredcsresponse.VMwareDC.length > 0) {
|
if (response.listvmwaredcsresponse.vmwaredc && response.listvmwaredcsresponse.vmwaredc.length > 0) {
|
||||||
this.existingvcenter = response.listvmwaredcsresponse.VMwareDC
|
this.existingvcenter = response.listvmwaredcsresponse.vmwaredc
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
this.$notifyError(error)
|
||||||
|
}).finally(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
listZoneVmwareDcHosts () {
|
||||||
|
this.loading = true
|
||||||
|
const params = {}
|
||||||
|
if (this.vcenterSelectedOption === 'new') {
|
||||||
|
params.datacentername = this.datacenter
|
||||||
|
params.vcenter = this.vcenter
|
||||||
|
params.username = this.username
|
||||||
|
params.password = this.password
|
||||||
|
} else {
|
||||||
|
params.existingvcenterid = this.selectedExistingVcenterId
|
||||||
|
}
|
||||||
|
api('listVmwareDcHosts', params).then(response => {
|
||||||
|
if (response.listvmwaredchostsresponse.host && response.listvmwaredchostsresponse.host.length > 0) {
|
||||||
|
this.hosts = response.listvmwaredchostsresponse.host
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.$notifyError(error)
|
this.$notifyError(error)
|
||||||
@ -257,6 +306,15 @@ export default {
|
|||||||
},
|
},
|
||||||
onSelectExistingVmwareDatacenter (value) {
|
onSelectExistingVmwareDatacenter (value) {
|
||||||
this.selectedExistingVcenterId = value
|
this.selectedExistingVcenterId = value
|
||||||
|
this.listZoneVmwareDcHosts()
|
||||||
|
},
|
||||||
|
onSelectExternalVmwareDatacenter (value) {
|
||||||
|
if (this.vcenterSelectedOption === 'new' && !(this.vcenter === '' || this.datacentername === '' || this.username === '' || this.password === '')) {
|
||||||
|
this.listZoneVmwareDcHosts()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSelectExistingVmwareHost (value) {
|
||||||
|
this.selectedHost = value
|
||||||
},
|
},
|
||||||
onVcenterTypeChange () {
|
onVcenterTypeChange () {
|
||||||
this.$emit('onVcenterTypeChanged', this.vcenterSelectedOption)
|
this.$emit('onVcenterTypeChanged', this.vcenterSelectedOption)
|
||||||
|
|||||||
@ -19,14 +19,25 @@ package com.cloud.hypervisor.vmware.mo;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
|
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
||||||
|
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
|
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||||
|
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
||||||
|
|
||||||
import com.vmware.vim25.CustomFieldDef;
|
import com.vmware.vim25.CustomFieldDef;
|
||||||
import com.vmware.vim25.CustomFieldStringValue;
|
import com.vmware.vim25.CustomFieldStringValue;
|
||||||
import com.vmware.vim25.ManagedObjectReference;
|
import com.vmware.vim25.ManagedObjectReference;
|
||||||
|
import com.vmware.vim25.InvalidPropertyFaultMsg;
|
||||||
|
import com.vmware.vim25.RuntimeFaultFaultMsg;
|
||||||
|
import com.vmware.vim25.ObjectContent;
|
||||||
|
import com.vmware.vim25.RetrieveResult;
|
||||||
|
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class BaseMO {
|
public class BaseMO {
|
||||||
protected Logger logger = LogManager.getLogger(getClass());
|
protected static Logger logger = LogManager.getLogger(BaseMO.class);
|
||||||
|
|
||||||
protected VmwareContext _context;
|
protected VmwareContext _context;
|
||||||
protected ManagedObjectReference _mor;
|
protected ManagedObjectReference _mor;
|
||||||
@ -51,6 +62,15 @@ public class BaseMO {
|
|||||||
_mor.setValue(morValue);
|
_mor.setValue(morValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static Pair<String, List<ObjectContent>> createReturnObjectPair(RetrieveResult result) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("vmware result : {} ", ReflectionToStringBuilderUtils.reflectCollection(result));
|
||||||
|
}
|
||||||
|
String tokenForRetrievingNewResults = result.getToken();
|
||||||
|
List<ObjectContent> listOfObjects = result.getObjects();
|
||||||
|
return new Pair<>(tokenForRetrievingNewResults, listOfObjects);
|
||||||
|
}
|
||||||
|
|
||||||
public VmwareContext getContext() {
|
public VmwareContext getContext() {
|
||||||
return _context;
|
return _context;
|
||||||
}
|
}
|
||||||
@ -61,12 +81,12 @@ public class BaseMO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ManagedObjectReference getParentMor() throws Exception {
|
public ManagedObjectReference getParentMor() throws Exception {
|
||||||
return (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "parent");
|
return _context.getVimClient().getDynamicProperty(_mor, "parent");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() throws Exception {
|
public String getName() throws Exception {
|
||||||
if (_name == null)
|
if (_name == null)
|
||||||
_name = (String)_context.getVimClient().getDynamicProperty(_mor, "name");
|
_name = _context.getVimClient().getDynamicProperty(_mor, "name");
|
||||||
|
|
||||||
return _name;
|
return _name;
|
||||||
}
|
}
|
||||||
@ -83,7 +103,7 @@ public class BaseMO {
|
|||||||
_context.waitForTaskProgressDone(morTask);
|
_context.waitForTaskProgressDone(morTask);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
logger.error("VMware destroy_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
|
logger.error("VMware destroy_Task failed due to {}", TaskMO.getTaskFailureInfo(_context, morTask));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -100,7 +120,7 @@ public class BaseMO {
|
|||||||
_context.waitForTaskProgressDone(morTask);
|
_context.waitForTaskProgressDone(morTask);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
logger.error("VMware rename_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
|
logger.error("VMware rename_Task failed due to {}", TaskMO.getTaskFailureInfo(_context, morTask));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -131,18 +151,18 @@ public class BaseMO {
|
|||||||
if (key == 0)
|
if (key == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
CustomFieldStringValue cfValue = (CustomFieldStringValue)_context.getVimClient().getDynamicProperty(getMor(), String.format("value[%d]", key));
|
CustomFieldStringValue cfValue = _context.getVimClient().getDynamicProperty(getMor(), String.format("value[%d]", key));
|
||||||
if (cfValue != null)
|
if (cfValue != null)
|
||||||
return cfValue.getValue();
|
return cfValue.getValue();
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCustomFieldKey(String fieldName) throws Exception {
|
public int getCustomFieldKey(String fieldName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
return getCustomFieldKey(getMor().getType(), fieldName);
|
return getCustomFieldKey(getMor().getType(), fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCustomFieldKey(String morType, String fieldName) throws Exception {
|
public int getCustomFieldKey(String morType, String fieldName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
assert (morType != null);
|
assert (morType != null);
|
||||||
|
|
||||||
ManagedObjectReference cfmMor = _context.getServiceContent().getCustomFieldsManager();
|
ManagedObjectReference cfmMor = _context.getServiceContent().getCustomFieldsManager();
|
||||||
@ -154,4 +174,30 @@ public class BaseMO {
|
|||||||
|
|
||||||
return cfmMo.getCustomFieldKey(morType, fieldName);
|
return cfmMo.getCustomFieldKey(morType, fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Pair<String, List<ObjectContent>> retrieveNextSetOfProperties(String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
|
RetrieveResult result = _context.getService().continueRetrievePropertiesEx(_context.getPropertyCollector(), tokenForPriorQuery);
|
||||||
|
return BaseMO.createReturnObjectPair(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void objectContentToUnmanagedInstanceTO(Pair<String, List<ObjectContent>> objectContents, List<UnmanagedInstanceTO> vms) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
|
List<ObjectContent> ocs = objectContents.second();
|
||||||
|
if (ocs != null) {
|
||||||
|
for (ObjectContent oc : ocs) {
|
||||||
|
ManagedObjectReference vmMor = oc.getObj();
|
||||||
|
if (vmMor != null) {
|
||||||
|
VirtualMachineMO vmMo = new VirtualMachineMO(_context, vmMor);
|
||||||
|
try {
|
||||||
|
if (!vmMo.isTemplate()) {
|
||||||
|
HostMO hostMO = vmMo.getRunningHost();
|
||||||
|
UnmanagedInstanceTO unmanagedInstance = VmwareHelper.getUnmanagedInstance(hostMO, vmMo);
|
||||||
|
vms.add(unmanagedInstance);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.debug("Unexpected error checking unmanaged instance {}, excluding it: {}", vmMo.getVmName(), e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,11 +16,14 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.hypervisor.vmware.mo;
|
package com.cloud.hypervisor.vmware.mo;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.vmware.vim25.CustomFieldDef;
|
import com.vmware.vim25.CustomFieldDef;
|
||||||
import com.vmware.vim25.ManagedObjectReference;
|
import com.vmware.vim25.ManagedObjectReference;
|
||||||
import com.vmware.vim25.PrivilegePolicyDef;
|
import com.vmware.vim25.PrivilegePolicyDef;
|
||||||
|
import com.vmware.vim25.InvalidPropertyFaultMsg;
|
||||||
|
import com.vmware.vim25.RuntimeFaultFaultMsg;
|
||||||
|
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||||
|
|
||||||
@ -50,12 +53,12 @@ public class CustomFieldsManagerMO extends BaseMO {
|
|||||||
_context.getService().setField(getMor(), morEntity, key, value);
|
_context.getService().setField(getMor(), morEntity, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CustomFieldDef> getFields() throws Exception {
|
public List<CustomFieldDef> getFields() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
return _context.getVimClient().getDynamicProperty(getMor(), "field");
|
return _context.getVimClient().getDynamicProperty(getMor(), "field");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCustomFieldKey(String morType, String fieldName) throws Exception {
|
public int getCustomFieldKey(String morType, String fieldName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
List<CustomFieldDef> fields = getFields();
|
List<CustomFieldDef> fields = getFields();
|
||||||
if (fields != null) {
|
if (fields != null) {
|
||||||
for (CustomFieldDef field : fields) {
|
for (CustomFieldDef field : fields) {
|
||||||
|
|||||||
@ -17,11 +17,12 @@
|
|||||||
|
|
||||||
package com.cloud.hypervisor.vmware.mo;
|
package com.cloud.hypervisor.vmware.mo;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
import com.cloud.utils.StringUtils;
|
||||||
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
|
||||||
@ -38,6 +39,10 @@ import com.vmware.vim25.PropertySpec;
|
|||||||
import com.vmware.vim25.SelectionSpec;
|
import com.vmware.vim25.SelectionSpec;
|
||||||
import com.vmware.vim25.TraversalSpec;
|
import com.vmware.vim25.TraversalSpec;
|
||||||
import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
|
import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
|
||||||
|
import com.vmware.vim25.RetrieveOptions;
|
||||||
|
import com.vmware.vim25.RetrieveResult;
|
||||||
|
import com.vmware.vim25.InvalidPropertyFaultMsg;
|
||||||
|
import com.vmware.vim25.RuntimeFaultFaultMsg;
|
||||||
|
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||||
import com.cloud.utils.Pair;
|
import com.cloud.utils.Pair;
|
||||||
@ -52,35 +57,18 @@ public class DatacenterMO extends BaseMO {
|
|||||||
super(context, morType, morValue);
|
super(context, morType, morValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DatacenterMO(VmwareContext context, String dcName) throws Exception {
|
public DatacenterMO(VmwareContext context, String dcName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
super(context, null);
|
super(context, null);
|
||||||
|
|
||||||
_mor = _context.getVimClient().getDecendentMoRef(_context.getRootFolder(), "Datacenter", dcName);
|
_mor = _context.getVimClient().getDecendentMoRef(_context.getRootFolder(), "Datacenter", dcName);
|
||||||
if (_mor == null) {
|
if (_mor == null) {
|
||||||
logger.error("Unable to locate DC " + dcName);
|
logger.error("Unable to locate DC {}", dcName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() throws Exception {
|
public String getName() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
return (String)_context.getVimClient().getDynamicProperty(_mor, "name");
|
return _context.getVimClient().getDynamicProperty(_mor, "name");
|
||||||
}
|
|
||||||
|
|
||||||
public void registerTemplate(ManagedObjectReference morHost, String datastoreName, String templateName, String templateFileName) throws Exception {
|
|
||||||
|
|
||||||
ManagedObjectReference morFolder = (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "vmFolder");
|
|
||||||
assert (morFolder != null);
|
|
||||||
|
|
||||||
ManagedObjectReference morTask =
|
|
||||||
_context.getService()
|
|
||||||
.registerVMTask(morFolder, String.format("[%s] %s/%s", datastoreName, templateName, templateFileName), templateName, true, null, morHost);
|
|
||||||
|
|
||||||
boolean result = _context.getVimClient().waitForTask(morTask);
|
|
||||||
if (!result) {
|
|
||||||
throw new Exception("Unable to register template due to " + TaskMO.getTaskFailureInfo(_context, morTask));
|
|
||||||
} else {
|
|
||||||
_context.waitForTaskProgressDone(morTask);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public VirtualMachineMO findVm(String vmName) throws Exception {
|
public VirtualMachineMO findVm(String vmName) throws Exception {
|
||||||
@ -89,7 +77,7 @@ public class DatacenterMO extends BaseMO {
|
|||||||
logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
|
logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
|
||||||
}
|
}
|
||||||
String instanceNameCustomField = "value[" + key + "]";
|
String instanceNameCustomField = "value[" + key + "]";
|
||||||
List<ObjectContent> ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name", instanceNameCustomField});
|
List<ObjectContent> ocs = getVmProperties(new String[] {"name", instanceNameCustomField});
|
||||||
return HypervisorHostHelper.findVmFromObjectContent(_context, ocs.toArray(new ObjectContent[0]), vmName, instanceNameCustomField);
|
return HypervisorHostHelper.findVmFromObjectContent(_context, ocs.toArray(new ObjectContent[0]), vmName, instanceNameCustomField);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,10 +86,10 @@ public class DatacenterMO extends BaseMO {
|
|||||||
int key = cfmMo.getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_UUID);
|
int key = cfmMo.getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_UUID);
|
||||||
assert (key != 0);
|
assert (key != 0);
|
||||||
|
|
||||||
List<VirtualMachineMO> list = new ArrayList<VirtualMachineMO>();
|
List<VirtualMachineMO> list = new ArrayList<>();
|
||||||
|
|
||||||
List<ObjectContent> ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name", String.format("value[%d]", key)});
|
List<ObjectContent> ocs = getVmProperties(new String[] {"name", String.format("value[%d]", key)});
|
||||||
if (ocs != null && ocs.size() > 0) {
|
if (CollectionUtils.isNotEmpty(ocs)) {
|
||||||
for (ObjectContent oc : ocs) {
|
for (ObjectContent oc : ocs) {
|
||||||
List<DynamicProperty> props = oc.getPropSet();
|
List<DynamicProperty> props = oc.getPropSet();
|
||||||
if (props != null) {
|
if (props != null) {
|
||||||
@ -133,8 +121,8 @@ public class DatacenterMO extends BaseMO {
|
|||||||
logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
|
logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ObjectContent> ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name", String.format("value[%d]", key)});
|
List<ObjectContent> ocs = getVmProperties(new String[] {"name", String.format("value[%d]", key)});
|
||||||
if (ocs != null && ocs.size() > 0) {
|
if (CollectionUtils.isNotEmpty(ocs)) {
|
||||||
for (ObjectContent oc : ocs) {
|
for (ObjectContent oc : ocs) {
|
||||||
List<DynamicProperty> props = oc.getPropSet();
|
List<DynamicProperty> props = oc.getPropSet();
|
||||||
if (props != null) {
|
if (props != null) {
|
||||||
@ -159,31 +147,18 @@ public class DatacenterMO extends BaseMO {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UnmanagedInstanceTO> getAllVmsOnDatacenter() throws Exception {
|
public Pair<String, List<UnmanagedInstanceTO>> getVms(Integer maxObjects, String token) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
List<UnmanagedInstanceTO> vms = new ArrayList<>();
|
List<UnmanagedInstanceTO> vms = new ArrayList<>();
|
||||||
List<ObjectContent> ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name"});
|
Pair<String, List<ObjectContent>> objectContents = getVmProperties(new String[] {"name"}, maxObjects, token);
|
||||||
if (ocs != null) {
|
logger.debug("returning token {} for future retrievals, currently {} objects retrieved.", objectContents.first(), objectContents.second().size());
|
||||||
for (ObjectContent oc : ocs) {
|
Pair<String, List<UnmanagedInstanceTO>> retval = new Pair<>(objectContents.first(), vms);
|
||||||
ManagedObjectReference vmMor = oc.getObj();
|
|
||||||
if (vmMor != null) {
|
|
||||||
VirtualMachineMO vmMo = new VirtualMachineMO(_context, vmMor);
|
|
||||||
try {
|
|
||||||
if (!vmMo.isTemplate()) {
|
|
||||||
HostMO hostMO = vmMo.getRunningHost();
|
|
||||||
UnmanagedInstanceTO unmanagedInstance = VmwareHelper.getUnmanagedInstance(hostMO, vmMo);
|
|
||||||
vms.add(unmanagedInstance);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.debug(String.format("Unexpected error checking unmanaged instance %s, excluding it: %s", vmMo.getVmName(), e.getMessage()), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vms;
|
objectContentToUnmanagedInstanceTO(objectContents, vms);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<HostMO> getAllHostsOnDatacenter() throws Exception {
|
public List<HostMO> getAllHostsOnDatacenter() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
List<HostMO> hosts = new ArrayList<>();
|
List<HostMO> hosts = new ArrayList<>();
|
||||||
|
|
||||||
List<ObjectContent> ocs = getHostPropertiesOnDatacenterHostFolder(new String[] {"name"});
|
List<ObjectContent> ocs = getHostPropertiesOnDatacenterHostFolder(new String[] {"name"});
|
||||||
@ -210,21 +185,7 @@ public class DatacenterMO extends BaseMO {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManagedObjectReference listDatastore(String name) throws Exception {
|
public ManagedObjectReference findHost(String name) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
assert (name != null);
|
|
||||||
|
|
||||||
List<ObjectContent> ocs = getDatastorePropertiesOnDatacenter(new String[] {"name"});
|
|
||||||
if (ocs != null) {
|
|
||||||
for (ObjectContent oc : ocs) {
|
|
||||||
if (oc.getPropSet().get(0).getVal().toString().equals(name)) {
|
|
||||||
return oc.getObj();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ManagedObjectReference findHost(String name) throws Exception {
|
|
||||||
List<ObjectContent> ocs = getHostPropertiesOnDatacenterHostFolder(new String[] {"name"});
|
List<ObjectContent> ocs = getHostPropertiesOnDatacenterHostFolder(new String[] {"name"});
|
||||||
|
|
||||||
if (ocs != null) {
|
if (ocs != null) {
|
||||||
@ -238,10 +199,10 @@ public class DatacenterMO extends BaseMO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ManagedObjectReference getVmFolder() throws Exception {
|
public ManagedObjectReference getVmFolder() throws Exception {
|
||||||
return (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "vmFolder");
|
return _context.getVimClient().getDynamicProperty(_mor, "vmFolder");
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ObjectContent> getHostPropertiesOnDatacenterHostFolder(String[] propertyPaths) throws Exception {
|
public List<ObjectContent> getHostPropertiesOnDatacenterHostFolder(String[] propertyPaths) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
PropertySpec pSpec = new PropertySpec();
|
PropertySpec pSpec = new PropertySpec();
|
||||||
pSpec.setType("HostSystem");
|
pSpec.setType("HostSystem");
|
||||||
pSpec.getPathSet().addAll(Arrays.asList(propertyPaths));
|
pSpec.getPathSet().addAll(Arrays.asList(propertyPaths));
|
||||||
@ -275,7 +236,7 @@ public class DatacenterMO extends BaseMO {
|
|||||||
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
||||||
pfSpec.getPropSet().add(pSpec);
|
pfSpec.getPropSet().add(pSpec);
|
||||||
pfSpec.getObjectSet().add(oSpec);
|
pfSpec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
|
||||||
pfSpecArr.add(pfSpec);
|
pfSpecArr.add(pfSpec);
|
||||||
|
|
||||||
return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
||||||
@ -301,14 +262,37 @@ public class DatacenterMO extends BaseMO {
|
|||||||
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
||||||
pfSpec.getPropSet().add(pSpec);
|
pfSpec.getPropSet().add(pSpec);
|
||||||
pfSpec.getObjectSet().add(oSpec);
|
pfSpec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
|
||||||
pfSpecArr.add(pfSpec);
|
pfSpecArr.add(pfSpec);
|
||||||
|
|
||||||
return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ObjectContent> getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths) throws Exception {
|
public List<ObjectContent> getVmProperties(String[] propertyPaths) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
|
return getVmProperties(propertyPaths, null, null).second();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param propertyPaths Vmware side property names to query, for instance {"name"}
|
||||||
|
* @param maxObjects the number of objects to retrieve
|
||||||
|
* @param tokenForPriorQuery restart the query or continue a previous query
|
||||||
|
* @return The propertyPaths requested for the objects of type "VirtualMachine" in a list are found/returned by the DC
|
||||||
|
* @throws InvalidPropertyFaultMsg property does not exist as thrown by Vmware.
|
||||||
|
* @throws RuntimeFaultFaultMsg generic vmware runtime exception
|
||||||
|
*/
|
||||||
|
public Pair<String, List<ObjectContent>> getVmProperties(String[] propertyPaths, Integer maxObjects, String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
|
if(StringUtils.isNotBlank(tokenForPriorQuery)) {
|
||||||
|
logger.debug("running repeat query with token '{}'", tokenForPriorQuery);
|
||||||
|
return retrieveNextSetOfProperties(tokenForPriorQuery);
|
||||||
|
} else {
|
||||||
|
logger.debug("running query for {} propertypaths and max {} objects", propertyPaths.length, maxObjects);
|
||||||
|
return retrieveNextSetOfProperties(propertyPaths, maxObjects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<String, List<ObjectContent>> retrieveNextSetOfProperties(String[] propertyPaths, Integer maxObjects) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
PropertySpec pSpec = new PropertySpec();
|
PropertySpec pSpec = new PropertySpec();
|
||||||
pSpec.setType("VirtualMachine");
|
pSpec.setType("VirtualMachine");
|
||||||
pSpec.getPathSet().addAll(Arrays.asList(propertyPaths));
|
pSpec.getPathSet().addAll(Arrays.asList(propertyPaths));
|
||||||
@ -336,10 +320,16 @@ public class DatacenterMO extends BaseMO {
|
|||||||
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
||||||
pfSpec.getPropSet().add(pSpec);
|
pfSpec.getPropSet().add(pSpec);
|
||||||
pfSpec.getObjectSet().add(oSpec);
|
pfSpec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
|
||||||
pfSpecArr.add(pfSpec);
|
pfSpecArr.add(pfSpec);
|
||||||
|
|
||||||
return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
RetrieveOptions ro = new RetrieveOptions();
|
||||||
|
if (maxObjects != null && maxObjects > 0) {
|
||||||
|
ro.setMaxObjects(maxObjects);
|
||||||
|
}
|
||||||
|
|
||||||
|
RetrieveResult result = _context.getService().retrievePropertiesEx(_context.getPropertyCollector(), pfSpecArr, ro);
|
||||||
|
return createReturnObjectPair(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pair<DatacenterMO, String> getOwnerDatacenter(VmwareContext context, ManagedObjectReference morEntity) throws Exception {
|
public static Pair<DatacenterMO, String> getOwnerDatacenter(VmwareContext context, ManagedObjectReference morEntity) throws Exception {
|
||||||
@ -364,18 +354,18 @@ public class DatacenterMO extends BaseMO {
|
|||||||
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
||||||
pfSpec.getPropSet().add(pSpec);
|
pfSpec.getPropSet().add(pSpec);
|
||||||
pfSpec.getObjectSet().add(oSpec);
|
pfSpec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
|
||||||
pfSpecArr.add(pfSpec);
|
pfSpecArr.add(pfSpec);
|
||||||
|
|
||||||
List<ObjectContent> ocs = context.getService().retrieveProperties(context.getPropertyCollector(), pfSpecArr);
|
List<ObjectContent> ocs = context.getService().retrieveProperties(context.getPropertyCollector(), pfSpecArr);
|
||||||
|
|
||||||
assert (ocs != null && ocs.size() > 0);
|
assert (CollectionUtils.isNotEmpty(ocs));
|
||||||
assert (ocs.get(0).getObj() != null);
|
assert (ocs.get(0).getObj() != null);
|
||||||
assert (ocs.get(0).getPropSet().get(0) != null);
|
assert (ocs.get(0).getPropSet().get(0) != null);
|
||||||
assert (ocs.get(0).getPropSet().get(0).getVal() != null);
|
assert (ocs.get(0).getPropSet().get(0).getVal() != null);
|
||||||
|
|
||||||
String dcName = ocs.get(0).getPropSet().get(0).getVal().toString();
|
String dcName = ocs.get(0).getPropSet().get(0).getVal().toString();
|
||||||
return new Pair<DatacenterMO, String>(new DatacenterMO(context, ocs.get(0).getObj()), dcName);
|
return new Pair<>(new DatacenterMO(context, ocs.get(0).getObj()), dcName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManagedObjectReference getDvPortGroupMor(String dvPortGroupName) throws Exception {
|
public ManagedObjectReference getDvPortGroupMor(String dvPortGroupName) throws Exception {
|
||||||
@ -396,7 +386,7 @@ public class DatacenterMO extends BaseMO {
|
|||||||
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
||||||
pfSpec.getPropSet().add(pSpec);
|
pfSpec.getPropSet().add(pSpec);
|
||||||
pfSpec.getObjectSet().add(oSpec);
|
pfSpec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
|
||||||
pfSpecArr.add(pfSpec);
|
pfSpecArr.add(pfSpec);
|
||||||
|
|
||||||
List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
||||||
@ -417,9 +407,7 @@ public class DatacenterMO extends BaseMO {
|
|||||||
|
|
||||||
public boolean hasDvPortGroup(String dvPortGroupName) throws Exception {
|
public boolean hasDvPortGroup(String dvPortGroupName) throws Exception {
|
||||||
ManagedObjectReference morNetwork = getDvPortGroupMor(dvPortGroupName);
|
ManagedObjectReference morNetwork = getDvPortGroupMor(dvPortGroupName);
|
||||||
if (morNetwork != null)
|
return morNetwork != null;
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DVPortgroupConfigInfo getDvPortGroupSpec(String dvPortGroupName) throws Exception {
|
public DVPortgroupConfigInfo getDvPortGroupSpec(String dvPortGroupName) throws Exception {
|
||||||
@ -443,7 +431,7 @@ public class DatacenterMO extends BaseMO {
|
|||||||
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
||||||
pfSpec.getPropSet().add(pSpec);
|
pfSpec.getPropSet().add(pSpec);
|
||||||
pfSpec.getObjectSet().add(oSpec);
|
pfSpec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
|
||||||
pfSpecArr.add(pfSpec);
|
pfSpecArr.add(pfSpec);
|
||||||
|
|
||||||
List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
||||||
@ -460,7 +448,7 @@ public class DatacenterMO extends BaseMO {
|
|||||||
nameProperty = prop.getVal().toString();
|
nameProperty = prop.getVal().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nameProperty.equalsIgnoreCase(dvPortGroupName)) {
|
if (nameProperty != null && nameProperty.equalsIgnoreCase(dvPortGroupName)) {
|
||||||
return configSpec;
|
return configSpec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -490,7 +478,7 @@ public class DatacenterMO extends BaseMO {
|
|||||||
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
||||||
pfSpec.getPropSet().add(pSpec);
|
pfSpec.getPropSet().add(pSpec);
|
||||||
pfSpec.getObjectSet().add(oSpec);
|
pfSpec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
|
||||||
pfSpecArr.add(pfSpec);
|
pfSpecArr.add(pfSpec);
|
||||||
|
|
||||||
List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
||||||
@ -518,7 +506,7 @@ public class DatacenterMO extends BaseMO {
|
|||||||
|
|
||||||
public String getDvSwitchUuid(ManagedObjectReference dvSwitchMor) throws Exception {
|
public String getDvSwitchUuid(ManagedObjectReference dvSwitchMor) throws Exception {
|
||||||
assert (dvSwitchMor != null);
|
assert (dvSwitchMor != null);
|
||||||
return (String)_context.getVimClient().getDynamicProperty(dvSwitchMor, "uuid");
|
return _context.getVimClient().getDynamicProperty(dvSwitchMor, "uuid");
|
||||||
}
|
}
|
||||||
|
|
||||||
public VirtualEthernetCardDistributedVirtualPortBackingInfo getDvPortBackingInfo(Pair<ManagedObjectReference, String> networkInfo) throws Exception {
|
public VirtualEthernetCardDistributedVirtualPortBackingInfo getDvPortBackingInfo(Pair<ManagedObjectReference, String> networkInfo) throws Exception {
|
||||||
@ -536,8 +524,8 @@ public class DatacenterMO extends BaseMO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ManagedObjectReference getDvSwitchMor(String dvSwitchName) throws Exception {
|
public ManagedObjectReference getDvSwitchMor(String dvSwitchName) throws Exception {
|
||||||
ManagedObjectReference dvSwitchMor = null;
|
ManagedObjectReference dvSwitchMor;
|
||||||
ManagedObjectReference networkFolderMor = null;
|
ManagedObjectReference networkFolderMor;
|
||||||
networkFolderMor = _context.getVimClient().getMoRefProp(_mor, "networkFolder");
|
networkFolderMor = _context.getVimClient().getMoRefProp(_mor, "networkFolder");
|
||||||
dvSwitchMor = _context.getVimClient().getDecendentMoRef(networkFolderMor, "VmwareDistributedVirtualSwitch", dvSwitchName);
|
dvSwitchMor = _context.getVimClient().getDecendentMoRef(networkFolderMor, "VmwareDistributedVirtualSwitch", dvSwitchName);
|
||||||
return dvSwitchMor;
|
return dvSwitchMor;
|
||||||
@ -549,7 +537,6 @@ public class DatacenterMO extends BaseMO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DatacenterConfigInfo getDatacenterConfigInfo() throws Exception {
|
public DatacenterConfigInfo getDatacenterConfigInfo() throws Exception {
|
||||||
DatacenterConfigInfo configInfo = (DatacenterConfigInfo)_context.getVimClient().getDynamicProperty(_mor, "configuration");
|
return _context.getVimClient().getDynamicProperty(_mor, "configuration");
|
||||||
return configInfo;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.hypervisor.vmware.mo;
|
package com.cloud.hypervisor.vmware.mo;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -24,10 +25,19 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
||||||
|
|
||||||
|
import com.cloud.hypervisor.vmware.util.VmwareClientException;
|
||||||
|
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||||
|
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
||||||
|
import com.cloud.utils.LogUtils;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
|
import com.cloud.utils.StringUtils;
|
||||||
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import com.vmware.vim25.AboutInfo;
|
import com.vmware.vim25.AboutInfo;
|
||||||
import com.vmware.vim25.AlreadyExistsFaultMsg;
|
import com.vmware.vim25.AlreadyExistsFaultMsg;
|
||||||
import com.vmware.vim25.ClusterDasConfigInfo;
|
import com.vmware.vim25.ClusterDasConfigInfo;
|
||||||
@ -57,6 +67,7 @@ import com.vmware.vim25.HostRuntimeInfo;
|
|||||||
import com.vmware.vim25.HostSystemConnectionState;
|
import com.vmware.vim25.HostSystemConnectionState;
|
||||||
import com.vmware.vim25.HostVirtualNic;
|
import com.vmware.vim25.HostVirtualNic;
|
||||||
import com.vmware.vim25.HostVirtualSwitch;
|
import com.vmware.vim25.HostVirtualSwitch;
|
||||||
|
import com.vmware.vim25.InvalidPropertyFaultMsg;
|
||||||
import com.vmware.vim25.ManagedObjectReference;
|
import com.vmware.vim25.ManagedObjectReference;
|
||||||
import com.vmware.vim25.NasDatastoreInfo;
|
import com.vmware.vim25.NasDatastoreInfo;
|
||||||
import com.vmware.vim25.ObjectContent;
|
import com.vmware.vim25.ObjectContent;
|
||||||
@ -64,16 +75,15 @@ import com.vmware.vim25.ObjectSpec;
|
|||||||
import com.vmware.vim25.OptionValue;
|
import com.vmware.vim25.OptionValue;
|
||||||
import com.vmware.vim25.PropertyFilterSpec;
|
import com.vmware.vim25.PropertyFilterSpec;
|
||||||
import com.vmware.vim25.PropertySpec;
|
import com.vmware.vim25.PropertySpec;
|
||||||
|
import com.vmware.vim25.RetrieveOptions;
|
||||||
|
import com.vmware.vim25.RetrieveResult;
|
||||||
|
import com.vmware.vim25.RuntimeFaultFaultMsg;
|
||||||
import com.vmware.vim25.TraversalSpec;
|
import com.vmware.vim25.TraversalSpec;
|
||||||
import com.vmware.vim25.VirtualMachineConfigSpec;
|
import com.vmware.vim25.VirtualMachineConfigSpec;
|
||||||
import com.vmware.vim25.VirtualNicManagerNetConfig;
|
import com.vmware.vim25.VirtualNicManagerNetConfig;
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
|
||||||
import com.cloud.utils.LogUtils;
|
|
||||||
import com.cloud.utils.Pair;
|
|
||||||
|
|
||||||
public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
||||||
Map<String, VirtualMachineMO> _vmCache = new HashMap<String, VirtualMachineMO>();
|
Map<String, VirtualMachineMO> _vmCache = new HashMap<>();
|
||||||
|
|
||||||
//Map<String, String> _vmInternalNameMapCache = new HashMap<String, String>();
|
//Map<String, String> _vmInternalNameMapCache = new HashMap<String, String>();
|
||||||
|
|
||||||
@ -87,12 +97,11 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
|
|
||||||
public HostHardwareSummary getHostHardwareSummary() throws Exception {
|
public HostHardwareSummary getHostHardwareSummary() throws Exception {
|
||||||
HostConnectInfo hostInfo = _context.getService().queryHostConnectionInfo(_mor);
|
HostConnectInfo hostInfo = _context.getService().queryHostConnectionInfo(_mor);
|
||||||
HostHardwareSummary hardwareSummary = hostInfo.getHost().getHardware();
|
return hostInfo.getHost().getHardware();
|
||||||
return hardwareSummary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HostConfigManager getHostConfigManager() throws Exception {
|
public HostConfigManager getHostConfigManager() throws Exception {
|
||||||
return (HostConfigManager)_context.getVimClient().getDynamicProperty(_mor, "configManager");
|
return _context.getVimClient().getDynamicProperty(_mor, "configManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<VirtualNicManagerNetConfig> getHostVirtualNicManagerNetConfig() throws Exception {
|
public List<VirtualNicManagerNetConfig> getHostVirtualNicManagerNetConfig() throws Exception {
|
||||||
@ -104,15 +113,15 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public HostListSummaryQuickStats getHostQuickStats() throws Exception {
|
public HostListSummaryQuickStats getHostQuickStats() throws Exception {
|
||||||
return (HostListSummaryQuickStats)_context.getVimClient().getDynamicProperty(_mor, "summary.quickStats");
|
return _context.getVimClient().getDynamicProperty(_mor, "summary.quickStats");
|
||||||
}
|
}
|
||||||
|
|
||||||
public HostHyperThreadScheduleInfo getHostHyperThreadInfo() throws Exception {
|
public HostHyperThreadScheduleInfo getHostHyperThreadInfo() throws Exception {
|
||||||
return (HostHyperThreadScheduleInfo)_context.getVimClient().getDynamicProperty(_mor, "config.hyperThread");
|
return _context.getVimClient().getDynamicProperty(_mor, "config.hyperThread");
|
||||||
}
|
}
|
||||||
|
|
||||||
public HostNetworkInfo getHostNetworkInfo() throws Exception {
|
public HostNetworkInfo getHostNetworkInfo() throws Exception {
|
||||||
return (HostNetworkInfo)_context.getVimClient().getDynamicProperty(_mor, "config.network");
|
return _context.getVimClient().getDynamicProperty(_mor, "config.network");
|
||||||
}
|
}
|
||||||
|
|
||||||
public HostPortGroupSpec getHostPortGroupSpec(String portGroupName) throws Exception {
|
public HostPortGroupSpec getHostPortGroupSpec(String portGroupName) throws Exception {
|
||||||
@ -142,7 +151,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<HostPortGroupSpec> portGroupSpecs = new ArrayList<HostPortGroupSpec>();
|
List<HostPortGroupSpec> portGroupSpecs = new ArrayList<>();
|
||||||
for (HostPortGroup portGroup : portGroups) {
|
for (HostPortGroup portGroup : portGroups) {
|
||||||
if (!isVMKernelPort(portGroup)) {
|
if (!isVMKernelPort(portGroup)) {
|
||||||
portGroupSpecs.add(portGroup.getSpec());
|
portGroupSpecs.add(portGroup.getSpec());
|
||||||
@ -216,20 +225,20 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public HostStorageSystemMO getHostStorageSystemMO() throws Exception {
|
public HostStorageSystemMO getHostStorageSystemMO() throws Exception {
|
||||||
return new HostStorageSystemMO(_context, (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "configManager.storageSystem"));
|
return new HostStorageSystemMO(_context, _context.getVimClient().getDynamicProperty(_mor, "configManager.storageSystem"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public HostDatastoreSystemMO getHostDatastoreSystemMO() throws Exception {
|
public HostDatastoreSystemMO getHostDatastoreSystemMO() throws Exception {
|
||||||
return new HostDatastoreSystemMO(_context, (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "configManager.datastoreSystem"));
|
return new HostDatastoreSystemMO(_context, _context.getVimClient().getDynamicProperty(_mor, "configManager.datastoreSystem"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public HostDatastoreBrowserMO getHostDatastoreBrowserMO() throws Exception {
|
public HostDatastoreBrowserMO getHostDatastoreBrowserMO() throws Exception {
|
||||||
return new HostDatastoreBrowserMO(_context, (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "datastoreBrowser"));
|
return new HostDatastoreBrowserMO(_context, _context.getVimClient().getDynamicProperty(_mor, "datastoreBrowser"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private DatastoreMO getHostDatastoreMO(String datastoreName) throws Exception {
|
private DatastoreMO getHostDatastoreMO(String datastoreName) throws Exception {
|
||||||
ObjectContent[] ocs = getDatastorePropertiesOnHyperHost(new String[] {"name"});
|
ObjectContent[] ocs = getDatastorePropertiesOnHyperHost(new String[] {"name"});
|
||||||
if (ocs != null && ocs.length > 0) {
|
if (ocs != null) {
|
||||||
for (ObjectContent oc : ocs) {
|
for (ObjectContent oc : ocs) {
|
||||||
List<DynamicProperty> objProps = oc.getPropSet();
|
List<DynamicProperty> objProps = oc.getPropSet();
|
||||||
if (objProps != null) {
|
if (objProps != null) {
|
||||||
@ -267,13 +276,13 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ManagedObjectReference getHyperHostOwnerResourcePool() throws Exception {
|
public ManagedObjectReference getHyperHostOwnerResourcePool() throws Exception {
|
||||||
ManagedObjectReference morComputerResource = (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "parent");
|
ManagedObjectReference morComputerResource = _context.getVimClient().getDynamicProperty(_mor, "parent");
|
||||||
return (ManagedObjectReference)_context.getVimClient().getDynamicProperty(morComputerResource, "resourcePool");
|
return _context.getVimClient().getDynamicProperty(morComputerResource, "resourcePool");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ManagedObjectReference getHyperHostCluster() throws Exception {
|
public ManagedObjectReference getHyperHostCluster() throws Exception {
|
||||||
ManagedObjectReference morParent = (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "parent");
|
ManagedObjectReference morParent = _context.getVimClient().getDynamicProperty(_mor, "parent");
|
||||||
|
|
||||||
if (morParent.getType().equalsIgnoreCase("ClusterComputeResource")) {
|
if (morParent.getType().equalsIgnoreCase("ClusterComputeResource")) {
|
||||||
return morParent;
|
return morParent;
|
||||||
@ -285,10 +294,10 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
|
|
||||||
public ManagedObjectReference[] getHostLocalDatastore() throws Exception {
|
public ManagedObjectReference[] getHostLocalDatastore() throws Exception {
|
||||||
List<ManagedObjectReference> datastores = _context.getVimClient().getDynamicProperty(_mor, "datastore");
|
List<ManagedObjectReference> datastores = _context.getVimClient().getDynamicProperty(_mor, "datastore");
|
||||||
List<ManagedObjectReference> l = new ArrayList<ManagedObjectReference>();
|
List<ManagedObjectReference> l = new ArrayList<>();
|
||||||
if (datastores != null) {
|
if (datastores != null) {
|
||||||
for (ManagedObjectReference mor : datastores) {
|
for (ManagedObjectReference mor : datastores) {
|
||||||
DatastoreSummary summary = (DatastoreSummary)_context.getVimClient().getDynamicProperty(mor, "summary");
|
DatastoreSummary summary = _context.getVimClient().getDynamicProperty(mor, "summary");
|
||||||
if (summary.getType().equalsIgnoreCase("VMFS") && !summary.isMultipleHostAccess())
|
if (summary.getType().equalsIgnoreCase("VMFS") && !summary.isMultipleHostAccess())
|
||||||
l.add(mor);
|
l.add(mor);
|
||||||
}
|
}
|
||||||
@ -313,7 +322,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public AboutInfo getHostAboutInfo() throws Exception {
|
public AboutInfo getHostAboutInfo() throws Exception {
|
||||||
return (AboutInfo)_context.getVimClient().getDynamicProperty(_mor, "config.product");
|
return _context.getVimClient().getDynamicProperty(_mor, "config.product");
|
||||||
}
|
}
|
||||||
|
|
||||||
public VmwareHostType getHostType() throws Exception {
|
public VmwareHostType getHostType() throws Exception {
|
||||||
@ -507,7 +516,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
||||||
pfSpec.getPropSet().add(pSpec);
|
pfSpec.getPropSet().add(pSpec);
|
||||||
pfSpec.getObjectSet().add(oSpec);
|
pfSpec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
|
||||||
pfSpecArr.add(pfSpec);
|
pfSpecArr.add(pfSpec);
|
||||||
|
|
||||||
List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
||||||
@ -533,18 +542,22 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHostName() throws Exception {
|
public String getHostName() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
return (String)_context.getVimClient().getDynamicProperty(_mor, "name");
|
return _context.getVimClient().getDynamicProperty(_mor, "name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized List<VirtualMachineMO> listVmsOnHyperHostWithHypervisorName(String vmName) throws Exception {
|
public synchronized List<VirtualMachineMO> listVmsOnHyperHostWithHypervisorName(String vmName) throws VmwareClientException {
|
||||||
List<VirtualMachineMO> vms = new ArrayList<>();
|
List<VirtualMachineMO> vms = new ArrayList<>();
|
||||||
if (StringUtils.isNotEmpty(vmName)) {
|
try {
|
||||||
vms.add(findVmOnHyperHostWithHypervisorName(vmName));
|
if (StringUtils.isNotEmpty(vmName)) {
|
||||||
} else {
|
vms.add(findVmOnHyperHostWithHypervisorName(vmName));
|
||||||
loadVmCache();
|
} else {
|
||||||
vms.addAll(_vmCache.values());
|
loadVmCache();
|
||||||
|
vms.addAll(_vmCache.values());
|
||||||
|
}
|
||||||
|
} catch (InvalidPropertyFaultMsg | RuntimeFaultFaultMsg | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
|
||||||
|
throw new VmwareClientException("problem loading vm cache.", e);
|
||||||
}
|
}
|
||||||
return vms;
|
return vms;
|
||||||
}
|
}
|
||||||
@ -580,9 +593,8 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadVmCache() throws Exception {
|
private void loadVmCache() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
if (logger.isDebugEnabled())
|
logger.debug("load VM cache on host");
|
||||||
logger.debug("load VM cache on host");
|
|
||||||
|
|
||||||
_vmCache.clear();
|
_vmCache.clear();
|
||||||
|
|
||||||
@ -594,7 +606,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
// name is the name of the VM as it appears in vCenter. The CLOUD_VM_INTERNAL_NAME custom
|
// name is the name of the VM as it appears in vCenter. The CLOUD_VM_INTERNAL_NAME custom
|
||||||
// field value contains the name of the VM as it is maintained internally by cloudstack (i-x-y).
|
// field value contains the name of the VM as it is maintained internally by cloudstack (i-x-y).
|
||||||
ObjectContent[] ocs = getVmPropertiesOnHyperHost(new String[] {"name", "value[" + key + "]"});
|
ObjectContent[] ocs = getVmPropertiesOnHyperHost(new String[] {"name", "value[" + key + "]"});
|
||||||
if (ocs != null && ocs.length > 0) {
|
if (ocs != null) {
|
||||||
for (ObjectContent oc : ocs) {
|
for (ObjectContent oc : ocs) {
|
||||||
List<DynamicProperty> props = oc.getPropSet();
|
List<DynamicProperty> props = oc.getPropSet();
|
||||||
if (props != null) {
|
if (props != null) {
|
||||||
@ -608,7 +620,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
vmInternalCSName = ((CustomFieldStringValue)prop.getVal()).getValue();
|
vmInternalCSName = ((CustomFieldStringValue)prop.getVal()).getValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String vmName = null;
|
String vmName;
|
||||||
if (vmInternalCSName != null && isUserVMInternalCSName(vmInternalCSName)) {
|
if (vmInternalCSName != null && isUserVMInternalCSName(vmInternalCSName)) {
|
||||||
vmName = vmInternalCSName;
|
vmName = vmInternalCSName;
|
||||||
} else {
|
} else {
|
||||||
@ -668,8 +680,8 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
|
|
||||||
ObjectContent[] ocs = getVmPropertiesOnHyperHost(new String[] {"name", "config.extraConfig[\"RemoteDisplay.vnc.port\"]", "value[" + key + "]"});
|
ObjectContent[] ocs = getVmPropertiesOnHyperHost(new String[] {"name", "config.extraConfig[\"RemoteDisplay.vnc.port\"]", "value[" + key + "]"});
|
||||||
|
|
||||||
HashMap<String, Integer> portInfo = new HashMap<String, Integer>();
|
HashMap<String, Integer> portInfo = new HashMap<>();
|
||||||
if (ocs != null && ocs.length > 0) {
|
if (ocs != null) {
|
||||||
for (ObjectContent oc : ocs) {
|
for (ObjectContent oc : ocs) {
|
||||||
List<DynamicProperty> objProps = oc.getPropSet();
|
List<DynamicProperty> objProps = oc.getPropSet();
|
||||||
if (objProps != null) {
|
if (objProps != null) {
|
||||||
@ -702,11 +714,16 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectContent[] getVmPropertiesOnHyperHost(String[] propertyPaths) throws Exception {
|
public ObjectContent[] getVmPropertiesOnHyperHost(String[] propertyPaths) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
if (logger.isTraceEnabled())
|
List<ObjectContent> properties = getVmProperties(propertyPaths, null).second();
|
||||||
|
return properties.toArray(new ObjectContent[properties.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<String, List<ObjectContent>> getVmProperties(String[] propertyPaths, Integer maxObjects) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("vCenter API trace - retrieveProperties() for VM properties. target MOR: " + _mor.getValue() + ", properties: " +
|
logger.trace("vCenter API trace - retrieveProperties() for VM properties. target MOR: " + _mor.getValue() + ", properties: " +
|
||||||
new Gson().toJson(propertyPaths));
|
new Gson().toJson(propertyPaths));
|
||||||
|
}
|
||||||
PropertySpec pSpec = new PropertySpec();
|
PropertySpec pSpec = new PropertySpec();
|
||||||
pSpec.setType("VirtualMachine");
|
pSpec.setType("VirtualMachine");
|
||||||
pSpec.getPathSet().addAll(Arrays.asList(propertyPaths));
|
pSpec.getPathSet().addAll(Arrays.asList(propertyPaths));
|
||||||
@ -724,14 +741,18 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
||||||
pfSpec.getPropSet().add(pSpec);
|
pfSpec.getPropSet().add(pSpec);
|
||||||
pfSpec.getObjectSet().add(oSpec);
|
pfSpec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
|
||||||
pfSpecArr.add(pfSpec);
|
pfSpecArr.add(pfSpec);
|
||||||
|
|
||||||
List<ObjectContent> properties = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
RetrieveOptions ro = new RetrieveOptions();
|
||||||
|
if (maxObjects != null && maxObjects > 0) {
|
||||||
|
ro.setMaxObjects(maxObjects);
|
||||||
|
}
|
||||||
|
|
||||||
if (logger.isTraceEnabled())
|
RetrieveResult result = _context.getService().retrievePropertiesEx(_context.getPropertyCollector(), pfSpecArr, ro);
|
||||||
logger.trace("vCenter API trace - retrieveProperties() done");
|
|
||||||
return properties.toArray(new ObjectContent[properties.size()]);
|
logger.trace("vCenter API trace - retrieveProperties() done");
|
||||||
|
return createReturnObjectPair(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -757,7 +778,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
PropertyFilterSpec pfSpec = new PropertyFilterSpec();
|
||||||
pfSpec.getPropSet().add(pSpec);
|
pfSpec.getPropSet().add(pSpec);
|
||||||
pfSpec.getObjectSet().add(oSpec);
|
pfSpec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> pfSpecArr = new ArrayList<>();
|
||||||
pfSpecArr.add(pfSpec);
|
pfSpecArr.add(pfSpec);
|
||||||
|
|
||||||
List<ObjectContent> properties = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
List<ObjectContent> properties = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
||||||
@ -768,12 +789,12 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Pair<ManagedObjectReference, String>> getDatastoreMountsOnHost() throws Exception {
|
public List<Pair<ManagedObjectReference, String>> getDatastoreMountsOnHost() throws Exception {
|
||||||
List<Pair<ManagedObjectReference, String>> mounts = new ArrayList<Pair<ManagedObjectReference, String>>();
|
List<Pair<ManagedObjectReference, String>> mounts = new ArrayList<>();
|
||||||
|
|
||||||
ObjectContent[] ocs = getDatastorePropertiesOnHyperHost(new String[] {String.format("host[\"%s\"].mountInfo.path", _mor.getValue())});
|
ObjectContent[] ocs = getDatastorePropertiesOnHyperHost(new String[] {String.format("host[\"%s\"].mountInfo.path", _mor.getValue())});
|
||||||
if (ocs != null) {
|
if (ocs != null) {
|
||||||
for (ObjectContent oc : ocs) {
|
for (ObjectContent oc : ocs) {
|
||||||
Pair<ManagedObjectReference, String> mount = new Pair<ManagedObjectReference, String>(oc.getObj(), oc.getPropSet().get(0).getVal().toString());
|
Pair<ManagedObjectReference, String> mount = new Pair<>(oc.getObj(), oc.getPropSet().get(0).getVal().toString());
|
||||||
mounts.add(mount);
|
mounts.add(mount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -781,7 +802,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Pair<ManagedObjectReference, String>> getLocalDatastoreOnHost() throws Exception {
|
public List<Pair<ManagedObjectReference, String>> getLocalDatastoreOnHost() throws Exception {
|
||||||
List<Pair<ManagedObjectReference, String>> dsList = new ArrayList<Pair<ManagedObjectReference, String>>();
|
List<Pair<ManagedObjectReference, String>> dsList = new ArrayList<>();
|
||||||
|
|
||||||
ObjectContent[] ocs = getDatastorePropertiesOnHyperHost(new String[] {"name", "summary"});
|
ObjectContent[] ocs = getDatastorePropertiesOnHyperHost(new String[] {"name", "summary"});
|
||||||
if (ocs != null) {
|
if (ocs != null) {
|
||||||
@ -792,7 +813,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
String name = (String)VmwareHelper.getPropValue(oc, "name");
|
String name = (String)VmwareHelper.getPropValue(oc, "name");
|
||||||
|
|
||||||
if (!name.startsWith("-iqn.") && !name.startsWith("_iqn.")) {
|
if (!name.startsWith("-iqn.") && !name.startsWith("_iqn.")) {
|
||||||
dsList.add(new Pair<ManagedObjectReference, String>(morDs, name));
|
dsList.add(new Pair<>(morDs, name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -854,7 +875,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Next, get all the NAS datastores from this array of datastores.
|
// Next, get all the NAS datastores from this array of datastores.
|
||||||
if (morArray.size() > 0) {
|
if (!morArray.isEmpty()) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < morArray.size(); i++) {
|
for (i = 0; i < morArray.size(); i++) {
|
||||||
NasDatastoreInfo nasDS;
|
NasDatastoreInfo nasDS;
|
||||||
@ -978,7 +999,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ManagedObjectReference findMigrationTarget(VirtualMachineMO vmMo) throws Exception {
|
public ManagedObjectReference findMigrationTarget(VirtualMachineMO vmMo) {
|
||||||
return _mor;
|
return _mor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1102,7 +1123,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isHyperHostConnected() throws Exception {
|
public boolean isHyperHostConnected() throws Exception {
|
||||||
HostRuntimeInfo runtimeInfo = (HostRuntimeInfo)_context.getVimClient().getDynamicProperty(_mor, "runtime");
|
HostRuntimeInfo runtimeInfo = _context.getVimClient().getDynamicProperty(_mor, "runtime");
|
||||||
return runtimeInfo != null && runtimeInfo.getConnectionState() == HostSystemConnectionState.CONNECTED;
|
return runtimeInfo != null && runtimeInfo.getConnectionState() == HostSystemConnectionState.CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1316,9 +1337,8 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized VirtualMachineMO findVmOnHyperHostWithHypervisorName(String vmName) throws Exception {
|
private synchronized VirtualMachineMO findVmOnHyperHostWithHypervisorName(String vmName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
if (logger.isDebugEnabled())
|
logger.debug("find VM hypervisor name: {} on host", vmName );
|
||||||
logger.debug("find VM hypervisor name: " + vmName + " on host");
|
|
||||||
|
|
||||||
VirtualMachineMO vmMo = getVmWithHypervisorName(_vmCache.values(), vmName);
|
VirtualMachineMO vmMo = getVmWithHypervisorName(_vmCache.values(), vmName);
|
||||||
if (vmMo != null) {
|
if (vmMo != null) {
|
||||||
@ -1348,4 +1368,24 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Pair<String, List<UnmanagedInstanceTO>> getVms(Integer maxObjects, String token) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
|
||||||
|
List<UnmanagedInstanceTO> vms = new ArrayList<>();
|
||||||
|
Pair<String, List<ObjectContent>> objectContents = getVmProperties(new String[] {"name"}, maxObjects, token);
|
||||||
|
logger.debug("returning token {} for future retrievals, currently {} objects retrieved.", objectContents.first(), objectContents.second().size());
|
||||||
|
Pair<String, List<UnmanagedInstanceTO>> retval = new Pair<>(objectContents.first(), vms);
|
||||||
|
|
||||||
|
objectContentToUnmanagedInstanceTO(objectContents, vms);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<String, List<ObjectContent>> getVmProperties(String[] propertyPaths, Integer maxObjects, String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
|
if(com.cloud.utils.StringUtils.isNotBlank(tokenForPriorQuery)) {
|
||||||
|
logger.debug("running repeat query with token '{}'", tokenForPriorQuery);
|
||||||
|
return retrieveNextSetOfProperties(tokenForPriorQuery);
|
||||||
|
} else {
|
||||||
|
logger.debug("running query for {} propertypaths and max {} objects", propertyPaths.length, maxObjects);
|
||||||
|
return getVmProperties(propertyPaths, maxObjects);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -16,8 +16,10 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.hypervisor.vmware.util;
|
package com.cloud.hypervisor.vmware.util;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -36,21 +38,26 @@ import javax.xml.ws.handler.Handler;
|
|||||||
import javax.xml.ws.handler.HandlerResolver;
|
import javax.xml.ws.handler.HandlerResolver;
|
||||||
import javax.xml.ws.handler.PortInfo;
|
import javax.xml.ws.handler.PortInfo;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.cloudstack.utils.security.SSLUtils;
|
import org.apache.cloudstack.utils.security.SSLUtils;
|
||||||
import org.apache.cloudstack.utils.security.SecureSSLSocketFactory;
|
import org.apache.cloudstack.utils.security.SecureSSLSocketFactory;
|
||||||
|
|
||||||
|
import com.cloud.utils.StringUtils;
|
||||||
|
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
import com.vmware.pbm.PbmPortType;
|
import com.vmware.pbm.PbmPortType;
|
||||||
import com.vmware.pbm.PbmService;
|
import com.vmware.pbm.PbmService;
|
||||||
import com.vmware.pbm.PbmServiceInstanceContent;
|
import com.vmware.pbm.PbmServiceInstanceContent;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.w3c.dom.Element;
|
|
||||||
|
|
||||||
import com.vmware.vim25.DynamicProperty;
|
import com.vmware.vim25.DynamicProperty;
|
||||||
import com.vmware.vim25.InvalidCollectorVersionFaultMsg;
|
import com.vmware.vim25.InvalidCollectorVersionFaultMsg;
|
||||||
|
import com.vmware.vim25.InvalidLocaleFaultMsg;
|
||||||
|
import com.vmware.vim25.InvalidLoginFaultMsg;
|
||||||
import com.vmware.vim25.InvalidPropertyFaultMsg;
|
import com.vmware.vim25.InvalidPropertyFaultMsg;
|
||||||
|
import com.vmware.vim25.InvalidStateFaultMsg;
|
||||||
import com.vmware.vim25.LocalizedMethodFault;
|
import com.vmware.vim25.LocalizedMethodFault;
|
||||||
import com.vmware.vim25.ManagedObjectReference;
|
import com.vmware.vim25.ManagedObjectReference;
|
||||||
import com.vmware.vim25.MethodFault;
|
import com.vmware.vim25.MethodFault;
|
||||||
@ -93,12 +100,10 @@ public class VmwareClient {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException {
|
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException {
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException {
|
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException {
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +164,7 @@ public class VmwareClient {
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
* the exception
|
* the exception
|
||||||
*/
|
*/
|
||||||
public void connect(String url, String userName, String password) throws Exception {
|
public void connect(String url, String userName, String password) throws RuntimeFaultFaultMsg, URISyntaxException, VmwareClientException, InvalidLocaleFaultMsg, InvalidLoginFaultMsg {
|
||||||
svcInstRef.setType(SVC_INST_NAME);
|
svcInstRef.setType(SVC_INST_NAME);
|
||||||
svcInstRef.setValue(SVC_INST_NAME);
|
svcInstRef.setValue(SVC_INST_NAME);
|
||||||
|
|
||||||
@ -189,7 +194,7 @@ public class VmwareClient {
|
|||||||
if (cookies == null) {
|
if (cookies == null) {
|
||||||
String msg = "Login successful, but failed to get server cookies from url :[" + url + "]";
|
String msg = "Login successful, but failed to get server cookies from url :[" + url + "]";
|
||||||
LOGGER.error(msg);
|
LOGGER.error(msg);
|
||||||
throw new Exception(msg);
|
throw new VmwareClientException(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,14 +203,14 @@ public class VmwareClient {
|
|||||||
cookieValue = tokenizer.nextToken();
|
cookieValue = tokenizer.nextToken();
|
||||||
String pathData = "$" + tokenizer.nextToken();
|
String pathData = "$" + tokenizer.nextToken();
|
||||||
serviceCookie = "$Version=\"1\"; " + cookieValue + "; " + pathData;
|
serviceCookie = "$Version=\"1\"; " + cookieValue + "; " + pathData;
|
||||||
Map<String, List<String>> map = new HashMap<String, List<String>>();
|
Map<String, List<String>> map = new HashMap<>();
|
||||||
map.put("Cookie", Collections.singletonList(serviceCookie));
|
map.put("Cookie", Collections.singletonList(serviceCookie));
|
||||||
((BindingProvider)vimPort).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, map);
|
((BindingProvider)vimPort).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, map);
|
||||||
pbmConnect(url, cookieValue);
|
pbmConnect(url, cookieValue);
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pbmConnect(String url, String cookieValue) throws Exception {
|
private void pbmConnect(String url, String cookieValue) throws URISyntaxException {
|
||||||
URI uri = new URI(url);
|
URI uri = new URI(url);
|
||||||
String pbmurl = "https://" + uri.getHost() + "/pbm";
|
String pbmurl = "https://" + uri.getHost() + "/pbm";
|
||||||
String[] tokens = cookieValue.split("=");
|
String[] tokens = cookieValue.split("=");
|
||||||
@ -215,8 +220,8 @@ public class VmwareClient {
|
|||||||
@Override
|
@Override
|
||||||
public List<Handler> getHandlerChain(PortInfo portInfo) {
|
public List<Handler> getHandlerChain(PortInfo portInfo) {
|
||||||
VcenterSessionHandler VcSessionHandler = new VcenterSessionHandler(extractedCookie);
|
VcenterSessionHandler VcSessionHandler = new VcenterSessionHandler(extractedCookie);
|
||||||
List<Handler> handlerChain = new ArrayList<Handler>();
|
List<Handler> handlerChain = new ArrayList<>();
|
||||||
handlerChain.add((Handler)VcSessionHandler);
|
handlerChain.add(VcSessionHandler);
|
||||||
return handlerChain;
|
return handlerChain;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -257,6 +262,7 @@ public class VmwareClient {
|
|||||||
try {
|
try {
|
||||||
return vimPort.retrieveServiceContent(svcInstRef);
|
return vimPort.retrieveServiceContent(svcInstRef);
|
||||||
} catch (RuntimeFaultFaultMsg e) {
|
} catch (RuntimeFaultFaultMsg e) {
|
||||||
|
// ignored
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -275,6 +281,7 @@ public class VmwareClient {
|
|||||||
try {
|
try {
|
||||||
return pbmPort.pbmRetrieveServiceContent(pbmSvcInstRef);
|
return pbmPort.pbmRetrieveServiceContent(pbmSvcInstRef);
|
||||||
} catch (com.vmware.pbm.RuntimeFaultFaultMsg e) {
|
} catch (com.vmware.pbm.RuntimeFaultFaultMsg e) {
|
||||||
|
// ignored
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -323,12 +330,12 @@ public class VmwareClient {
|
|||||||
PropertyFilterSpec spec = new PropertyFilterSpec();
|
PropertyFilterSpec spec = new PropertyFilterSpec();
|
||||||
spec.getPropSet().add(pSpec);
|
spec.getPropSet().add(pSpec);
|
||||||
spec.getObjectSet().add(oSpec);
|
spec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> specArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> specArr = new ArrayList<>();
|
||||||
specArr.add(spec);
|
specArr.add(spec);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<ObjectContent> ocary = vimPort.retrieveProperties(getPropCol(), specArr);
|
List<ObjectContent> ocary = vimPort.retrieveProperties(getPropCol(), specArr);
|
||||||
if (ocary != null && ocary.size() > 0)
|
if (ocary != null && !ocary.isEmpty())
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return false;
|
return false;
|
||||||
@ -345,19 +352,17 @@ public class VmwareClient {
|
|||||||
* @param propertyName
|
* @param propertyName
|
||||||
* property name.
|
* property name.
|
||||||
* @return property value.
|
* @return property value.
|
||||||
* @throws Exception
|
|
||||||
* in case of error.
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> T getDynamicProperty(ManagedObjectReference mor, String propertyName) throws Exception {
|
public <T> T getDynamicProperty(ManagedObjectReference mor, String propertyName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||||
List<String> props = new ArrayList<String>();
|
List<String> props = new ArrayList<>();
|
||||||
props.add(propertyName);
|
props.add(propertyName);
|
||||||
List<ObjectContent> objContent = retrieveMoRefProperties(mor, props);
|
List<ObjectContent> objContent = retrieveMoRefProperties(mor, props);
|
||||||
|
|
||||||
Object propertyValue = null;
|
Object propertyValue = null;
|
||||||
if (objContent != null && objContent.size() > 0) {
|
if (objContent != null && !objContent.isEmpty()) {
|
||||||
List<DynamicProperty> dynamicProperty = objContent.get(0).getPropSet();
|
List<DynamicProperty> dynamicProperty = objContent.get(0).getPropSet();
|
||||||
if (dynamicProperty != null && dynamicProperty.size() > 0) {
|
if (dynamicProperty != null && !dynamicProperty.isEmpty()) {
|
||||||
DynamicProperty dp = dynamicProperty.get(0);
|
DynamicProperty dp = dynamicProperty.get(0);
|
||||||
propertyValue = dp.getVal();
|
propertyValue = dp.getVal();
|
||||||
/*
|
/*
|
||||||
@ -369,7 +374,7 @@ public class VmwareClient {
|
|||||||
*/
|
*/
|
||||||
Class dpCls = propertyValue.getClass();
|
Class dpCls = propertyValue.getClass();
|
||||||
String dynamicPropertyName = dpCls.getName();
|
String dynamicPropertyName = dpCls.getName();
|
||||||
if (dynamicPropertyName.indexOf("ArrayOf") != -1) {
|
if (dynamicPropertyName.contains("ArrayOf")) {
|
||||||
String methodName = "get" + dynamicPropertyName.substring(dynamicPropertyName.indexOf("ArrayOf") + "ArrayOf".length(), dynamicPropertyName.length());
|
String methodName = "get" + dynamicPropertyName.substring(dynamicPropertyName.indexOf("ArrayOf") + "ArrayOf".length(), dynamicPropertyName.length());
|
||||||
|
|
||||||
Method getMorMethod = dpCls.getDeclaredMethod(methodName, null);
|
Method getMorMethod = dpCls.getDeclaredMethod(methodName, null);
|
||||||
@ -380,7 +385,7 @@ public class VmwareClient {
|
|||||||
return (T)propertyValue;
|
return (T)propertyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ObjectContent> retrieveMoRefProperties(ManagedObjectReference mObj, List<String> props) throws Exception {
|
private List<ObjectContent> retrieveMoRefProperties(ManagedObjectReference mObj, List<String> props) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
PropertySpec pSpec = new PropertySpec();
|
PropertySpec pSpec = new PropertySpec();
|
||||||
pSpec.setAll(false);
|
pSpec.setAll(false);
|
||||||
pSpec.setType(mObj.getType());
|
pSpec.setType(mObj.getType());
|
||||||
@ -392,7 +397,7 @@ public class VmwareClient {
|
|||||||
PropertyFilterSpec spec = new PropertyFilterSpec();
|
PropertyFilterSpec spec = new PropertyFilterSpec();
|
||||||
spec.getPropSet().add(pSpec);
|
spec.getPropSet().add(pSpec);
|
||||||
spec.getObjectSet().add(oSpec);
|
spec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> specArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> specArr = new ArrayList<>();
|
||||||
specArr.add(spec);
|
specArr.add(spec);
|
||||||
|
|
||||||
return vimPort.retrieveProperties(getPropCol(), specArr);
|
return vimPort.retrieveProperties(getPropCol(), specArr);
|
||||||
@ -410,7 +415,7 @@ public class VmwareClient {
|
|||||||
* @throws RuntimeFaultFaultMsg
|
* @throws RuntimeFaultFaultMsg
|
||||||
* @throws InvalidPropertyFaultMsg
|
* @throws InvalidPropertyFaultMsg
|
||||||
*/
|
*/
|
||||||
public boolean waitForTask(ManagedObjectReference task) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvalidCollectorVersionFaultMsg, Exception {
|
public boolean waitForTask(ManagedObjectReference task) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvalidCollectorVersionFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException, InvalidStateFaultMsg {
|
||||||
|
|
||||||
boolean retVal = false;
|
boolean retVal = false;
|
||||||
|
|
||||||
@ -665,7 +670,7 @@ public class VmwareClient {
|
|||||||
visitFolders.setPath("childEntity");
|
visitFolders.setPath("childEntity");
|
||||||
visitFolders.setSkip(Boolean.FALSE);
|
visitFolders.setSkip(Boolean.FALSE);
|
||||||
visitFolders.setName("VisitFolders");
|
visitFolders.setName("VisitFolders");
|
||||||
List<SelectionSpec> sspecarrvf = new ArrayList<SelectionSpec>();
|
List<SelectionSpec> sspecarrvf = new ArrayList<>();
|
||||||
sspecarrvf.add(getSelectionSpec("crToRp"));
|
sspecarrvf.add(getSelectionSpec("crToRp"));
|
||||||
sspecarrvf.add(getSelectionSpec("crToH"));
|
sspecarrvf.add(getSelectionSpec("crToH"));
|
||||||
sspecarrvf.add(getSelectionSpec("dcToVmf"));
|
sspecarrvf.add(getSelectionSpec("dcToVmf"));
|
||||||
@ -679,7 +684,7 @@ public class VmwareClient {
|
|||||||
|
|
||||||
visitFolders.getSelectSet().addAll(sspecarrvf);
|
visitFolders.getSelectSet().addAll(sspecarrvf);
|
||||||
|
|
||||||
List<SelectionSpec> resultspec = new ArrayList<SelectionSpec>();
|
List<SelectionSpec> resultspec = new ArrayList<>();
|
||||||
resultspec.add(visitFolders);
|
resultspec.add(visitFolders);
|
||||||
resultspec.add(crToRp);
|
resultspec.add(crToRp);
|
||||||
resultspec.add(crToH);
|
resultspec.add(crToH);
|
||||||
@ -705,8 +710,8 @@ public class VmwareClient {
|
|||||||
*
|
*
|
||||||
* @return First ManagedObjectReference of the type / name pair found
|
* @return First ManagedObjectReference of the type / name pair found
|
||||||
*/
|
*/
|
||||||
public ManagedObjectReference getDecendentMoRef(ManagedObjectReference root, String type, String name) throws Exception {
|
public ManagedObjectReference getDecendentMoRef(ManagedObjectReference root, String type, String name) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
|
||||||
if (name == null || name.length() == 0) {
|
if (name == null || name.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,13 +730,13 @@ public class VmwareClient {
|
|||||||
PropertyFilterSpec spec = new PropertyFilterSpec();
|
PropertyFilterSpec spec = new PropertyFilterSpec();
|
||||||
spec.getPropSet().add(pSpec);
|
spec.getPropSet().add(pSpec);
|
||||||
spec.getObjectSet().add(oSpec);
|
spec.getObjectSet().add(oSpec);
|
||||||
List<PropertyFilterSpec> specArr = new ArrayList<PropertyFilterSpec>();
|
List<PropertyFilterSpec> specArr = new ArrayList<>();
|
||||||
specArr.add(spec);
|
specArr.add(spec);
|
||||||
|
|
||||||
ManagedObjectReference propCollector = getPropCol();
|
ManagedObjectReference propCollector = getPropCol();
|
||||||
List<ObjectContent> ocary = vimPort.retrieveProperties(propCollector, specArr);
|
List<ObjectContent> ocary = vimPort.retrieveProperties(propCollector, specArr);
|
||||||
|
|
||||||
if (ocary == null || ocary.size() == 0) {
|
if (ocary == null || ocary.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -740,19 +745,16 @@ public class VmwareClient {
|
|||||||
ManagedObjectReference mor = oc.getObj();
|
ManagedObjectReference mor = oc.getObj();
|
||||||
List<DynamicProperty> propary = oc.getPropSet();
|
List<DynamicProperty> propary = oc.getPropSet();
|
||||||
if (type == null || type.equals(mor.getType())) {
|
if (type == null || type.equals(mor.getType())) {
|
||||||
if (propary.size() > 0) {
|
if (!propary.isEmpty()) {
|
||||||
String propval = (String)propary.get(0).getVal();
|
String propval = (String)propary.get(0).getVal();
|
||||||
if (propval != null && name.equalsIgnoreCase(propval))
|
if (name.equalsIgnoreCase(propval))
|
||||||
return mor;
|
return mor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (InvalidPropertyFaultMsg invalidPropertyException) {
|
} catch (InvalidPropertyFaultMsg | RuntimeFaultFaultMsg invalidPropertyException) {
|
||||||
LOGGER.debug("Failed to get Vmware ManagedObjectReference for name: " + name + " and type: " + type + " due to " + invalidPropertyException.getMessage());
|
LOGGER.debug("Failed to get Vmware ManagedObjectReference for name: " + name + " and type: " + type + " due to " + invalidPropertyException.getMessage());
|
||||||
throw invalidPropertyException;
|
throw invalidPropertyException;
|
||||||
} catch (RuntimeFaultFaultMsg runtimeFaultException) {
|
|
||||||
LOGGER.debug("Failed to get Vmware ManagedObjectReference for name: " + name + " and type: " + type + " due to " + runtimeFaultException.getMessage());
|
|
||||||
throw runtimeFaultException;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -0,0 +1,33 @@
|
|||||||
|
// 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.hypervisor.vmware.util;
|
||||||
|
|
||||||
|
import com.cloud.exception.CloudException;
|
||||||
|
|
||||||
|
public class VmwareClientException extends CloudException {
|
||||||
|
public VmwareClientException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VmwareClientException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
// TODO embed vmware classes in this one for use downstream
|
||||||
|
public VmwareClientException(String msg, Exception embedded) {
|
||||||
|
super(msg, embedded);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user