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

pearl11594 pushed a commit to branch fr03-nsx-reorder-acl-rules
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 6a55d1d7fc9fef0413c662863df9bf4d8981b849
Author: Pearl Dsilva <pearl1...@gmail.com>
AuthorDate: Mon Feb 5 23:32:38 2024 -0500

    [WIP] NSX: Add support to re-order ACL rules (NSX FW rules)
---
 .../network/element/NetworkACLServiceProvider.java |  3 ++
 .../com/cloud/network/vpc/NetworkACLManager.java   |  2 +
 .../cloud/network/element/BigSwitchBcfElement.java |  5 +++
 .../management/ContrailVpcElementImpl.java         |  5 +++
 .../org/apache/cloudstack/service/NsxElement.java  | 44 +++++++++++++++-------
 .../network/element/VpcVirtualRouterElement.java   |  5 +++
 .../cloud/network/vpc/NetworkACLManagerImpl.java   | 15 ++++++++
 .../cloud/network/vpc/NetworkACLServiceImpl.java   | 15 +++++++-
 8 files changed, 79 insertions(+), 15 deletions(-)

diff --git 
a/api/src/main/java/com/cloud/network/element/NetworkACLServiceProvider.java 
b/api/src/main/java/com/cloud/network/element/NetworkACLServiceProvider.java
index 8c3243c99f4..92d3519d596 100644
--- a/api/src/main/java/com/cloud/network/element/NetworkACLServiceProvider.java
+++ b/api/src/main/java/com/cloud/network/element/NetworkACLServiceProvider.java
@@ -21,6 +21,7 @@ import java.util.List;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.network.Network;
 import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.Vpc;
 
 public interface NetworkACLServiceProvider extends NetworkElement {
 
@@ -32,4 +33,6 @@ public interface NetworkACLServiceProvider extends 
NetworkElement {
      */
     boolean applyNetworkACLs(Network config, List<? extends NetworkACLItem> 
rules) throws ResourceUnavailableException;
 
+    boolean reorderAclRules(Vpc vpc, List<? extends NetworkACLItem> 
networkACLItems);
+
 }
diff --git 
a/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java
 
b/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java
index 4200ea8c601..9d1caa1c031 100644
--- 
a/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java
+++ 
b/engine/components-api/src/main/java/com/cloud/network/vpc/NetworkACLManager.java
@@ -91,4 +91,6 @@ public interface NetworkACLManager {
     boolean revokeACLItemsForPrivateGw(PrivateGateway gateway) throws 
ResourceUnavailableException;
 
     boolean applyACLToPrivateGw(PrivateGateway gateway) throws 
ResourceUnavailableException;
+
+    boolean reorderAclRules(VpcVO vpc, List<? extends NetworkACLItem> 
networkACLItems);
 }
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 776f76fabca..c4b8de2ed95 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
@@ -700,6 +700,11 @@ NetworkACLServiceProvider, FirewallServiceProvider, 
ResourceStateAdapter {
         return true;
     }
 
+    @Override
+    public boolean reorderAclRules(Vpc vpc, List<? extends NetworkACLItem> 
networkACLItems) {
+        return true;
+    }
+
     @Override
     public boolean applyFWRules(Network network,
             List<? extends FirewallRule> rules)
diff --git 
a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java
 
b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java
index 689b252b2a7..58169f22d7b 100644
--- 
a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java
+++ 
b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java
@@ -185,6 +185,11 @@ public class ContrailVpcElementImpl extends 
ContrailElementImpl implements Netwo
         return true;
     }
 
+    @Override
+    public boolean reorderAclRules(Vpc vpc, List<? extends NetworkACLItem> 
networkACLItems) {
+        return true;
+    }
+
     @Override
     public boolean applyACLItemsToPrivateGw(PrivateGateway privateGateway,
             List<? extends NetworkACLItem> rules)
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 05a7d141a86..99beb099bed 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
@@ -72,6 +72,7 @@ import com.cloud.network.rules.LoadBalancerContainer;
 import com.cloud.network.rules.PortForwardingRule;
 import com.cloud.network.rules.StaticNat;
 import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.NetworkACLItemVO;
 import com.cloud.network.vpc.PrivateGateway;
 import com.cloud.network.vpc.StaticRouteProfile;
 import com.cloud.network.vpc.Vpc;
@@ -97,7 +98,9 @@ import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.VMInstanceDao;
 import net.sf.ehcache.config.InvalidConfigurationException;
