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

winterhazel pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/main by this push:
     new 236e01aad8d Soft delete port forwarding, load balancing and firewall 
rules (#13015)
236e01aad8d is described below

commit 236e01aad8d75cc84c9c05737984be501ff15d5f
Author: Bernardo De Marco Gonçalves <[email protected]>
AuthorDate: Mon Jun 29 18:21:19 2026 -0300

    Soft delete port forwarding, load balancing and firewall rules (#13015)
---
 .../java/com/cloud/network/LBHealthCheckPolicyVO.java |  8 ++++++++
 .../com/cloud/network/dao/FirewallRulesDaoImpl.java   |  1 +
 .../cloud/network/dao/LBHealthCheckPolicyDaoImpl.java |  6 ++++--
 .../com/cloud/network/dao/LBStickinessPolicyDao.java  |  2 ++
 .../cloud/network/dao/LBStickinessPolicyDaoImpl.java  | 12 ++++++++++--
 .../com/cloud/network/dao/LBStickinessPolicyVO.java   |  8 ++++++++
 .../com/cloud/network/dao/LoadBalancerCertMapVO.java  |  8 ++++++++
 .../cloud/network/dao/LoadBalancerVMMapDaoImpl.java   |  9 ++++++---
 .../com/cloud/network/dao/LoadBalancerVMMapVO.java    |  9 +++++++++
 .../java/com/cloud/network/rules/FirewallRuleVO.java  | 10 ++++++++++
 .../region/gslb/GlobalLoadBalancerRuleVO.java         |  8 ++++++++
 .../resources/META-INF/db/schema-42210to42300.sql     | 19 +++++++++++++++++++
 .../main/java/com/cloud/network/ElasticLbVmMapVO.java |  9 +++++++++
 .../tungsten/dao/TungstenFabricLBHealthMonitorVO.java |  8 ++++++++
 .../network/lb/LoadBalancingRulesManagerImpl.java     | 15 +++++++++++++--
 .../integration/component/test_vpc_network_lbrules.py |  8 ++------
 test/integration/smoke/test_network.py                | 15 ++++-----------
 17 files changed, 129 insertions(+), 26 deletions(-)

diff --git 
a/engine/schema/src/main/java/com/cloud/network/LBHealthCheckPolicyVO.java 
b/engine/schema/src/main/java/com/cloud/network/LBHealthCheckPolicyVO.java
index ee5f67b09cd..23f0b0f15ae 100644
--- a/engine/schema/src/main/java/com/cloud/network/LBHealthCheckPolicyVO.java
+++ b/engine/schema/src/main/java/com/cloud/network/LBHealthCheckPolicyVO.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.network;
 
+import java.util.Date;
 import java.util.UUID;
 
 import javax.persistence.Column;
@@ -25,8 +26,11 @@ import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.PrimaryKeyJoinColumn;
 import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
 
 import com.cloud.network.rules.HealthCheckPolicy;
+import com.cloud.utils.db.GenericDao;
 import 
org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
 
 @Entity
@@ -68,6 +72,10 @@ public class LBHealthCheckPolicyVO implements 
HealthCheckPolicy {
     @Column(name = "display", updatable = true, nullable = false)
     protected boolean display = true;
 
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date removed;
+
     protected LBHealthCheckPolicyVO() {
         this.uuid = UUID.randomUUID().toString();
     }
diff --git 
a/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDaoImpl.java 
b/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDaoImpl.java
index 27bf7ba6aa8..57d53f92572 100644
--- 
a/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDaoImpl.java
+++ 
b/engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDaoImpl.java
@@ -94,6 +94,7 @@ public class FirewallRulesDaoImpl extends 
GenericDaoBase<FirewallRuleVO, Long> i
         ReleaseSearch.and("ipId", 
ReleaseSearch.entity().getSourceIpAddressId(), Op.EQ);
         ReleaseSearch.and("purpose", ReleaseSearch.entity().getPurpose(), 
Op.EQ);
         ReleaseSearch.and("ports", 
ReleaseSearch.entity().getSourcePortStart(), Op.IN);
+        ReleaseSearch.and("removed", ReleaseSearch.entity().getRemoved(), 
Op.NULL);
         ReleaseSearch.done();
 
         SystemRuleSearch = createSearchBuilder();
diff --git 
a/engine/schema/src/main/java/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java
 
b/engine/schema/src/main/java/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java
index 45927f3c377..a9b4e02ba87 100644
--- 
a/engine/schema/src/main/java/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java
+++ 
b/engine/schema/src/main/java/com/cloud/network/dao/LBHealthCheckPolicyDaoImpl.java
@@ -32,8 +32,9 @@ public class LBHealthCheckPolicyDaoImpl extends 
GenericDaoBase<LBHealthCheckPoli
     public void remove(long loadBalancerId) {
         SearchCriteria<LBHealthCheckPolicyVO> sc = createSearchCriteria();
         sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
+        sc.addAnd("removed", SearchCriteria.Op.NULL);
 
-        expunge(sc);
+        remove(sc);
     }
 
     @Override
@@ -41,8 +42,9 @@ public class LBHealthCheckPolicyDaoImpl extends 
GenericDaoBase<LBHealthCheckPoli
         SearchCriteria<LBHealthCheckPolicyVO> sc = createSearchCriteria();
         sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
         sc.addAnd("revoke", SearchCriteria.Op.EQ, revoke);
+        sc.addAnd("removed", SearchCriteria.Op.NULL);
 
-        expunge(sc);
+        remove(sc);
     }
 
     @Override
diff --git 
a/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDao.java 
b/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDao.java
index 6669d70824a..03fadbbd659 100644
--- 
a/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDao.java
+++ 
b/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDao.java
@@ -28,4 +28,6 @@ public interface LBStickinessPolicyDao extends 
GenericDao<LBStickinessPolicyVO,
     List<LBStickinessPolicyVO> listByLoadBalancerIdAndDisplayFlag(long 
loadBalancerId, boolean forDisplay);
 
     List<LBStickinessPolicyVO> listByLoadBalancerId(long loadBalancerId, 
boolean revoke);
+
+    List<LBStickinessPolicyVO> listByLoadBalancerId(long loadBalancerId);
 }
diff --git 
a/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java
 
b/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java
index 717458fdb99..86fd908b6b7 100644
--- 
a/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java
+++ 
b/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyDaoImpl.java
@@ -31,8 +31,9 @@ public class LBStickinessPolicyDaoImpl extends 
GenericDaoBase<LBStickinessPolicy
     public void remove(long loadBalancerId) {
         SearchCriteria<LBStickinessPolicyVO> sc = createSearchCriteria();
         sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
+        sc.addAnd("removed", SearchCriteria.Op.NULL);
 
-        expunge(sc);
+        remove(sc);
     }
 
     @Override
@@ -40,8 +41,9 @@ public class LBStickinessPolicyDaoImpl extends 
GenericDaoBase<LBStickinessPolicy
         SearchCriteria<LBStickinessPolicyVO> sc = createSearchCriteria();
         sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
         sc.addAnd("revoke", SearchCriteria.Op.EQ, revoke);
+        sc.addAnd("removed", SearchCriteria.Op.NULL);
 
-        expunge(sc);
+        remove(sc);
     }
 
     @Override
