From 14f4956651112e2cc157581000b8ca51239dd448 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 13 Nov 2024 18:01:30 +0100 Subject: [PATCH 01/24] add maximum results number to retrieval of unregistered VMs on vmware --- .../apache/cloudstack/api/ApiConstants.java | 1 + .../vmware/manager/VmwareManagerImpl.java | 3 ++- .../command/admin/zone/ListVmwareDcVmsCmd.java | 7 +++++++ .../hypervisor/vmware/mo/DatacenterMO.java | 18 ++++++++++++++---- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index b2042c116a7f..a9c5d68c787d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -1106,6 +1106,7 @@ public class ApiConstants { public static final String PARAMETER_DESCRIPTION_IS_TAG_A_RULE = "Whether the informed tag is a JS interpretable rule or not."; public static final String NFS_MOUNT_OPTIONS = "nfsmountopts"; + public static final String MAX_NUMBER = "maxnumber"; /** * This enum specifies IO Drivers, each option controls specific policies on I/O. diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 61a949f42d3e..c28c6394c62c 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -1593,6 +1593,7 @@ public List listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { String datacenterName = cmd.getDatacenterName(); String username = cmd.getUsername(); String password = cmd.getPassword(); + Integer maxObjects = cmd.getMaxNumber(); Long existingVcenterId = cmd.getExistingVcenterId(); String keyword = cmd.getKeyword(); @@ -1632,7 +1633,7 @@ public List listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { s_logger.error(msg); throw new InvalidParameterValueException(msg); } - List instances = dcMo.getAllVmsOnDatacenter(); + List instances = dcMo.getVmsOnDatacenter(maxObjects); return StringUtils.isBlank(keyword) ? instances : instances.stream().filter(x -> x.getName().toLowerCase().contains(keyword.toLowerCase())).collect(Collectors.toList()); } catch (Exception e) { diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java index 4dd1b4beb091..fc4ac207a5ae 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java @@ -70,6 +70,9 @@ public class ListVmwareDcVmsCmd extends BaseListCmd { @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.") private String password; + @Parameter(name = ApiConstants.MAX_NUMBER, type = CommandType.INTEGER, description = "The maximum number of results to return.") + private Integer maxNumber; + public String getVcenter() { return vcenter; } @@ -82,6 +85,10 @@ public String getPassword() { return password; } + public Integer getMaxNumber() { + return maxNumber; + } + public String getDatacenterName() { return datacenterName; } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index d8c7e8a61ea6..901fe6f426c8 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -39,6 +39,7 @@ import com.vmware.vim25.SelectionSpec; import com.vmware.vim25.TraversalSpec; import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo; +import com.vmware.vim25.RetrieveOptions; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.utils.Pair; @@ -161,9 +162,9 @@ public VirtualMachineMO checkIfVmAlreadyExistsInVcenter(String vmNameOnVcenter, return null; } - public List getAllVmsOnDatacenter() throws Exception { + public List getVmsOnDatacenter(Integer maxObjects) throws Exception { List vms = new ArrayList<>(); - List ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name"}); + List ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name"}, maxObjects); if (ocs != null) { for (ObjectContent oc : ocs) { ManagedObjectReference vmMor = oc.getObj(); @@ -311,6 +312,10 @@ public List getDatastorePropertiesOnDatacenter(String[] propertyP } public List getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths) throws Exception { + return getVmPropertiesOnDatacenterVmFolder(propertyPaths, null); + } + + public List getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths, Integer maxObjects) throws Exception { PropertySpec pSpec = new PropertySpec(); pSpec.setType("VirtualMachine"); pSpec.getPathSet().addAll(Arrays.asList(propertyPaths)); @@ -338,10 +343,15 @@ public List getVmPropertiesOnDatacenterVmFolder(String[] property PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); - return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); + RetrieveOptions ro = new RetrieveOptions(); + if(maxObjects != null && maxObjects > 0) { + ro.setMaxObjects(maxObjects); + } + + return _context.getService().retrievePropertiesEx(_context.getPropertyCollector(), pfSpecArr, ro).getObjects(); } public static Pair getOwnerDatacenter(VmwareContext context, ManagedObjectReference morEntity) throws Exception { From c8cdaff8e0ba015208ad1ceee9d35d8020b98e92 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 20 Nov 2024 10:44:34 +0100 Subject: [PATCH 02/24] add paging indicator --- .../vmware/manager/VmwareManagerImpl.java | 5 +++-- .../command/admin/zone/ListVmwareDcVmsCmd.java | 18 ++++++++++++++---- .../hypervisor/vmware/mo/DatacenterMO.java | 16 ++++++++++++---- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index c28c6394c62c..4cb50f1d19fd 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -1593,7 +1593,8 @@ public List listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { String datacenterName = cmd.getDatacenterName(); String username = cmd.getUsername(); String password = cmd.getPassword(); - Integer maxObjects = cmd.getMaxNumber(); + Integer maxObjects = cmd.getPageSize(); + boolean nextPage = cmd.getPageNumber() != null && cmd.getPageNumber() > 1 ? false : true; Long existingVcenterId = cmd.getExistingVcenterId(); String keyword = cmd.getKeyword(); @@ -1633,7 +1634,7 @@ public List listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { s_logger.error(msg); throw new InvalidParameterValueException(msg); } - List instances = dcMo.getVmsOnDatacenter(maxObjects); + List instances = dcMo.getVmsOnDatacenter(maxObjects, nextPage); return StringUtils.isBlank(keyword) ? instances : instances.stream().filter(x -> x.getName().toLowerCase().contains(keyword.toLowerCase())).collect(Collectors.toList()); } catch (Exception e) { diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java index fc4ac207a5ae..414a19b86ad6 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java @@ -70,8 +70,14 @@ public class ListVmwareDcVmsCmd extends BaseListCmd { @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.") private String password; - @Parameter(name = ApiConstants.MAX_NUMBER, type = CommandType.INTEGER, description = "The maximum number of results to return.") - private Integer maxNumber; + @Parameter(name = ApiConstants.PAGE_SIZE, type = CommandType.INTEGER, description = "The maximum number of results to return.") + private Integer pageSize; + + @Parameter(name = ApiConstants.PAGE, type = CommandType.INTEGER, + description = "For listVmwareDcVms, the maximum number of results to return is either 0, 1 or more." + + " When more than 1, the next page as returned by the vcenter will be propagated to the caller." + + " If no previous call has been done, this is the same as the first page") + private Integer pageNumber; public String getVcenter() { return vcenter; @@ -85,8 +91,12 @@ public String getPassword() { return password; } - public Integer getMaxNumber() { - return maxNumber; + public Integer getPageSize() { + return pageSize; + } + + public Integer getPageNumber() { + return pageNumber; } public String getDatacenterName() { diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index 901fe6f426c8..4522191e0f5a 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -162,9 +162,9 @@ public VirtualMachineMO checkIfVmAlreadyExistsInVcenter(String vmNameOnVcenter, return null; } - public List getVmsOnDatacenter(Integer maxObjects) throws Exception { + public List getVmsOnDatacenter(Integer maxObjects, boolean nextPage) throws Exception { List vms = new ArrayList<>(); - List ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name"}, maxObjects); + List ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name"}, maxObjects, nextPage); if (ocs != null) { for (ObjectContent oc : ocs) { ManagedObjectReference vmMor = oc.getObj(); @@ -312,10 +312,18 @@ public List getDatastorePropertiesOnDatacenter(String[] propertyP } public List getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths) throws Exception { - return getVmPropertiesOnDatacenterVmFolder(propertyPaths, null); + return getVmPropertiesOnDatacenterVmFolder(propertyPaths, null, false); } - public List getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths, Integer maxObjects) throws Exception { + /** + * + * @param propertyPaths Vmware side property names to query, for instance {"name"} + * @param maxObjects the number of objects to retrieve + * @param nextPage 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 Exception generic {code}Exception{code} as thrown by Vmware. + */ + public List getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths, Integer maxObjects, boolean nextPage) throws Exception { PropertySpec pSpec = new PropertySpec(); pSpec.setType("VirtualMachine"); pSpec.getPathSet().addAll(Arrays.asList(propertyPaths)); From 964fbdcce7c5a00008009d87ce49a7584754b7c0 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Thu, 12 Dec 2024 08:46:45 +0100 Subject: [PATCH 03/24] continue retrieving method added --- .../vmware/manager/VmwareManagerImpl.java | 5 ++- .../hypervisor/vmware/mo/DatacenterMO.java | 44 +++++++++++++++---- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 4cb50f1d19fd..bfa9a4eb5b23 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -1634,7 +1634,8 @@ public List listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { s_logger.error(msg); throw new InvalidParameterValueException(msg); } - List instances = dcMo.getVmsOnDatacenter(maxObjects, nextPage); + List instances = java.util.Collections.synchronizedList(new ArrayList()); + instances.addAll(dcMo.getVmsOnDatacenter(maxObjects, null).second()); return StringUtils.isBlank(keyword) ? instances : instances.stream().filter(x -> x.getName().toLowerCase().contains(keyword.toLowerCase())).collect(Collectors.toList()); } catch (Exception e) { @@ -1697,7 +1698,7 @@ private void startTemplateCleanJobSchedule() { } /** - * 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 {@link com.cloud.storage.StorageManagerImpl.StorageGarbageCollector}. * it is called at regular intervals when storage.template.cleanup.enabled == true * It collect all templates that * - are deleted from cloudstack diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index 4522191e0f5a..b2e166cb3055 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -22,6 +22,7 @@ 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.commons.collections.CollectionUtils; import org.apache.log4j.Logger; @@ -40,6 +41,9 @@ import com.vmware.vim25.TraversalSpec; 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.utils.Pair; @@ -162,9 +166,11 @@ public VirtualMachineMO checkIfVmAlreadyExistsInVcenter(String vmNameOnVcenter, return null; } - public List getVmsOnDatacenter(Integer maxObjects, boolean nextPage) throws Exception { + public Pair> getVmsOnDatacenter(Integer maxObjects, String token) throws Exception { List vms = new ArrayList<>(); - List ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name"}, maxObjects, nextPage); + Pair> objectContents = getVmPropertiesOnDatacenterVmFolder(new String[] {"name"}, maxObjects, token); + Pair> retval = new Pair<>(objectContents.first(), vms); + List ocs = objectContents.second(); if (ocs != null) { for (ObjectContent oc : ocs) { ManagedObjectReference vmMor = oc.getObj(); @@ -183,7 +189,7 @@ public List getVmsOnDatacenter(Integer maxObjects, boolean } } - return vms; + return retval; } public List getAllHostsOnDatacenter() throws Exception { @@ -311,19 +317,32 @@ public List getDatastorePropertiesOnDatacenter(String[] propertyP } - public List getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths) throws Exception { - return getVmPropertiesOnDatacenterVmFolder(propertyPaths, null, false); + public List getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { + return getVmPropertiesOnDatacenterVmFolder(propertyPaths, null, null).second(); } /** * * @param propertyPaths Vmware side property names to query, for instance {"name"} * @param maxObjects the number of objects to retrieve - * @param nextPage restart the query or continue a previous query + * @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 Exception generic {code}Exception{code} as thrown by Vmware. */ - public List getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths, Integer maxObjects, boolean nextPage) throws Exception { + public Pair> getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths, Integer maxObjects, String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { + if(StringUtils.isNotBlank(tokenForPriorQuery)) { + return retrieveNextSetOfPropertiesOnDatacenterVmFolder(tokenForPriorQuery); + } else { + return retrieveNextSetOfPropertiesOnDatacenterVmFolder(propertyPaths, maxObjects); + } + } + + private Pair> retrieveNextSetOfPropertiesOnDatacenterVmFolder(String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { + RetrieveResult result = _context.getService().continueRetrievePropertiesEx(_context.getPropertyCollector(), tokenForPriorQuery); + return createReturnObjectPair(result); + } + + private Pair> retrieveNextSetOfPropertiesOnDatacenterVmFolder(String[] propertyPaths, Integer maxObjects) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { PropertySpec pSpec = new PropertySpec(); pSpec.setType("VirtualMachine"); pSpec.getPathSet().addAll(Arrays.asList(propertyPaths)); @@ -355,11 +374,18 @@ public List getVmPropertiesOnDatacenterVmFolder(String[] property pfSpecArr.add(pfSpec); RetrieveOptions ro = new RetrieveOptions(); - if(maxObjects != null && maxObjects > 0) { + if (maxObjects != null && maxObjects > 0) { ro.setMaxObjects(maxObjects); } - return _context.getService().retrievePropertiesEx(_context.getPropertyCollector(), pfSpecArr, ro).getObjects(); + RetrieveResult result = _context.getService().retrievePropertiesEx(_context.getPropertyCollector(), pfSpecArr, ro); + return createReturnObjectPair(result); + } + + private static Pair> createReturnObjectPair(RetrieveResult result) { + String tokenForRetrievingNewResults = result.getToken(); + List listOfObjects = result.getObjects(); + return new Pair<>(tokenForRetrievingNewResults, listOfObjects); } public static Pair getOwnerDatacenter(VmwareContext context, ManagedObjectReference morEntity) throws Exception { From cff61f79a358964b34d2afd7301d581bf54bd692 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Fri, 13 Dec 2024 16:59:16 +0100 Subject: [PATCH 04/24] cleanup --- .../vmware/manager/VmwareManagerImpl.java | 201 +++--- .../admin/zone/ListVmwareDcVmsCmd.java | 7 + .../hypervisor/vmware/mo/DatacenterMO.java | 80 +-- .../vmware/mo/VirtualMachineMO.java | 625 ++++-------------- .../hypervisor/vmware/util/VmwareClient.java | 30 +- .../vmware/util/VmwareClientException.java | 29 + 6 files changed, 294 insertions(+), 678 deletions(-) create mode 100644 vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClientException.java diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index bfa9a4eb5b23..50616b2b3015 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -19,10 +19,12 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.rmi.RemoteException; import java.time.Duration; import java.time.Instant; @@ -43,7 +45,6 @@ import javax.naming.ConfigurationException; 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.ImportVsphereStoragePoliciesCmd; import org.apache.cloudstack.api.command.admin.zone.ListVmwareDcVmsCmd; @@ -87,6 +88,7 @@ import com.cloud.dc.ClusterVO; import com.cloud.dc.ClusterVSMMapVO; import com.cloud.dc.DataCenterVO; +import com.cloud.dc.VmwareDatacenter; import com.cloud.dc.VsphereStoragePolicy; import com.cloud.dc.VsphereStoragePolicyVO; import com.cloud.dc.dao.ClusterDao; @@ -112,7 +114,8 @@ import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.hypervisor.vmware.LegacyZoneVO; 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.dc.VmwareDatacenterVO; import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMap; @@ -165,13 +168,17 @@ import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; -import com.cloud.utils.ssh.SshHelper; -import com.cloud.vm.DomainRouterVO; import com.cloud.vm.dao.UserVmCloneSettingDao; import com.cloud.vm.dao.VMInstanceDao; + +// TODO move these items upstream import com.vmware.pbm.PbmProfile; import com.vmware.vim25.AboutInfo; 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; public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService, Configurable { private static final Logger s_logger = Logger.getLogger(VmwareManagerImpl.class); @@ -247,11 +254,11 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw private StorageLayer _storage; 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 _instanceNameFlag; private String _serviceConsoleName; - private String _managemetPortGroupName; + private String _managementPortGroupName; private String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString(); private String _recycleHungWorker = "false"; private int _additionalPortRangeStart; @@ -265,7 +272,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw 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 GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op"); @@ -349,9 +356,9 @@ public boolean configure(String name, Map params) throws Configu _serviceConsoleName = "Service Console"; } - _managemetPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key()); - if (_managemetPortGroupName == null) { - _managemetPortGroupName = "Management Network"; + _managementPortGroupName = _configDao.getValue(Config.VmwareManagementPortGroup.key()); + if (_managementPortGroupName == null) { + _managementPortGroupName = "Management Network"; } _defaultSystemVmNicAdapterType = _configDao.getValue(Config.VmwareSystemVmNicDeviceType.key()); @@ -450,7 +457,7 @@ private void prepareHost(HostMO hostMo, String privateTrafficLabel) throws Excep s_logger.info("Preparing network on host " + hostMo.getContext().toString() + " for " + privateTrafficLabel); 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) { HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null, null); } @@ -459,7 +466,7 @@ private void prepareHost(HostMO hostMo, String privateTrafficLabel) throws Excep AboutInfo about = hostMo.getHostAboutInfo(); if (about != null) { 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; } } @@ -482,7 +489,7 @@ private HostMO getOldestExistentHostInCluster(Long clusterId, VmwareContext serv } 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) { return null; } @@ -498,31 +505,26 @@ public List addHostToPodCluster(VmwareContext serviceCon throw new CloudRuntimeException("Invalid serviceContext"); } ManagedObjectReference mor = serviceContext.getHostMorByPath(hostInventoryPath); - String privateTrafficLabel = null; + String privateTrafficLabel; privateTrafficLabel = serviceContext.getStockObject("privateTrafficLabel"); if (privateTrafficLabel == null) { privateTrafficLabel = _privateNetworkVSwitchName; } if (mor != null) { - List returnedHostList = new ArrayList(); + List returnedHostList = new ArrayList<>(); if (mor.getType().equals("ComputeResource")) { List hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host"); - assert (hosts != null && hosts.size() > 0); - - // For ESX host, we need to enable host firewall to allow VNC access - HostMO hostMo = new HostMO(serviceContext, hosts.get(0)); - - prepareHost(hostMo, privateTrafficLabel); + assert (CollectionUtils.isNullOrEmpty(hosts)); returnedHostList.add(hosts.get(0)); return returnedHostList; } else if (mor.getType().equals("ClusterComputeResource")) { List hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host"); assert (hosts != null); - if (hosts.size() > 0) { - AboutInfo about = (AboutInfo)(serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product")); + if (!hosts.isEmpty()) { + AboutInfo about = serviceContext.getVimClient().getDynamicProperty(hosts.get(0), "config.product"); String version = about.getApiVersion(); int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(HypervisorType.VMware, version); if (hosts.size() > maxHostsPerCluster) { @@ -551,7 +553,7 @@ public List addHostToPodCluster(VmwareContext serviceCon returnedHostList.add(mor); return returnedHostList; } else { - s_logger.error("Unsupport host type " + mor.getType() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath); + s_logger.error("Unsupported host type " + mor.getType() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath); return null; } } @@ -616,13 +618,13 @@ public String getServiceConsolePortGroupName() { @Override public String getManagementPortGroupName() { - return _managemetPortGroupName; + return _managementPortGroupName; } @Override public String getManagementPortGroupByHost(HostMO hostMo) throws Exception { if (hostMo.getHostType() == VmwareHostType.ESXi) { - return _managemetPortGroupName; + return _managementPortGroupName; } return _serviceConsoleName; } @@ -632,7 +634,7 @@ public void setupResourceStartupParams(Map params) { params.put("vmware.create.full.clone", _fullCloneFlag); params.put("vm.instancename.flag", _instanceNameFlag); 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.data.disk.controller", _dataDiskController); params.put("vmware.recycle.hung.wokervm", _recycleHungWorker); @@ -659,25 +661,25 @@ public boolean needRecycle(String workerTag) { return false; } - String tokens[] = workerTag.split("-"); + String[] tokens = workerTag.split("-"); if (tokens.length != 3) { s_logger.error("Invalid worker VM tag " + workerTag); return false; } long startTick = Long.parseLong(tokens[0]); - long msid = Long.parseLong(tokens[1]); - long runid = Long.parseLong(tokens[2]); + long msId = Long.parseLong(tokens[1]); + 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 (s_logger.isInfoEnabled()) s_logger.info("Worker VM's owner management server node has been detected down from peer nodes, recycle it"); return true; } - if (runid != clusterManager.getManagementRunId(msid)) { + if (runId != clusterManager.getManagementRunId(msId)) { if (s_logger.isInfoEnabled()) - s_logger.info("Worker VM's owner management server has changed runid, recycle it"); + s_logger.info("Worker VM's owner management server has changed runId, recycle it"); return true; } @@ -712,7 +714,7 @@ public void prepareSecondaryStorageStore(String storageUrl, Long storeId) { File patchFolder = new File(mountPoint + "/systemvm"); if (!patchFolder.exists()) { 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; s_logger.error(msg); throw new CloudRuntimeException(msg); } @@ -731,7 +733,7 @@ public void prepareSecondaryStorageStore(String storageUrl, Long storeId) { } catch (IOException e) { s_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; s_logger.error(msg); throw new CloudRuntimeException(msg); } @@ -773,9 +775,8 @@ private File getSystemVMPatchIsoFile() { isoFile = new File("/usr/share/cloudstack-common/vms/systemvm.iso"); } - assert (isoFile != null); if (!isoFile.exists()) { - s_logger.error("Unable to locate systemvm.iso in your setup at " + isoFile.toString()); + s_logger.error("Unable to locate systemvm.iso in your setup at " + isoFile); } return isoFile; } @@ -790,16 +791,16 @@ public File getSystemVMKeyFile() { if (keyFile == null || !keyFile.exists()) { keyFile = new File("/usr/share/cloudstack-common/scripts/vm/systemvm/id_rsa.cloud"); } - assert (keyFile != null); + if (!keyFile.exists()) { - s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile.toString()); + s_logger.error("Unable to locate id_rsa.cloud in your setup at " + keyFile); } return keyFile; } @Override public String getMountPoint(String storageUrl, String nfsVersion) { - String mountPoint = null; + String mountPoint; synchronized (_storageMounts) { mountPoint = _storageMounts.get(storageUrl); if (mountPoint != null) { @@ -829,7 +830,7 @@ private String setupMountPoint(String parent) { String mountPoint = null; long mshostId = ManagementServerNode.getManagementServerId(); 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); if (!file.exists()) { if (_storage.mkdir(mntPt)) { @@ -854,10 +855,9 @@ private void startupCleanup(String parent) { for (String mountPoint : mounts) { s_logger.info("umount NFS mount from previous session: " + mountPoint); - String result = null; Script command = new Script(true, "umount", _timeout, s_logger); command.add(mountPoint); - result = command.execute(); + String result = command.execute(); if (result != null) { s_logger.warn("Unable to umount " + mountPoint + " due to " + result); } @@ -875,7 +875,7 @@ private void shutdownCleanup() { for (String mountPoint : _storageMounts.values()) { s_logger.info("umount NFS mount: " + mountPoint); - String result = null; + String result; Script command = new Script(true, "umount", _timeout, s_logger); command.add(mountPoint); result = command.execute(); @@ -896,8 +896,8 @@ protected String mount(String path, String parent, String nfsVersion) { return null; } - Script script = null; - String result = null; + Script script; + String result; Script command = new Script(true, "mount", _timeout, s_logger); command.add("-t", "nfs"); if (nfsVersion != null){ @@ -984,40 +984,15 @@ public void processHostAdded(long hostId) { @Override public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) { - if (cmd instanceof StartupCommand) { + if (cmd != null) { if (host.getHypervisorType() == HypervisorType.VMware) { updateClusterNativeHAState(host, cmd); - } else { - return; } } } protected final static int DEFAULT_DOMR_SSHPORT = 3922; - protected boolean shutdownRouterVM(DomainRouterVO router) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Try to shutdown router VM " + router.getInstanceName() + " directly."); - } - - Pair result; - try { - result = SshHelper.sshExecute(router.getPrivateIpAddress(), DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "poweroff -f"); - - if (!result.first()) { - s_logger.debug("Unable to shutdown " + router.getInstanceName() + " directly"); - return false; - } - } catch (Throwable e) { - s_logger.warn("Unable to shutdown router " + router.getInstanceName() + " directly."); - return false; - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Shutdown router " + router.getInstanceName() + " successful."); - } - return true; - } - @Override public boolean processDisconnect(long agentId, Status state) { return false; @@ -1058,16 +1033,16 @@ public void endExclusiveOperation() { @Override public Pair getAddiionalVncPortRange() { - return new Pair(_additionalPortRangeStart, _additionalPortRangeSize); + return new Pair<>(_additionalPortRangeStart, _additionalPortRangeSize); } @Override public Map getNexusVSMCredentialsByClusterId(Long clusterId) { - CiscoNexusVSMDeviceVO nexusVSM = null; - ClusterVSMMapVO vsmMapVO = null; + CiscoNexusVSMDeviceVO nexusVSM; + ClusterVSMMapVO vsmMapVO; vsmMapVO = _vsmMapDao.findByClusterId(clusterId); - long vsmId = 0; + long vsmId; if (vsmMapVO != null) { vsmId = vsmMapVO.getVsmId(); s_logger.info("vsmId is " + vsmId); @@ -1078,7 +1053,7 @@ public Map getNexusVSMCredentialsByClusterId(Long clusterId) { return null; } - Map nexusVSMCredentials = new HashMap(); + Map nexusVSMCredentials = new HashMap<>(); if (nexusVSM != null) { nexusVSMCredentials.put("vsmip", nexusVSM.getipaddr()); nexusVSMCredentials.put("vsmusername", nexusVSM.getUserName()); @@ -1105,7 +1080,7 @@ public int getVcenterSessionTimeout() { @Override public List> getCommands() { - List> cmdList = new ArrayList>(); + List> cmdList = new ArrayList<>(); cmdList.add(AddVmwareDcCmd.class); cmdList.add(UpdateVmwareDcCmd.class); cmdList.add(RemoveVmwareDcCmd.class); @@ -1120,7 +1095,7 @@ public List> getCommands() { @Override @DB public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException { - VmwareDatacenterVO vmwareDc = null; + VmwareDatacenterVO vmwareDc; Long zoneId = cmd.getZoneId(); String userName = cmd.getUsername(); String password = cmd.getPassword(); @@ -1176,10 +1151,10 @@ public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws Resourc checkIfDcIsUsed(vCenterHost, vmwareDcName, zoneId); VmwareContext context = null; - DatacenterMO dcMo = null; + DatacenterMO dcMo; String dcCustomFieldValue; boolean addDcCustomFieldDef = false; - boolean dcInUse = false; + boolean dcInUse; String guid; ManagedObjectReference dcMor; try { @@ -1212,7 +1187,7 @@ public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws Resourc // Map zone with vmware datacenter vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId()); - vmwareDcZoneMap = vmwareDatacenterZoneMapDao.persist(vmwareDcZoneMap); + vmwareDatacenterZoneMapDao.persist(vmwareDcZoneMap); // Set custom field for this DC if (addDcCustomFieldDef) { @@ -1232,7 +1207,6 @@ public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws Resourc if (context != null) { context.close(); } - context = null; } importVsphereStoragePoliciesInternal(zoneId, vmwareDc.getId()); return vmwareDc; @@ -1257,9 +1231,9 @@ VmwareDatacenterVO createOrUpdateDc(String guid, String name, String host, Strin * 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 * - * @param vCenterHost - * @param vmwareDcName - * @param zoneId + * @param vCenterHost the vcenter appliance hostname + * @param vmwareDcName the name of the vmware DC + * @param zoneId zone that the DC should be connected to * @throws ResourceInUseException if the DC can not be used. */ private void checkIfDcIsUsed(String vCenterHost, String vmwareDcName, Long zoneId) throws ResourceInUseException { @@ -1267,7 +1241,7 @@ private void checkIfDcIsUsed(String vCenterHost, String vmwareDcName, Long zoneI vmwareDc = vmwareDcDao.getVmwareDatacenterByGuid(vmwareDcName + "@" + vCenterHost); if (vmwareDc != null) { 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)); } } @@ -1276,7 +1250,7 @@ private void checkIfDcIsUsed(String vCenterHost, String vmwareDcName, Long zoneI @Override @ActionEvent(eventType = EventTypes.EVENT_ZONE_EDIT, eventDescription = "updating VMware datacenter") public VmwareDatacenter updateVmwareDatacenter(UpdateVmwareDcCmd cmd) { - final Long zoneId = cmd.getZoneId(); + final long zoneId = cmd.getZoneId(); final String userName = cmd.getUsername(); final String password = cmd.getPassword(); final String vCenterHost = cmd.getVcenter(); @@ -1304,7 +1278,7 @@ public VmwareDatacenter updateVmwareDatacenter(UpdateVmwareDcCmd cmd) { } vmwareDc.setGuid(String.format("%s@%s", vmwareDc.getVmwareDatacenterName(), vmwareDc.getVcenterHost())); - return Transaction.execute(new TransactionCallback() { + return Transaction.execute(new TransactionCallback<>() { @Override public VmwareDatacenter doInTransaction(TransactionStatus status) { if (vmwareDcDao.update(vmwareDc.getId(), vmwareDc)) { @@ -1353,7 +1327,7 @@ public boolean removeVmwareDatacenter(RemoveVmwareDcCmd cmd) throws ResourceInUs String vCenterHost; String userName; String password; - DatacenterMO dcMo = null; + DatacenterMO dcMo; final VmwareDatacenterZoneMapVO vmwareDcZoneMap = vmwareDatacenterZoneMapDao.findByZoneId(zoneId); // Check if zone is associated with VMware DC if (vmwareDcZoneMap == null) { @@ -1390,11 +1364,9 @@ public void doInTransactionWithoutResult(TransactionStatus status) { throw new DiscoveryException(msg); } - assert (dcMo != null); - // Reset custom field property cloud.zone over this DC dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "false"); - s_logger.info("Sucessfully reset custom field property cloud.zone over DC " + vmwareDcName); + s_logger.info("Successfully reset custom field property cloud.zone over DC " + vmwareDcName); } catch (Exception e) { String msg = "Unable to reset custom field property cloud.zone over DC " + vmwareDcName + " due to : " + VmwareHelper.getExceptionMessage(e); s_logger.error(msg); @@ -1403,7 +1375,6 @@ public void doInTransactionWithoutResult(TransactionStatus status) { if (context != null) { context.close(); } - context = null; } return true; } @@ -1424,7 +1395,7 @@ private void validateZone(Long zoneId) throws InvalidParameterValueException { private void validateZoneWithResources(Long zoneId, String errStr) throws ResourceInUseException { // Check if zone has resources? - For now look for clusters List clusters = clusterDao.listByZoneId(zoneId); - if (clusters != null && clusters.size() > 0) { + if (!CollectionUtils.isNullOrEmpty(clusters)) { // Look for VMware hypervisor. for (ClusterVO cluster : clusters) { if (cluster.getHypervisorType().equals(HypervisorType.VMware)) { @@ -1445,9 +1416,9 @@ public boolean isLegacyZone(long dcId) { } @Override - public List listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException, InvalidParameterValueException { + public List listVmwareDatacenters(ListVmwareDcsCmd cmd) throws CloudRuntimeException { Long zoneId = cmd.getZoneId(); - List vmwareDcList = new ArrayList(); + List vmwareDcList = new ArrayList<>(); VmwareDatacenterZoneMapVO vmwareDcZoneMap; VmwareDatacenterVO vmwareDatacenter; long vmwareDcId; @@ -1505,7 +1476,7 @@ public List importVsphereStoragePoliciesInternal String vCenterHost = vmwareDatacenter.getVcenterHost(); String userName = vmwareDatacenter.getUser(); String password = vmwareDatacenter.getPassword(); - List storageProfiles = null; + List storageProfiles; try { s_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); @@ -1533,16 +1504,15 @@ public List importVsphereStoragePoliciesInternal List allStoragePolicies = vsphereStoragePolicyDao.listAll(); List finalStorageProfiles = storageProfiles; List needToMarkRemoved = allStoragePolicies.stream() - .filter(existingPolicy -> !finalStorageProfiles.stream() - .anyMatch(storageProfile -> storageProfile.getProfileId().getUniqueId().equals(existingPolicy.getPolicyId()))) + .filter(existingPolicy -> finalStorageProfiles.stream() + .noneMatch(storageProfile -> storageProfile.getProfileId().getUniqueId().equals(existingPolicy.getPolicyId()))) .collect(Collectors.toList()); for (VsphereStoragePolicyVO storagePolicy : needToMarkRemoved) { vsphereStoragePolicyDao.remove(storagePolicy.getId()); } - List storagePolicies = vsphereStoragePolicyDao.listAll(); - return storagePolicies; + return vsphereStoragePolicyDao.listAll(); } @Override @@ -1594,7 +1564,16 @@ public List listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { String username = cmd.getUsername(); String password = cmd.getPassword(); Integer maxObjects = cmd.getPageSize(); - boolean nextPage = cmd.getPageNumber() != null && cmd.getPageNumber() > 1 ? false : true; + boolean forced = cmd.isForced(); + // TODO refactor to check if the page is available + boolean nextPage = cmd.getPageNumber() == null || cmd.getPageNumber() <= 1; + if (forced) { +// remove existing data from local map + } + if (nextPage) { +// check if there is a next page possible + } + Long existingVcenterId = cmd.getExistingVcenterId(); String keyword = cmd.getKeyword(); @@ -1618,11 +1597,11 @@ public List listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { password = vmwareDc.getPassword(); } + s_logger.debug(String.format("Connecting to the VMware datacenter %s at vCenter %s to retrieve VMs", + datacenterName, vcenter)); + String serviceUrl = String.format("https://%s/sdk/vimService", vcenter); + VmwareClient vimClient = new VmwareClient(vcenter); try { - s_logger.debug(String.format("Connecting to the VMware datacenter %s at vCenter %s to retrieve VMs", - datacenterName, vcenter)); - String serviceUrl = String.format("https://%s/sdk/vimService", vcenter); - VmwareClient vimClient = new VmwareClient(vcenter); vimClient.connect(serviceUrl, username, password); VmwareContext context = new VmwareContext(vimClient, vcenter); @@ -1634,11 +1613,13 @@ public List listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { s_logger.error(msg); throw new InvalidParameterValueException(msg); } - List instances = java.util.Collections.synchronizedList(new ArrayList()); + List instances = Collections.synchronizedList(new ArrayList<>()); instances.addAll(dcMo.getVmsOnDatacenter(maxObjects, null).second()); return StringUtils.isBlank(keyword) ? instances : instances.stream().filter(x -> x.getName().toLowerCase().contains(keyword.toLowerCase())).collect(Collectors.toList()); - } catch (Exception e) { + } 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", vcenter, datacenterName, e.getMessage()); s_logger.error(errorMsg, e); @@ -1648,7 +1629,7 @@ public List listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { @Override public boolean hasNexusVSM(Long clusterId) { - ClusterVSMMapVO vsmMapVo = null; + ClusterVSMMapVO vsmMapVo; vsmMapVo = _vsmMapDao.findByClusterId(clusterId); if (vsmMapVo == null) { diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java index 414a19b86ad6..77ca35359362 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java @@ -79,6 +79,9 @@ public class ListVmwareDcVmsCmd extends BaseListCmd { " If no previous call has been done, this is the same as the first page") private Integer pageNumber; + @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, description = "force retrieving new results, ignoring any cached data.") + private Boolean forced; + public String getVcenter() { return vcenter; } @@ -99,6 +102,10 @@ public Integer getPageNumber() { return pageNumber; } + public boolean isForced() { + return forced == null ? true : forced; + } + public String getDatacenterName() { return datacenterName; } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index b2e166cb3055..58ec33003caa 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -17,6 +17,7 @@ package com.cloud.hypervisor.vmware.mo; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -59,7 +60,7 @@ public DatacenterMO(VmwareContext context, String morType, String 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); _mor = _context.getVimClient().getDecendentMoRef(_context.getRootFolder(), "Datacenter", dcName); @@ -70,24 +71,7 @@ public DatacenterMO(VmwareContext context, String dcName) throws Exception { @Override public String getName() throws Exception { - return (String)_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); - } + return _context.getVimClient().getDynamicProperty(_mor, "name"); } public VirtualMachineMO findVm(String vmName) throws Exception { @@ -105,10 +89,10 @@ public List findVmByNameAndLabel(String vmLabel) throws Except int key = cfmMo.getCustomFieldKey("VirtualMachine", CustomFieldConstants.CLOUD_UUID); assert (key != 0); - List list = new ArrayList(); + List list = new ArrayList<>(); List ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name", String.format("value[%d]", key)}); - if (ocs != null && ocs.size() > 0) { + if (CollectionUtils.isNotEmpty(ocs)) { for (ObjectContent oc : ocs) { List props = oc.getPropSet(); if (props != null) { @@ -141,7 +125,7 @@ public VirtualMachineMO checkIfVmAlreadyExistsInVcenter(String vmNameOnVcenter, } List ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name", String.format("value[%d]", key)}); - if (ocs != null && ocs.size() > 0) { + if (CollectionUtils.isNotEmpty(ocs)) { for (ObjectContent oc : ocs) { List props = oc.getPropSet(); if (props != null) { @@ -166,7 +150,7 @@ public VirtualMachineMO checkIfVmAlreadyExistsInVcenter(String vmNameOnVcenter, return null; } - public Pair> getVmsOnDatacenter(Integer maxObjects, String token) throws Exception { + public Pair> getVmsOnDatacenter(Integer maxObjects, String token) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { List vms = new ArrayList<>(); Pair> objectContents = getVmPropertiesOnDatacenterVmFolder(new String[] {"name"}, maxObjects, token); Pair> retval = new Pair<>(objectContents.first(), vms); @@ -219,20 +203,6 @@ public ManagedObjectReference findDatastore(String name) throws Exception { return null; } - public ManagedObjectReference listDatastore(String name) throws Exception { - assert (name != null); - - List 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 ocs = getHostPropertiesOnDatacenterHostFolder(new String[] {"name"}); @@ -247,7 +217,7 @@ public ManagedObjectReference findHost(String name) throws Exception { } public ManagedObjectReference getVmFolder() throws Exception { - return (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "vmFolder"); + return _context.getVimClient().getDynamicProperty(_mor, "vmFolder"); } public List getHostPropertiesOnDatacenterHostFolder(String[] propertyPaths) throws Exception { @@ -284,7 +254,7 @@ public List getHostPropertiesOnDatacenterHostFolder(String[] prop PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); @@ -310,7 +280,7 @@ public List getDatastorePropertiesOnDatacenter(String[] propertyP PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); @@ -327,7 +297,8 @@ public List getVmPropertiesOnDatacenterVmFolder(String[] property * @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 Exception generic {code}Exception{code} as thrown by Vmware. + * @throws InvalidPropertyFaultMsg property does not exist as thrown by Vmware. + * @throws RuntimeFaultFaultMsg generic vmware runtime exception */ public Pair> getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths, Integer maxObjects, String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { if(StringUtils.isNotBlank(tokenForPriorQuery)) { @@ -410,18 +381,18 @@ public static Pair getOwnerDatacenter(VmwareContext contex PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); List 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).getPropSet().get(0) != null); assert (ocs.get(0).getPropSet().get(0).getVal() != null); String dcName = ocs.get(0).getPropSet().get(0).getVal().toString(); - return new Pair(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 { @@ -442,7 +413,7 @@ public ManagedObjectReference getDvPortGroupMor(String dvPortGroupName) throws E PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); List ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); @@ -463,9 +434,7 @@ public ManagedObjectReference getDvPortGroupMor(String dvPortGroupName) throws E public boolean hasDvPortGroup(String dvPortGroupName) throws Exception { ManagedObjectReference morNetwork = getDvPortGroupMor(dvPortGroupName); - if (morNetwork != null) - return true; - return false; + return morNetwork != null; } public DVPortgroupConfigInfo getDvPortGroupSpec(String dvPortGroupName) throws Exception { @@ -489,7 +458,7 @@ public DVPortgroupConfigInfo getDvPortGroupSpec(String dvPortGroupName) throws E PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); List ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); @@ -506,7 +475,7 @@ public DVPortgroupConfigInfo getDvPortGroupSpec(String dvPortGroupName) throws E nameProperty = prop.getVal().toString(); } } - if (nameProperty.equalsIgnoreCase(dvPortGroupName)) { + if (nameProperty != null && nameProperty.equalsIgnoreCase(dvPortGroupName)) { return configSpec; } } @@ -536,7 +505,7 @@ public ManagedObjectReference getDvSwitchMor(ManagedObjectReference dvPortGroupM PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); List ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); @@ -564,7 +533,7 @@ public ManagedObjectReference getDvSwitchMor(ManagedObjectReference dvPortGroupM public String getDvSwitchUuid(ManagedObjectReference dvSwitchMor) throws Exception { assert (dvSwitchMor != null); - return (String)_context.getVimClient().getDynamicProperty(dvSwitchMor, "uuid"); + return _context.getVimClient().getDynamicProperty(dvSwitchMor, "uuid"); } public VirtualEthernetCardDistributedVirtualPortBackingInfo getDvPortBackingInfo(Pair networkInfo) throws Exception { @@ -582,8 +551,8 @@ public VirtualEthernetCardDistributedVirtualPortBackingInfo getDvPortBackingInfo } public ManagedObjectReference getDvSwitchMor(String dvSwitchName) throws Exception { - ManagedObjectReference dvSwitchMor = null; - ManagedObjectReference networkFolderMor = null; + ManagedObjectReference dvSwitchMor; + ManagedObjectReference networkFolderMor; networkFolderMor = _context.getVimClient().getMoRefProp(_mor, "networkFolder"); dvSwitchMor = _context.getVimClient().getDecendentMoRef(networkFolderMor, "VmwareDistributedVirtualSwitch", dvSwitchName); return dvSwitchMor; @@ -595,7 +564,6 @@ public boolean ensureCustomFieldDef(String fieldName) throws Exception { } public DatacenterConfigInfo getDatacenterConfigInfo() throws Exception { - DatacenterConfigInfo configInfo = (DatacenterConfigInfo)_context.getVimClient().getDynamicProperty(_mor, "configuration"); - return configInfo; + return _context.getVimClient().getDynamicProperty(_mor, "configuration"); } } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index 742f33575f50..3f3dbc61d8b5 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -26,7 +26,8 @@ import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; -import java.net.URLEncoder; +import java.lang.reflect.InvocationTargetException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -41,11 +42,6 @@ import com.cloud.storage.Storage; import com.cloud.utils.exception.CloudRuntimeException; -import com.vmware.vim25.InvalidStateFaultMsg; -import com.vmware.vim25.RuntimeFaultFaultMsg; -import com.vmware.vim25.TaskInfo; -import com.vmware.vim25.TaskInfoState; -import com.vmware.vim25.VirtualMachineTicket; import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -55,12 +51,13 @@ import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareHelper; import com.cloud.utils.ActionDelegate; -import com.cloud.utils.LogUtils; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.script.Script; + import com.google.gson.Gson; + import com.vmware.vim25.ArrayOfManagedObjectReference; import com.vmware.vim25.ChoiceOption; import com.vmware.vim25.CustomFieldStringValue; @@ -72,6 +69,8 @@ import com.vmware.vim25.HttpNfcLeaseDeviceUrl; import com.vmware.vim25.HttpNfcLeaseInfo; import com.vmware.vim25.HttpNfcLeaseState; +import com.vmware.vim25.InvalidPropertyFaultMsg; +import com.vmware.vim25.InvalidStateFaultMsg; import com.vmware.vim25.ManagedObjectReference; import com.vmware.vim25.ObjectContent; import com.vmware.vim25.ObjectSpec; @@ -82,12 +81,14 @@ import com.vmware.vim25.ParaVirtualSCSIController; import com.vmware.vim25.PropertyFilterSpec; import com.vmware.vim25.PropertySpec; +import com.vmware.vim25.RuntimeFaultFaultMsg; +import com.vmware.vim25.TaskInfo; +import com.vmware.vim25.TaskInfoState; import com.vmware.vim25.TraversalSpec; import com.vmware.vim25.VirtualBusLogicController; import com.vmware.vim25.VirtualCdrom; import com.vmware.vim25.VirtualCdromIsoBackingInfo; import com.vmware.vim25.VirtualCdromRemotePassthroughBackingInfo; -import com.vmware.vim25.VirtualController; import com.vmware.vim25.VirtualDevice; import com.vmware.vim25.VirtualDeviceBackingInfo; import com.vmware.vim25.VirtualDeviceConfigSpec; @@ -126,6 +127,7 @@ import com.vmware.vim25.VirtualMachineRuntimeInfo; import com.vmware.vim25.VirtualMachineSnapshotInfo; import com.vmware.vim25.VirtualMachineSnapshotTree; +import com.vmware.vim25.VirtualMachineTicket; import com.vmware.vim25.VirtualSCSIController; import com.vmware.vim25.VirtualSCSISharing; @@ -160,54 +162,17 @@ public Pair getOwnerDatacenter() throws Exception { return DatacenterMO.getOwnerDatacenter(getContext(), getMor()); } - public Pair getOwnerDatastore(String dsFullPath) throws Exception { - String dsName = DatastoreFile.getDatastoreNameFromPath(dsFullPath); - - PropertySpec pSpec = new PropertySpec(); - pSpec.setType("Datastore"); - pSpec.getPathSet().add("name"); - - TraversalSpec vmDatastoreTraversal = new TraversalSpec(); - vmDatastoreTraversal.setType("VirtualMachine"); - vmDatastoreTraversal.setPath("datastore"); - vmDatastoreTraversal.setName("vmDatastoreTraversal"); - - ObjectSpec oSpec = new ObjectSpec(); - oSpec.setObj(_mor); - oSpec.setSkip(Boolean.TRUE); - oSpec.getSelectSet().add(vmDatastoreTraversal); - - PropertyFilterSpec pfSpec = new PropertyFilterSpec(); - pfSpec.getPropSet().add(pSpec); - pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); - pfSpecArr.add(pfSpec); - - List ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); - - if (ocs != null) { - for (ObjectContent oc : ocs) { - DynamicProperty prop = oc.getPropSet().get(0); - if (prop.getVal().toString().equals(dsName)) { - return new Pair(new DatastoreMO(_context, oc.getObj()), dsName); - } - } - } - - return null; - } - public HostMO getRunningHost() throws Exception { VirtualMachineRuntimeInfo runtimeInfo = getRuntimeInfo(); return new HostMO(_context, runtimeInfo.getHost()); } - public String getVmName() throws Exception { - return (String)getContext().getVimClient().getDynamicProperty(_mor, "name"); + public String getVmName() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { + return getContext().getVimClient().getDynamicProperty(_mor, "name"); } public GuestInfo getVmGuestInfo() throws Exception { - return (GuestInfo)getContext().getVimClient().getDynamicProperty(_mor, "guest"); + return getContext().getVimClient().getDynamicProperty(_mor, "guest"); } public void answerVM(String questionId, String choice) throws Exception { @@ -216,11 +181,7 @@ public void answerVM(String questionId, String choice) throws Exception { public boolean isVMwareToolsRunning() throws Exception { GuestInfo guestInfo = getVmGuestInfo(); - if (guestInfo != null) { - if ("guestToolsRunning".equalsIgnoreCase(guestInfo.getToolsRunningStatus())) - return true; - } - return false; + return guestInfo != null && "guestToolsRunning".equalsIgnoreCase(guestInfo.getToolsRunningStatus()); } public boolean powerOn() throws Exception { @@ -389,7 +350,7 @@ public VirtualMachinePowerState getResetSafePowerState() throws Exception { // In the future, VMsync should not kick off CloudStack action (this is not a HA case) based on VM // state report, until then we can remove this hacking fix for (int i = 0; i < 3; i++) { - powerState = (VirtualMachinePowerState)getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState"); + powerState = getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState"); if (powerState == VirtualMachinePowerState.POWERED_OFF) { try { Thread.sleep(1000); @@ -405,7 +366,7 @@ public VirtualMachinePowerState getResetSafePowerState() throws Exception { } public VirtualMachinePowerState getPowerState() throws Exception { - return (VirtualMachinePowerState)getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState"); + return getContext().getVimClient().getDynamicProperty(_mor, "runtime.powerState"); } public boolean reset() throws Exception { @@ -468,39 +429,6 @@ public boolean changeDatastore(VirtualMachineRelocateSpec relocateSpec) throws E return false; } - public boolean changeHost(VirtualMachineRelocateSpec relocateSpec) throws Exception { - ManagedObjectReference morTask = _context.getService().relocateVMTask(_mor, relocateSpec, VirtualMachineMovePriority.DEFAULT_PRIORITY); - boolean result = _context.getVimClient().waitForTask(morTask); - if (result) { - _context.waitForTaskProgressDone(morTask); - return true; - } else { - s_logger.error("VMware RelocateVM_Task to change host failed due to " + TaskMO.getTaskFailureInfo(_context, morTask)); - } - return false; - } - - public boolean changeDatastore(ManagedObjectReference morDataStore, VmwareHypervisorHost targetHost) throws Exception { - VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec(); - relocateSpec.setDatastore(morDataStore); - if (targetHost != null) { - relocateSpec.setHost(targetHost.getMor()); - relocateSpec.setPool(targetHost.getHyperHostOwnerResourcePool()); - } - - ManagedObjectReference morTask = _context.getService().relocateVMTask(_mor, relocateSpec, null); - - boolean result = _context.getVimClient().waitForTask(morTask); - if (result) { - _context.waitForTaskProgressDone(morTask); - return true; - } else { - s_logger.error("VMware change datastore relocateVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask)); - } - - return false; - } - public boolean relocate(ManagedObjectReference morTargetHost) throws Exception { VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec(); relocateSpec.setHost(morTargetHost); @@ -519,7 +447,7 @@ public boolean relocate(ManagedObjectReference morTargetHost) throws Exception { } public VirtualMachineSnapshotInfo getSnapshotInfo() throws Exception { - return (VirtualMachineSnapshotInfo)_context.getVimClient().getDynamicProperty(_mor, "snapshot"); + return _context.getVimClient().getDynamicProperty(_mor, "snapshot"); } public boolean createSnapshot(String snapshotName, String snapshotDescription, boolean dumpMemory, boolean quiesce) throws Exception { @@ -589,39 +517,6 @@ public boolean removeSnapshot(String snapshotName, boolean removeChildren) throw return false; } - public boolean revertToSnapshot(String snapshotName) throws Exception { - ManagedObjectReference morSnapshot = getSnapshotMor(snapshotName); - if (morSnapshot == null) { - s_logger.warn("Unable to find snapshot: " + snapshotName); - return false; - } - ManagedObjectReference morTask = _context.getService().revertToSnapshotTask(morSnapshot, _mor, null); - boolean result = _context.getVimClient().waitForTask(morTask); - if (result) { - _context.waitForTaskProgressDone(morTask); - return true; - } else { - s_logger.error("VMware revert to snapshot failed due to " + TaskMO.getTaskFailureInfo(_context, morTask)); - } - - return false; - } - - /** - * Deletes all of the snapshots of a VM. - */ - public void consolidateAllSnapshots() throws Exception { - ManagedObjectReference task = _context.getService().removeAllSnapshotsTask(_mor, true); - - boolean result = _context.getVimClient().waitForTask(task); - - if (result) { - _context.waitForTaskProgressDone(task); - } else { - throw new Exception("Unable to register VM due to the following issue: " + TaskMO.getTaskFailureInfo(_context, task)); - } - } - public boolean removeAllSnapshots() throws Exception { VirtualMachineSnapshotInfo snapshotInfo = getSnapshotInfo(); @@ -701,7 +596,7 @@ public String getSnapshotDescriptorDatastorePath() throws Exception { PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); List ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); @@ -750,9 +645,7 @@ public boolean hasSnapshot() throws Exception { return true; } List rootSnapshotList = info.getRootSnapshotList(); - if (rootSnapshotList != null && rootSnapshotList.size() > 0) { - return true; - } + return CollectionUtils.isNotEmpty(rootSnapshotList); } return false; } @@ -905,11 +798,11 @@ public boolean createLinkedClone(String cloneName, ManagedObjectReference morBas VirtualDisk[] independentDisks = getAllIndependentDiskDevice(); VirtualMachineRelocateSpec rSpec = new VirtualMachineRelocateSpec(); if (independentDisks.length > 0) { - List diskLocator = new ArrayList(independentDisks.length); - for (int i = 0; i < independentDisks.length; i++) { + List diskLocator = new ArrayList<>(independentDisks.length); + for (VirtualDisk independentDisk : independentDisks) { VirtualMachineRelocateSpecDiskLocator loc = new VirtualMachineRelocateSpecDiskLocator(); loc.setDatastore(morDs); - loc.setDiskId(independentDisks[i].getKey()); + loc.setDiskId(independentDisk.getKey()); loc.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING.value()); diskLocator.add(loc); } @@ -941,26 +834,26 @@ public boolean createLinkedClone(String cloneName, ManagedObjectReference morBas } public VirtualMachineRuntimeInfo getRuntimeInfo() throws Exception { - return (VirtualMachineRuntimeInfo)_context.getVimClient().getDynamicProperty(_mor, "runtime"); + return _context.getVimClient().getDynamicProperty(_mor, "runtime"); } public VirtualMachineConfigInfo getConfigInfo() throws Exception { - return (VirtualMachineConfigInfo)_context.getVimClient().getDynamicProperty(_mor, "config"); + return _context.getVimClient().getDynamicProperty(_mor, "config"); } public boolean isToolsInstallerMounted() throws Exception { return _context.getVimClient().getDynamicProperty(_mor, "runtime.toolsInstallerMounted"); } public GuestInfo getGuestInfo() throws Exception { - return (GuestInfo)_context.getVimClient().getDynamicProperty(_mor, "guest"); + return _context.getVimClient().getDynamicProperty(_mor, "guest"); } public VirtualMachineConfigSummary getConfigSummary() throws Exception { - return (VirtualMachineConfigSummary)_context.getVimClient().getDynamicProperty(_mor, "summary.config"); + return _context.getVimClient().getDynamicProperty(_mor, "summary.config"); } public VirtualMachineFileInfo getFileInfo() throws Exception { - return (VirtualMachineFileInfo)_context.getVimClient().getDynamicProperty(_mor, "config.files"); + return _context.getVimClient().getDynamicProperty(_mor, "config.files"); } public VirtualMachineFileLayoutEx getFileLayout() throws Exception { @@ -976,7 +869,7 @@ public VirtualMachineFileLayoutEx getFileLayout() throws Exception { PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); List ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); @@ -1000,7 +893,7 @@ public VirtualMachineFileLayoutEx getFileLayout() throws Exception { @Override public ManagedObjectReference getParentMor() throws Exception { - return (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "parent"); + return _context.getVimClient().getDynamicProperty(_mor, "parent"); } public String[] getNetworks() throws Exception { @@ -1021,13 +914,13 @@ public String[] getNetworks() throws Exception { PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); List ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); - List networks = new ArrayList(); - if (ocs != null && ocs.size() > 0) { + List networks = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(ocs)) { for (ObjectContent oc : ocs) { networks.add(oc.getPropSet().get(0).getVal().toString()); } @@ -1036,7 +929,7 @@ public String[] getNetworks() throws Exception { } public List getNetworksWithDetails() throws Exception { - List networks = new ArrayList(); + List networks = new ArrayList<>(); int gcTagKey = getCustomFieldKey("Network", CustomFieldConstants.CLOUD_GC); @@ -1064,12 +957,12 @@ public List getNetworksWithDetails() throws Exception { PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); List ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); - if (ocs != null && ocs.size() > 0) { + if (CollectionUtils.isNotEmpty(ocs)) { for (ObjectContent oc : ocs) { ArrayOfManagedObjectReference morVms = null; String gcTagValue = null; @@ -1117,12 +1010,12 @@ public List getAllDatastores() throws Exception { PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); List ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); - List datastores = new ArrayList(); + List datastores = new ArrayList<>(); if (CollectionUtils.isNotEmpty(ocs)) { for (ObjectContent oc : ocs) { datastores.add(new DatastoreMO(_context, oc.getObj())); @@ -1131,61 +1024,6 @@ public List getAllDatastores() throws Exception { return datastores; } - /** - * Retrieve path info to access VM files via vSphere web interface - * @return [0] vm-name, [1] data-center-name, [2] datastore-name - * @throws Exception - */ - public String[] getHttpAccessPathInfo() throws Exception { - String[] pathInfo = new String[3]; - - Pair dcInfo = getOwnerDatacenter(); - - VirtualMachineFileInfo fileInfo = getFileInfo(); - String vmxFilePath = fileInfo.getVmPathName(); - String vmxPathTokens[] = vmxFilePath.split("\\[|\\]|/"); - assert (vmxPathTokens.length == 4); - pathInfo[1] = vmxPathTokens[1].trim(); // vSphere vm name - pathInfo[2] = dcInfo.second(); // vSphere datacenter name - pathInfo[3] = vmxPathTokens[0].trim(); // vSphere datastore name - return pathInfo; - } - - public String getVmxHttpAccessUrl() throws Exception { - Pair dcInfo = getOwnerDatacenter(); - - VirtualMachineFileInfo fileInfo = getFileInfo(); - String vmxFilePath = fileInfo.getVmPathName(); - String vmxPathTokens[] = vmxFilePath.split("\\[|\\]|/"); - - StringBuffer sb = new StringBuffer("https://" + _context.getServerAddress() + "/folder/"); - sb.append(URLEncoder.encode(vmxPathTokens[2].trim(), "UTF-8")); - sb.append("/"); - sb.append(URLEncoder.encode(vmxPathTokens[3].trim(), "UTF-8")); - sb.append("?dcPath="); - sb.append(URLEncoder.encode(dcInfo.second(), "UTF-8")); - sb.append("&dsName="); - sb.append(URLEncoder.encode(vmxPathTokens[1].trim(), "UTF-8")); - - return sb.toString(); - } - - public boolean setVncConfigInfo(boolean enableVnc, String vncPassword, int vncPort, String keyboard) throws Exception { - VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); - OptionValue[] vncOptions = VmwareHelper.composeVncOptions(null, enableVnc, vncPassword, vncPort, keyboard); - vmConfigSpec.getExtraConfig().addAll(Arrays.asList(vncOptions)); - ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, vmConfigSpec); - - boolean result = _context.getVimClient().waitForTask(morTask); - if (result) { - _context.waitForTaskProgressDone(morTask); - return true; - } else { - s_logger.error("VMware reconfigVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask)); - } - return false; - } - public boolean configureVm(VirtualMachineConfigSpec vmConfigSpec) throws Exception { ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, vmConfigSpec); @@ -1239,12 +1077,12 @@ public Pair getVncPort(String hostNetworkName) throws Exception if (option.getKey().equals("RemoteDisplay.vnc.port")) { String value = (String)option.getValue(); if (value != null) { - return new Pair(summary.getHostIp(), Integer.parseInt(value)); + return new Pair<>(summary.getHostIp(), Integer.parseInt(value)); } } } } - return new Pair(summary.getHostIp(), 0); + return new Pair<>(summary.getHostIp(), 0); } // vmdkDatastorePath: [datastore name] vmdkFilePath @@ -1255,11 +1093,11 @@ public void createDisk(String vmdkDatastorePath, long sizeInMb, ManagedObjectRef // vmdkDatastorePath: [datastore name] vmdkFilePath public void createDisk(String vmdkDatastorePath, VirtualDiskType diskType, VirtualDiskMode diskMode, String rdmDeviceName, long sizeInMb, ManagedObjectReference morDs, int controllerKey, String vSphereStoragePolicyId) throws Exception { + assert (morDs != null); s_logger.trace(String.format("Creating disk in target MOR [%s] with values: vmdkDatastorePath [%s], sizeInMb [%s], diskType [%s], diskMode [%s], rdmDeviceName [%s]" + ", datastore [%s], controllerKey [%s].", _mor.getValue(), vmdkDatastorePath, sizeInMb, diskType, diskMode, rdmDeviceName, morDs.getValue(), controllerKey)); assert (vmdkDatastorePath != null); - assert (morDs != null); int ideControllerKey = getIDEDeviceControllerKey(); if (controllerKey < 0) { @@ -1271,17 +1109,9 @@ public void createDisk(String vmdkDatastorePath, VirtualDiskType diskType, Virtu VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo(); backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value()); - if (diskType == VirtualDiskType.THIN) { - backingInfo.setThinProvisioned(true); - } else { - backingInfo.setThinProvisioned(false); - } + backingInfo.setThinProvisioned(diskType == VirtualDiskType.THIN); - if (diskType == VirtualDiskType.EAGER_ZEROED_THICK) { - backingInfo.setEagerlyScrub(true); - } else { - backingInfo.setEagerlyScrub(false); - } + backingInfo.setEagerlyScrub(diskType == VirtualDiskType.EAGER_ZEROED_THICK); backingInfo.setDatastore(morDs); backingInfo.setFileName(vmdkDatastorePath); @@ -1358,7 +1188,7 @@ public void updateVmdkAdapter(String vmdkFileName, String diskController) throws if (!currentAdapterType.equalsIgnoreCase(newAdapterType)) { s_logger.info("Updating adapter type to " + newAdapterType + " for VMDK file " + vmdkFileName); Pair dcInfo = getOwnerDatacenter(); - byte[] newVmdkContent = vmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType); + byte[] newVmdkContent = VmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType); String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcInfo.first().getName(), vmdkFileName); getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent); s_logger.info("Updated VMDK file " + vmdkFileName); @@ -1385,7 +1215,7 @@ public void updateAdapterTypeIfRequired(String vmdkFileName) throws Exception { VmdkAdapterType newAdapterType = VmdkAdapterType.lsilogic; s_logger.debug("Updating adapter type to " + newAdapterType + " from " + currentAdapterTypeStr + " for VMDK file " + vmdkFileName); Pair dcInfo = getOwnerDatacenter(); - byte[] newVmdkContent = vmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType.toString()); + byte[] newVmdkContent = VmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(), newAdapterType.toString()); String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcInfo.first().getName(), vmdkFileName); getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent); @@ -1406,8 +1236,8 @@ public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference m if(s_logger.isTraceEnabled()) s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + GSON.toJson(vmdkDatastorePathChain) + ", datastore: " + morDs.getValue()); - int controllerKey = 0; - int unitNumber = 0; + int controllerKey; + int unitNumber; if (DiskControllerType.getType(diskController) == DiskControllerType.ide) { // IDE virtual disk cannot be added if VM is running @@ -1468,21 +1298,6 @@ public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference m s_logger.trace("vCenter API trace - attachDisk() done(successfully)"); } - private int getControllerBusNumber(int controllerKey) throws Exception { - List devices = (List)_context.getVimClient(). - getDynamicProperty(_mor, "config.hardware.device"); - - if (devices != null && devices.size() > 0) { - for (VirtualDevice device : devices) { - if (device instanceof VirtualController && device.getKey() == controllerKey) { - return ((VirtualController)device).getBusNumber(); - } - } - } - throw new Exception("SCSI Controller with key " + controllerKey + " is Not Found"); - - } - // vmdkDatastorePath: [datastore name] vmdkFilePath public List> detachDisk(String vmdkDatastorePath, boolean deleteBackingFile) throws Exception { @@ -1792,7 +1607,7 @@ public Pair getVmdkFileInfo(String vmdkDatastorePath VmdkFileDescriptor descriptor = new VmdkFileDescriptor(); descriptor.parse(content); - Pair result = new Pair(descriptor, content); + Pair result = new Pair<>(descriptor, content); if (s_logger.isTraceEnabled()) { s_logger.trace("vCenter API trace - getVmdkFileInfo() done"); s_logger.trace("VMDK file descriptor: " + GSON.toJson(result.first())); @@ -1871,7 +1686,7 @@ public void exportVm(String exportDir, String exportName, boolean packToOva, boo if (s_logger.isInfoEnabled()) { s_logger.info("Download VMDK file for export url: " + deviceUrlStr + ", size: " + diskFileSize); } - long lengthOfDiskFile = _context.downloadVmdkFile(diskUrlStr, diskLocalPath, totalBytesDownloaded, new ActionDelegate() { + long lengthOfDiskFile = _context.downloadVmdkFile(diskUrlStr, diskLocalPath, totalBytesDownloaded, new ActionDelegate<>() { @Override public void action(Long param) { if (s_logger.isTraceEnabled()) { @@ -1896,7 +1711,7 @@ public void action(Long param) { CompletableFuture future = CompletableFuture.supplyAsync(() -> { long lengthOfDiskFile = 0; try { - lengthOfDiskFile = _context.downloadVmdkFile(diskUrl, diskLocalPath, totalBytesDownloaded, new ActionDelegate() { + lengthOfDiskFile = _context.downloadVmdkFile(diskUrl, diskLocalPath, totalBytesDownloaded, new ActionDelegate<>() { @Override public void action(Long param) { if (s_logger.isTraceEnabled()) { @@ -1947,7 +1762,7 @@ public void action(Long param) { String ovfPath = exportDir + File.separator + exportName + ".ovf"; fileNames.add(ovfPath); - OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(ovfPath),"UTF-8"); + OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(ovfPath), StandardCharsets.UTF_8); out.write(ovfCreateDescriptorResult.getOvfDescriptor()); out.close(); @@ -1969,7 +1784,7 @@ public void action(Long param) { } } - s_logger.info("Package OVA with command: " + command.toString()); + s_logger.info("Package OVA with command: " + command); command.execute(); // to be safe, physically test existence of the target OVA file @@ -2018,8 +1833,8 @@ public void setSnapshotDirectory(String snapshotDir) throws Exception { boolean replaced = false; try { - in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(vmxContent),"UTF-8")); - out = new BufferedWriter(new OutputStreamWriter(bos,"UTF-8")); + in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(vmxContent), StandardCharsets.UTF_8)); + out = new BufferedWriter(new OutputStreamWriter(bos, StandardCharsets.UTF_8)); String line; while ((line = in.readLine()) != null) { if (line.startsWith("workingDir")) { @@ -2052,70 +1867,6 @@ public void setSnapshotDirectory(String snapshotDir) throws Exception { // redoRegistration(); } - // destName does not contain extension name - public void backupCurrentSnapshot(String deviceName, ManagedObjectReference morDestDs, String destDsDirectory, String destName, boolean includeBase) throws Exception { - - SnapshotDescriptor descriptor = getSnapshotDescriptor(); - SnapshotInfo[] snapshotInfo = descriptor.getCurrentDiskChain(); - if (snapshotInfo.length == 0) { - String msg = "No snapshot found in this VM"; - throw new Exception(msg); - } - - HostMO hostMo = getRunningHost(); - DatacenterMO dcMo = getOwnerDatacenter().first(); - List> mounts = hostMo.getDatastoreMountsOnHost(); - VirtualMachineFileInfo vmFileInfo = getFileInfo(); - - List> backupInfo = new ArrayList>(); - - for (int i = 0; i < snapshotInfo.length; i++) { - if (!includeBase && i == snapshotInfo.length - 1) { - break; - } - - SnapshotDescriptor.DiskInfo[] disks = snapshotInfo[i].getDisks(); - if (disks != null) { - String destBaseFileName; - String destFileName; - String destParentFileName; - for (SnapshotDescriptor.DiskInfo disk : disks) { - if (deviceName == null || deviceName.equals(disk.getDeviceName())) { - String srcVmdkFullDsPath = getSnapshotDiskFileDatastorePath(vmFileInfo, mounts, disk.getDiskFileName()); - Pair srcDsInfo = getOwnerDatastore(srcVmdkFullDsPath); - - Pair vmdkInfo = getVmdkFileInfo(srcVmdkFullDsPath); - String srcVmdkBaseFilePath = DatastoreFile.getCompanionDatastorePath(srcVmdkFullDsPath, vmdkInfo.first().getBaseFileName()); - - destFileName = destName + (snapshotInfo.length - i - 1) + ".vmdk"; - if (vmdkInfo.first().getParentFileName() != null) { - destBaseFileName = destName + (snapshotInfo.length - i - 1) + "-delta.vmdk"; - destParentFileName = destName + (snapshotInfo.length - i - 2) + ".vmdk"; - } else { - destBaseFileName = destName + (snapshotInfo.length - i - 1) + "-flat.vmdk"; - destParentFileName = null; - } - - s_logger.info("Copy VMDK base file " + srcVmdkBaseFilePath + " to " + destDsDirectory + "/" + destBaseFileName); - srcDsInfo.first().copyDatastoreFile(srcVmdkBaseFilePath, dcMo.getMor(), morDestDs, destDsDirectory + "/" + destBaseFileName, dcMo.getMor(), true); - - byte[] newVmdkContent = VmdkFileDescriptor.changeVmdkContentBaseInfo(vmdkInfo.second(), destBaseFileName, destParentFileName); - String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcMo.getName(), destDsDirectory + "/" + destFileName); - - s_logger.info("Upload VMDK content file to " + destDsDirectory + "/" + destFileName); - getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent); - - backupInfo.add(new Ternary(destFileName, destBaseFileName, destParentFileName)); - } - } - } - } - - byte[] vdiskInfo = VmwareHelper.composeDiskInfo(backupInfo, snapshotInfo.length, includeBase); - String vdiskUploadUrl = getContext().composeDatastoreBrowseUrl(dcMo.getName(), destDsDirectory + "/" + destName + ".vdisk"); - getContext().uploadResourceContent(vdiskUploadUrl, vdiskInfo); - } - public String[] getCurrentSnapshotDiskChainDatastorePaths(String diskDevice) throws Exception { HostMO hostMo = getRunningHost(); List> mounts = hostMo.getDatastoreMountsOnHost(); @@ -2124,9 +1875,9 @@ public String[] getCurrentSnapshotDiskChainDatastorePaths(String diskDevice) thr SnapshotDescriptor descriptor = getSnapshotDescriptor(); SnapshotInfo[] snapshotInfo = descriptor.getCurrentDiskChain(); - List diskDsFullPaths = new ArrayList(); - for (int i = 0; i < snapshotInfo.length; i++) { - SnapshotDescriptor.DiskInfo[] disks = snapshotInfo[i].getDisks(); + List diskDsFullPaths = new ArrayList<>(); + for (SnapshotInfo info : snapshotInfo) { + SnapshotDescriptor.DiskInfo[] disks = info.getDisks(); if (disks != null) { for (SnapshotDescriptor.DiskInfo disk : disks) { String deviceNameInDisk = disk.getDeviceName(); @@ -2146,7 +1897,7 @@ public Pair cloneFromCurrentSnapshot(String clonedVm assert (morDs != null); String[] disks = getCurrentSnapshotDiskChainDatastorePaths(diskDevice); VirtualMachineMO clonedVm = cloneFromDiskChain(clonedVmName, cpuSpeedMHz, memoryMb, disks, morDs, virtualHardwareVersion); - return new Pair(clonedVm, disks); + return new Pair<>(clonedVm, disks); } public VirtualMachineMO cloneFromDiskChain(String clonedVmName, int cpuSpeedMHz, int memoryMb, String[] disks, ManagedObjectReference morDs, String cloneHardwareVersion) throws Exception { @@ -2197,19 +1948,6 @@ public GuestOsDescriptor getGuestOsDescriptor(String guestOsId) throws Exception return guestOsDescriptor; } - public void plugDevice(VirtualDevice device) throws Exception { - s_logger.debug(LogUtils.logGsonWithoutException("Pluging device [%s] to VM [%s].", device, getVmName())); - VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); - VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); - deviceConfigSpec.setDevice(device); - deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); - - vmConfigSpec.getDeviceChange().add(deviceConfigSpec); - if (!configureVm(vmConfigSpec)) { - throw new Exception("Failed to add devices"); - } - } - public void tearDownDevice(VirtualDevice device) throws Exception { VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); @@ -2242,40 +1980,8 @@ public void tearDownDevices(Class[] deviceClasses) throws Exception { } } - public void copyAllVmDiskFiles(DatastoreMO destDsMo, String destDsDir, boolean followDiskChain) throws Exception { - VirtualDevice[] disks = getAllDiskDevice(); - DatacenterMO dcMo = getOwnerDatacenter().first(); - if (disks != null) { - for (VirtualDevice disk : disks) { - List> vmdkFiles = getDiskDatastorePathChain((VirtualDisk)disk, followDiskChain); - for (Pair fileItem : vmdkFiles) { - DatastoreMO srcDsMo = new DatastoreMO(_context, fileItem.second()); - - DatastoreFile srcFile = new DatastoreFile(fileItem.first()); - DatastoreFile destFile = new DatastoreFile(destDsMo.getName(), destDsDir, srcFile.getFileName()); - - Pair vmdkDescriptor = null; - - vmdkDescriptor = getVmdkFileInfo(fileItem.first()); - - s_logger.info("Copy VM disk file " + srcFile.getPath() + " to " + destFile.getPath()); - srcDsMo.copyDatastoreFile(fileItem.first(), dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true); - - if (vmdkDescriptor != null) { - String vmdkBaseFileName = vmdkDescriptor.first().getBaseFileName(); - String baseFilePath = srcFile.getCompanionPath(vmdkBaseFileName); - destFile = new DatastoreFile(destDsMo.getName(), destDsDir, vmdkBaseFileName); - - s_logger.info("Copy VM disk file " + baseFilePath + " to " + destFile.getPath()); - srcDsMo.copyDatastoreFile(baseFilePath, dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true); - } - } - } - } - } - public List getVmdkFileBaseNames() throws Exception { - List vmdkFileBaseNames = new ArrayList(); + List vmdkFileBaseNames = new ArrayList<>(); VirtualDevice[] devices = getAllDiskDevice(); for(VirtualDevice device : devices) { if(device instanceof VirtualDisk) { @@ -2310,7 +2016,7 @@ public void moveAllVmDiskFiles(DatastoreMO destDsMo, String destDsDir, boolean f DatastoreFile srcFile = new DatastoreFile(fileItem.first()); DatastoreFile destFile = new DatastoreFile(destDsMo.getName(), destDsDir, srcFile.getFileName()); - Pair vmdkDescriptor = null; + Pair vmdkDescriptor; vmdkDescriptor = getVmdkFileInfo(fileItem.first()); s_logger.info("Move VM disk file " + srcFile.getPath() + " to " + destFile.getPath()); @@ -2329,37 +2035,6 @@ public void moveAllVmDiskFiles(DatastoreMO destDsMo, String destDsDir, boolean f } } - public int getPvScsiDeviceControllerKeyNoException() throws Exception { - List devices = (List)_context.getVimClient(). - getDynamicProperty(_mor, "config.hardware.device"); - - if (devices != null && devices.size() > 0) { - for (VirtualDevice device : devices) { - if (device instanceof ParaVirtualSCSIController) { - return device.getKey(); - } - } - } - - return -1; - } - - public int getPvScsiDeviceControllerKey() throws Exception { - List devices = (List)_context.getVimClient(). - getDynamicProperty(_mor, "config.hardware.device"); - - if (devices != null && devices.size() > 0) { - for (VirtualDevice device : devices) { - if (device instanceof ParaVirtualSCSIController) { - return device.getKey(); - } - } - } - - assert (false); - throw new Exception("VMware Paravirtual SCSI Controller Not Found"); - } - protected VirtualSCSIController getScsiController(DiskControllerType type) { switch (type) { case pvscsi: @@ -2443,23 +2118,23 @@ public boolean isPvScsiSupported() throws Exception { // Would be useful if there exists multiple sub types of SCSI controllers per VM are supported in CloudStack f public int getScsiDiskControllerKey(String diskController) throws Exception { - List devices = (List)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); + List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); if (CollectionUtils.isNotEmpty(devices)) { DiskControllerType diskControllerType = DiskControllerType.getType(diskController); for (VirtualDevice device : devices) { if ((diskControllerType == DiskControllerType.lsilogic || diskControllerType == DiskControllerType.scsi) && device instanceof VirtualLsiLogicController && isValidScsiDiskController((VirtualLsiLogicController)device)) { - return ((VirtualLsiLogicController)device).getKey(); + return device.getKey(); } else if ((diskControllerType == DiskControllerType.lsisas1068 || diskControllerType == DiskControllerType.scsi) && device instanceof VirtualLsiLogicSASController && isValidScsiDiskController((VirtualLsiLogicSASController)device)) { - return ((VirtualLsiLogicSASController)device).getKey(); + return device.getKey(); } else if ((diskControllerType == DiskControllerType.pvscsi || diskControllerType == DiskControllerType.scsi) && device instanceof ParaVirtualSCSIController && isValidScsiDiskController((ParaVirtualSCSIController)device)) { - return ((ParaVirtualSCSIController)device).getKey(); + return device.getKey(); } else if ((diskControllerType == DiskControllerType.buslogic || diskControllerType == DiskControllerType.scsi) && device instanceof VirtualBusLogicController && isValidScsiDiskController((VirtualBusLogicController)device)) { - return ((VirtualBusLogicController)device).getKey(); + return device.getKey(); } } } @@ -2469,7 +2144,7 @@ && device instanceof VirtualBusLogicController && isValidScsiDiskController((Vir } public int getScsiDiskControllerKeyNoException(String diskController, int scsiUnitNumber) throws Exception { - List devices = (List)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); + List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); if (CollectionUtils.isNotEmpty(devices) && scsiUnitNumber >= 0) { int requiredScsiController = scsiUnitNumber / VmwareHelper.MAX_ALLOWED_DEVICES_SCSI_CONTROLLER; @@ -2479,7 +2154,7 @@ public int getScsiDiskControllerKeyNoException(String diskController, int scsiUn if ((diskControllerType == DiskControllerType.lsilogic || diskControllerType == DiskControllerType.scsi) && device instanceof VirtualLsiLogicController) { if (scsiControllerDeviceCount == requiredScsiController) { if (isValidScsiDiskController((VirtualLsiLogicController)device)) { - return ((VirtualLsiLogicController)device).getKey(); + return device.getKey(); } break; } @@ -2487,7 +2162,7 @@ public int getScsiDiskControllerKeyNoException(String diskController, int scsiUn } else if ((diskControllerType == DiskControllerType.lsisas1068 || diskControllerType == DiskControllerType.scsi) && device instanceof VirtualLsiLogicSASController) { if (scsiControllerDeviceCount == requiredScsiController) { if (isValidScsiDiskController((VirtualLsiLogicSASController)device)) { - return ((VirtualLsiLogicSASController)device).getKey(); + return device.getKey(); } break; } @@ -2495,7 +2170,7 @@ public int getScsiDiskControllerKeyNoException(String diskController, int scsiUn } else if ((diskControllerType == DiskControllerType.pvscsi || diskControllerType == DiskControllerType.scsi) && device instanceof ParaVirtualSCSIController) { if (scsiControllerDeviceCount == requiredScsiController) { if (isValidScsiDiskController((ParaVirtualSCSIController)device)) { - return ((ParaVirtualSCSIController)device).getKey(); + return device.getKey(); } break; } @@ -2503,7 +2178,7 @@ public int getScsiDiskControllerKeyNoException(String diskController, int scsiUn } else if ((diskControllerType == DiskControllerType.buslogic || diskControllerType == DiskControllerType.scsi) && device instanceof VirtualBusLogicController) { if (scsiControllerDeviceCount == requiredScsiController) { if (isValidScsiDiskController((VirtualBusLogicController)device)) { - return ((VirtualBusLogicController)device).getKey(); + return device.getKey(); } break; } @@ -2516,15 +2191,13 @@ public int getScsiDiskControllerKeyNoException(String diskController, int scsiUn public int getNextScsiDiskDeviceNumber() throws Exception { int scsiControllerKey = getScsiDeviceControllerKey(); - int deviceNumber = getNextDeviceNumber(scsiControllerKey); - - return deviceNumber; + return getNextDeviceNumber(scsiControllerKey); } public int getScsiDeviceControllerKey() throws Exception { List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); - if (devices != null && devices.size() > 0) { + if (CollectionUtils.isNotEmpty(devices)) { for (VirtualDevice device : devices) { if (device instanceof VirtualSCSIController && isValidScsiDiskController((VirtualSCSIController)device)) { return device.getKey(); @@ -2539,7 +2212,7 @@ public int getScsiDeviceControllerKey() throws Exception { public int getScsiDeviceControllerKeyNoException() throws Exception { List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); - if (devices != null && devices.size() > 0) { + if (CollectionUtils.isNotEmpty(devices)) { for (VirtualDevice device : devices) { if (device instanceof VirtualSCSIController && isValidScsiDiskController((VirtualSCSIController)device)) { return device.getKey(); @@ -2577,10 +2250,10 @@ public void ensureLsiLogicDeviceControllers(int count, int availableBusNum) thro } private int getLsiLogicDeviceControllerKeyNoException() throws Exception { - List devices = (List)_context.getVimClient(). + List devices = _context.getVimClient(). getDynamicProperty(_mor, "config.hardware.device"); - if (devices != null && devices.size() > 0) { + if (CollectionUtils.isNotEmpty(devices)) { for (VirtualDevice device : devices) { if (device instanceof VirtualLsiLogicController) { return device.getKey(); @@ -2612,32 +2285,6 @@ public void ensureScsiDeviceController() throws Exception { } } - public void ensureScsiDeviceControllers(int count, int availableBusNum) throws Exception { - int scsiControllerKey = getScsiDeviceControllerKeyNoException(); - if (scsiControllerKey < 0) { - VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec(); - - int busNum = availableBusNum; - while (busNum < count) { - VirtualLsiLogicController scsiController = new VirtualLsiLogicController(); - scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING); - scsiController.setBusNumber(busNum); - scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT); - VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec(); - scsiControllerSpec.setDevice(scsiController); - scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); - - vmConfig.getDeviceChange().add(scsiControllerSpec); - busNum++; - } - if (configureVm(vmConfig)) { - throw new Exception("Unable to add Scsi controllers to the VM " + getName()); - } else { - s_logger.info("Successfully added " + count + " SCSI controllers."); - } - } - } - private boolean isValidScsiDiskController(VirtualSCSIController scsiDiskController) { if (scsiDiskController == null) { return false; @@ -2648,11 +2295,7 @@ private boolean isValidScsiDiskController(VirtualSCSIController scsiDiskControll return false; } - if (scsiDiskController.getBusNumber() >= VmwareHelper.MAX_SCSI_CONTROLLER_COUNT) { - return false; - } - - return true; + return scsiDiskController.getBusNumber() < VmwareHelper.MAX_SCSI_CONTROLLER_COUNT; } // return pair of VirtualDisk and disk device bus name(ide0:0, etc) @@ -2670,7 +2313,7 @@ public Pair getDiskDevice(String vmdkDatastorePath) throws s_logger.info(String.format("Looking for disk device info for volume [%s] with base name [%s].", vmdkDatastorePath, srcBaseName)); - if (devices != null && devices.size() > 0) { + if (CollectionUtils.isNotEmpty(devices)) { for (VirtualDevice device : devices) { if (device instanceof VirtualDisk) { s_logger.info(String.format("Testing if disk device with controller key [%s] and unit number [%s] has backing of type VirtualDiskFlatVer2BackingInfo.", @@ -2754,12 +2397,12 @@ public Pair getDiskDevice(String vmdkDatastorePath, boolean s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath + " with trimmed base name: " + trimmedSrcBaseName); } - if (devices != null && devices.size() > 0) { + if (CollectionUtils.isNotEmpty(devices)) { for (VirtualDevice device : devices) { if (device instanceof VirtualDisk) { s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber()); - VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking(); + VirtualDeviceBackingInfo backingInfo = device.getBacking(); if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) { VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; do { @@ -2772,14 +2415,14 @@ public Pair getDiskDevice(String vmdkDatastorePath, boolean String deviceNumbering = getDeviceBusName(devices, device); s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering); - return new Pair((VirtualDisk)device, deviceNumbering); + return new Pair<>((VirtualDisk)device, deviceNumbering); } } else { if (backingBaseName.contains(trimmedSrcBaseName)) { String deviceNumbering = getDeviceBusName(devices, device); s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering); - return new Pair((VirtualDisk)device, deviceNumbering); + return new Pair<>((VirtualDisk)device, deviceNumbering); } } @@ -2795,12 +2438,12 @@ public Pair getDiskDevice(String vmdkDatastorePath, boolean public String getDiskCurrentTopBackingFileInChain(String deviceBusName) throws Exception { List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); - if (devices != null && devices.size() > 0) { + if (CollectionUtils.isNotEmpty(devices)) { for (VirtualDevice device : devices) { if (device instanceof VirtualDisk) { s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber()); - VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking(); + VirtualDeviceBackingInfo backingInfo = device.getBacking(); if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) { VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; @@ -2815,31 +2458,15 @@ public String getDiskCurrentTopBackingFileInChain(String deviceBusName) throws E return null; } - public VirtualDisk getDiskDeviceByDeviceBusName(String deviceBusName) throws Exception { - List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); - - if (devices != null && devices.size() > 0) { - for (VirtualDevice device : devices) { - if (device instanceof VirtualDisk) { - String deviceNumbering = getDeviceBusName(devices, device); - if (deviceNumbering.equals(deviceBusName)) - return (VirtualDisk)device; - } - } - } - - return null; - } - public VirtualMachineDiskInfoBuilder getDiskInfoBuilder() throws Exception { VirtualMachineDiskInfoBuilder builder = new VirtualMachineDiskInfoBuilder(); List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); - if (devices != null && devices.size() > 0) { + if (CollectionUtils.isNotEmpty(devices)) { for (VirtualDevice device : devices) { if (device instanceof VirtualDisk) { - VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking(); + VirtualDeviceBackingInfo backingInfo = device.getBacking(); if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) { VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; while (diskBackingInfo != null) { @@ -2856,16 +2483,16 @@ public VirtualMachineDiskInfoBuilder getDiskInfoBuilder() throws Exception { } public List> getAllDiskDatastores() throws Exception { - List> disks = new ArrayList>(); + List> disks = new ArrayList<>(); List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); if (devices != null && devices.size() > 0) { for (VirtualDevice device : devices) { if (device instanceof VirtualDisk) { - VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking(); + VirtualDeviceBackingInfo backingInfo = device.getBacking(); if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) { VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; - disks.add(new Pair(new Integer(device.getKey()), diskBackingInfo.getDatastore())); + disks.add(new Pair(Integer.valueOf(device.getKey()), diskBackingInfo.getDatastore())); } } } @@ -3072,24 +2699,22 @@ public VirtualDisk getDiskDeviceByBusName(List allDevices, String public VirtualDisk[] getAllIndependentDiskDevice() throws Exception { List independentDisks = new ArrayList(); VirtualDisk[] allDisks = getAllDiskDevice(); - if (allDisks.length > 0) { - for (VirtualDisk disk : allDisks) { - String diskMode = ""; - if (disk.getBacking() instanceof VirtualDiskFlatVer1BackingInfo) { - diskMode = ((VirtualDiskFlatVer1BackingInfo)disk.getBacking()).getDiskMode(); - } else if (disk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) { - diskMode = ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getDiskMode(); - } else if (disk.getBacking() instanceof VirtualDiskRawDiskMappingVer1BackingInfo) { - diskMode = ((VirtualDiskRawDiskMappingVer1BackingInfo)disk.getBacking()).getDiskMode(); - } else if (disk.getBacking() instanceof VirtualDiskSparseVer1BackingInfo) { - diskMode = ((VirtualDiskSparseVer1BackingInfo)disk.getBacking()).getDiskMode(); - } else if (disk.getBacking() instanceof VirtualDiskSparseVer2BackingInfo) { - diskMode = ((VirtualDiskSparseVer2BackingInfo)disk.getBacking()).getDiskMode(); - } + for (VirtualDisk disk : allDisks) { + String diskMode = ""; + if (disk.getBacking() instanceof VirtualDiskFlatVer1BackingInfo) { + diskMode = ((VirtualDiskFlatVer1BackingInfo) disk.getBacking()).getDiskMode(); + } else if (disk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) { + diskMode = ((VirtualDiskFlatVer2BackingInfo) disk.getBacking()).getDiskMode(); + } else if (disk.getBacking() instanceof VirtualDiskRawDiskMappingVer1BackingInfo) { + diskMode = ((VirtualDiskRawDiskMappingVer1BackingInfo) disk.getBacking()).getDiskMode(); + } else if (disk.getBacking() instanceof VirtualDiskSparseVer1BackingInfo) { + diskMode = ((VirtualDiskSparseVer1BackingInfo) disk.getBacking()).getDiskMode(); + } else if (disk.getBacking() instanceof VirtualDiskSparseVer2BackingInfo) { + diskMode = ((VirtualDiskSparseVer2BackingInfo) disk.getBacking()).getDiskMode(); + } - if (diskMode.indexOf("independent") != -1) { - independentDisks.add(disk); - } + if (diskMode.indexOf("independent") != -1) { + independentDisks.add(disk); } } @@ -3102,7 +2727,7 @@ public int tryGetIDEDeviceControllerKey() throws Exception { if (devices != null && devices.size() > 0) { for (VirtualDevice device : devices) { if (device instanceof VirtualIDEController) { - return ((VirtualIDEController)device).getKey(); + return device.getKey(); } } } @@ -3116,7 +2741,7 @@ public int getIDEDeviceControllerKey() throws Exception { if (devices != null && devices.size() > 0) { for (VirtualDevice device : devices) { if (device instanceof VirtualIDEController) { - return ((VirtualIDEController)device).getKey(); + return device.getKey(); } } } @@ -3126,7 +2751,7 @@ public int getIDEDeviceControllerKey() throws Exception { } public int getIDEControllerKey(int ideUnitNumber) throws Exception { - List devices = (List)_context.getVimClient(). + List devices = _context.getVimClient(). getDynamicProperty(_mor, "config.hardware.device"); int requiredIdeController = ideUnitNumber / VmwareHelper.MAX_IDE_CONTROLLER_COUNT; @@ -3136,7 +2761,7 @@ public int getIDEControllerKey(int ideUnitNumber) throws Exception { for(VirtualDevice device : devices) { if(device instanceof VirtualIDEController) { if (ideControllerCount == requiredIdeController) { - return ((VirtualIDEController)device).getKey(); + return device.getKey(); } ideControllerCount++; } @@ -3149,7 +2774,7 @@ public int getIDEControllerKey(int ideUnitNumber) throws Exception { public int getNumberOfIDEDevices() throws Exception { int ideDeviceCount = 0; - List devices = (List)_context.getVimClient(). + List devices = _context.getVimClient(). getDynamicProperty(_mor, "config.hardware.device"); if (devices != null && devices.size() > 0) { @@ -3164,7 +2789,7 @@ public int getNumberOfIDEDevices() throws Exception { public int getFreeUnitNumberOnIDEController(int controllerKey) throws Exception { int freeUnitNumber = 0; - List devices = (List)_context.getVimClient(). + List devices = _context.getVimClient(). getDynamicProperty(_mor, "config.hardware.device"); int deviceCount = 0; @@ -3224,7 +2849,7 @@ public VirtualDevice getIsoDevice(int key) throws Exception { } public VirtualDevice getIsoDevice(String filename) throws Exception { - List devices = (List)_context.getVimClient(). + List devices = _context.getVimClient(). getDynamicProperty(_mor, "config.hardware.device"); if(devices != null && devices.size() > 0) { long isoDevices = devices.stream() @@ -3324,19 +2949,19 @@ public Pair getNicDeviceIndex(String networkNamePrefix) String attachedNetworkSummary; String dvPortGroupName; for (VirtualDevice nic : nics) { - attachedNetworkSummary = ((VirtualEthernetCard)nic).getDeviceInfo().getSummary(); + attachedNetworkSummary = nic.getDeviceInfo().getSummary(); if (attachedNetworkSummary.startsWith(networkNamePrefix)) { - return new Pair(new Integer(index), nic); + return new Pair(Integer.valueOf(index), nic); } else if (attachedNetworkSummary.endsWith("DistributedVirtualPortBackingInfo.summary") || attachedNetworkSummary.startsWith("DVSwitch")) { dvPortGroupName = getDvPortGroupName((VirtualEthernetCard)nic); if (dvPortGroupName != null && dvPortGroupName.startsWith(networkNamePrefix)) { s_logger.debug("Found a dvPortGroup already associated with public NIC."); - return new Pair(new Integer(index), nic); + return new Pair(Integer.valueOf(index), nic); } } index++; } - return new Pair(new Integer(-1), null); + return new Pair(Integer.valueOf(-1), null); } public String getDvPortGroupName(VirtualEthernetCard nic) throws Exception { @@ -3346,7 +2971,7 @@ public String getDvPortGroupName(VirtualEthernetCard nic) throws Exception { ManagedObjectReference dvPortGroupMor = new ManagedObjectReference(); dvPortGroupMor.setValue(dvPortGroupKey); dvPortGroupMor.setType("DistributedVirtualPortgroup"); - return (String)_context.getVimClient().getDynamicProperty(dvPortGroupMor, "name"); + return _context.getVimClient().getDynamicProperty(dvPortGroupMor, "name"); } public VirtualDevice[] getMatchedDevices(Class[] deviceClasses) throws Exception { @@ -3498,14 +3123,14 @@ public void redoRegistration(ManagedObjectReference morHost) throws Exception { } public long getHotAddMemoryIncrementSizeInMb() throws Exception { - return (Long)_context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryIncrementSize"); + return _context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryIncrementSize"); } public long getHotAddMemoryLimitInMb() throws Exception { - return (Long)_context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryLimit"); + return _context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryLimit"); } public String getGuestId() throws Exception { - return (String)_context.getVimClient().getDynamicProperty(_mor, "config.guestId"); + return _context.getVimClient().getDynamicProperty(_mor, "config.guestId"); } public int getCoresPerSocket() throws Exception { @@ -3514,7 +3139,7 @@ public int getCoresPerSocket() throws Exception { if (apiVersion.compareTo("5.0") < 0) { return 1; } - Integer coresPerSocket = (Integer)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.numCoresPerSocket"); + Integer coresPerSocket = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.numCoresPerSocket"); return coresPerSocket != null ? coresPerSocket : 1; } @@ -3621,7 +3246,7 @@ public void ensureLsiLogicSasDeviceControllers(int count, int availableBusNum) t } private int getLsiLogicSasDeviceControllerKeyNoException() throws Exception { - List devices = (List)_context.getVimClient(). + List devices = _context.getVimClient(). getDynamicProperty(_mor, "config.hardware.device"); if (devices != null && devices.size() > 0) { @@ -3664,7 +3289,7 @@ public void ensureBusLogicDeviceControllers(int count, int availableBusNum) thro } private int getBusLogicDeviceControllerKeyNoException() throws Exception { - List devices = (List)_context.getVimClient(). + List devices = _context.getVimClient(). getDynamicProperty(_mor, "config.hardware.device"); if (devices != null && devices.size() > 0) { @@ -3679,7 +3304,7 @@ private int getBusLogicDeviceControllerKeyNoException() throws Exception { } public Ternary getScsiControllerInfo() throws Exception { - List devices = (List)_context.getVimClient(). + List devices = _context.getVimClient(). getDynamicProperty(_mor, "config.hardware.device"); int scsiControllerCount = 0; @@ -3710,7 +3335,7 @@ public Ternary getScsiControllerInfo() thr } public int getNumberOfVirtualDisks() throws Exception { - List devices = (List)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); + List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); s_logger.info("Counting disk devices attached to VM " + getVmName()); int count = 0; @@ -3726,7 +3351,7 @@ public int getNumberOfVirtualDisks() throws Exception { } public String getExternalDiskUUID(String datastoreVolumePath) throws Exception{ - List devices = (List)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); + List devices = _context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); if (CollectionUtils.isEmpty(devices) || datastoreVolumePath == null) { return null; } @@ -3798,7 +3423,7 @@ public void cancelPendingTasks() throws Exception { int vmTasks = 0, vmPendingTasks = 0; for (ManagedObjectReference task : tasks) { - TaskInfo info = (TaskInfo) (_context.getVimClient().getDynamicProperty(task, "info")); + TaskInfo info = _context.getVimClient().getDynamicProperty(task, "info"); if (info.getEntityName().equals(vmName)) { vmTasks++; if (!(info.getState().equals(TaskInfoState.SUCCESS) || info.getState().equals(TaskInfoState.ERROR))) { @@ -3835,7 +3460,7 @@ public void removeChangeTrackPathFromVmdkForDisks() throws Exception { if (content == null || content.length == 0) { break; } - byte[] newVmdkContent = vmdkFileDescriptor.removeChangeTrackPath(content); + byte[] newVmdkContent = VmdkFileDescriptor.removeChangeTrackPath(content); Pair dcPair = getOwnerDatacenter(); String vmdkUrl = getContext().composeDatastoreBrowseUrl(dcPair.second(), diskBackingInfo.getFileName()); diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java index ccc68283d062..6ef0840f89ab 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClient.java @@ -16,8 +16,10 @@ // under the License. package com.cloud.hypervisor.vmware.util; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -36,19 +38,23 @@ import javax.xml.ws.handler.HandlerResolver; import javax.xml.ws.handler.PortInfo; - import org.apache.cloudstack.utils.security.SSLUtils; import org.apache.cloudstack.utils.security.SecureSSLSocketFactory; -import com.vmware.pbm.PbmPortType; -import com.vmware.pbm.PbmService; -import com.vmware.pbm.PbmServiceInstanceContent; -import org.apache.commons.lang3.StringUtils; +import com.cloud.utils.StringUtils; + import org.apache.log4j.Logger; + import org.w3c.dom.Element; +import com.vmware.pbm.PbmPortType; +import com.vmware.pbm.PbmService; +import com.vmware.pbm.PbmServiceInstanceContent; + import com.vmware.vim25.DynamicProperty; import com.vmware.vim25.InvalidCollectorVersionFaultMsg; +import com.vmware.vim25.InvalidLocaleFaultMsg; +import com.vmware.vim25.InvalidLoginFaultMsg; import com.vmware.vim25.InvalidPropertyFaultMsg; import com.vmware.vim25.LocalizedMethodFault; import com.vmware.vim25.ManagedObjectReference; @@ -158,7 +164,7 @@ public VmwareClient(String name) { * @throws 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.setValue(SVC_INST_NAME); @@ -188,7 +194,7 @@ public void connect(String url, String userName, String password) throws Excepti if (cookies == null) { String msg = "Login successful, but failed to get server cookies from url :[" + url + "]"; s_logger.error(msg); - throw new Exception(msg); + throw new VmwareClientException(msg); } } @@ -204,7 +210,7 @@ public void connect(String url, String userName, String password) throws Excepti 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); String pbmurl = "https://" + uri.getHost() + "/pbm"; String[] tokens = cookieValue.split("="); @@ -348,8 +354,8 @@ public boolean validate() { * in case of error. */ @SuppressWarnings("unchecked") - public T getDynamicProperty(ManagedObjectReference mor, String propertyName) throws Exception { - List props = new ArrayList(); + public T getDynamicProperty(ManagedObjectReference mor, String propertyName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + List props = new ArrayList<>(); props.add(propertyName); List objContent = retrieveMoRefProperties(mor, props); @@ -379,7 +385,7 @@ public T getDynamicProperty(ManagedObjectReference mor, String propertyName) return (T)propertyValue; } - private List retrieveMoRefProperties(ManagedObjectReference mObj, List props) throws Exception { + private List retrieveMoRefProperties(ManagedObjectReference mObj, List props) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { PropertySpec pSpec = new PropertySpec(); pSpec.setAll(false); pSpec.setType(mObj.getType()); @@ -704,7 +710,7 @@ private List constructCompleteTraversalSpec() { * * @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) { return null; } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClientException.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClientException.java new file mode 100644 index 000000000000..f191e8ea3eb9 --- /dev/null +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClientException.java @@ -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 com.cloud.hypervisor.vmware.util; + +import com.cloud.exception.CloudException; + +public class VmwareClientException extends CloudException { + 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); + } +} From 55dfe402dec8236029aa7985c44fa7ff3ad82b5d Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 18 Dec 2024 16:21:37 +0100 Subject: [PATCH 05/24] propagate token to user/UI --- .../vmware/VmwareDatacenterService.java | 3 +- .../vmware/manager/VmwareManagerImpl.java | 17 ++-------- .../admin/zone/ListVmwareDcVmsCmd.java | 29 +++++++--------- .../admin/zone/VmwarRequestReponse.java | 33 +++++++++++++++++++ 4 files changed, 49 insertions(+), 33 deletions(-) create mode 100644 plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwarRequestReponse.java diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java index bbac78b879a4..9e0bbf803e2f 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java @@ -23,6 +23,7 @@ import com.cloud.exception.DiscoveryException; import com.cloud.exception.ResourceInUseException; import com.cloud.storage.StoragePool; +import com.cloud.utils.Pair; import com.cloud.utils.component.PluggableService; import com.cloud.utils.exception.CloudRuntimeException; import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd; @@ -53,5 +54,5 @@ public interface VmwareDatacenterService extends PluggableService { List listVsphereStoragePolicyCompatibleStoragePools(ListVsphereStoragePolicyCompatiblePoolsCmd cmd); - List listVMsInDatacenter(ListVmwareDcVmsCmd cmd); + Pair> listVMsInDatacenter(ListVmwareDcVmsCmd cmd); } diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 50616b2b3015..efe63c43782d 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -1558,21 +1558,13 @@ public List listVsphereStoragePolicyCompatibleStoragePools(ListVsph } @Override - public List listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { + public Pair> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { String vcenter = cmd.getVcenter(); String datacenterName = cmd.getDatacenterName(); String username = cmd.getUsername(); String password = cmd.getPassword(); Integer maxObjects = cmd.getPageSize(); - boolean forced = cmd.isForced(); - // TODO refactor to check if the page is available - boolean nextPage = cmd.getPageNumber() == null || cmd.getPageNumber() <= 1; - if (forced) { -// remove existing data from local map - } - if (nextPage) { -// check if there is a next page possible - } + String token = cmd.getToken(); Long existingVcenterId = cmd.getExistingVcenterId(); String keyword = cmd.getKeyword(); @@ -1613,10 +1605,7 @@ public List listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { s_logger.error(msg); throw new InvalidParameterValueException(msg); } - List instances = Collections.synchronizedList(new ArrayList<>()); - instances.addAll(dcMo.getVmsOnDatacenter(maxObjects, null).second()); - return StringUtils.isBlank(keyword) ? instances : - instances.stream().filter(x -> x.getName().toLowerCase().contains(keyword.toLowerCase())).collect(Collectors.toList()); + return dcMo.getVmsOnDatacenter(maxObjects, token); } catch (InvalidParameterValueException | VmwareClientException | InvalidLocaleFaultMsg | InvalidLoginFaultMsg | RuntimeFaultFaultMsg | URISyntaxException | InvalidPropertyFaultMsg | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java index 77ca35359362..eb2538580211 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java @@ -23,6 +23,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.hypervisor.vmware.VmwareDatacenterService; import com.cloud.user.Account; +import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -31,7 +32,6 @@ import org.apache.cloudstack.api.BaseResponse; import org.apache.cloudstack.api.Parameter; 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.VmwareDatacenterResponse; import org.apache.cloudstack.vm.UnmanagedInstanceTO; @@ -73,11 +73,10 @@ public class ListVmwareDcVmsCmd extends BaseListCmd { @Parameter(name = ApiConstants.PAGE_SIZE, type = CommandType.INTEGER, description = "The maximum number of results to return.") private Integer pageSize; - @Parameter(name = ApiConstants.PAGE, type = CommandType.INTEGER, - description = "For listVmwareDcVms, the maximum number of results to return is either 0, 1 or more." + - " When more than 1, the next page as returned by the vcenter will be propagated to the caller." + - " If no previous call has been done, this is the same as the first page") - private Integer pageNumber; + @Parameter(name = ApiConstants.TOKEN, type = CommandType.STRING, + description = "For listVmwareDcVms, if the maximum number of results (the `pagesize`) is exceeded, " + + " a token is returned. This token can be used in subsequent calls to retrieve more results") + private String token; @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, description = "force retrieving new results, ignoring any cached data.") private Boolean forced; @@ -94,16 +93,8 @@ public String getPassword() { return password; } - public Integer getPageSize() { - return pageSize; - } - - public Integer getPageNumber() { - return pageNumber; - } - - public boolean isForced() { - return forced == null ? true : forced; + public String getToken() { + return token; } public String getDatacenterName() { @@ -118,7 +109,8 @@ public Long getExistingVcenterId() { public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { checkParameters(); try { - List vms = _vmwareDatacenterService.listVMsInDatacenter(this); + Pair> results = _vmwareDatacenterService.listVMsInDatacenter(this); + List vms = results.second(); List baseResponseList = new ArrayList<>(); if (CollectionUtils.isNotEmpty(vms)) { for (UnmanagedInstanceTO vmwareVm : vms) { @@ -130,9 +122,10 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE if (CollectionUtils.isEmpty(pagingList)) { pagingList = baseResponseList; } - ListResponse response = new ListResponse<>(); + VmwarRequestReponse response = new VmwarRequestReponse<>(); response.setResponses(pagingList, baseResponseList.size()); response.setResponseName(getCommandName()); + response.setToken(results.first()); setResponseObject(response); } catch (CloudRuntimeException e) { String errorMsg = String.format("Error retrieving VMs from VMware VC: %s", e.getMessage()); diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwarRequestReponse.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwarRequestReponse.java new file mode 100644 index 000000000000..fbb833103510 --- /dev/null +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwarRequestReponse.java @@ -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 org.apache.cloudstack.api.command.admin.zone; + +import org.apache.cloudstack.api.ResponseObject; +import org.apache.cloudstack.api.response.ListResponse; + +public class VmwarRequestReponse extends ListResponse { + private transient String token; + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } +} From aac47c90a01b765b34ce6ab7047c43001524c9bf Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Mon, 23 Dec 2024 15:39:50 +0100 Subject: [PATCH 06/24] some suggestions applied and initial batch size in UI --- .../apache/cloudstack/api/ApiConstants.java | 1 + .../vmware/manager/VmwareManagerImpl.java | 4 ++++ .../admin/zone/ListVmwareDcVmsCmd.java | 18 ++++++--------- ...Reponse.java => VmwareRequestReponse.java} | 2 +- ui/src/views/tools/ManageInstances.vue | 22 ++++++++++++++++++- ui/src/views/tools/SelectVmwareVcenter.vue | 1 + 6 files changed, 35 insertions(+), 13 deletions(-) rename plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/{VmwarRequestReponse.java => VmwareRequestReponse.java} (94%) diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index a9c5d68c787d..0a951d0870db 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -46,6 +46,7 @@ public class ApiConstants { public static final String BACKUP_OFFERING_NAME = "backupofferingname"; public static final String BACKUP_OFFERING_ID = "backupofferingid"; public static final String BASE64_IMAGE = "base64image"; + public static final String BATCH_SIZE = "batchsize"; public static final String BITS = "bits"; public static final String BOOTABLE = "bootable"; public static final String BIND_DN = "binddn"; diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index efe63c43782d..97833edf646c 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -517,6 +517,10 @@ public List addHostToPodCluster(VmwareContext serviceCon if (mor.getType().equals("ComputeResource")) { List hosts = serviceContext.getVimClient().getDynamicProperty(mor, "host"); assert (CollectionUtils.isNullOrEmpty(hosts)); + // For ESX host, we need to enable host firewall to allow VNC access + HostMO hostMo = new HostMO(serviceContext, hosts.get(0)); + + prepareHost(hostMo, privateTrafficLabel); returnedHostList.add(hosts.get(0)); return returnedHostList; } else if (mor.getType().equals("ClusterComputeResource")) { diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java index eb2538580211..89efa08881c3 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java @@ -70,17 +70,14 @@ public class ListVmwareDcVmsCmd extends BaseListCmd { @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.") private String password; - @Parameter(name = ApiConstants.PAGE_SIZE, type = CommandType.INTEGER, description = "The maximum number of results to return.") - private Integer pageSize; + @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 `pagesize`) is exceeded, " + " a token is returned. This token can be used in subsequent calls to retrieve more results") private String token; - @Parameter(name = ApiConstants.FORCED, type = CommandType.BOOLEAN, description = "force retrieving new results, ignoring any cached data.") - private Boolean forced; - public String getVcenter() { return vcenter; } @@ -93,6 +90,10 @@ public String getPassword() { return password; } + public Integer getBatchSize() { + return batchSize; + } + public String getToken() { return token; } @@ -122,7 +123,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE if (CollectionUtils.isEmpty(pagingList)) { pagingList = baseResponseList; } - VmwarRequestReponse response = new VmwarRequestReponse<>(); + VmwareRequestReponse response = new VmwareRequestReponse<>(); response.setResponses(pagingList, baseResponseList.size()); response.setResponseName(getCommandName()); response.setToken(results.first()); @@ -148,9 +149,4 @@ private void checkParameters() { public long getEntityOwnerId() { return Account.ACCOUNT_ID_SYSTEM; } - - @Override - public String getCommandName() { - return "listvmwaredcvmsresponse"; - } } diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwarRequestReponse.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestReponse.java similarity index 94% rename from plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwarRequestReponse.java rename to plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestReponse.java index fbb833103510..a63b2507ed42 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwarRequestReponse.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestReponse.java @@ -20,7 +20,7 @@ import org.apache.cloudstack.api.ResponseObject; import org.apache.cloudstack.api.response.ListResponse; -public class VmwarRequestReponse extends ListResponse { +public class VmwareRequestReponse extends ListResponse { private transient String token; public String getToken() { diff --git a/ui/src/views/tools/ManageInstances.vue b/ui/src/views/tools/ManageInstances.vue index 2ff9052d8b98..42112339a6fa 100644 --- a/ui/src/views/tools/ManageInstances.vue +++ b/ui/src/views/tools/ManageInstances.vue @@ -1408,11 +1408,31 @@ export default { }) } }, + async fetchMoreVms (obj) { + var params = obj.params + params.token = obj.response.token + api('listVmwareDcVms', params).then(json => { + const obj = { + params: params, + response: json.listvmwaredcvmsresponse + } + this.unmanagedInstances.append(obj.response.unmanagedinstance) + this.checkForMoreVms(obj) + }) + }, onListUnmanagedInstancesFromVmware (obj) { this.selectedVmwareVcenter = obj.params this.unmanagedInstances = obj.response.unmanagedinstance this.itemCount.unmanaged = obj.response.count - this.unmanagedInstancesLoading = false + this.checkForMoreVms(obj) + }, + checkForMoreVms (obj) { + if (obj.response.token) { + this.fetchMoreVms(obj) + // keep loading, for now this means the API called was api('listVmwareDcVms', params) + } else { + this.unmanagedInstancesLoading = false + } }, updateVmwareVcenterType (type) { this.vmwareVcenterType = type diff --git a/ui/src/views/tools/SelectVmwareVcenter.vue b/ui/src/views/tools/SelectVmwareVcenter.vue index 78e38f107f37..31e7499c75b0 100644 --- a/ui/src/views/tools/SelectVmwareVcenter.vue +++ b/ui/src/views/tools/SelectVmwareVcenter.vue @@ -217,6 +217,7 @@ export default { } else { params.existingvcenterid = this.selectedExistingVcenterId } + params.batchsize = 2 api('listVmwareDcVms', params).then(json => { const obj = { params: params, From 127d18241baad584793abfa9b1f08ff17fec3db2 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Mon, 30 Dec 2024 11:09:18 +0100 Subject: [PATCH 07/24] extra logging --- .../com/cloud/hypervisor/vmware/mo/DatacenterMO.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index 58ec33003caa..5ff3fc2ef824 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -153,6 +153,9 @@ public VirtualMachineMO checkIfVmAlreadyExistsInVcenter(String vmNameOnVcenter, public Pair> getVmsOnDatacenter(Integer maxObjects, String token) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { List vms = new ArrayList<>(); Pair> objectContents = getVmPropertiesOnDatacenterVmFolder(new String[] {"name"}, maxObjects, token); + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("returning token %s for future retrievals, currently %d objects retrieved.", objectContents.first(), objectContents.second().size())); + } Pair> retval = new Pair<>(objectContents.first(), vms); List ocs = objectContents.second(); if (ocs != null) { @@ -302,8 +305,14 @@ public List getVmPropertiesOnDatacenterVmFolder(String[] property */ public Pair> getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths, Integer maxObjects, String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { if(StringUtils.isNotBlank(tokenForPriorQuery)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("running repeat query with token \'%s\'", tokenForPriorQuery)); + } return retrieveNextSetOfPropertiesOnDatacenterVmFolder(tokenForPriorQuery); } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("running query for %d propertypaths and max %d objects", propertyPaths.length, maxObjects)); + } return retrieveNextSetOfPropertiesOnDatacenterVmFolder(propertyPaths, maxObjects); } } From fba40d3c430262bb40432d42badfd897dbae0c78 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Mon, 30 Dec 2024 14:31:04 +0100 Subject: [PATCH 08/24] cleanup and comments applied --- .../org/apache/cloudstack/api/ApiConstants.java | 1 - .../vmware/manager/VmwareManagerImpl.java | 3 +-- .../command/admin/zone/ListVmwareDcVmsCmd.java | 15 ++++++--------- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index 0a951d0870db..5ee68ed91af1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -1107,7 +1107,6 @@ public class ApiConstants { public static final String PARAMETER_DESCRIPTION_IS_TAG_A_RULE = "Whether the informed tag is a JS interpretable rule or not."; public static final String NFS_MOUNT_OPTIONS = "nfsmountopts"; - public static final String MAX_NUMBER = "maxnumber"; /** * This enum specifies IO Drivers, each option controls specific policies on I/O. diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 97833edf646c..1780e8869c7a 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -1567,11 +1567,10 @@ public Pair> listVMsInDatacenter(ListVmwareDcV String datacenterName = cmd.getDatacenterName(); String username = cmd.getUsername(); String password = cmd.getPassword(); - Integer maxObjects = cmd.getPageSize(); + Integer maxObjects = cmd.getBatchSize(); String token = cmd.getToken(); Long existingVcenterId = cmd.getExistingVcenterId(); - String keyword = cmd.getKeyword(); if ((existingVcenterId == null && StringUtils.isBlank(vcenter)) || (existingVcenterId != null && StringUtils.isNotBlank(vcenter))) { diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java index 89efa08881c3..9dcb29b5dc7d 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java @@ -28,7 +28,7 @@ import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; 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.Parameter; import org.apache.cloudstack.api.ServerApiException; @@ -45,7 +45,7 @@ @APICommand(name = "listVmwareDcVms", responseObject = UnmanagedInstanceResponse.class, description = "Lists the VMs in a VMware Datacenter", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class ListVmwareDcVmsCmd extends BaseListCmd { +public class ListVmwareDcVmsCmd extends BaseCmd { @Inject public VmwareDatacenterService _vmwareDatacenterService; @@ -74,8 +74,9 @@ public class ListVmwareDcVmsCmd extends BaseListCmd { private Integer batchSize; @Parameter(name = ApiConstants.TOKEN, type = CommandType.STRING, - description = "For listVmwareDcVms, if the maximum number of results (the `pagesize`) is exceeded, " + - " a token is returned. This token can be used in subsequent calls to retrieve more results") + 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() { @@ -119,12 +120,8 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE baseResponseList.add(resp); } } - List pagingList = com.cloud.utils.StringUtils.applyPagination(baseResponseList, this.getStartIndex(), this.getPageSizeVal()); - if (CollectionUtils.isEmpty(pagingList)) { - pagingList = baseResponseList; - } VmwareRequestReponse response = new VmwareRequestReponse<>(); - response.setResponses(pagingList, baseResponseList.size()); + response.setResponses(baseResponseList, baseResponseList.size()); response.setResponseName(getCommandName()); response.setToken(results.first()); setResponseObject(response); From 5c61ec4b49ad1593f3137dc7bf7ef7b356d72cd1 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Mon, 30 Dec 2024 15:43:54 +0100 Subject: [PATCH 09/24] response object --- .../cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java index 9dcb29b5dc7d..7829f61689cc 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java @@ -42,7 +42,7 @@ import java.util.ArrayList; import java.util.List; -@APICommand(name = "listVmwareDcVms", responseObject = UnmanagedInstanceResponse.class, +@APICommand(name = "listVmwareDcVms", responseObject = VmwareRequestReponse.class, description = "Lists the VMs in a VMware Datacenter", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVmwareDcVmsCmd extends BaseCmd { From 0bf417ee9366cb16e72b5d70156c4bc133266f84 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 31 Dec 2024 13:51:06 +0100 Subject: [PATCH 10/24] response object --- .../api/command/admin/zone/VmwareRequestReponse.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestReponse.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestReponse.java index a63b2507ed42..aaf4214e554e 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestReponse.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestReponse.java @@ -17,11 +17,16 @@ 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 VmwareRequestReponse extends ListResponse { - private transient String token; + @SerializedName(ApiConstants.TOKEN) + @Param(description = "The VMware API token to use for retrieving further responses with") + private String token; public String getToken() { return token; From ac8a0cfb9f93fd72e16e72c2c365bbf4b2e09e5d Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Thu, 2 Jan 2025 10:50:04 +0100 Subject: [PATCH 11/24] log token --- .../java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index 5ff3fc2ef824..ceb299ecbe30 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -24,6 +24,7 @@ import com.cloud.hypervisor.vmware.util.VmwareHelper; import com.cloud.utils.StringUtils; +import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; import org.apache.cloudstack.vm.UnmanagedInstanceTO; import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; @@ -363,6 +364,9 @@ private Pair> retrieveNextSetOfPropertiesOnDatacente } private static Pair> createReturnObjectPair(RetrieveResult result) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("vmware result : " + ReflectionToStringBuilderUtils.reflectCollection(result)); + } String tokenForRetrievingNewResults = result.getToken(); List listOfObjects = result.getObjects(); return new Pair<>(tokenForRetrievingNewResults, listOfObjects); From 1ae6166d8a7529638edcf853e09d1a58bd73adb6 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 7 Jan 2025 14:09:13 +0100 Subject: [PATCH 12/24] get hosts for dc --- .../vmware/VmwareDatacenterService.java | 4 + .../vmware/manager/VmwareManagerImpl.java | 112 +++++++++--- .../admin/zone/ListVmwareDcHostsCmd.java | 161 ++++++++++++++++++ .../command/admin/zone/ListVmwareDcItems.java | 13 ++ .../admin/zone/ListVmwareDcVmsCmd.java | 2 +- .../hypervisor/vmware/mo/DatacenterMO.java | 4 +- .../cloud/hypervisor/vmware/mo/HostMO.java | 5 +- 7 files changed, 270 insertions(+), 31 deletions(-) create mode 100644 plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java create mode 100644 plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcItems.java diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java index 9e0bbf803e2f..6bb473536b86 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/VmwareDatacenterService.java @@ -22,6 +22,7 @@ import com.cloud.dc.VsphereStoragePolicy; import com.cloud.exception.DiscoveryException; import com.cloud.exception.ResourceInUseException; +import com.cloud.hypervisor.vmware.mo.HostMO; import com.cloud.storage.StoragePool; import com.cloud.utils.Pair; import com.cloud.utils.component.PluggableService; @@ -29,6 +30,7 @@ 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.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.ListVsphereStoragePoliciesCmd; import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd; @@ -54,5 +56,7 @@ public interface VmwareDatacenterService extends PluggableService { List listVsphereStoragePolicyCompatibleStoragePools(ListVsphereStoragePolicyCompatiblePoolsCmd cmd); + List listHostsInDatacenter(ListVmwareDcHostsCmd cmd); + Pair> listVMsInDatacenter(ListVmwareDcVmsCmd cmd); } diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 1780e8869c7a..85837a28916a 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -48,6 +48,8 @@ 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.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.ListVsphereStoragePoliciesCmd; import org.apache.cloudstack.api.command.admin.zone.ListVsphereStoragePolicyCompatiblePoolsCmd; @@ -179,6 +181,7 @@ 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 { private static final Logger s_logger = Logger.getLogger(VmwareManagerImpl.class); @@ -1093,6 +1096,7 @@ public List> getCommands() { cmdList.add(ListVsphereStoragePoliciesCmd.class); cmdList.add(ListVsphereStoragePolicyCompatiblePoolsCmd.class); cmdList.add(ListVmwareDcVmsCmd.class); + cmdList.add(ListVmwareDcHostsCmd.class); return cmdList; } @@ -1561,15 +1565,79 @@ public List listVsphereStoragePolicyCompatibleStoragePools(ListVsph return compatiblePools; } + @Override + public List listHostsInDatacenter(ListVmwareDcHostsCmd cmd) { + Integer maxObjects = cmd.getBatchSize(); + String token = cmd.getToken(); + + 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()); + s_logger.error(errorMsg, e); + throw new CloudRuntimeException(errorMsg); + } + + } + @Override public Pair> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { + Integer maxObjects = cmd.getBatchSize(); + String token = cmd.getToken(); + + VcenterData vmwaredc = getVcenterData(cmd); + + try { + VmwareContext context = getVmwareContext(vmwaredc); + + DatacenterMO dcMo = getDatacenterMO(context, vmwaredc); + return dcMo.getVmsOnDatacenter(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()); + s_logger.error(errorMsg, e); + throw new CloudRuntimeException(errorMsg); + } + } + + @NotNull + private static 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); + s_logger.error(msg); + throw new InvalidParameterValueException(msg); + } + return dcMo; + } + + @NotNull + private static VmwareContext getVmwareContext(VcenterData vmwaredc) throws RuntimeFaultFaultMsg, URISyntaxException, VmwareClientException, InvalidLocaleFaultMsg, InvalidLoginFaultMsg { + s_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 datacenterName = cmd.getDatacenterName(); String username = cmd.getUsername(); String password = cmd.getPassword(); - Integer maxObjects = cmd.getBatchSize(); - String token = cmd.getToken(); - Long existingVcenterId = cmd.getExistingVcenterId(); if ((existingVcenterId == null && StringUtils.isBlank(vcenter)) || @@ -1591,31 +1659,21 @@ public Pair> listVMsInDatacenter(ListVmwareDcV username = vmwareDc.getUser(); password = vmwareDc.getPassword(); } + VcenterData vmwaredc = new VcenterData(vcenter, datacenterName, username, password); + return vmwaredc; + } - s_logger.debug(String.format("Connecting to the VMware datacenter %s at vCenter %s to retrieve VMs", - datacenterName, vcenter)); - String serviceUrl = String.format("https://%s/sdk/vimService", vcenter); - VmwareClient vimClient = new VmwareClient(vcenter); - try { - vimClient.connect(serviceUrl, username, password); - VmwareContext context = new VmwareContext(vimClient, vcenter); + private static class VcenterData { + public final String vcenter; + public final String datacenterName; + public final String username; + public final String password; - DatacenterMO dcMo = new DatacenterMO(context, datacenterName); - ManagedObjectReference dcMor = dcMo.getMor(); - if (dcMor == null) { - String msg = String.format("Unable to find VMware datacenter %s in vCenter %s", - datacenterName, vcenter); - s_logger.error(msg); - throw new InvalidParameterValueException(msg); - } - return dcMo.getVmsOnDatacenter(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", - vcenter, datacenterName, e.getMessage()); - s_logger.error(errorMsg, e); - throw new CloudRuntimeException(errorMsg); + public VcenterData(String vcenter, String datacenterName, String username, String password) { + this.vcenter = vcenter; + this.datacenterName = datacenterName; + this.username = username; + this.password = password; } } @@ -1671,7 +1729,7 @@ private void startTemplateCleanJobSchedule() { } /** - * This task is to clean-up 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 collect all templates that * - are deleted from cloudstack diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java new file mode 100644 index 000000000000..b7588d4a4a07 --- /dev/null +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java @@ -0,0 +1,161 @@ +// 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 = VmwareRequestReponse.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; + + @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() { + return vcenter; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public Integer getBatchSize() { + return batchSize; + } + + public String getToken() { + return token; + } + + public String getDatacenterName() { + return datacenterName; + } + + public Long getExistingVcenterId() { + return existingVcenterId; + } + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { + checkParameters(); + try { + List hosts = _vmwareDatacenterService.listHostsInDatacenter(this); + List baseResponseList = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(hosts)) { + for (HostMO vmwareHost : hosts) { + HostResponse resp = createHostResponse(vmwareHost); + baseResponseList.add(resp); + } + } + VmwareRequestReponse response = new VmwareRequestReponse<>(); + 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()); + 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; + } +} diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcItems.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcItems.java new file mode 100644 index 000000000000..52c4bb04ef57 --- /dev/null +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcItems.java @@ -0,0 +1,13 @@ +package org.apache.cloudstack.api.command.admin.zone; + +public interface ListVmwareDcItems { + String getVcenter(); + + String getDatacenterName(); + + String getUsername(); + + String getPassword(); + + Long getExistingVcenterId(); +} diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java index 7829f61689cc..4514042aefdf 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java @@ -45,7 +45,7 @@ @APICommand(name = "listVmwareDcVms", responseObject = VmwareRequestReponse.class, description = "Lists the VMs in a VMware Datacenter", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) -public class ListVmwareDcVmsCmd extends BaseCmd { +public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems { @Inject public VmwareDatacenterService _vmwareDatacenterService; diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index ceb299ecbe30..e2db6333e9e6 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -180,7 +180,7 @@ public Pair> getVmsOnDatacenter(Integer maxObj return retval; } - public List getAllHostsOnDatacenter() throws Exception { + public List getAllHostsOnDatacenter() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { List hosts = new ArrayList<>(); List ocs = getHostPropertiesOnDatacenterHostFolder(new String[] {"name"}); @@ -224,7 +224,7 @@ public ManagedObjectReference getVmFolder() throws Exception { return _context.getVimClient().getDynamicProperty(_mor, "vmFolder"); } - public List getHostPropertiesOnDatacenterHostFolder(String[] propertyPaths) throws Exception { + public List getHostPropertiesOnDatacenterHostFolder(String[] propertyPaths) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { PropertySpec pSpec = new PropertySpec(); pSpec.setType("HostSystem"); pSpec.getPathSet().addAll(Arrays.asList(propertyPaths)); diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java index 3b96e7e19990..1f3c6d6ae5d4 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.hypervisor.vmware.mo; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -58,6 +59,7 @@ import com.vmware.vim25.HostSystemConnectionState; import com.vmware.vim25.HostVirtualNic; import com.vmware.vim25.HostVirtualSwitch; +import com.vmware.vim25.InvalidPropertyFaultMsg; import com.vmware.vim25.ManagedObjectReference; import com.vmware.vim25.NasDatastoreInfo; import com.vmware.vim25.ObjectContent; @@ -65,6 +67,7 @@ import com.vmware.vim25.OptionValue; import com.vmware.vim25.PropertyFilterSpec; import com.vmware.vim25.PropertySpec; +import com.vmware.vim25.RuntimeFaultFaultMsg; import com.vmware.vim25.TraversalSpec; import com.vmware.vim25.VirtualMachineConfigSpec; import com.vmware.vim25.VirtualNicManagerNetConfig; @@ -535,7 +538,7 @@ public List getVmMorsOnNetwork(String portGroupName) thr return null; } - public String getHostName() throws Exception { + public String getHostName() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return (String)_context.getVimClient().getDynamicProperty(_mor, "name"); } From cd6d42ce2ab804b01485eb73e7424ca89e816b6f Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 8 Jan 2025 11:35:43 +0100 Subject: [PATCH 13/24] get all vms for a host --- .../vmware/manager/VmwareManagerImpl.java | 15 +++- .../admin/zone/ListVmwareDcVmsCmd.java | 7 ++ .../cloud/hypervisor/vmware/mo/BaseMO.java | 52 ++++++++++- .../vmware/mo/CustomFieldsManagerMO.java | 7 +- .../hypervisor/vmware/mo/DatacenterMO.java | 60 +++---------- .../cloud/hypervisor/vmware/mo/HostMO.java | 86 ++++++++++++++----- .../vmware/util/VmwareClientException.java | 4 + 7 files changed, 158 insertions(+), 73 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 85837a28916a..52a8580c9543 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -173,7 +173,7 @@ import com.cloud.vm.dao.UserVmCloneSettingDao; import com.cloud.vm.dao.VMInstanceDao; -// TODO move these items upstream +// TODO move these items upstream? import com.vmware.pbm.PbmProfile; import com.vmware.vim25.AboutInfo; import com.vmware.vim25.ManagedObjectReference; @@ -1590,6 +1590,7 @@ public List listHostsInDatacenter(ListVmwareDcHostsCmd cmd) { public Pair> listVMsInDatacenter(ListVmwareDcVmsCmd cmd) { Integer maxObjects = cmd.getBatchSize(); String token = cmd.getToken(); + String host = cmd.getHost(); VcenterData vmwaredc = getVcenterData(cmd); @@ -1597,7 +1598,17 @@ public Pair> listVMsInDatacenter(ListVmwareDcV VmwareContext context = getVmwareContext(vmwaredc); DatacenterMO dcMo = getDatacenterMO(context, vmwaredc); - return dcMo.getVmsOnDatacenter(maxObjects, token); + + if (com.cloud.utils.StringUtils.isNotBlank(host)) { + ManagedObjectReference hostMor = dcMo.findHost(host); + if (hostMor == null) { + throw new VmwareClientException(String.format("no host '%s' found.",host)); + } + 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) { diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java index 4514042aefdf..45dfb27f097b 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java @@ -70,6 +70,9 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems { @Parameter(name = ApiConstants.PASSWORD, type = CommandType.STRING, description = "The password for specified username.") 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; @@ -95,6 +98,10 @@ public Integer getBatchSize() { return batchSize; } + public String getHost() { + return host; + } + public String getToken() { return token; } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java index 88f6c871fbde..15fc4ab8b2e7 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/BaseMO.java @@ -16,13 +16,24 @@ // under the License. package com.cloud.hypervisor.vmware.mo; +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 org.apache.log4j.Logger; import com.vmware.vim25.CustomFieldDef; import com.vmware.vim25.CustomFieldStringValue; 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 { private static final Logger s_logger = Logger.getLogger(BaseMO.class); @@ -50,6 +61,15 @@ public BaseMO(VmwareContext context, String morType, String morValue) { _mor.setValue(morValue); } + protected static Pair> createReturnObjectPair(RetrieveResult result) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("vmware result : " + ReflectionToStringBuilderUtils.reflectCollection(result)); + } + String tokenForRetrievingNewResults = result.getToken(); + List listOfObjects = result.getObjects(); + return new Pair<>(tokenForRetrievingNewResults, listOfObjects); + } + public VmwareContext getContext() { return _context; } @@ -137,11 +157,11 @@ public String getCustomFieldValue(String fieldName) throws Exception { 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); } - 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); ManagedObjectReference cfmMor = _context.getServiceContent().getCustomFieldsManager(); @@ -153,4 +173,30 @@ public int getCustomFieldKey(String morType, String fieldName) throws Exception return cfmMo.getCustomFieldKey(morType, fieldName); } + + protected Pair> retrieveNextSetOfProperties(String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { + RetrieveResult result = _context.getService().continueRetrievePropertiesEx(_context.getPropertyCollector(), tokenForPriorQuery); + return BaseMO.createReturnObjectPair(result); + } + + protected void objectContentToUnmanagedInstanceTO(Pair> objectContents, List vms) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { + List 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) { + s_logger.debug(String.format("Unexpected error checking unmanaged instance %s, excluding it: %s", vmMo.getVmName(), e.getMessage()), e); + } + } + } + } + } } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java index 78ce9a83c687..61958d1b9529 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/CustomFieldsManagerMO.java @@ -16,11 +16,14 @@ // under the License. package com.cloud.hypervisor.vmware.mo; +import java.lang.reflect.InvocationTargetException; import java.util.List; import com.vmware.vim25.CustomFieldDef; import com.vmware.vim25.ManagedObjectReference; import com.vmware.vim25.PrivilegePolicyDef; +import com.vmware.vim25.InvalidPropertyFaultMsg; +import com.vmware.vim25.RuntimeFaultFaultMsg; import com.cloud.hypervisor.vmware.util.VmwareContext; @@ -50,12 +53,12 @@ public void setField(ManagedObjectReference morEntity, int key, String value) th _context.getService().setField(getMor(), morEntity, key, value); } - public List getFields() throws Exception { + public List getFields() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return _context.getVimClient().getDynamicProperty(getMor(), "field"); } @Override - public int getCustomFieldKey(String morType, String fieldName) throws Exception { + public int getCustomFieldKey(String morType, String fieldName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { List fields = getFields(); if (fields != null) { for (CustomFieldDef field : fields) { diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index e2db6333e9e6..d571f6fbb986 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -22,9 +22,7 @@ import java.util.Arrays; import java.util.List; -import com.cloud.hypervisor.vmware.util.VmwareHelper; import com.cloud.utils.StringUtils; -import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; import org.apache.cloudstack.vm.UnmanagedInstanceTO; import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; @@ -81,7 +79,7 @@ public VirtualMachineMO findVm(String vmName) throws Exception { s_logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!"); } String instanceNameCustomField = "value[" + key + "]"; - List ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name", instanceNameCustomField}); + List ocs = getVmProperties(new String[] {"name", instanceNameCustomField}); return HypervisorHostHelper.findVmFromObjectContent(_context, ocs.toArray(new ObjectContent[0]), vmName, instanceNameCustomField); } @@ -92,7 +90,7 @@ public List findVmByNameAndLabel(String vmLabel) throws Except List list = new ArrayList<>(); - List ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name", String.format("value[%d]", key)}); + List ocs = getVmProperties(new String[] {"name", String.format("value[%d]", key)}); if (CollectionUtils.isNotEmpty(ocs)) { for (ObjectContent oc : ocs) { List props = oc.getPropSet(); @@ -125,7 +123,7 @@ public VirtualMachineMO checkIfVmAlreadyExistsInVcenter(String vmNameOnVcenter, s_logger.warn("Custom field " + CustomFieldConstants.CLOUD_VM_INTERNAL_NAME + " is not registered ?!"); } - List ocs = getVmPropertiesOnDatacenterVmFolder(new String[] {"name", String.format("value[%d]", key)}); + List ocs = getVmProperties(new String[] {"name", String.format("value[%d]", key)}); if (CollectionUtils.isNotEmpty(ocs)) { for (ObjectContent oc : ocs) { List props = oc.getPropSet(); @@ -151,31 +149,15 @@ public VirtualMachineMO checkIfVmAlreadyExistsInVcenter(String vmNameOnVcenter, return null; } - public Pair> getVmsOnDatacenter(Integer maxObjects, String token) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { + public Pair> getVms(Integer maxObjects, String token) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { List vms = new ArrayList<>(); - Pair> objectContents = getVmPropertiesOnDatacenterVmFolder(new String[] {"name"}, maxObjects, token); + Pair> objectContents = getVmProperties(new String[] {"name"}, maxObjects, token); if (s_logger.isDebugEnabled()) { s_logger.debug(String.format("returning token %s for future retrievals, currently %d objects retrieved.", objectContents.first(), objectContents.second().size())); } Pair> retval = new Pair<>(objectContents.first(), vms); - List 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) { - s_logger.debug(String.format("Unexpected error checking unmanaged instance %s, excluding it: %s", vmMo.getVmName(), e.getMessage()), e); - } - } - } - } + + objectContentToUnmanagedInstanceTO(objectContents, vms); return retval; } @@ -207,7 +189,7 @@ public ManagedObjectReference findDatastore(String name) throws Exception { return null; } - public ManagedObjectReference findHost(String name) throws Exception { + public ManagedObjectReference findHost(String name) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { List ocs = getHostPropertiesOnDatacenterHostFolder(new String[] {"name"}); if (ocs != null) { @@ -291,8 +273,8 @@ public List getDatastorePropertiesOnDatacenter(String[] propertyP } - public List getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { - return getVmPropertiesOnDatacenterVmFolder(propertyPaths, null, null).second(); + public List getVmProperties(String[] propertyPaths) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { + return getVmProperties(propertyPaths, null, null).second(); } /** @@ -304,26 +286,21 @@ public List getVmPropertiesOnDatacenterVmFolder(String[] property * @throws InvalidPropertyFaultMsg property does not exist as thrown by Vmware. * @throws RuntimeFaultFaultMsg generic vmware runtime exception */ - public Pair> getVmPropertiesOnDatacenterVmFolder(String[] propertyPaths, Integer maxObjects, String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { + public Pair> getVmProperties(String[] propertyPaths, Integer maxObjects, String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { if(StringUtils.isNotBlank(tokenForPriorQuery)) { if (s_logger.isDebugEnabled()) { s_logger.debug(String.format("running repeat query with token \'%s\'", tokenForPriorQuery)); } - return retrieveNextSetOfPropertiesOnDatacenterVmFolder(tokenForPriorQuery); + return retrieveNextSetOfProperties(tokenForPriorQuery); } else { if (s_logger.isDebugEnabled()) { s_logger.debug(String.format("running query for %d propertypaths and max %d objects", propertyPaths.length, maxObjects)); } - return retrieveNextSetOfPropertiesOnDatacenterVmFolder(propertyPaths, maxObjects); + return retrieveNextSetOfProperties(propertyPaths, maxObjects); } } - private Pair> retrieveNextSetOfPropertiesOnDatacenterVmFolder(String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { - RetrieveResult result = _context.getService().continueRetrievePropertiesEx(_context.getPropertyCollector(), tokenForPriorQuery); - return createReturnObjectPair(result); - } - - private Pair> retrieveNextSetOfPropertiesOnDatacenterVmFolder(String[] propertyPaths, Integer maxObjects) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { + private Pair> retrieveNextSetOfProperties(String[] propertyPaths, Integer maxObjects) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { PropertySpec pSpec = new PropertySpec(); pSpec.setType("VirtualMachine"); pSpec.getPathSet().addAll(Arrays.asList(propertyPaths)); @@ -363,15 +340,6 @@ private Pair> retrieveNextSetOfPropertiesOnDatacente return createReturnObjectPair(result); } - private static Pair> createReturnObjectPair(RetrieveResult result) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("vmware result : " + ReflectionToStringBuilderUtils.reflectCollection(result)); - } - String tokenForRetrievingNewResults = result.getToken(); - List listOfObjects = result.getObjects(); - return new Pair<>(tokenForRetrievingNewResults, listOfObjects); - } - public static Pair getOwnerDatacenter(VmwareContext context, ManagedObjectReference morEntity) throws Exception { PropertySpec pSpec = new PropertySpec(); diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java index 1f3c6d6ae5d4..edffd8b09068 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/HostMO.java @@ -25,11 +25,20 @@ import java.util.Map; 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.lang3.StringUtils; import org.apache.log4j.Logger; import com.google.gson.Gson; + import com.vmware.vim25.AboutInfo; import com.vmware.vim25.AlreadyExistsFaultMsg; import com.vmware.vim25.ClusterDasConfigInfo; @@ -67,14 +76,12 @@ import com.vmware.vim25.OptionValue; import com.vmware.vim25.PropertyFilterSpec; 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.VirtualMachineConfigSpec; 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 { private static final Logger s_logger = Logger.getLogger(HostMO.class); @@ -543,13 +550,17 @@ public String getHostName() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg } @Override - public synchronized List listVmsOnHyperHostWithHypervisorName(String vmName) throws Exception { + public synchronized List listVmsOnHyperHostWithHypervisorName(String vmName) throws VmwareClientException { List vms = new ArrayList<>(); - if (StringUtils.isNotEmpty(vmName)) { - vms.add(findVmOnHyperHostWithHypervisorName(vmName)); - } else { - loadVmCache(); - vms.addAll(_vmCache.values()); + try { + if (StringUtils.isNotEmpty(vmName)) { + vms.add(findVmOnHyperHostWithHypervisorName(vmName)); + } else { + loadVmCache(); + vms.addAll(_vmCache.values()); + } + } catch (InvalidPropertyFaultMsg | RuntimeFaultFaultMsg | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { + throw new VmwareClientException("problem loading vm cache.", e); } return vms; } @@ -585,7 +596,7 @@ private boolean isUserVMInternalCSName(String vmInternalCSName) { } } - private void loadVmCache() throws Exception { + private void loadVmCache() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { if (s_logger.isDebugEnabled()) s_logger.debug("load VM cache on host"); @@ -707,11 +718,16 @@ public HashMap getVmVncPortsOnHost() throws Exception { } @Override - public ObjectContent[] getVmPropertiesOnHyperHost(String[] propertyPaths) throws Exception { - if (s_logger.isTraceEnabled()) + public ObjectContent[] getVmPropertiesOnHyperHost(String[] propertyPaths) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { + List properties = getVmProperties(propertyPaths, null, null).second(); + return properties.toArray(new ObjectContent[properties.size()]); + } + + public Pair> getVmProperties(String[] propertyPaths, Integer maxObjects) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { + if (s_logger.isTraceEnabled()) { s_logger.trace("vCenter API trace - retrieveProperties() for VM properties. target MOR: " + _mor.getValue() + ", properties: " + new Gson().toJson(propertyPaths)); - + } PropertySpec pSpec = new PropertySpec(); pSpec.setType("VirtualMachine"); pSpec.getPathSet().addAll(Arrays.asList(propertyPaths)); @@ -729,14 +745,19 @@ public ObjectContent[] getVmPropertiesOnHyperHost(String[] propertyPaths) throws PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); - List properties = _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); if (s_logger.isTraceEnabled()) s_logger.trace("vCenter API trace - retrieveProperties() done"); - return properties.toArray(new ObjectContent[properties.size()]); + return createReturnObjectPair(result); } @Override @@ -762,7 +783,7 @@ public ObjectContent[] getDatastorePropertiesOnHyperHost(String[] propertyPaths) PropertyFilterSpec pfSpec = new PropertyFilterSpec(); pfSpec.getPropSet().add(pSpec); pfSpec.getObjectSet().add(oSpec); - List pfSpecArr = new ArrayList(); + List pfSpecArr = new ArrayList<>(); pfSpecArr.add(pfSpec); List properties = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr); @@ -1321,7 +1342,7 @@ public boolean isUefiLegacySupported() throws Exception { return false; } - private synchronized VirtualMachineMO findVmOnHyperHostWithHypervisorName(String vmName) throws Exception { + private synchronized VirtualMachineMO findVmOnHyperHostWithHypervisorName(String vmName) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { if (s_logger.isDebugEnabled()) s_logger.debug("find VM hypervisor name: " + vmName + " on host"); @@ -1353,4 +1374,29 @@ private VirtualMachineMO getVmWithHypervisorName(Collection vm return null; } + public Pair> getVms(Integer maxObjects, String token) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { + List vms = new ArrayList<>(); + Pair> objectContents = getVmProperties(new String[] {"name"}, maxObjects, token); + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("returning token %s for future retrievals, currently %d objects retrieved.", objectContents.first(), objectContents.second().size())); + } + Pair> retval = new Pair<>(objectContents.first(), vms); + + objectContentToUnmanagedInstanceTO(objectContents, vms); + + return retval; + } + public Pair> getVmProperties(String[] propertyPaths, Integer maxObjects, String tokenForPriorQuery) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { + if(com.cloud.utils.StringUtils.isNotBlank(tokenForPriorQuery)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("running repeat query with token \'%s\'", tokenForPriorQuery)); + } + return retrieveNextSetOfProperties(tokenForPriorQuery); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("running query for %d propertypaths and max %d objects", propertyPaths.length, maxObjects)); + } + return getVmProperties(propertyPaths, maxObjects); + } + } } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClientException.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClientException.java index f191e8ea3eb9..828eed4622de 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClientException.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareClientException.java @@ -19,6 +19,10 @@ 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); } From 11ca5182ab4715cad7c9aee9c67b0828d4b6d884 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Mon, 13 Jan 2025 17:15:08 +0100 Subject: [PATCH 14/24] use host to list vms --- .../admin/zone/ListVmwareDcHostsCmd.java | 2 +- ui/public/locales/en.json | 1 + ui/src/views/tools/SelectVmwareVcenter.vue | 53 +++++++++++++++++-- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java index b7588d4a4a07..76022d92c4cc 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java @@ -139,10 +139,10 @@ private HostResponse createHostResponse(HostMO hostInstance) throws InvalidPrope 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, diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 8cc17bbb1286..c80f02938c05 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -3004,6 +3004,7 @@ "message.license.agreements.not.accepted": "License agreements not accepted.", "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.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.load.host.failed": "Failed to load hosts.", "message.loadbalancer.stickypolicy.configuration": "Customize the load balancer stickiness policy:", diff --git a/ui/src/views/tools/SelectVmwareVcenter.vue b/ui/src/views/tools/SelectVmwareVcenter.vue index 31e7499c75b0..294469cd97e4 100644 --- a/ui/src/views/tools/SelectVmwareVcenter.vue +++ b/ui/src/views/tools/SelectVmwareVcenter.vue @@ -119,11 +119,31 @@ /> +
+ + + + {{ 'ESXi: ' + opt.host + ' - DC: ' + opt.name }} + + + +
+ {{ $t('message.list.zone.vmware.hosts.empty') }} +
+
- + - - {{ 'ESXi: ' + opt.host + ' - DC: ' + opt.name }} + + {{ 'ESXi: ' + opt.name }} @@ -239,7 +239,7 @@ export default { } else { params.existingvcenterid = this.selectedExistingVcenterId } - params.host = this.selectedhost + params.host = this.selectedHost api('listVmwareDcVms', params).then(json => { const obj = { params: params, @@ -290,8 +290,8 @@ export default { params.existingvcenterid = this.selectedExistingVcenterId } api('listVmwareDcHosts', params).then(response => { - if (response.listvmwaredchostsresponse.VMwareDC && response.listvmwaredchostsresponse.VMwareDC.length > 0) { - this.hosts = response.listvmwaredchostsresponse.hosts + if (response.listvmwaredchostsresponse.host && response.listvmwaredchostsresponse.host.length > 0) { + this.hosts = response.listvmwaredchostsresponse.host } }).catch(error => { this.$notifyError(error) From 2bc09a551574d9d68268bfcdaf94e50149d556d4 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Mon, 20 Jan 2025 11:07:12 +0100 Subject: [PATCH 17/24] cleanup --- .../apache/cloudstack/api/ApiConstants.java | 8 +++--- .../command/admin/zone/AddVmwareDcCmd.java | 12 ++++----- .../zone/ImportVsphereStoragePoliciesCmd.java | 15 ++++++----- .../admin/zone/ListVmwareDcHostsCmd.java | 10 +++---- .../admin/zone/ListVmwareDcVmsCmd.java | 15 +++++++---- .../command/admin/zone/ListVmwareDcsCmd.java | 26 +++++++++++-------- .../zone/ListVsphereStoragePoliciesCmd.java | 17 ++++++------ ...sphereStoragePolicyCompatiblePoolsCmd.java | 2 +- .../command/admin/zone/RemoveVmwareDcCmd.java | 8 +++--- .../command/admin/zone/UpdateVmwareDcCmd.java | 11 +++----- ...eponse.java => VmwareRequestResponse.java} | 4 +-- ui/src/views/tools/SelectVmwareVcenter.vue | 4 +-- 12 files changed, 71 insertions(+), 61 deletions(-) rename plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/{VmwareRequestReponse.java => VmwareRequestResponse.java} (89%) diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index 5ee68ed91af1..efceafd1a3a2 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -438,11 +438,12 @@ public class ApiConstants { public static final String STATE = "state"; public static final String STATS = "stats"; 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_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 OWNER = "owner"; public static final String SWAP_OWNER = "swapowner"; @@ -1107,6 +1108,7 @@ public class ApiConstants { public static final String PARAMETER_DESCRIPTION_IS_TAG_A_RULE = "Whether the informed tag is a JS interpretable rule or not."; public static final String NFS_MOUNT_OPTIONS = "nfsmountopts"; + public static final String VMWARE_DC = "vmwaredc"; /** * This enum specifies IO Drivers, each option controls specific policies on I/O. diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java index 9f4985a1363b..5da2c7b70033 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java @@ -37,8 +37,8 @@ import com.cloud.user.Account; import com.cloud.utils.exception.CloudRuntimeException; -@APICommand(name = "addVmwareDc", description = "Adds a VMware datacenter to specified zone", responseObject = VmwareDatacenterResponse.class, - requestHasSensitiveInfo = true, responseHasSensitiveInfo = false) +@APICommand(name = "addVmwareDc", description = "Adds a Vmware datacenter to specified zone", + responseObject = VmwareDatacenterResponse.class, responseHasSensitiveInfo = false) public class AddVmwareDcCmd extends BaseCmd { @Inject @@ -47,7 +47,7 @@ public class AddVmwareDcCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(AddVmwareDcCmd.class.getName()); - @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; @Parameter(name = ApiConstants.VCENTER, @@ -56,10 +56,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.") 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; - @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; @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "The Zone ID.") @@ -101,7 +101,7 @@ public void execute() { response.setResponseName(getCommandName()); response.setObjectName("vmwaredc"); } 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); } catch (DiscoveryException ex) { diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ImportVsphereStoragePoliciesCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ImportVsphereStoragePoliciesCmd.java index c7ba63c02a77..40b479f809cc 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ImportVsphereStoragePoliciesCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ImportVsphereStoragePoliciesCmd.java @@ -37,7 +37,6 @@ import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.context.CallContext; -import org.apache.log4j.Logger; import javax.inject.Inject; import java.util.ArrayList; @@ -49,9 +48,6 @@ authorized = {RoleType.Admin}) public class ImportVsphereStoragePoliciesCmd extends BaseCmd { - public static final Logger LOGGER = Logger.getLogger(ImportVsphereStoragePoliciesCmd.class.getName()); - - @Inject public VmwareDatacenterService _vmwareDatacenterService; @@ -76,6 +72,13 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE List storagePolicies = _vmwareDatacenterService.importVsphereStoragePolicies(this); final ListResponse responseList = new ListResponse<>(); + final List storagePoliciesResponseList = getVsphereStoragePoliciesResponses(storagePolicies, dataCenter); + responseList.setResponses(storagePoliciesResponseList); + responseList.setResponseName(getCommandName()); + setResponseObject(responseList); + } + + private static List getVsphereStoragePoliciesResponses(List storagePolicies, DataCenter dataCenter) { final List storagePoliciesResponseList = new ArrayList<>(); for (VsphereStoragePolicy storagePolicy : storagePolicies) { final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse(); @@ -88,9 +91,7 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE storagePoliciesResponseList.add(storagePoliciesResponse); } - responseList.setResponses(storagePoliciesResponseList); - responseList.setResponseName(getCommandName()); - setResponseObject(responseList); + return storagePoliciesResponseList; } @Override diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java index e5d4a68a9d45..6f193c9c1b27 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcHostsCmd.java @@ -47,8 +47,8 @@ import java.util.ArrayList; import java.util.List; -@APICommand(name = "listVmwareDcHosts", responseObject = VmwareRequestReponse.class, - description = "Lists the VMs in a VMware Datacenter", +@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 { @@ -66,7 +66,7 @@ public class ListVmwareDcHostsCmd extends BaseCmd implements ListVmwareDcItems { 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.") + @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.") @@ -107,13 +107,13 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE baseResponseList.add(resp); } } - VmwareRequestReponse response = new VmwareRequestReponse<>(); + VmwareRequestResponse 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()); + String errorMsg = String.format("Error retrieving VMs from Vmware VC: %s", e.getMessage()); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errorMsg); } } diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java index 45dfb27f097b..544e756fe807 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcVmsCmd.java @@ -42,8 +42,8 @@ import java.util.ArrayList; import java.util.List; -@APICommand(name = "listVmwareDcVms", responseObject = VmwareRequestReponse.class, - description = "Lists the VMs in a VMware Datacenter", +@APICommand(name = "listVmwareDcVms", responseObject = VmwareRequestResponse.class, + description = "Lists the VMs in a Vmware Datacenter", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems { @@ -61,7 +61,7 @@ public class ListVmwareDcVmsCmd extends BaseCmd implements ListVmwareDcItems { 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.") + @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.") @@ -127,13 +127,13 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE baseResponseList.add(resp); } } - VmwareRequestReponse response = new VmwareRequestReponse<>(); + VmwareRequestResponse response = new VmwareRequestResponse<>(); response.setResponses(baseResponseList, baseResponseList.size()); response.setResponseName(getCommandName()); response.setToken(results.first()); setResponseObject(response); } 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); } } @@ -153,4 +153,9 @@ private void checkParameters() { public long getEntityOwnerId() { return Account.ACCOUNT_ID_SYSTEM; } + + @Override + public String getCommandName() { + return "listVmwareDcVmsResponse".toLowerCase(); + } } diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java index 61b5210bb3a5..6df4122f4bad 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java @@ -43,7 +43,7 @@ import com.cloud.hypervisor.vmware.VmwareDatacenterService; 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) public class ListVmwareDcsCmd extends BaseListCmd { @@ -52,7 +52,6 @@ public class ListVmwareDcsCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListVmwareDcsCmd.class.getName()); - ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// @@ -75,20 +74,27 @@ public Long getZoneId() { @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { - List vmwareDcList = null; + List vmwareDcList; try { vmwareDcList = _vmwareDatacenterService.listVmwareDatacenters(this); } catch (InvalidParameterValueException ie) { throw new InvalidParameterValueException("Invalid zone id " + getZoneId()); } 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 response = new ListResponse(); - List vmwareDcResponses = new ArrayList(); + ListResponse response = new ListResponse<>(); + List vmwareDcResponses = getVmwareDatacenterResponses(vmwareDcList); + response.setResponses(vmwareDcResponses); + response.setResponseName(getCommandName()); + setResponseObject(response); + } - if (vmwareDcList != null && vmwareDcList.size() > 0) { + private List getVmwareDatacenterResponses(List vmwareDcList) { + List vmwareDcResponses = new ArrayList<>(); + + if (vmwareDcList != null && !vmwareDcList.isEmpty()) { for (VmwareDatacenter vmwareDc : vmwareDcList) { VmwareDatacenterResponse vmwareDcResponse = new VmwareDatacenterResponse(); @@ -96,14 +102,12 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE vmwareDcResponse.setVcenter(vmwareDc.getVcenterHost()); vmwareDcResponse.setName(vmwareDc.getVmwareDatacenterName()); vmwareDcResponse.setZoneId(getZoneId()); - vmwareDcResponse.setObjectName("VMwareDC"); + vmwareDcResponse.setObjectName("VmwareDC"); vmwareDcResponses.add(vmwareDcResponse); } } - response.setResponses(vmwareDcResponses); - response.setResponseName(getCommandName()); - setResponseObject(response); + return vmwareDcResponses; } @Override diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePoliciesCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePoliciesCmd.java index ac909a0dc647..35631ba1315a 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePoliciesCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePoliciesCmd.java @@ -36,7 +36,6 @@ import org.apache.cloudstack.api.response.VsphereStoragePoliciesResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.cloudstack.context.CallContext; -import org.apache.log4j.Logger; import javax.inject.Inject; import java.util.ArrayList; @@ -48,9 +47,6 @@ authorized = {RoleType.Admin}) public class ListVsphereStoragePoliciesCmd extends BaseCmd { - public static final Logger LOGGER = Logger.getLogger(ListVsphereStoragePoliciesCmd.class.getName()); - - @Inject public VmwareDatacenterService _vmwareDatacenterService; @@ -75,6 +71,13 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE List storagePolicies = _vmwareDatacenterService.listVsphereStoragePolicies(this); final ListResponse responseList = new ListResponse<>(); + final List storagePoliciesResponseList = getVsphereStoragePoliciesResponses(storagePolicies, dataCenter); + responseList.setResponses(storagePoliciesResponseList); + responseList.setResponseName(getCommandName()); + setResponseObject(responseList); + } + + private static List getVsphereStoragePoliciesResponses(List storagePolicies, DataCenter dataCenter) { final List storagePoliciesResponseList = new ArrayList<>(); for (VsphereStoragePolicy storagePolicy : storagePolicies) { final VsphereStoragePoliciesResponse storagePoliciesResponse = new VsphereStoragePoliciesResponse(); @@ -83,13 +86,11 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE storagePoliciesResponse.setName(storagePolicy.getName()); storagePoliciesResponse.setPolicyId(storagePolicy.getPolicyId()); storagePoliciesResponse.setDescription(storagePolicy.getDescription()); - storagePoliciesResponse.setObjectName("StoragePolicy"); + storagePoliciesResponse.setObjectName(ApiConstants.STORAGE_POLICY); storagePoliciesResponseList.add(storagePoliciesResponse); } - responseList.setResponses(storagePoliciesResponseList); - responseList.setResponseName(getCommandName()); - setResponseObject(responseList); + return storagePoliciesResponseList; } @Override diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePolicyCompatiblePoolsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePolicyCompatiblePoolsCmd.java index d66972ded2e7..ab697fbad67f 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePolicyCompatiblePoolsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVsphereStoragePolicyCompatiblePoolsCmd.java @@ -68,7 +68,7 @@ public void execute() throws ServerApiException, ConcurrentOperationException { List poolResponses = new ArrayList<>(); for (StoragePool pool : pools) { StoragePoolResponse poolResponse = _responseGenerator.createStoragePoolForMigrationResponse(pool); - poolResponse.setObjectName("storagepool"); + poolResponse.setObjectName(ApiConstants.STORAGE_POOL); poolResponses.add(poolResponse); } response.setResponses(poolResponses); diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java index 735d00d6ca99..d15369d2983a 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java @@ -35,7 +35,7 @@ import com.cloud.user.Account; 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) public class RemoveVmwareDcCmd extends BaseCmd { @@ -49,7 +49,7 @@ public class RemoveVmwareDcCmd extends BaseCmd { type = CommandType.UUID, entityType = ZoneResponse.class, 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; public Long getZoneId() { @@ -65,10 +65,10 @@ public void execute() { response.setResponseName(getCommandName()); setResponseObject(response); } 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) { - s_logger.warn("The zone has one or more resources (like cluster), hence not able to remove VMware datacenter from zone." + s_logger.warn("The zone has one or more resources (like cluster), hence not able to remove Vmware datacenter from zone." + " Please remove all resource from zone, and retry. Exception: ", ex); ServerApiException e = new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); for (String proxyObj : ex.getIdProxyList()) { diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateVmwareDcCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateVmwareDcCmd.java index 2b6cf5984c51..5e02d5a96c20 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateVmwareDcCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/UpdateVmwareDcCmd.java @@ -28,18 +28,15 @@ import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.VmwareDatacenterResponse; import org.apache.cloudstack.api.response.ZoneResponse; -import org.apache.log4j.Logger; import com.cloud.dc.VmwareDatacenter; import com.cloud.hypervisor.vmware.VmwareDatacenterService; 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, since = "4.12.0", authorized = {RoleType.Admin}) public class UpdateVmwareDcCmd extends BaseCmd { - public static final Logger LOG = Logger.getLogger(UpdateVmwareDcCmd.class); - @Inject public VmwareDatacenterService vmwareDatacenterService; @@ -53,7 +50,7 @@ public class UpdateVmwareDcCmd extends BaseCmd { private Long zoneId; @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, - description = "VMware datacenter name.") + description = "Vmware datacenter name.") private String name; @Parameter(name = ApiConstants.VCENTER, type = CommandType.STRING, @@ -108,13 +105,13 @@ public Boolean isRecursive() { public void execute() { final VmwareDatacenter vmwareDatacenter = vmwareDatacenterService.updateVmwareDatacenter(this); 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(); response.setId(vmwareDatacenter.getUuid()); response.setName(vmwareDatacenter.getVmwareDatacenterName()); response.setResponseName(getCommandName()); - response.setObjectName("vmwaredc"); + response.setObjectName(ApiConstants.VMWARE_DC); setResponseObject(response); } diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestReponse.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestResponse.java similarity index 89% rename from plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestReponse.java rename to plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestResponse.java index aaf4214e554e..81c58ef27baf 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestReponse.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/VmwareRequestResponse.java @@ -23,9 +23,9 @@ import org.apache.cloudstack.api.ResponseObject; import org.apache.cloudstack.api.response.ListResponse; -public class VmwareRequestReponse extends ListResponse { +public class VmwareRequestResponse extends ListResponse { @SerializedName(ApiConstants.TOKEN) - @Param(description = "The VMware API token to use for retrieving further responses with") + @Param(description = "The Vmware API token to use for retrieving further responses with") private String token; public String getToken() { diff --git a/ui/src/views/tools/SelectVmwareVcenter.vue b/ui/src/views/tools/SelectVmwareVcenter.vue index c96265bb0ef2..98a2eab5048c 100644 --- a/ui/src/views/tools/SelectVmwareVcenter.vue +++ b/ui/src/views/tools/SelectVmwareVcenter.vue @@ -269,8 +269,8 @@ export default { listZoneVmwareDcs () { this.loading = true api('listVmwareDcs', { zoneid: this.sourcezoneid }).then(response => { - if (response.listvmwaredcsresponse.VMwareDC && response.listvmwaredcsresponse.VMwareDC.length > 0) { - this.existingvcenter = response.listvmwaredcsresponse.VMwareDC + if (response.listvmwaredcsresponse.vmwaredc && response.listvmwaredcsresponse.vmwaredc.length > 0) { + this.existingvcenter = response.listvmwaredcsresponse.vmwaredc } }).catch(error => { this.$notifyError(error) From 290111fa7a2b301ce771ae7d1024b76fbb98dd6d Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Thu, 23 Jan 2025 11:46:14 +0100 Subject: [PATCH 18/24] stop loading --- ui/src/views/tools/ManageInstances.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/src/views/tools/ManageInstances.vue b/ui/src/views/tools/ManageInstances.vue index d01dcbbcb96e..27ad4cc96960 100644 --- a/ui/src/views/tools/ManageInstances.vue +++ b/ui/src/views/tools/ManageInstances.vue @@ -1413,6 +1413,7 @@ export default { this.selectedVmwareVcenter = obj.params this.unmanagedInstances = obj.response.unmanagedinstance this.itemCount.unmanaged = obj.response.count + this.unmanagedInstancesLoading = false }, updateVmwareVcenterType (type) { this.vmwareVcenterType = type From f3085a6ead80b7be625e34a9a3129fcc7680526b Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Thu, 23 Jan 2025 14:44:38 +0100 Subject: [PATCH 19/24] host choice for external datacenters --- ui/src/views/tools/SelectVmwareVcenter.vue | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ui/src/views/tools/SelectVmwareVcenter.vue b/ui/src/views/tools/SelectVmwareVcenter.vue index 98a2eab5048c..1d25657b11bf 100644 --- a/ui/src/views/tools/SelectVmwareVcenter.vue +++ b/ui/src/views/tools/SelectVmwareVcenter.vue @@ -89,6 +89,7 @@ @@ -98,6 +99,7 @@ @@ -107,6 +109,7 @@ @@ -116,10 +119,12 @@
-
+
{{ $t('label.list.vmware.vcenter.vms') }} @@ -303,6 +308,11 @@ export default { 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 }, From e208bbb65d829fd01684378deb103226066e3950 Mon Sep 17 00:00:00 2001 From: dahn Date: Fri, 24 Jan 2025 08:24:33 +0100 Subject: [PATCH 20/24] sugested log message improvement Co-authored-by: Nicolas Vazquez --- .../com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 7fdcde0217b3..2d733e8a16cb 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -1599,7 +1599,7 @@ public Pair> listVMsInDatacenter(ListVmwareDcV if (com.cloud.utils.StringUtils.isNotBlank(host)) { ManagedObjectReference hostMor = dcMo.findHost(host); if (hostMor == null) { - throw new VmwareClientException(String.format("no host '%s' found.",host)); + 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); From 3ba54bbbb3324efd3697a8198eee6979ae611e86 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2025 16:26:56 +0100 Subject: [PATCH 21/24] lower case API standard in response --- .../cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java index 6df4122f4bad..9f7c4cf2944e 100644 --- a/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java +++ b/plugins/hypervisors/vmware/src/main/java/org/apache/cloudstack/api/command/admin/zone/ListVmwareDcsCmd.java @@ -102,7 +102,7 @@ private List getVmwareDatacenterResponses(List Date: Tue, 28 Jan 2025 16:31:49 +0100 Subject: [PATCH 22/24] more specific exceptions thrown --- .../main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index d571f6fbb986..211972f2efc5 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -69,7 +69,7 @@ public DatacenterMO(VmwareContext context, String dcName) throws InvalidProperty } @Override - public String getName() throws Exception { + public String getName() throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return _context.getVimClient().getDynamicProperty(_mor, "name"); } From a6d9d7073275e18ea47b9574d77777f1e63fc7c6 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 29 Jan 2025 15:01:22 +0100 Subject: [PATCH 23/24] deal with globbing in marvin test data --- .../cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java | 4 ++-- test/integration/smoke/test_dynamicroles.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java b/plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java index 1dfe20a10be2..005eb2a8fd4f 100644 --- a/plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java +++ b/plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java @@ -47,14 +47,14 @@ public class DynamicRoleBasedAPIAccessChecker extends AdapterBase implements API private RoleService roleService; private List services; - private Map> annotationRoleBasedApisMap = new HashMap>(); + private Map> annotationRoleBasedApisMap = new HashMap<>(); private static final Logger LOGGER = Logger.getLogger(DynamicRoleBasedAPIAccessChecker.class.getName()); protected DynamicRoleBasedAPIAccessChecker() { super(); for (RoleType roleType : RoleType.values()) { - annotationRoleBasedApisMap.put(roleType, new HashSet()); + annotationRoleBasedApisMap.put(roleType, new HashSet<>()); } } diff --git a/test/integration/smoke/test_dynamicroles.py b/test/integration/smoke/test_dynamicroles.py index b91ba9c2eba8..017acf4a386b 100644 --- a/test/integration/smoke/test_dynamicroles.py +++ b/test/integration/smoke/test_dynamicroles.py @@ -73,6 +73,7 @@ def __init__(self): "listApis": "allow", "listAccounts": "allow", "listClusters": "deny", + "*VMwareDC*": "allow", "*VM*": "allow", "*Host*": "deny" } From d39e23e5fa45176b74f5e239ae0943ccf34fdd25 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Fri, 31 Jan 2025 14:47:38 +0100 Subject: [PATCH 24/24] something fishy going on with case sensitifity in dynamic roles --- test/integration/smoke/test_dynamicroles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/smoke/test_dynamicroles.py b/test/integration/smoke/test_dynamicroles.py index 017acf4a386b..39f995a14a3b 100644 --- a/test/integration/smoke/test_dynamicroles.py +++ b/test/integration/smoke/test_dynamicroles.py @@ -73,7 +73,7 @@ def __init__(self): "listApis": "allow", "listAccounts": "allow", "listClusters": "deny", - "*VMwareDC*": "allow", + "*VmwareDc*": "allow", "*VM*": "allow", "*Host*": "deny" }