This is an automated email from the ASF dual-hosted git repository.

nvazquez pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/main by this push:
     new 550c810  [VMware] Support for removal of NIC on IP disassociation on 
the VR (#5985)
550c810 is described below

commit 550c810538f8367922e32af16def42e9a8f3a5f0
Author: Pearl Dsilva <[email protected]>
AuthorDate: Fri Feb 18 07:14:03 2022 +0530

    [VMware] Support for removal of NIC on IP disassociation on the VR (#5985)
    
    * [VMware] Support for removal of NIC on IP disassociation on the VR
    
    * address comments - extract code + add appropriate operation name in logs
    
    * Do not remove/unplug nic on removal of static nat on last IP (Public NIC)
    
    * address comments
    
    * address comment
---
 .../hypervisor/vmware/resource/VmwareResource.java | 138 ++++++++++++++-------
 1 file changed, 90 insertions(+), 48 deletions(-)

diff --git 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index 80b4ba2..50c7c4d 100644
--- 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -1101,6 +1101,9 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
 
     @Override
     public ExecutionResult cleanupCommand(NetworkElementCommand cmd) {
+        if (cmd instanceof IpAssocCommand && !(cmd instanceof 
IpAssocVpcCommand)) {
+            return cleanupNetworkElementCommand((IpAssocCommand)cmd);
+        }
         return new ExecutionResult(true, null);
     }
 
@@ -1326,15 +1329,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                     nicTo.getMac(), deviceNumber + 1, true, true);
         }
 
-        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
-        VirtualDeviceConfigSpec deviceConfigSpec = new 
VirtualDeviceConfigSpec();
-        deviceConfigSpec.setDevice(nic);
-        deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
-
-        vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-        if (!vmMo.configureVm(vmConfigSpec)) {
-            throw new Exception("Failed to configure devices when running 
PlugNicCommand");
-        }
+        configureNicDevice(vmMo, nic, VirtualDeviceConfigSpecOperation.ADD, 
"PlugNicCommand");
     }
 
     private ReplugNicAnswer execute(ReplugNicCommand cmd) {
@@ -1395,16 +1390,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                 VmwareHelper.updateNicDevice(nic, networkInfo.first(), 
networkInfo.second());
             }
 
-            VirtualMachineConfigSpec vmConfigSpec = new 
VirtualMachineConfigSpec();
-            //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new 
VirtualDeviceConfigSpec[1];
-            VirtualDeviceConfigSpec deviceConfigSpec = new 
VirtualDeviceConfigSpec();
-            deviceConfigSpec.setDevice(nic);
-            
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-
-            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to configure devices when running 
ReplugNicCommand");
-            }
+            configureNicDevice(vmMo, nic, 
VirtualDeviceConfigSpecOperation.EDIT, "ReplugNicCommand");
 
             return new ReplugNicAnswer(cmd, true, "success");
         } catch (Exception e) {
@@ -1445,16 +1431,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
             if (nic == null) {
                 return new UnPlugNicAnswer(cmd, true, "success");
             }
-            VirtualMachineConfigSpec vmConfigSpec = new 
VirtualMachineConfigSpec();
-            //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new 
VirtualDeviceConfigSpec[1];
-            VirtualDeviceConfigSpec deviceConfigSpec = new 
VirtualDeviceConfigSpec();
-            deviceConfigSpec.setDevice(nic);
-            
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.REMOVE);
-
-            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to configure devices when running 
unplugNicCommand");
-            }
+            configureNicDevice(vmMo, nic, 
VirtualDeviceConfigSpecOperation.REMOVE, "unplugNicCommand");
 
             return new UnPlugNicAnswer(cmd, true, "success");
         } catch (Exception e) {
@@ -1501,17 +1478,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                 
device.setBacking(dataCenterMo.getDvPortBackingInfo(networkInfo));
             }
 
-            VirtualMachineConfigSpec vmConfigSpec = new 
VirtualMachineConfigSpec();
-
-            //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new 
VirtualDeviceConfigSpec[1];
-            VirtualDeviceConfigSpec deviceConfigSpec = new 
VirtualDeviceConfigSpec();
-            deviceConfigSpec.setDevice(device);
-            
deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
-
-            vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
-            if (!vmMo.configureVm(vmConfigSpec)) {
-                throw new Exception("Failed to configure devices when 
plugPublicNic");
-            }
+            configureNicDevice(vmMo, device, 
VirtualDeviceConfigSpecOperation.EDIT, "plugPublicNic");
         } catch (Exception e) {
 
             // restore allocation mask in case of exceptions
@@ -1579,15 +1546,15 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                 }
                 String vlanId = BroadcastDomainType.getValue(broadcastUri);
 
-                String publicNeworkName = 
HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId);
-                Pair<Integer, VirtualDevice> publicNicInfo = 
vmMo.getNicDeviceIndex(publicNeworkName);
+                String publicNetworkName = 
HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId);
+                Pair<Integer, VirtualDevice> publicNicInfo = 
vmMo.getNicDeviceIndex(publicNetworkName);
 
                 if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Find public NIC index, public network 
name: " + publicNeworkName + ", index: " + publicNicInfo.first());
+                    s_logger.debug("Find public NIC index, public network 
name: " + publicNetworkName + ", index: " + publicNicInfo.first());
                 }
 
                 boolean addVif = false;