@@ -62,4 +64,10 @@ public class LBStickinessPolicyDaoImpl extends 
GenericDaoBase<LBStickinessPolicy
         return listBy(sc);
     }
 
+    @Override
+    public List<LBStickinessPolicyVO> listByLoadBalancerId(long 
loadBalancerId) {
+        SearchCriteria<LBStickinessPolicyVO> sc = createSearchCriteria();
+        sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
+        return listBy(sc);
+    }
 }
diff --git 
a/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyVO.java 
b/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyVO.java
index 72b8fc151b7..ae658f0757f 100644
--- 
a/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyVO.java
+++ 
b/engine/schema/src/main/java/com/cloud/network/dao/LBStickinessPolicyVO.java
@@ -17,6 +17,7 @@
 package com.cloud.network.dao;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -30,9 +31,12 @@ import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.PrimaryKeyJoinColumn;
 import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
 
 import com.cloud.network.rules.StickinessPolicy;
 import com.cloud.utils.Pair;
+import com.cloud.utils.db.GenericDao;
 import 
org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
 
 @Entity
@@ -68,6 +72,10 @@ public class LBStickinessPolicyVO implements 
StickinessPolicy {
     @Column(name = "display", updatable = true, nullable = false)
     protected boolean display = true;
 
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date removed;
+
     protected LBStickinessPolicyVO() {
         this.uuid = UUID.randomUUID().toString();
     }
diff --git 
a/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerCertMapVO.java 
b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerCertMapVO.java
index f95c61733f2..7fbe58df930 100644
--- 
a/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerCertMapVO.java
+++ 
b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerCertMapVO.java
@@ -16,13 +16,17 @@
 // under the License.
 package com.cloud.network.dao;
 
+import java.util.Date;
 import java.util.UUID;
 
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
 
+import com.cloud.utils.db.GenericDao;
 import org.apache.cloudstack.api.InternalIdentity;
 
 @Entity
@@ -45,6 +49,10 @@ public class LoadBalancerCertMapVO implements 
InternalIdentity {
     @Column(name = "revoke")
     private boolean revoke = false;
 
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date removed;
+
     public LoadBalancerCertMapVO() {
         this.uuid = UUID.randomUUID().toString();
     }
diff --git 
a/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java
 
b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java
index dc37cdeefe3..03a1e45d917 100644
--- 
a/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java
+++ 
b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java
@@ -34,8 +34,9 @@ public class LoadBalancerVMMapDaoImpl extends 
GenericDaoBase<LoadBalancerVMMapVO
     public void remove(long loadBalancerId) {
         SearchCriteria<LoadBalancerVMMapVO> sc = createSearchCriteria();
         sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
+        sc.addAnd("removed", SearchCriteria.Op.NULL);
 
-        expunge(sc);
+        remove(sc);
     }
 
     @Override
@@ -43,11 +44,12 @@ public class LoadBalancerVMMapDaoImpl extends 
GenericDaoBase<LoadBalancerVMMapVO
         SearchCriteria<LoadBalancerVMMapVO> sc = createSearchCriteria();
         sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
         sc.addAnd("instanceId", SearchCriteria.Op.IN, instanceIds.toArray());
+        sc.addAnd("removed", SearchCriteria.Op.NULL);
         if (revoke != null) {
             sc.addAnd("revoke", SearchCriteria.Op.EQ, revoke);
         }
 
-        expunge(sc);
+        remove(sc);
     }
 
     @Override
@@ -56,12 +58,13 @@ public class LoadBalancerVMMapDaoImpl extends 
GenericDaoBase<LoadBalancerVMMapVO
         sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
         sc.addAnd("instanceId", SearchCriteria.Op.IN, instanceId);
         sc.addAnd("instanceIp", SearchCriteria.Op.EQ, instanceIp);
+        sc.addAnd("removed", SearchCriteria.Op.NULL);
 
         if (revoke != null) {
             sc.addAnd("revoke", SearchCriteria.Op.EQ, revoke);
         }
 
-        expunge(sc);
+        remove(sc);
     }
 
 
