diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 341c6c4c555..55502df669d 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -112,7 +112,7 @@ public interface Network extends ControlledEntity, StateObject, I public static class Provider { private static List supportedProviders = new ArrayList(); - public static final Provider VirtualRouter = new Provider("VirtualRouter", false); + public static final Provider VirtualRouter = new Provider("VirtualRouter", false, false); public static final Provider JuniperContrailRouter = new Provider("JuniperContrailRouter", false); public static final Provider JuniperContrailVpcRouter = new Provider("JuniperContrailVpcRouter", false); public static final Provider JuniperSRX = new Provider("JuniperSRX", true); @@ -140,9 +140,21 @@ public interface Network extends ControlledEntity, StateObject, I private final String name; private final boolean isExternal; + // set to true, if on network shutdown resources (acquired/configured at implemented phase) needed to cleaned up. set to false + // if no clean-up is required ( for e.g appliance based providers like VirtualRouter, VM is destroyed so there is no need to cleanup). + private final boolean needCleanupOnShutdown; + public Provider(String name, boolean isExternal) { this.name = name; this.isExternal = isExternal; + needCleanupOnShutdown = true; + supportedProviders.add(this); + } + + public Provider(String name, boolean isExternal, boolean needCleanupOnShutdown) { + this.name = name; + this.isExternal = isExternal; + this.needCleanupOnShutdown = needCleanupOnShutdown; supportedProviders.add(this); } @@ -154,6 +166,10 @@ public interface Network extends ControlledEntity, StateObject, I return isExternal; } + public boolean cleanupNeededOnShutdown() { + return needCleanupOnShutdown; + } + public static Provider getProvider(String providerName) { for (Provider provider : supportedProviders) { if (provider.getName().equalsIgnoreCase(providerName)) { diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 265515c50b5..20f8212e742 100755 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -2095,11 +2095,24 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra @Override public boolean shutdownNetworkElementsAndResources(ReservationContext context, boolean cleanupElements, Network network) { + + // get providers to shutdown + List providersToShutdown = getNetworkProviders(network.getId()); + // 1) Cleanup all the rules for the network. If it fails, just log the failure and proceed with shutting down // the elements boolean cleanupResult = true; + boolean cleanupNeeded = false; try { - cleanupResult = shutdownNetworkResources(network.getId(), context.getAccount(), context.getCaller().getId()); + for (Provider provider: providersToShutdown) { + if (provider.cleanupNeededOnShutdown()) { + cleanupNeeded = true; + break; + } + } + if (cleanupNeeded) { + cleanupResult = shutdownNetworkResources(network.getId(), context.getAccount(), context.getCaller().getId()); + } } catch (Exception ex) { s_logger.warn("shutdownNetworkRules failed during the network " + network + " shutdown due to ", ex); } finally { @@ -2110,8 +2123,6 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } // 2) Shutdown all the network elements - // get providers to shutdown - List providersToShutdown = getNetworkProviders(network.getId()); boolean success = true; for (NetworkElement element : networkElements) { if (providersToShutdown.contains(element.getProvider())) {