+import org.apache.cloudstack.NsxAnswer;
 import org.apache.cloudstack.StartupNsxCommand;
+import 
org.apache.cloudstack.agent.api.DeleteNsxDistributedFirewallRulesCommand;
 import 
org.apache.cloudstack.api.command.admin.internallb.ConfigureInternalLoadBalancerElementCmd;
 import 
org.apache.cloudstack.api.command.admin.internallb.CreateInternalLoadBalancerElementCmd;
 import 
org.apache.cloudstack.api.command.admin.internallb.ListInternalLoadBalancerElementsCmd;
@@ -712,18 +715,7 @@ public class NsxElement extends AdapterBase implements  
DhcpServiceProvider, Dns
         boolean success = true;
         for (NetworkACLItem rule : rules) {
             String privatePort = getPrivatePortRangeForACLRule(rule);
-            NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
-                    .setRuleId(rule.getId())
-                    
.setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ? 
transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY"))
-                    .setAclAction(transformActionValue(rule.getAction()))
-                    .setTrafficType(rule.getTrafficType().toString())
-                    .setProtocol(rule.getProtocol().toUpperCase())
-                    .setPublicPort(String.valueOf(rule.getSourcePortStart()))
-                    .setPrivatePort(privatePort)
-                    .setIcmpCode(rule.getIcmpCode())
-                    .setIcmpType(rule.getIcmpType())
-                    .setService(Network.Service.NetworkACL)
-                    .build();
+            NsxNetworkRule networkRule = getNsxNetworkRuleForAcl(rule, 
privatePort);
             if (Arrays.asList(NetworkACLItem.State.Active, 
NetworkACLItem.State.Add).contains(rule.getState())) {
                 success = success && nsxService.addFirewallRules(network, 
List.of(networkRule));
             } else if (NetworkACLItem.State.Revoke == rule.getState()) {
@@ -740,9 +732,33 @@ public class NsxElement extends AdapterBase implements  
DhcpServiceProvider, Dns
         return success;
     }
 
-    private void reorderRules(List<? extends NetworkACLItem> rules) {
-        rules.sort((Comparator) (r1, r2) -> ((NetworkACLItem) r2).getNumber() 
- ((NetworkACLItem) r1).getNumber());
+    @Override
+    public boolean reorderAclRules(Vpc vpc, List<? extends NetworkACLItem> 
networkACLItems) {
+        List<NsxNetworkRule> aclRulesList = new ArrayList<>();
+        for (NetworkACLItem rule : networkACLItems) {
+            String privatePort = getPrivatePortRangeForACLRule(rule);
+            aclRulesList.add(getNsxNetworkRuleForAcl(rule, privatePort));
+        }
+        DeleteNsxDistributedFirewallRulesCommand command = new 
DeleteNsxDistributedFirewallRulesCommand(vpc.getDomainId(),
+                vpc.getAccountId(), vpc.getZoneId(), vpc.getId(), 
network.getId(), netRules);
+        NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, 
network.getDataCenterId());
+        return result.getResult();
+        return true;
+    }
 
+    private NsxNetworkRule getNsxNetworkRuleForAcl(NetworkACLItem rule, String 
privatePort) {
+        return new NsxNetworkRule.Builder()
+                .setRuleId(rule.getId())
+                .setSourceCidrList(Objects.nonNull(rule.getSourceCidrList()) ? 
transformCidrListValues(rule.getSourceCidrList()) : List.of("ANY"))
+                .setAclAction(transformActionValue(rule.getAction()))
+                .setTrafficType(rule.getTrafficType().toString())
+                .setProtocol(rule.getProtocol().toUpperCase())
+                .setPublicPort(String.valueOf(rule.getSourcePortStart()))
+                .setPrivatePort(privatePort)
+                .setIcmpCode(rule.getIcmpCode())
+                .setIcmpType(rule.getIcmpType())
+                .setService(Network.Service.NetworkACL)
+                .build();
     }
         @Override
     public boolean applyFWRules(Network network, List<? extends FirewallRule> 
rules) throws ResourceUnavailableException {
diff --git 
a/server/src/main/java/com/cloud/network/element/VpcVirtualRouterElement.java 
b/server/src/main/java/com/cloud/network/element/VpcVirtualRouterElement.java
index d740f80bd25..6b79950949d 100644
--- 
a/server/src/main/java/com/cloud/network/element/VpcVirtualRouterElement.java
+++ 
b/server/src/main/java/com/cloud/network/element/VpcVirtualRouterElement.java
@@ -531,6 +531,11 @@ public class VpcVirtualRouterElement extends 
VirtualRouterElement implements Vpc
         return result;
     }
 
+    @Override
+    public boolean reorderAclRules(Vpc vpc, List<? extends NetworkACLItem> 
networkACLItems) {
+        return true;
+    }
+
     @Override
     protected Type getVirtualRouterProvider() {
         return Type.VPCVirtualRouter;
diff --git 
a/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java 
b/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java
index 2e54474772d..16b797fd94f 100644
--- a/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java
+++ b/server/src/main/java/com/cloud/network/vpc/NetworkACLManagerImpl.java
@@ -21,6 +21,7 @@ import java.util.List;
 
 import javax.inject.Inject;
 
+import com.cloud.network.nsx.NsxProvider;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.messagebus.MessageBus;
 import org.apache.cloudstack.framework.messagebus.PublishScope;
@@ -370,6 +371,20 @@ public class NetworkACLManagerImpl extends ManagerBase 
implements NetworkACLMana
         return applyACLToPrivateGw(gateway, rules);
     }
 
+    @Override
+    public boolean reorderAclRules(VpcVO vpc, List<? extends NetworkACLItem> 
networkACLItems) {
+        List<NetworkACLServiceProvider> nsxElements = new ArrayList<>();
+        nsxElements.add((NetworkACLServiceProvider) 
_ntwkModel.getElementImplementingProvider(Network.Provider.Nsx.getName()));
+        try {
+            for (final NetworkACLServiceProvider provider : nsxElements) {
+                return provider.reorderAclRules(networkACLItems);
+            }
+        } catch (final Exception ex) {
+            s_logger.debug("Failed to reorder ACLs on NSX due to: " + 
ex.getLocalizedMessage());
+        }
+        return false;
+    }
+
     private boolean applyACLToPrivateGw(final PrivateGateway gateway, final 
List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
         List<VpcProvider> vpcElements = new ArrayList<VpcProvider>();
         
vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Network.Provider.VPCVirtualRouter.getName()));
diff --git 
a/server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java 
b/server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java
index 59e7d441e69..59b7eb62a2c 100644
--- a/server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java
+++ b/server/src/main/java/com/cloud/network/vpc/NetworkACLServiceImpl.java
@@ -1000,7 +1000,15 @@ public class NetworkACLServiceImpl extends ManagerBase 
implements NetworkACLServ
             if (nextRule == null) {
                 return moveRuleToTheBottom(ruleBeingMoved, allAclRules);
             }