diff --git 
a/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapVO.java 
b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapVO.java
index 721349613d8..2c88bf9c5a6 100644
--- a/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapVO.java
+++ b/engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerVMMapVO.java
@@ -22,9 +22,14 @@ import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
 
+import com.cloud.utils.db.GenericDao;
 import org.apache.cloudstack.api.InternalIdentity;
 
+import java.util.Date;
+
 @Entity
 @Table(name = "load_balancer_vm_map")
 public class LoadBalancerVMMapVO implements InternalIdentity {
@@ -48,6 +53,10 @@ public class LoadBalancerVMMapVO implements InternalIdentity 
{
     @Column(name = "state")
     private String state;
 
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date removed = null;
+
     public LoadBalancerVMMapVO() {
     }
 
diff --git 
a/engine/schema/src/main/java/com/cloud/network/rules/FirewallRuleVO.java 
b/engine/schema/src/main/java/com/cloud/network/rules/FirewallRuleVO.java
index 1dfdc5093a5..6ce9e6a118b 100644
--- a/engine/schema/src/main/java/com/cloud/network/rules/FirewallRuleVO.java
+++ b/engine/schema/src/main/java/com/cloud/network/rules/FirewallRuleVO.java
@@ -32,6 +32,8 @@ import javax.persistence.Id;
 import javax.persistence.Inheritance;
 import javax.persistence.InheritanceType;
 import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
 import javax.persistence.Transient;
 
 import com.cloud.utils.db.GenericDao;
@@ -82,6 +84,10 @@ public class FirewallRuleVO implements FirewallRule {
     @Column(name = GenericDao.CREATED_COLUMN)
     Date created;
 
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date removed;
+
     @Column(name = "network_id")
     Long networkId;
 
@@ -203,6 +209,10 @@ public class FirewallRuleVO implements FirewallRule {
         return created;
     }
 
+    public Date getRemoved() {
+        return removed;
+    }
+
     protected FirewallRuleVO() {
         uuid = UUID.randomUUID().toString();
     }
diff --git 
a/engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java
 
b/engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java
index 4ce7033156f..47e2d130d87 100644
--- 
a/engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java
+++ 
b/engine/schema/src/main/java/org/apache/cloudstack/region/gslb/GlobalLoadBalancerRuleVO.java
@@ -17,6 +17,7 @@
 
 package org.apache.cloudstack.region.gslb;
 
+import java.util.Date;
 import java.util.UUID;
 
 import javax.persistence.Column;
@@ -27,8 +28,11 @@ import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
 
 import com.cloud.region.ha.GlobalLoadBalancerRule;
+import com.cloud.utils.db.GenericDao;
 import 
org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
 
 @Entity
@@ -74,6 +78,10 @@ public class GlobalLoadBalancerRuleVO implements 
GlobalLoadBalancerRule {
     @Column(name = "state")
     GlobalLoadBalancerRule.State state;
 
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date removed;
+
     public GlobalLoadBalancerRuleVO() {
         uuid = UUID.randomUUID().toString();
     }
diff --git 
a/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql 
b/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql
index 69e2d4b484f..c2349c06936 100644
--- a/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql
+++ b/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql
@@ -288,3 +288,22 @@ WHERE rule = 'quotaStatement' AND NOT EXISTS(SELECT 1 FROM 
cloud.role_permission
 
 -- Add description for secondary IP addresses
 CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.nic_secondary_ips', 'description', 
'VARCHAR(2048) DEFAULT NULL');
+
+-- Soft delete port forwarding, load balancing and firewall rules
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.firewall_rules', 'removed', 
'datetime DEFAULT NULL');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.load_balancer_vm_map', 'removed', 
'datetime DEFAULT NULL');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.load_balancer_cert_map', 
'removed', 'datetime DEFAULT NULL');
+CALL 
`cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.load_balancer_healthcheck_policies', 
'removed', 'datetime DEFAULT NULL');
+CALL 
`cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.load_balancer_stickiness_policies', 
'removed', 'datetime DEFAULT NULL');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.global_load_balancer_lb_rule_map', 
'removed', 'datetime DEFAULT NULL');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.elastic_lb_vm_map', 'removed', 
'datetime DEFAULT NULL');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.tungsten_lb_health_monitor', 
'removed', 'datetime DEFAULT NULL');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.global_load_balancing_rules', 
'removed', 'datetime DEFAULT NULL');
+
+ALTER TABLE `cloud`.`load_balancer_vm_map`
+DROP KEY `load_balancer_id`,
+ADD UNIQUE KEY `load_balancer_id` (`load_balancer_id`, `instance_id`, 
`instance_ip`, `removed`);
+
+ALTER TABLE `cloud`.`global_load_balancer_lb_rule_map`
+DROP KEY `gslb_rule_id`,
+ADD UNIQUE KEY `gslb_rule_id` (`gslb_rule_id`, `lb_rule_id`, `removed`);
diff --git 
a/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/ElasticLbVmMapVO.java
 
