You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by pe...@apache.org on 2025/03/05 22:52:00 UTC

(cloudstack) 30/44: Release NAT IP subnet when VPC is removed or IP is released (#44)

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 <pe...@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;
+    }
 }