-                if (ip.isAdd() && publicNicInfo.first().intValue() == -1) {
+                if (ip.isAdd() && publicNicInfo.first() == -1) {
                     if (s_logger.isDebugEnabled()) {
                         s_logger.debug("Plug new NIC to associate" + controlIp 
+ " to " + ip.getPublicIp());
                     }
@@ -1601,18 +1568,18 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                         nicDeviceType = 
VirtualEthernetCardType.valueOf(ip.getDetails().get("nicAdapter"));
                     }
                     plugNicCommandInternal(routerName, nicDeviceType, nicTO, 
VirtualMachine.Type.DomainRouter);
-                    publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName);
-                    if (publicNicInfo.first().intValue() >= 0) {
+                    publicNicInfo = vmMo.getNicDeviceIndex(publicNetworkName);
+                    if (publicNicInfo.first() >= 0) {
                         networkUsage(controlIp, "addVif", "eth" + 
publicNicInfo.first());
                     }
                 }
 
-                if (publicNicInfo.first().intValue() < 0) {
+                if (publicNicInfo.first() < 0) {
                     String msg = "Failed to find DomR VIF to 
associate/disassociate IP with.";
                     s_logger.error(msg);
                     throw new InternalErrorException(msg);
                 }
-                ip.setNicDevId(publicNicInfo.first().intValue());
+                ip.setNicDevId(publicNicInfo.first());
                 ip.setNewNic(addVif);
             }
         } catch (Throwable e) {
@@ -1622,6 +1589,81 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
         return new ExecutionResult(true, null);
     }
 
+    private ExecutionResult cleanupNetworkElementCommand(IpAssocCommand cmd) {
+        VmwareContext context = getServiceContext();
+        try {
+            VmwareHypervisorHost hyperHost = getHyperHost(context);
+            IpAddressTO[] ips = cmd.getIpAddresses();
+            String routerName = 
cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+
+            VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(routerName);
+            // command may sometimes be redirected to a wrong host, we relax
+            // the check and will try to find it within datacenter
+            if (vmMo == null) {
+                if (hyperHost instanceof HostMO) {
+                    final DatacenterMO dcMo = new DatacenterMO(context, 
hyperHost.getHyperHostDatacenter());
+                    vmMo = dcMo.findVm(routerName);
+                }
+            }
+
+            if (vmMo == null) {
+                String msg = String.format("Router %s no longer exists to 
execute IPAssoc command ", routerName);
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+            final String lastIp = 
cmd.getAccessDetail(NetworkElementCommand.NETWORK_PUB_LAST_IP);
+            for (IpAddressTO ip : ips) {
+                if (ip.isAdd() || lastIp.equalsIgnoreCase("false")) {
+                    continue;
+                }
+                Pair<VirtualDevice, Integer> nicInfo = getVirtualDevice(vmMo, 
ip);
+
+                if (nicInfo.second() == 2) {
+                    return new ExecutionResult(true, "Not removing eth2 in 
network VR because it is the public NIC of source NAT");
+                }
+                if (nicInfo.first() == null) {
+                    return new ExecutionResult(false, "Couldn't find NIC");
+                }
+                configureNicDevice(vmMo, nicInfo.first(), 
VirtualDeviceConfigSpecOperation.REMOVE, "unplugNicCommand");
+            }
+        } catch (Throwable e) {
+            s_logger.error("Unexpected exception: " + e.toString() + " will 
shortcut rest of IPAssoc commands", e);
+            return new ExecutionResult(false, e.toString());
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    private Pair<VirtualDevice, Integer> getVirtualDevice(VirtualMachineMO 
vmMo, IpAddressTO ip) throws Exception {
+        NicTO nicTO = ip.getNicTO();
+        URI broadcastUri = 
BroadcastDomainType.fromString(ip.getBroadcastUri());
+        if (BroadcastDomainType.getSchemeValue(broadcastUri) != 
BroadcastDomainType.Vlan) {
+            throw new InternalErrorException(String.format("Unable to assign a 
public IP to a VIF on network %s", ip.getBroadcastUri()));
+        }
+        String vlanId = BroadcastDomainType.getValue(broadcastUri);
+
+        String publicNetworkName = 
HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId);
+        Pair<Integer, VirtualDevice> publicNicInfo = 
vmMo.getNicDeviceIndex(publicNetworkName);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug(String.format("Find public NIC index, public 
network name: %s , index: %s", publicNetworkName, publicNicInfo.first()));
+        }
+
+        return new Pair<>(findVirtualNicDevice(vmMo, nicTO.getMac()), 
publicNicInfo.first());
+    }
+
+    private void configureNicDevice(VirtualMachineMO vmMo, VirtualDevice nic, 
VirtualDeviceConfigSpecOperation operation, String commandName) throws 
Exception {
+        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
+        VirtualDeviceConfigSpec deviceConfigSpec = new 
VirtualDeviceConfigSpec();
+        deviceConfigSpec.setDevice(nic);
+        deviceConfigSpec.setOperation(operation);
+
+
+        vmConfigSpec.getDeviceChange().add(deviceConfigSpec);
+        if (!vmMo.configureVm(vmConfigSpec)) {
+            throw new Exception(String.format("Failed to configure devices 
when running %s", commandName));
+        }
+    }
+
     @Override
     public ExecutionResult executeInVR(String routerIP, String script, String 
args) {
         return executeInVR(routerIP, script, args, 
VRScripts.VR_SCRIPT_EXEC_TIMEOUT);

Reply via email to