b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/ElasticLbVmMapVO.java
index 96a43dfb19e..f4fa1cb776a 100644
--- 
a/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/ElasticLbVmMapVO.java
+++ 
b/plugins/network-elements/elastic-loadbalancer/src/main/java/com/cloud/network/ElasticLbVmMapVO.java
@@ -27,11 +27,16 @@ import javax.persistence.PrimaryKeyJoinColumn;
 import javax.persistence.SecondaryTable;
 import javax.persistence.SecondaryTables;
 import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
 
+import com.cloud.utils.db.GenericDao;
 import org.apache.cloudstack.api.InternalIdentity;
 
 import com.cloud.utils.net.Ip;
 
+import java.util.Date;
+
 @Entity
 @Table(name = "elastic_lb_vm_map")
 @SecondaryTables({@SecondaryTable(name = "user_ip_address", pkJoinColumns = 
{@PrimaryKeyJoinColumn(name = "ip_addr_id", referencedColumnName = "id")})})
@@ -57,6 +62,10 @@ public class ElasticLbVmMapVO implements InternalIdentity {
     @Enumerated(value = EnumType.STRING)
     private Ip address = null;
 
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date removed;
+
     public ElasticLbVmMapVO() {
     }
 
diff --git 
a/plugins/network-elements/tungsten/src/main/java/org/apache/cloudstack/network/tungsten/dao/TungstenFabricLBHealthMonitorVO.java
 
b/plugins/network-elements/tungsten/src/main/java/org/apache/cloudstack/network/tungsten/dao/TungstenFabricLBHealthMonitorVO.java
index e7b93798942..70263f9cc41 100644
--- 
a/plugins/network-elements/tungsten/src/main/java/org/apache/cloudstack/network/tungsten/dao/TungstenFabricLBHealthMonitorVO.java
+++ 
b/plugins/network-elements/tungsten/src/main/java/org/apache/cloudstack/network/tungsten/dao/TungstenFabricLBHealthMonitorVO.java
@@ -16,9 +16,11 @@
 // under the License.
 package org.apache.cloudstack.network.tungsten.dao;
 
+import com.cloud.utils.db.GenericDao;
 import org.apache.cloudstack.api.Identity;
 import org.apache.cloudstack.api.InternalIdentity;
 
+import java.util.Date;
 import java.util.UUID;
 
 import javax.persistence.Column;
@@ -28,6 +30,8 @@ import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.PrimaryKeyJoinColumn;
 import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
 
 @Entity
 @Table(name = "tungsten_lb_health_monitor")
@@ -66,6 +70,10 @@ public class TungstenFabricLBHealthMonitorVO implements 
InternalIdentity, Identi
     @Column(name = "url_path")
     private String urlPath;
 
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    @Temporal(value = TemporalType.TIMESTAMP)
+    private Date removed = null;
+
     public TungstenFabricLBHealthMonitorVO() {
         this.uuid = UUID.randomUUID().toString();
     }
diff --git 
a/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java 
b/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
index 5f00261f329..37c219b750d 100644
--- 
a/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ 
b/server/src/main/java/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@ -862,7 +862,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends 
ManagerBase implements
                 success = false;
             }
         } else {
-            _lb2stickinesspoliciesDao.expunge(stickinessPolicyId);
+            _lb2stickinesspoliciesDao.remove(stickinessPolicyId);
         }
         return success;
     }
