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);