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

pearl11594 pushed a commit to branch netris-update-vpc-and-tier-names
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit f54cb50d17854be0cc74583eb510d14ba2663109
Author: Pearl Dsilva <pearl1...@gmail.com>
AuthorDate: Thu Jan 9 10:24:45 2025 -0500

    Release NAT IP subnet when VPC is removed or IP is released (#44)
    
    * Release NAT IP subnet when VPC is removed or IP is released
    
    * add license
---
 .../com/cloud/network/element/NetworkElement.java  |  7 +++++
 .../com/cloud/network/netris/NetrisService.java    |  2 ++
 .../network/vpc/dao/VpcOfferingServiceMapDao.java  |  2 ++
 .../vpc/dao/VpcOfferingServiceMapDaoImpl.java      | 10 ++++++++
 .../networkservice/BaremetalDhcpElement.java       |  6 +++++
 .../networkservice/BaremetalPxeElement.java        |  6 +++++
 .../networkservice/BaremetalUserdataElement.java   |  6 +++++
 .../network/element/CiscoNexusVSMElement.java      |  7 ++++-
 .../cloud/network/element/BigSwitchBcfElement.java |  6 +++++
 .../cloud/network/element/BrocadeVcsElement.java   |  6 +++++
 .../cloud/network/element/CiscoVnmcElement.java    |  5 ++++
 .../cloudstack/network/element/DnsNotifier.java    |  6 +++++
 .../element/ElasticLoadBalancerElement.java        |  6 +++++
 .../cloudstack/element/GloboDnsElement.java        |  6 +++++
 .../element/InternalLoadBalancerElement.java       |  6 +++++
 .../contrail/management/ContrailElementImpl.java   |  5 ++++
 .../cloudstack/agent/api/ReleaseNatIpCommand.java  | 30 ++++++++++++++++++++++
 .../apache/cloudstack/resource/NetrisResource.java | 11 ++++++++
 .../apache/cloudstack/service/NetrisApiClient.java |  2 ++
 .../cloudstack/service/NetrisApiClientImpl.java    | 26 +++++++++++++++++++
 .../apache/cloudstack/service/NetrisElement.java   |  5 ++++
 .../cloudstack/service/NetrisServiceImpl.java      |  8 ++++++
 .../cloud/network/element/NetscalerElement.java    |  5 ++++
 .../cloud/network/element/NiciraNvpElement.java    |  5 ++++
 .../org/apache/cloudstack/service/NsxElement.java  |  5 ++++
 .../network/opendaylight/OpendaylightElement.java  |  6 +++++
 .../java/com/cloud/network/element/OvsElement.java |  6 +++++
 .../element/PaloAltoExternalFirewallElement.java   |  6 +++++
 .../cloudstack/network/element/SspElement.java     |  6 +++++
 .../network/tungsten/service/TungstenElement.java  |  6 +++++
 .../com/cloud/network/IpAddressManagerImpl.java    | 30 ++++++++++++++++++++++
 .../network/element/ConfigDriveNetworkElement.java |  6 +++++
 .../network/element/SecurityGroupElement.java      |  6 +++++
 .../network/element/VirtualRouterElement.java      |  6 +++++
 .../vpc/dao/MockVpcOfferingServiceMapDaoImpl.java  |  5 ++++
 .../cloudstack/service/NetrisServiceMockTest.java  |  5 ++++
 36 files changed, 276 insertions(+), 1 deletion(-)

diff --git a/api/src/main/java/com/cloud/network/element/NetworkElement.java 
b/api/src/main/java/com/cloud/network/element/NetworkElement.java
index fa67575edd3..00c530ce114 100644
--- a/api/src/main/java/com/cloud/network/element/NetworkElement.java
+++ b/api/src/main/java/com/cloud/network/element/NetworkElement.java
@@ -23,6 +23,7 @@ import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
 import com.cloud.network.Network;
 import com.cloud.network.Network.Capability;
 import com.cloud.network.Network.Provider;
@@ -87,6 +88,12 @@ public interface NetworkElement extends Adapter {
     boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, 
ReservationContext context) throws ConcurrentOperationException,
         ResourceUnavailableException;
 
+    /**
+     * Release IP from the network provider if reserved
+     * @param ipAddress
+     */
+    boolean releaseIp(IpAddress ipAddress);
+
     /**
      * The network is being shutdown.
      * @param network
diff --git a/api/src/main/java/com/cloud/network/netris/NetrisService.java 
b/api/src/main/java/com/cloud/network/netris/NetrisService.java
index 355586f7d91..6fd860f26be 100644
--- a/api/src/main/java/com/cloud/network/netris/NetrisService.java
+++ b/api/src/main/java/com/cloud/network/netris/NetrisService.java
@@ -46,4 +46,6 @@ public interface NetrisService {
     boolean addOrUpdateStaticRoute(long zoneId, long accountId, long domainId, 
String networkResourceName, Long networkResourceId, boolean isForVpc, String 
prefix, String nextHop, Long routeId, boolean updateRoute);
 
     boolean deleteStaticRoute(long zoneId, long accountId, long domainId, 
String networkResourceName, Long networkResourceId, boolean isForVpc, String 
prefix, String nextHop, Long routeId);
+
+    boolean releaseNatIp(long zoneId, String publicIp);
 }
diff --git 
a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
 
b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
index 9519cd08a0b..020536e97ec 100644
--- 
a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
+++ 
b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDao.java
@@ -40,4 +40,6 @@ public interface VpcOfferingServiceMapDao extends 
GenericDao<VpcOfferingServiceM
 
     boolean isProviderForVpcOffering(Network.Provider provider, long 
vpcOfferingId);
 
+    List<VpcOfferingServiceMapVO> listProvidersForServiceForVpcOffering(long 
vpcOfferingId, Service service);
+
 }
diff --git 
a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java
 
b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java
index 672955a3ecc..dcb1becf9e8 100644
--- 
a/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java
+++ 
b/engine/schema/src/main/java/com/cloud/network/vpc/dao/VpcOfferingServiceMapDaoImpl.java
@@ -119,4 +119,14 @@ public class VpcOfferingServiceMapDaoImpl extends 
GenericDaoBase<VpcOfferingServ
         sc.setParameters("provider", provider.getName());
         return findOneBy(sc) != null;
     }
+
+    @Override
+    public List<VpcOfferingServiceMapVO> 
listProvidersForServiceForVpcOffering(long vpcOfferingId, Service service) {
+        SearchCriteria<VpcOfferingServiceMapVO> sc = AllFieldsSearch.create();
+
+        sc.setParameters("vpcOffId", vpcOfferingId);
+        sc.setParameters("service", service.getName());
+
+        return customSearch(sc, null);
+    }
 }
diff --git 
a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
 
b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
index e39b40cfc68..2e9d6989550 100644
--- 
a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
+++ 
b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalDhcpElement.java
@@ -34,6 +34,7 @@ import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.host.Host;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
 import com.cloud.network.Network;
 import com.cloud.network.Network.Capability;
 import com.cloud.network.Network.GuestType;
@@ -125,6 +126,11 @@ public class BaremetalDhcpElement extends AdapterBase 
implements DhcpServiceProv
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         return true;
diff --git 
a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
 
b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
index fa708e7be4c..adcb96f6116 100644
--- 
a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
+++ 
b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalPxeElement.java
@@ -29,6 +29,7 @@ import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
 import com.cloud.network.Network;
 import com.cloud.network.Network.Capability;
 import com.cloud.network.Network.GuestType;
@@ -161,6 +162,11 @@ public class BaremetalPxeElement extends AdapterBase 
implements NetworkElement {
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     private void releaseVlan(Network network, VirtualMachineProfile vm) {
         vlanMgr.releaseVlan(network, vm);
     }
diff --git 
a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
 
b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
index d2c9731ddd1..2ec05d443aa 100644
--- 
a/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
+++ 
b/plugins/hypervisors/baremetal/src/main/java/com/cloud/baremetal/networkservice/BaremetalUserdataElement.java
@@ -30,6 +30,7 @@ import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.IpAddress;
 import com.cloud.network.Network;
 import com.cloud.network.Network.Capability;
 import com.cloud.network.Network.Provider;
@@ -124,6 +125,11 @@ public class BaremetalUserdataElement extends AdapterBase 
implements NetworkElem
         return false;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         // TODO Auto-generated method stub
diff --git 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElement.java
 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElement.java
index 2503e0ac7fd..441bdb83854 100644
--- 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElement.java
+++ 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/network/element/CiscoNexusVSMElement.java
@@ -24,7 +24,7 @@ import java.util.Set;
 
 import javax.inject.Inject;
 
-
+import com.cloud.network.IpAddress;
 import com.cloud.api.commands.DeleteCiscoNexusVSMCmd;
 import com.cloud.api.commands.DisableCiscoNexusVSMCmd;
 import com.cloud.api.commands.EnableCiscoNexusVSMCmd;
@@ -106,6 +106,11 @@ public class CiscoNexusVSMElement extends 
CiscoNexusVSMDeviceManagerImpl impleme
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         return true;
diff --git 
a/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java
 
b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java
index 5fc9480c610..f3624ebeb40 100644
--- 
a/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java
+++ 
b/plugins/network-elements/bigswitch/src/main/java/com/cloud/network/element/BigSwitchBcfElement.java
@@ -29,6 +29,7 @@ import java.util.UUID;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.network.IpAddress;
 import org.springframework.stereotype.Component;
 import 
org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
 import org.apache.commons.net.util.SubnetUtils;
@@ -318,6 +319,11 @@ NetworkACLServiceProvider, FirewallServiceProvider, 
ResourceStateAdapter {
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         if (!canHandle(network, Service.Connectivity)) {
diff --git 
a/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElement.java
 
b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElement.java
index daf9c1c4e08..510900cc105 100644
--- 
a/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElement.java
+++ 
b/plugins/network-elements/brocade-vcs/src/main/java/com/cloud/network/element/BrocadeVcsElement.java
@@ -27,6 +27,7 @@ import java.util.UUID;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.network.IpAddress;
 import 
org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
 import 
org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
 import org.springframework.stereotype.Component;
@@ -194,6 +195,11 @@ public class BrocadeVcsElement extends AdapterBase 
implements NetworkElement, Re
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         if (!canHandle(network, Service.Connectivity)) {
diff --git 
a/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElement.java
 
b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElement.java
index bea5a2c3f25..352eba4674d 100644
--- 
a/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElement.java
+++ 
b/plugins/network-elements/cisco-vnmc/src/main/java/com/cloud/network/element/CiscoVnmcElement.java
@@ -434,6 +434,11 @@ public class CiscoVnmcElement extends AdapterBase 
implements SourceNatServicePro
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     private boolean cleanupLogicalEdgeFirewall(long vlanId, long hostId) {
         CleanupLogicalEdgeFirewallCommand cmd = new 
CleanupLogicalEdgeFirewallCommand(vlanId);
         Answer answer = _agentMgr.easySend(hostId, cmd);
diff --git 
a/plugins/network-elements/dns-notifier/src/main/java/org/apache/cloudstack/network/element/DnsNotifier.java
 
b/plugins/network-elements/dns-notifier/src/main/java/org/apache/cloudstack/network/element/DnsNotifier.java
index 0b96aa35150..04f092648c2 100644
--- 
a/plugins/network-elements/dns-notifier/src/main/java/org/apache/cloudstack/network/element/DnsNotifier.java
+++ 
b/plugins/network-elements/dns-notifier/src/main/java/org/apache/cloudstack/network/element/DnsNotifier.java
@@ -26,6 +26,7 @@ import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
 import com.cloud.network.Network;
 import com.cloud.network.Network.Capability;
 import com.cloud.network.Network.Provider;
@@ -86,6 +87,11 @@ public class DnsNotifier extends AdapterBase implements 
NetworkElement {
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         return true;
diff --git 
a/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/element/ElasticLoadBalancerElement.java
 
b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/element/ElasticLoadBalancerElement.java
index c1ea7823811..f512a08dffd 100644
--- 
a/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/element/ElasticLoadBalancerElement.java
+++ 
b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/element/ElasticLoadBalancerElement.java
@@ -24,6 +24,7 @@ import java.util.Set;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.network.IpAddress;
 import org.springframework.stereotype.Component;
 
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@@ -136,6 +137,11 @@ public class ElasticLoadBalancerElement extends 
AdapterBase implements LoadBalan
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         // TODO kill all loadbalancer vms by calling the 
ElasticLoadBalancerManager
diff --git 
a/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElement.java
 
b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElement.java
index 09830d9a810..c83a913a61c 100644
--- 
a/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElement.java
+++ 
b/plugins/network-elements/globodns/src/main/java/com/globo/globodns/cloudstack/element/GloboDnsElement.java
@@ -26,6 +26,7 @@ import java.util.Set;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.network.IpAddress;
 import org.apache.cloudstack.framework.config.ConfigKey;
 import org.apache.cloudstack.framework.config.Configurable;
 import org.springframework.stereotype.Component;
@@ -175,6 +176,11 @@ public class GloboDnsElement extends AdapterBase 
implements ResourceStateAdapter
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         return true;
diff --git 
a/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
 
b/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
index 0a9b4a7131a..dc48d70f8a7 100644
--- 
a/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
+++ 
b/plugins/network-elements/internal-loadbalancer/src/main/java/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
@@ -26,6 +26,7 @@ import java.util.Set;
 
 import javax.inject.Inject;
 
+import com.cloud.network.IpAddress;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 
@@ -221,6 +222,11 @@ public class InternalLoadBalancerElement extends 
AdapterBase implements LoadBala
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         List<? extends VirtualRouter> internalLbVms = 
_routerDao.listByNetworkAndRole(network.getId(), Role.INTERNAL_LB_VM);
diff --git 
a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
 
b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
index 44cbc6c305f..fb832bf1d82 100644
--- 
a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
+++ 
b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
@@ -244,6 +244,11 @@ public class ContrailElementImpl extends AdapterBase
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return false;
+    }
+
     /**
      * Network disable
      */
diff --git 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ReleaseNatIpCommand.java
 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ReleaseNatIpCommand.java
new file mode 100644
index 00000000000..ac3a4faba4d
--- /dev/null
+++ 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/ReleaseNatIpCommand.java
@@ -0,0 +1,30 @@
+// 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.agent.api;
+
+public class ReleaseNatIpCommand extends NetrisCommand {
+    private String natIp;
+
+    public ReleaseNatIpCommand(long zoneId, Long accountId, Long domainId, 
String name, Long id, boolean isVpc, String natIp) {
+        super(zoneId, accountId, domainId, name, id, isVpc);
+        this.natIp = natIp;
+    }
+
+    public String getNatIp() {
+        return natIp;
+    }
+}
diff --git 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResource.java
 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResource.java
index 4507eb7d82b..349b83132c7 100644
--- 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResource.java
+++ 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResource.java
@@ -38,6 +38,7 @@ import 
org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
 import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
 import org.apache.cloudstack.agent.api.NetrisAnswer;
 import org.apache.cloudstack.StartupNetrisCommand;
+import org.apache.cloudstack.agent.api.ReleaseNatIpCommand;
 import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
 import org.apache.cloudstack.service.NetrisApiClient;
 import org.apache.cloudstack.service.NetrisApiClientImpl;
@@ -109,6 +110,8 @@ public class NetrisResource implements ServerResource {
             return executeRequest((DeleteNetrisStaticRouteCommand) cmd);
         } else if (cmd instanceof AddOrUpdateNetrisStaticRouteCommand) {
             return executeRequest((AddOrUpdateNetrisStaticRouteCommand) cmd);
+        } else if (cmd instanceof ReleaseNatIpCommand) {
+          return executeRequest((ReleaseNatIpCommand) cmd);
         } else {
             return Answer.createUnsupportedCommandAnswer(cmd);
         }
@@ -319,6 +322,14 @@ public class NetrisResource implements ServerResource {
         return new NetrisAnswer(cmd, true, "OK");
     }
 
+    private Answer executeRequest(ReleaseNatIpCommand cmd) {
+        boolean result = netrisApiClient.releaseNatIp(cmd);
+        if (!result) {
+            return new NetrisAnswer(cmd, false, String.format("Failed to 
release NAT IP: %s", cmd.getNatIp()));
+        }
+        return new NetrisAnswer(cmd, true, "OK");
+    }
+
     @Override
     public boolean start() {
         return true;
diff --git 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClient.java
 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClient.java
index 59c2c9342a9..83e8b5fe0a3 100644
--- 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClient.java
+++ 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClient.java
@@ -28,6 +28,7 @@ import 
org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
 import org.apache.cloudstack.agent.api.DeleteNetrisStaticRouteCommand;
 import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
 import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
+import org.apache.cloudstack.agent.api.ReleaseNatIpCommand;
 import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
 
 import java.util.List;
@@ -78,4 +79,5 @@ public interface NetrisApiClient {
     boolean deleteNatRule(DeleteNetrisNatRuleCommand cmd);
     boolean addOrUpdateStaticRoute(AddOrUpdateNetrisStaticRouteCommand cmd);
     boolean deleteStaticRoute(DeleteNetrisStaticRouteCommand cmd);
+    boolean releaseNatIp(ReleaseNatIpCommand cmd);
 }
diff --git 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java
 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java
index 2c409482a19..8d6d088407e 100644
--- 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java
+++ 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java
@@ -88,6 +88,7 @@ import 
org.apache.cloudstack.agent.api.DeleteNetrisNatRuleCommand;
 import org.apache.cloudstack.agent.api.DeleteNetrisStaticRouteCommand;
 import org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
 import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
+import org.apache.cloudstack.agent.api.ReleaseNatIpCommand;
 import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
 import org.apache.cloudstack.resource.NetrisResourceObjectUtils;
 import org.apache.commons.collections.CollectionUtils;
@@ -441,6 +442,31 @@ public class NetrisApiClientImpl implements 
NetrisApiClient {
         return false;
     }
 
+    @Override
+    public boolean releaseNatIp(ReleaseNatIpCommand cmd) {
+        String natIp = cmd.getNatIp() + "/32";
+        try {
+            VPCListing systemVpc = getSystemVpc();
+            IpamApi ipamApi = apiClient.getApiStubForMethod(IpamApi.class);
+            FilterByVpc vpcFilter = new FilterByVpc();
+            vpcFilter.add(systemVpc.getId());
+            SubnetResBody subnetResponse = 
ipamApi.apiV2IpamSubnetsGet(vpcFilter);
+            if (subnetResponse == null || !subnetResponse.isIsSuccess()) {
+                String reason = subnetResponse == null ? "Empty response" : 
"Operation failed on Netris";
+                logger.debug("Failed to retrieve Netris Public NAT IPs due to 
{}", reason);
+                throw new CloudRuntimeException(reason);
+            }
+            List<IpTreeSubnet> natIps = 
subnetResponse.getData().stream().filter(ip -> 
ip.getPrefix().equals(natIp)).collect(Collectors.toList());
+            if (!natIps.isEmpty()) {
+                ipamApi.apiV2IpamTypeIdDelete("subnet", 
natIps.get(0).getId().intValue());
+            }
+
+        } catch (ApiException e) {
+            logAndThrowException("Failed to release Netris IP", e);
+        }
+        return true;
+    }
+
     private Pair<Boolean, RoutesGetBody> staticRouteExists(Integer 
netrisVpcId, String prefix, String nextHop, String description) {
         try {
             FilterByVpc vpcFilter = new FilterByVpc();
diff --git 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisElement.java
 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisElement.java
index 44339e38628..96b7379d285 100644
--- 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisElement.java
+++ 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisElement.java
@@ -320,6 +320,11 @@ public class NetrisElement extends AdapterBase implements 
DhcpServiceProvider, D
         return false;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return netrisService.releaseNatIp(ipAddress.getDataCenterId(), 
ipAddress.getAddress().addr());
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         return canHandle(network, Network.Service.Connectivity);
diff --git 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisServiceImpl.java
 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisServiceImpl.java
index 6d97f850243..cb2047e32e8 100644
--- 
a/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisServiceImpl.java
+++ 
b/plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisServiceImpl.java
@@ -52,6 +52,7 @@ import 
org.apache.cloudstack.agent.api.DeleteNetrisVnetCommand;
 import org.apache.cloudstack.agent.api.DeleteNetrisVpcCommand;
 import org.apache.cloudstack.agent.api.NetrisAnswer;
 import org.apache.cloudstack.agent.api.NetrisCommand;
+import org.apache.cloudstack.agent.api.ReleaseNatIpCommand;
 import org.apache.cloudstack.agent.api.SetupNetrisPublicRangeCommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.framework.config.ConfigKey;
@@ -354,6 +355,13 @@ public class NetrisServiceImpl implements NetrisService, 
Configurable {
         return answer.getResult();
     }
 
+    @Override
+    public boolean releaseNatIp(long zoneId, String publicIp) {
+        ReleaseNatIpCommand cmd = new ReleaseNatIpCommand(zoneId, null, null, 
null, null, false, publicIp);
+        NetrisAnswer answer = sendNetrisCommand(cmd, zoneId);
+        return answer.getResult();
+    }
+
     private String getResourceSuffix(Long vpcId, Long networkId, boolean 
isForVpc) {
         String suffix;
         if (isForVpc) {
diff --git 
a/plugins/network-elements/netscaler/src/main/java/com/cloud/network/element/NetscalerElement.java
 
b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/element/NetscalerElement.java
index 48b9006f34c..34df6e95482 100644
--- 
a/plugins/network-elements/netscaler/src/main/java/com/cloud/network/element/NetscalerElement.java
+++ 
b/plugins/network-elements/netscaler/src/main/java/com/cloud/network/element/NetscalerElement.java
@@ -420,6 +420,11 @@ IpDeployer, StaticNatServiceProvider, GslbServiceProvider {
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network guestConfig, ReservationContext context, 
boolean cleanup)
             throws ResourceUnavailableException, ConcurrentOperationException {
diff --git 
a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java
 
b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java
index 356b452a9e4..5ab85910dc9 100644
--- 
a/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java
+++ 
b/plugins/network-elements/nicira-nvp/src/main/java/com/cloud/network/element/NiciraNvpElement.java
@@ -448,6 +448,11 @@ NiciraNvpElementService, ResourceStateAdapter, IpDeployer {
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         if (!canHandle(network, Service.Connectivity)) {
diff --git 
a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
 
b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
index 753d0cf822e..a57868f864e 100644
--- 
a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
+++ 
b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java
@@ -284,6 +284,11 @@ public class NsxElement extends AdapterBase implements  
DhcpServiceProvider, Dns
         return false;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         return canHandle(network, Network.Service.Connectivity);
diff --git 
a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightElement.java
 
b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightElement.java
index b35190217d3..00d9ca8360b 100644
--- 
a/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightElement.java
+++ 
b/plugins/network-elements/opendaylight/src/main/java/org/apache/cloudstack/network/opendaylight/OpendaylightElement.java
@@ -27,6 +27,7 @@ import java.util.Set;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.network.IpAddress;
 import org.springframework.stereotype.Component;
 
 import 
org.apache.cloudstack.network.opendaylight.agent.commands.StartupOpenDaylightControllerCommand;
@@ -102,6 +103,11 @@ public class OpendaylightElement extends AdapterBase 
implements ConnectivityProv
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         return true;
diff --git 
a/plugins/network-elements/ovs/src/main/java/com/cloud/network/element/OvsElement.java
 
b/plugins/network-elements/ovs/src/main/java/com/cloud/network/element/OvsElement.java
index 69891954264..85877292c95 100644
--- 
a/plugins/network-elements/ovs/src/main/java/com/cloud/network/element/OvsElement.java
+++ 
b/plugins/network-elements/ovs/src/main/java/com/cloud/network/element/OvsElement.java
@@ -25,6 +25,7 @@ import java.util.Set;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.network.IpAddress;
 import org.apache.cloudstack.network.topology.NetworkTopology;
 import org.apache.cloudstack.network.topology.NetworkTopologyContext;
 
@@ -208,6 +209,11 @@ StaticNatServiceProvider, IpDeployer {
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(final Network network, final ReservationContext 
context,
             final boolean cleanup) throws ConcurrentOperationException,
diff --git 
a/plugins/network-elements/palo-alto/src/main/java/com/cloud/network/element/PaloAltoExternalFirewallElement.java
 
b/plugins/network-elements/palo-alto/src/main/java/com/cloud/network/element/PaloAltoExternalFirewallElement.java
index c81ac5f5f0c..e27fd88b5a8 100644
--- 
a/plugins/network-elements/palo-alto/src/main/java/com/cloud/network/element/PaloAltoExternalFirewallElement.java
+++ 
b/plugins/network-elements/palo-alto/src/main/java/com/cloud/network/element/PaloAltoExternalFirewallElement.java
@@ -25,6 +25,7 @@ import java.util.Set;
 import javax.inject.Inject;
 
 
+import com.cloud.network.IpAddress;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import 
org.apache.cloudstack.network.ExternalNetworkDeviceManager.NetworkDevice;
 
@@ -174,6 +175,11 @@ public class PaloAltoExternalFirewallElement extends 
ExternalFirewallDeviceManag
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ResourceUnavailableException, 
ConcurrentOperationException {
         DataCenter zone = _entityMgr.findById(DataCenter.class, 
network.getDataCenterId());
diff --git 
a/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspElement.java
 
b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspElement.java
index bfe9de2c837..978eb114588 100644
--- 
a/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspElement.java
+++ 
b/plugins/network-elements/stratosphere-ssp/src/main/java/org/apache/cloudstack/network/element/SspElement.java
@@ -30,6 +30,7 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 
+import com.cloud.network.IpAddress;
 import org.apache.cloudstack.api.commands.AddSspCmd;
 import org.apache.cloudstack.api.commands.DeleteSspCmd;
 import 
org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
@@ -510,6 +511,11 @@ public class SspElement extends AdapterBase implements 
ConnectivityProvider, Ssp
         return deleteNicEnv(network, nic, context);
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     /* (non-Javadoc)
      * Destroy a network implementation.
      *
diff --git 
a/plugins/network-elements/tungsten/src/main/java/org/apache/cloudstack/network/tungsten/service/TungstenElement.java
 
b/plugins/network-elements/tungsten/src/main/java/org/apache/cloudstack/network/tungsten/service/TungstenElement.java
index 106cf5180c3..18275f2e9d4 100644
--- 
a/plugins/network-elements/tungsten/src/main/java/org/apache/cloudstack/network/tungsten/service/TungstenElement.java
+++ 
b/plugins/network-elements/tungsten/src/main/java/org/apache/cloudstack/network/tungsten/service/TungstenElement.java
@@ -41,6 +41,7 @@ import com.cloud.host.HostVO;
 import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor;
+import com.cloud.network.IpAddress;
 import com.cloud.network.IpAddressManager;
 import com.cloud.network.Network;
 import com.cloud.network.NetworkMigrationResponder;
@@ -689,6 +690,11 @@ public class TungstenElement extends AdapterBase
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup)
         throws ConcurrentOperationException {
diff --git a/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java 
b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java
index 2c54a5d890c..e52eeb84fbd 100644
--- a/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java
@@ -43,6 +43,10 @@ import com.cloud.network.dao.Site2SiteVpnGatewayDao;
 import com.cloud.network.element.NetrisProviderVO;
 import com.cloud.network.element.NsxProviderVO;
 import com.cloud.network.vo.PublicIpQuarantineVO;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcOffering;
+import com.cloud.network.vpc.VpcOfferingServiceMapVO;
+import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
 import com.cloud.resourcelimit.CheckedReservation;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
@@ -275,6 +279,8 @@ public class IpAddressManagerImpl extends ManagerBase 
implements IpAddressManage
     @Inject
     NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
     @Inject
+    VpcOfferingServiceMapDao vpcOfferingServiceMapDao;
+    @Inject
     PhysicalNetworkDao _physicalNetworkDao;
     @Inject
     PhysicalNetworkServiceProviderDao _pNSPDao;
@@ -806,6 +812,30 @@ public class IpAddressManagerImpl extends ManagerBase 
implements IpAddressManage
             } else if (publicIpQuarantine != null) {
                 
removePublicIpAddressFromQuarantine(publicIpQuarantine.getId(), "Public IP 
address removed from quarantine as there was an error while disassociating 
it.");
             }
+            Network network = 
_networksDao.findById(ipToBeDisassociated.getAssociatedWithNetworkId());
+            Vpc vpc = _vpcDao.findById(ip.getVpcId());
+            if (ObjectUtils.allNull(network, vpc)) {
+                return success;
+            }
+            List<String> providers;
+            if (Objects.nonNull(network)) {
+                NetworkOffering offering = 
_networkOfferingDao.findById(network.getNetworkOfferingId());
+                providers = 
_ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(),
 Service.NetworkACL);
+            } else {
+                VpcOffering offering = 
vpcOfferingDao.findById(vpc.getVpcOfferingId());
+                List<VpcOfferingServiceMapVO> servicesMap = 
vpcOfferingServiceMapDao.listProvidersForServiceForVpcOffering(offering.getId(),
 Service.NetworkACL);
+                providers = 
servicesMap.stream().map(VpcOfferingServiceMapVO::getProvider).collect(Collectors.toList());
+            }
+
+            if (providers.isEmpty()) {
+                throw new InvalidParameterValueException("Unable to find the 
provider for this network");
+            }
+
+            String provider = providers.get(0);
+            NetworkElement element = 
_networkModel.getElementImplementingProvider(provider);
+            if (element != null) {
+                element.releaseIp(ipToBeDisassociated);
+            }
         } finally {
             _ipAddressDao.releaseFromLockTable(addrId);
         }
diff --git 
a/server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java 
b/server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java
index 3449f1f5d00..07a40c95b4a 100644
--- 
a/server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java
+++ 
b/server/src/main/java/com/cloud/network/element/ConfigDriveNetworkElement.java
@@ -25,6 +25,7 @@ import java.util.Set;
 
 import javax.inject.Inject;
 
+import com.cloud.network.IpAddress;
 import 
org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
@@ -179,6 +180,11 @@ public class ConfigDriveNetworkElement extends AdapterBase 
implements NetworkEle
         }
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         return true; // assume that the agent will remove userdata etc
diff --git 
a/server/src/main/java/com/cloud/network/element/SecurityGroupElement.java 
b/server/src/main/java/com/cloud/network/element/SecurityGroupElement.java
index 86c862bf072..c2e3317487c 100644
--- a/server/src/main/java/com/cloud/network/element/SecurityGroupElement.java
+++ b/server/src/main/java/com/cloud/network/element/SecurityGroupElement.java
@@ -25,6 +25,7 @@ import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
 import com.cloud.network.Network;
 import com.cloud.network.Network.Capability;
 import com.cloud.network.Network.Provider;
@@ -77,6 +78,11 @@ public class SecurityGroupElement extends AdapterBase 
implements NetworkElement
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
     @Override
     public boolean shutdown(Network network, ReservationContext context, 
boolean cleanup) throws ConcurrentOperationException, 
ResourceUnavailableException {
         return true;
diff --git 
a/server/src/main/java/com/cloud/network/element/VirtualRouterElement.java 
b/server/src/main/java/com/cloud/network/element/VirtualRouterElement.java
index 53cf838ca87..92ee5f76c16 100644
--- a/server/src/main/java/com/cloud/network/element/VirtualRouterElement.java
+++ b/server/src/main/java/com/cloud/network/element/VirtualRouterElement.java
@@ -24,6 +24,7 @@ import java.util.Set;
 
 import javax.inject.Inject;
 
+import com.cloud.network.IpAddress;
 import org.apache.cloudstack.network.BgpPeer;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.ObjectUtils;
@@ -943,6 +944,11 @@ NetworkMigrationResponder, AggregatedCommandExecutor, 
RedundantResource, DnsServ
         return true;
     }
 
+    @Override
+    public boolean releaseIp(IpAddress ipAddress) {
+        return true;
+    }
+
 
     @Override
     public boolean configDhcpSupportForSubnet(final Network network, final 
NicProfile nic, final VirtualMachineProfile vm, final DeployDestination dest,
diff --git 
a/server/src/test/java/com/cloud/vpc/dao/MockVpcOfferingServiceMapDaoImpl.java 
b/server/src/test/java/com/cloud/vpc/dao/MockVpcOfferingServiceMapDaoImpl.java
index 3d45d8e839f..27aba5c013c 100644
--- 
a/server/src/test/java/com/cloud/vpc/dao/MockVpcOfferingServiceMapDaoImpl.java
+++ 
b/server/src/test/java/com/cloud/vpc/dao/MockVpcOfferingServiceMapDaoImpl.java
@@ -68,6 +68,11 @@ public class MockVpcOfferingServiceMapDaoImpl extends 
GenericDaoBase<VpcOffering
         return false;
     }
 
+    @Override
+    public List<VpcOfferingServiceMapVO> 
listProvidersForServiceForVpcOffering(long vpcOfferingId, Service service) {
+        return List.of();
+    }
+
     @Override
     public VpcOfferingServiceMapVO persist(VpcOfferingServiceMapVO vo) {
         return vo;
diff --git 
a/server/src/test/java/org/apache/cloudstack/service/NetrisServiceMockTest.java 
b/server/src/test/java/org/apache/cloudstack/service/NetrisServiceMockTest.java
index b4e4509dc3a..05a6cd20213 100644
--- 
a/server/src/test/java/org/apache/cloudstack/service/NetrisServiceMockTest.java
+++ 
b/server/src/test/java/org/apache/cloudstack/service/NetrisServiceMockTest.java
@@ -86,4 +86,9 @@ public class NetrisServiceMockTest implements NetrisService {
     public boolean deleteStaticRoute(long zoneId, long accountId, long 
domainId, String networkResourceName, Long networkResourceId, boolean isForVpc, 
String prefix, String nextHop, Long routeId) {
         return true;
     }
+
+    @Override
+    public boolean releaseNatIp(long zoneId, String publicIp) {
+        return true;
+    }
 }


Reply via email to