@@ -1664,6 +1664,12 @@ public class LoadBalancingRulesManagerImpl<Type> extends 
ManagerBase implements
                     _lb2healthcheckDao.persist(lbHealthCheck);
                 }
 
+                List<LBStickinessPolicyVO> stickinessPolicies = 
_lb2stickinesspoliciesDao.listByLoadBalancerId(loadBalancerId);
+                for (LBStickinessPolicyVO stickinessPolicy : 
stickinessPolicies) {
+                    stickinessPolicy.setRevoke(true);
+                    _lb2stickinesspoliciesDao.persist(stickinessPolicy);
+                }
+
                 if (generateUsageEvent) {
                     // Generate usage event right after all rules were marked 
for revoke
                     Network network = 
_networkModel.getNetwork(lb.getNetworkId());
@@ -2678,7 +2684,12 @@ public class LoadBalancingRulesManagerImpl<Type> extends 
ManagerBase implements
 
     @Override
     public void removeLBRule(LoadBalancer rule) {
-        // remove the rule
+        FirewallRule relatedFirewallRule = 
_firewallDao.findByRelatedId(rule.getId());
+        if (relatedFirewallRule != null) {
+            logger.debug("Load balancer [{}] has a related firewall rule [{}]. 
Removing it.", rule.getUuid(), relatedFirewallRule.getUuid());
+            _firewallDao.remove(relatedFirewallRule.getId());
+        }
+
         _lbDao.remove(rule.getId());
     }
 
diff --git a/test/integration/component/test_vpc_network_lbrules.py 
b/test/integration/component/test_vpc_network_lbrules.py
index 8f137adf78d..395f5876099 100644
--- a/test/integration/component/test_vpc_network_lbrules.py
+++ b/test/integration/component/test_vpc_network_lbrules.py
@@ -939,10 +939,6 @@ class TestVPCNetworkLBRules(cloudstackTestCase):
         lb_rule = self.create_LB_Rule(public_ip_1, network_1, [vm_2, vm_1])
         public_ip_1.delete(self.apiclient)
         self.cleanup.remove(public_ip_1)
-
-        with self.assertRaises(Exception):
-            lb_rules = LoadBalancerRule.list(self.apiclient,
-                                        id=lb_rule.id,
-                                        listall=True
-                                        )
+        lb_rule_after_deletion = LoadBalancerRule.list(self.apiclient, 
id=lb_rule.id, listall=True)
+        self.assertEqual(lb_rule_after_deletion, None, 'Load balancer rule 
should be deleted.')
         return
diff --git a/test/integration/smoke/test_network.py 
b/test/integration/smoke/test_network.py
index b3e7fd3e42f..3a0db0feafe 100644
--- a/test/integration/smoke/test_network.py
+++ b/test/integration/smoke/test_network.py
@@ -470,10 +470,8 @@ class TestPortForwarding(cloudstackTestCase):
         except Exception as e:
             self.fail("NAT Rule Deletion Failed: %s" % e)
 
-        # NAT rule listing should fail as the nat rule does not exist
-        with self.assertRaises(Exception):
-            list_nat_rules(self.apiclient,
-                           id=nat_rule.id)
+        nat_rules_after_deletion = list_nat_rules(self.apiclient, 
id=nat_rule.id)
+        self.assertEqual(nat_rules_after_deletion, None, "Check that the port 
forwarding rule has been deleted.")
 
         # Check if the Public SSH port is inaccessible
         with self.assertRaises(Exception):
@@ -585,13 +583,8 @@ class TestPortForwarding(cloudstackTestCase):
 
         nat_rule.delete(self.apiclient)
 
-        try:
-            list_nat_rule_response = list_nat_rules(
-                self.apiclient,
-                id=nat_rule.id
-            )
-        except CloudstackAPIException:
-            logger.debug("Nat Rule is deleted")
+        nat_rules_after_deletion = list_nat_rules(self.apiclient, 
id=nat_rule.id)
+        self.assertEqual(nat_rules_after_deletion, None, "Check that the port 
forwarding rule has been deleted.")
 
         # Check if the Public SSH port is inaccessible
         with self.assertRaises(Exception):

Reply via email to