-            return moveRuleBetweenAclRules(ruleBeingMoved, allAclRules, 
previousRule, nextRule);
+            NetworkACLItem networkACLItem = 
moveRuleBetweenAclRules(ruleBeingMoved, allAclRules, previousRule, nextRule);
+            VpcVO vpc = _vpcDao.findById(lockedAcl.getVpcId());
+            final DataCenter dc = _entityMgr.findById(DataCenter.class, 
vpc.getZoneId());
+            final NsxProviderVO nsxProvider = 
nsxProviderDao.findByZoneId(dc.getId());
+            if (Objects.nonNull(nsxProvider)) {
+                allAclRules = getAllAclRulesSortedByNumber(lockedAcl.getId());
+                _networkAclMgr.reorderAclRules(vpc, allAclRules);
+            }
+            return networkACLItem;
         } finally {
             _networkACLDao.releaseFromLockTable(ruleBeingMoved.getAclId());
         }
@@ -1064,6 +1072,11 @@ public class NetworkACLServiceImpl extends ManagerBase 
implements NetworkACLServ
         return allAclRules;
     }
 
+    protected List<NetworkACLItem> getAclRulesSortedByNumber(long aclId) {
+        List<NetworkACLItemVO> allAclRules = 
getAllAclRulesSortedByNumber(aclId);
+        return new ArrayList<>(allAclRules);
+    }
+
     /**
      * Moves an ACL to the space between to other rules. If there is already 
enough room to accommodate the ACL rule being moved, we simply get the 'number' 
field from the previous ACL rule and add one, and then define this new value as 
the 'number' value for the ACL rule being moved.
      * Otherwise, we will need to make room. This process is executed via 
{@link #updateAclRuleToNewPositionAndExecuteShiftIfNecessary(NetworkACLItem, 
int, List, int)}, which will create the space between ACL rules if necessary. 
This involves shifting ACL rules to accommodate the rule being moved.

Reply via email to