@@ -1101,6 +1101,9 @@ public ExecutionResult prepareCommand(NetworkElementCommand cmd) {
11011101
11021102 @ Override
11031103 public ExecutionResult cleanupCommand (NetworkElementCommand cmd ) {
1104+ if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand )) {
1105+ return cleanupNetworkElementCommand ((IpAssocCommand )cmd );
1106+ }
11041107 return new ExecutionResult (true , null );
11051108 }
11061109
@@ -1326,15 +1329,7 @@ private void plugNicCommandInternal(String vmName, VirtualEthernetCardType nicDe
13261329 nicTo .getMac (), deviceNumber + 1 , true , true );
13271330 }
13281331
1329- VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec ();
1330- VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec ();
1331- deviceConfigSpec .setDevice (nic );
1332- deviceConfigSpec .setOperation (VirtualDeviceConfigSpecOperation .ADD );
1333-
1334- vmConfigSpec .getDeviceChange ().add (deviceConfigSpec );
1335- if (!vmMo .configureVm (vmConfigSpec )) {
1336- throw new Exception ("Failed to configure devices when running PlugNicCommand" );
1337- }
1332+ configureNicDevice (vmMo , nic , VirtualDeviceConfigSpecOperation .ADD , "PlugNicCommand" );
13381333 }
13391334
13401335 private ReplugNicAnswer execute (ReplugNicCommand cmd ) {
@@ -1395,16 +1390,7 @@ private ReplugNicAnswer execute(ReplugNicCommand cmd) {
13951390 VmwareHelper .updateNicDevice (nic , networkInfo .first (), networkInfo .second ());
13961391 }
13971392
1398- VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec ();
1399- //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
1400- VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec ();
1401- deviceConfigSpec .setDevice (nic );
1402- deviceConfigSpec .setOperation (VirtualDeviceConfigSpecOperation .EDIT );
1403-
1404- vmConfigSpec .getDeviceChange ().add (deviceConfigSpec );
1405- if (!vmMo .configureVm (vmConfigSpec )) {
1406- throw new Exception ("Failed to configure devices when running ReplugNicCommand" );
1407- }
1393+ configureNicDevice (vmMo , nic , VirtualDeviceConfigSpecOperation .EDIT , "ReplugNicCommand" );
14081394
14091395 return new ReplugNicAnswer (cmd , true , "success" );
14101396 } catch (Exception e ) {
@@ -1445,16 +1431,7 @@ private UnPlugNicAnswer execute(UnPlugNicCommand cmd) {
14451431 if (nic == null ) {
14461432 return new UnPlugNicAnswer (cmd , true , "success" );
14471433 }
1448- VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec ();
1449- //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
1450- VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec ();
1451- deviceConfigSpec .setDevice (nic );
1452- deviceConfigSpec .setOperation (VirtualDeviceConfigSpecOperation .REMOVE );
1453-
1454- vmConfigSpec .getDeviceChange ().add (deviceConfigSpec );
1455- if (!vmMo .configureVm (vmConfigSpec )) {
1456- throw new Exception ("Failed to configure devices when running unplugNicCommand" );
1457- }
1434+ configureNicDevice (vmMo , nic , VirtualDeviceConfigSpecOperation .REMOVE , "unplugNicCommand" );
14581435
14591436 return new UnPlugNicAnswer (cmd , true , "success" );
14601437 } catch (Exception e ) {
@@ -1501,17 +1478,7 @@ private void plugPublicNic(VirtualMachineMO vmMo, final String vlanId, final IpA
15011478 device .setBacking (dataCenterMo .getDvPortBackingInfo (networkInfo ));
15021479 }
15031480
1504- VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec ();
1505-
1506- //VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
1507- VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec ();
1508- deviceConfigSpec .setDevice (device );
1509- deviceConfigSpec .setOperation (VirtualDeviceConfigSpecOperation .EDIT );
1510-
1511- vmConfigSpec .getDeviceChange ().add (deviceConfigSpec );
1512- if (!vmMo .configureVm (vmConfigSpec )) {
1513- throw new Exception ("Failed to configure devices when plugPublicNic" );
1514- }
1481+ configureNicDevice (vmMo , device , VirtualDeviceConfigSpecOperation .EDIT , "plugPublicNic" );
15151482 } catch (Exception e ) {
15161483
15171484 // restore allocation mask in case of exceptions
@@ -1579,15 +1546,15 @@ private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) {
15791546 }
15801547 String vlanId = BroadcastDomainType .getValue (broadcastUri );
15811548
1582- String publicNeworkName = HypervisorHostHelper .getPublicNetworkNamePrefix (vlanId );
1583- Pair <Integer , VirtualDevice > publicNicInfo = vmMo .getNicDeviceIndex (publicNeworkName );
1549+ String publicNetworkName = HypervisorHostHelper .getPublicNetworkNamePrefix (vlanId );
1550+ Pair <Integer , VirtualDevice > publicNicInfo = vmMo .getNicDeviceIndex (publicNetworkName );
15841551
15851552 if (s_logger .isDebugEnabled ()) {
1586- s_logger .debug ("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo .first ());
1553+ s_logger .debug ("Find public NIC index, public network name: " + publicNetworkName + ", index: " + publicNicInfo .first ());
15871554 }
15881555
15891556 boolean addVif = false ;
1590- if (ip .isAdd () && publicNicInfo .first (). intValue () == -1 ) {
1557+ if (ip .isAdd () && publicNicInfo .first () == -1 ) {
15911558 if (s_logger .isDebugEnabled ()) {
15921559 s_logger .debug ("Plug new NIC to associate" + controlIp + " to " + ip .getPublicIp ());
15931560 }
@@ -1601,18 +1568,18 @@ private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) {
16011568 nicDeviceType = VirtualEthernetCardType .valueOf (ip .getDetails ().get ("nicAdapter" ));
16021569 }
16031570 plugNicCommandInternal (routerName , nicDeviceType , nicTO , VirtualMachine .Type .DomainRouter );
1604- publicNicInfo = vmMo .getNicDeviceIndex (publicNeworkName );
1605- if (publicNicInfo .first (). intValue () >= 0 ) {
1571+ publicNicInfo = vmMo .getNicDeviceIndex (publicNetworkName );
1572+ if (publicNicInfo .first () >= 0 ) {
16061573 networkUsage (controlIp , "addVif" , "eth" + publicNicInfo .first ());
16071574 }
16081575 }
16091576
1610- if (publicNicInfo .first (). intValue () < 0 ) {
1577+ if (publicNicInfo .first () < 0 ) {
16111578 String msg = "Failed to find DomR VIF to associate/disassociate IP with." ;
16121579 s_logger .error (msg );
16131580 throw new InternalErrorException (msg );
16141581 }
1615- ip .setNicDevId (publicNicInfo .first (). intValue () );
1582+ ip .setNicDevId (publicNicInfo .first ());
16161583 ip .setNewNic (addVif );
16171584 }
16181585 } catch (Throwable e ) {
@@ -1622,6 +1589,81 @@ private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) {
16221589 return new ExecutionResult (true , null );
16231590 }
16241591
1592+ private ExecutionResult cleanupNetworkElementCommand (IpAssocCommand cmd ) {
1593+ VmwareContext context = getServiceContext ();
1594+ try {
1595+ VmwareHypervisorHost hyperHost = getHyperHost (context );
1596+ IpAddressTO [] ips = cmd .getIpAddresses ();
1597+ String routerName = cmd .getAccessDetail (NetworkElementCommand .ROUTER_NAME );
1598+
1599+ VirtualMachineMO vmMo = hyperHost .findVmOnHyperHost (routerName );
1600+ // command may sometimes be redirected to a wrong host, we relax
1601+ // the check and will try to find it within datacenter
1602+ if (vmMo == null ) {
1603+ if (hyperHost instanceof HostMO ) {
1604+ final DatacenterMO dcMo = new DatacenterMO (context , hyperHost .getHyperHostDatacenter ());
1605+ vmMo = dcMo .findVm (routerName );
1606+ }
1607+ }
1608+
1609+ if (vmMo == null ) {
1610+ String msg = String .format ("Router %s no longer exists to execute IPAssoc command " , routerName );
1611+ s_logger .error (msg );
1612+ throw new Exception (msg );
1613+ }
1614+ final String lastIp = cmd .getAccessDetail (NetworkElementCommand .NETWORK_PUB_LAST_IP );
1615+ for (IpAddressTO ip : ips ) {
1616+ if (ip .isAdd () || lastIp .equalsIgnoreCase ("false" )) {
1617+ continue ;
1618+ }
1619+ Pair <VirtualDevice , Integer > nicInfo = getVirtualDevice (vmMo , ip );
1620+
1621+ if (nicInfo .second () == 2 ) {
1622+ return new ExecutionResult (true , "Not removing eth2 in network VR because it is the public NIC of source NAT" );
1623+ }
1624+ if (nicInfo .first () == null ) {
1625+ return new ExecutionResult (false , "Couldn't find NIC" );
1626+ }
1627+ configureNicDevice (vmMo , nicInfo .first (), VirtualDeviceConfigSpecOperation .REMOVE , "unplugNicCommand" );
1628+ }
1629+ } catch (Throwable e ) {
1630+ s_logger .error ("Unexpected exception: " + e .toString () + " will shortcut rest of IPAssoc commands" , e );
1631+ return new ExecutionResult (false , e .toString ());
1632+ }
1633+ return new ExecutionResult (true , null );
1634+ }
1635+
1636+ private Pair <VirtualDevice , Integer > getVirtualDevice (VirtualMachineMO vmMo , IpAddressTO ip ) throws Exception {
1637+ NicTO nicTO = ip .getNicTO ();
1638+ URI broadcastUri = BroadcastDomainType .fromString (ip .getBroadcastUri ());
1639+ if (BroadcastDomainType .getSchemeValue (broadcastUri ) != BroadcastDomainType .Vlan ) {
1640+ throw new InternalErrorException (String .format ("Unable to assign a public IP to a VIF on network %s" , ip .getBroadcastUri ()));
1641+ }
1642+ String vlanId = BroadcastDomainType .getValue (broadcastUri );
1643+
1644+ String publicNetworkName = HypervisorHostHelper .getPublicNetworkNamePrefix (vlanId );
1645+ Pair <Integer , VirtualDevice > publicNicInfo = vmMo .getNicDeviceIndex (publicNetworkName );
1646+
1647+ if (s_logger .isDebugEnabled ()) {
1648+ s_logger .debug (String .format ("Find public NIC index, public network name: %s , index: %s" , publicNetworkName , publicNicInfo .first ()));
1649+ }
1650+
1651+ return new Pair <>(findVirtualNicDevice (vmMo , nicTO .getMac ()), publicNicInfo .first ());
1652+ }
1653+
1654+ private void configureNicDevice (VirtualMachineMO vmMo , VirtualDevice nic , VirtualDeviceConfigSpecOperation operation , String commandName ) throws Exception {
1655+ VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec ();
1656+ VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec ();
1657+ deviceConfigSpec .setDevice (nic );
1658+ deviceConfigSpec .setOperation (operation );
1659+
1660+
1661+ vmConfigSpec .getDeviceChange ().add (deviceConfigSpec );
1662+ if (!vmMo .configureVm (vmConfigSpec )) {
1663+ throw new Exception (String .format ("Failed to configure devices when running %s" , commandName ));
1664+ }
1665+ }
1666+
16251667 @ Override
16261668 public ExecutionResult executeInVR (String routerIP , String script , String args ) {
16271669 return executeInVR (routerIP , script , args , VRScripts .VR_SCRIPT_EXEC_TIMEOUT );
0 commit comments