cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pran...@apache.org
Subject [37/56] [abbrv] CLOUDSTACK-763: Added replaceNetworkACLList API. Added support for ACL action allow/deny and also number
Date Tue, 14 May 2013 11:22:12 GMT
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2449cfc/server/src/com/cloud/network/vpc/NetworkACLItemVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/NetworkACLItemVO.java b/server/src/com/cloud/network/vpc/NetworkACLItemVO.java
new file mode 100644
index 0000000..9b24631
--- /dev/null
+++ b/server/src/com/cloud/network/vpc/NetworkACLItemVO.java
@@ -0,0 +1,198 @@
+// 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 com.cloud.network.vpc;
+
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.net.NetUtils;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+@Entity
+@Table(name="network_acl_item")
+public class NetworkACLItemVO implements NetworkACLItem {
+
+    @Id
+    @GeneratedValue(strategy=GenerationType.IDENTITY)
+    @Column(name="id")
+    long id;
+
+    @Column(name="start_port", updatable=false)
+    Integer sourcePortStart;
+
+    @Column(name="end_port", updatable=false)
+    Integer sourcePortEnd;
+
+    @Column(name="protocol", updatable=false)
+    String protocol = NetUtils.TCP_PROTO;
+
+    @Enumerated(value=EnumType.STRING)
+    @Column(name="state")
+    State state;
+
+    @Column(name=GenericDao.CREATED_COLUMN)
+    Date created;
+
+    @Column(name="acl_id")
+    Long ACLId;
+
+    @Column(name="icmp_code")
+    Integer icmpCode;
+
+    @Column(name="icmp_type")
+    Integer icmpType;
+
+    @Column(name="type")
+    @Enumerated(value=EnumType.STRING)
+    NetworkACLType type;
+
+    @Column(name="traffic_type")
+    @Enumerated(value=EnumType.STRING)
+    TrafficType trafficType;
+
+
+    // This is a delayed load value.  If the value is null,
+    // then this field has not been loaded yet.
+    // Call firewallrules dao to load it.
+    @Transient
+    List<String> sourceCidrs;
+
+    @Column(name="uuid")
+    String uuid;
+
+    public void setSourceCidrList(List<String> sourceCidrs) {
+        this.sourceCidrs=sourceCidrs;
+    }
+
+    @Override
+    public List<String> getSourceCidrList() {
+        return sourceCidrs;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public Integer getSourcePortStart() {
+        return sourcePortStart;
+    }
+
+    @Override
+    public Integer getSourcePortEnd() {
+        return sourcePortEnd;
+    }
+
+    @Override
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setState(State state) {
+        this.state = state;
+    }
+
+    @Override
+    public State getState() {
+        return state;
+    }
+
+    @Override
+    public long getACLId() {
+        return ACLId;
+    }
+
+    @Override
+    public NetworkACLType getType() {
+        return type;
+    }
+    public Date getCreated() {
+        return created;
+    }
+
+    protected NetworkACLItemVO() {
+        this.uuid = UUID.randomUUID().toString();
+    }
+
+    public NetworkACLItemVO(Integer portStart, Integer portEnd, String protocol,
+                            long aclId, List<String> sourceCidrs, Integer icmpCode,
+                            Integer icmpType, TrafficType trafficType) {
+        this.sourcePortStart = portStart;
+        this.sourcePortEnd = portEnd;
+        this.protocol = protocol;
+        this.ACLId = aclId;
+        this.state = State.Staged;
+        this.icmpCode = icmpCode;
+        this.icmpType = icmpType;
+        this.sourceCidrs = sourceCidrs;
+        this.uuid = UUID.randomUUID().toString();
+        this.type = NetworkACLType.User;
+        this.trafficType = trafficType;
+    }
+
+
+    public NetworkACLItemVO(int port, String protocol, long aclId, List<String> sourceCidrs,
Integer icmpCode, Integer icmpType) {
+        this(port, port, protocol, aclId, sourceCidrs, icmpCode, icmpType, null);
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder("Rule[").append(id).append("-").append("NetworkACL").append("-").append(state).append("]").toString();
+    }
+
+    @Override
+    public Integer getIcmpCode() {
+        return icmpCode;
+    }
+
+    @Override
+    public Integer getIcmpType() {
+        return icmpType;
+    }
+
+    @Override
+    public String getUuid() {
+        return this.uuid;
+    }
+
+    @Override
+    public Action getAction() {
+        return null;  //To change body of implemented methods use File | Settings | File
Templates.
+    }
+
+    @Override
+    public int getNumber() {
+        return 0;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public void setType(NetworkACLType type) {
+        this.type = type;
+    }
+
+    @Override
+    public TrafficType getTrafficType() {
+        return trafficType;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2449cfc/server/src/com/cloud/network/vpc/NetworkACLManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/NetworkACLManager.java b/server/src/com/cloud/network/vpc/NetworkACLManager.java
index 515c251..dba91b2 100644
--- a/server/src/com/cloud/network/vpc/NetworkACLManager.java
+++ b/server/src/com/cloud/network/vpc/NetworkACLManager.java
@@ -22,6 +22,7 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.network.firewall.NetworkACLService;
 import com.cloud.network.rules.FirewallRule;
 import com.cloud.user.Account;
+import com.cloud.utils.db.DB;
 import org.apache.cloudstack.api.command.user.network.CreateNetworkACLListCmd;
 
 
@@ -34,8 +35,12 @@ public interface NetworkACLManager extends NetworkACLService{
      * @return
      * @throws ResourceUnavailableException
      */
-    boolean revokeAllNetworkACLsForNetwork(long networkId, long userId, Account caller) throws
ResourceUnavailableException;
+    boolean revokeACLItemsForNetwork(long networkId, long userId, Account caller) throws
ResourceUnavailableException;
     
-    List<? extends FirewallRule> listNetworkACLs(long guestNtwkId);
+    List<NetworkACLItemVO> listNetworkACLItems(long guestNtwkId);
 
+    boolean applyNetworkACL(long networkId, Account caller) throws ResourceUnavailableException;
+
+    @DB
+    void revokeRule(NetworkACLItemVO rule, Account caller, long userId, boolean needUsageEvent);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2449cfc/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
index b00f8a1..a345cc6 100644
--- a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
@@ -24,7 +24,12 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.element.NetworkACLServiceProvider;
 import com.cloud.network.vpc.dao.NetworkACLDao;
+import com.cloud.network.vpc.NetworkACLItem.State;
+import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
 import org.apache.cloudstack.api.command.user.network.CreateNetworkACLListCmd;
 import org.apache.cloudstack.api.command.user.network.ListNetworkACLListsCmd;
 import org.apache.cloudstack.api.command.user.network.ListNetworkACLsCmd;
@@ -42,13 +47,7 @@ import com.cloud.network.Network.Capability;
 import com.cloud.network.Network.Service;
 import com.cloud.network.NetworkModel;
 import com.cloud.network.Networks;
-import com.cloud.network.dao.FirewallRulesDao;
 import com.cloud.network.firewall.NetworkACLService;
-import com.cloud.network.rules.FirewallManager;
-import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.FirewallRule.Purpose;
-import com.cloud.network.rules.FirewallRule.TrafficType;
-import com.cloud.network.rules.FirewallRuleVO;
 import com.cloud.projects.Project.ListProjectResourcesCriteria;
 import com.cloud.server.ResourceTag.TaggedResourceType;
 import com.cloud.tags.ResourceTagVO;
@@ -79,10 +78,6 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
     @Inject
     AccountManager _accountMgr;
     @Inject
-    FirewallManager _firewallMgr;
-    @Inject
-    FirewallRulesDao _firewallDao;
-    @Inject
     NetworkModel _networkMgr;
     @Inject
     VpcManager _vpcMgr;
@@ -90,51 +85,128 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
     ResourceTagDao _resourceTagDao;
     @Inject
     NetworkACLDao _networkACLDao;
+    @Inject
+    NetworkACLItemDao _networkACLItemDao;
+    @Inject
+    List<NetworkACLServiceProvider> _networkAclElements;
+    @Inject
+    NetworkModel _networkModel;
+    @Inject
+    NetworkDao _networkDao;
+
+
+    @Override
+    public boolean revokeACLItemsForNetwork(long networkId, long userId, Account caller)
throws ResourceUnavailableException {
+        Network network = _networkDao.findById(networkId);
+        List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(network.getNetworkACLId());
+        if (aclItems.isEmpty()) {
+            s_logger.debug("Found no network ACL Items for network id=" + networkId);
+            return true;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + aclItems.size() + " Network ACL Items for network
id=" + networkId);
+        }
+
+        for (NetworkACLItemVO aclItem : aclItems) {
+            // Mark all Network ACLs rules as Revoke, but don't revoke them yet - we have
to revoke all rules for ip, no
+            // need to send them one by one
+            revokeNetworkACLItem(aclItem.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
+        }
+
+        //List<NetworkACLItemVO> ACLsToRevoke = _networkACLItemDao.listByNetwork(networkId);
+
+        // now send everything to the backend
+        boolean success = applyNetworkACL(network.getNetworkACLId(), caller);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Successfully released Network ACLs for network id=" + networkId
+ " and # of rules now = "
+                    + aclItems.size());
+        }
+
+        return success;
+    }
+
+    @Override
+    public List<NetworkACLItemVO> listNetworkACLItems(long guestNtwkId) {
+        Network network = _networkMgr.getNetwork(guestNtwkId);
+        return _networkACLItemDao.listByACL(network.getNetworkACLId());
+    }
 
     @Override
-    public boolean applyNetworkACLs(long networkId, Account caller) throws ResourceUnavailableException
{
-        List<FirewallRuleVO> rules = _firewallDao.listByNetworkAndPurpose(networkId,
Purpose.NetworkACL);
-        return _firewallMgr.applyFirewallRules(rules, false, caller);
+    public NetworkACLItem getNetworkACLItem(long ruleId) {
+        return _networkACLItemDao.findById(ruleId);
     }
 
     @Override
-    public FirewallRule createNetworkACLItem(FirewallRule acl) throws NetworkRuleConflictException
{
-        if (acl.getSourceCidrList() == null && (acl.getPurpose() == Purpose.Firewall
|| acl.getPurpose() == Purpose.NetworkACL)) {
-            _firewallDao.loadSourceCidrs((FirewallRuleVO)acl);
+    public boolean applyNetworkACLtoNetworks(long aclId, Account caller) throws ResourceUnavailableException
{
+        boolean handled = false;
+        List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(aclId);
+        //Find all networks using this ACL
+        List<NetworkVO> networks = _networkDao.listByAclId(aclId);
+        for(NetworkVO network : networks){
+            applyNetworkACL(network.getId(), caller);
         }
-        return createNetworkACL(UserContext.current().getCaller(), acl.getXid(), acl.getSourcePortStart(),

-                acl.getSourcePortEnd(), acl.getProtocol(), acl.getSourceCidrList(), acl.getIcmpCode(),
-                acl.getIcmpType(), null, acl.getType(), acl.getNetworkId(), acl.getTrafficType());
+        return handled;
     }
 
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating
firewall rule", create = true)
-    protected FirewallRule createNetworkACL(Account caller, String xId, Integer portStart,

-            Integer portEnd, String protocol, List<String> sourceCidrList, Integer
icmpCode, Integer icmpType,
-            Long relatedRuleId, FirewallRule.FirewallRuleType type, long networkId, TrafficType
trafficType) throws NetworkRuleConflictException {
-        
-        Network network = _networkMgr.getNetwork(networkId);
-        if (network == null) {
-            throw new InvalidParameterValueException("Can't find network by id");
+    @Override
+    public boolean applyNetworkACL(long networkId, Account caller) throws ResourceUnavailableException
{
+        Network network = _networkDao.findById(networkId);
+        boolean handled = false;
+        List<NetworkACLItemVO> rules = _networkACLItemDao.listByACL(network.getNetworkACLId());
+        for (NetworkACLServiceProvider element: _networkAclElements) {
+            Network.Provider provider = element.getProvider();
+            boolean  isAclProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(),
Service.NetworkACL, provider);
+            if (!isAclProvider) {
+                continue;
+            }
+            handled = element.applyNetworkACLs(network, rules);
+            if (handled)
+                break;
+        }
+        return handled;
+    }
+
+    @Override
+    public NetworkACLItem createNetworkACLItem(CreateNetworkACLCmd aclItemCmd) throws NetworkRuleConflictException
{
+        if (aclItemCmd.getSourceCidrList() == null) {
+            //_networkACLItemDao.loadSourceCidrs(aclItemCmd);
         }
-        
-        if (network.getVpcId() == null) {
-            throw new UnsupportedOperationException("Network ACL rules are supported just
for VPC networks");
+        return createNetworkACLItem(UserContext.current().getCaller(), aclItemCmd.getSourcePortStart(),
+                aclItemCmd.getSourcePortEnd(), aclItemCmd.getProtocol(), aclItemCmd.getSourceCidrList(),
aclItemCmd.getIcmpCode(),
+                aclItemCmd.getIcmpType(), null, aclItemCmd.getType(), aclItemCmd.getNetworkId(),
aclItemCmd.getTrafficType(), aclItemCmd.getACLId());
+    }
+
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_ITEM_CREATE, eventDescription =
"creating network ACL Item", create = true)
+    protected NetworkACLItem createNetworkACLItem(Account caller, Integer portStart, Integer
portEnd, String protocol, List<String> sourceCidrList,
+                                                  Integer icmpCode, Integer icmpType, Long
relatedRuleId, NetworkACLItem.NetworkACLType type,
+                                                  Long networkId, NetworkACLItem.TrafficType
trafficType, Long aclId) throws NetworkRuleConflictException {
+
+        if(aclId == null){
+            Network network = _networkMgr.getNetwork(networkId);
+            if (network == null) {
+                throw new InvalidParameterValueException("Can't find network by id");
+            }
+            aclId = network.getNetworkACLId();
+
+            if (aclId == null) {
+                throw new InvalidParameterValueException("Network is not associated with
any ACL");
+            }
         }
-        
-        Vpc vpc = _vpcMgr.getVpc(network.getVpcId());
+
+        NetworkACL networkACL = _networkACLDao.findById(aclId);
+
+        Vpc vpc = _vpcMgr.getVpc(networkACL.getVpcId());
         Account aclOwner = _accountMgr.getAccount(vpc.getAccountId());
-        
+
         //check if the caller can access vpc
         _accountMgr.checkAccess(caller, null, false, vpc);
 
         //check if the acl can be created for this network
-        _accountMgr.checkAccess(aclOwner, AccessType.UseNetwork, false, network);
-        
-        if (!_networkMgr.areServicesSupportedInNetwork(networkId, Service.NetworkACL)) {
-            throw new InvalidParameterValueException("Service " + Service.NetworkACL + "
is not supported in network " + network);
-        }
-        
+        _accountMgr.checkAccess(aclOwner, AccessType.ModifyEntry, false, networkACL);
+
         // icmp code and icmp type can't be passed in for any other protocol rather than
icmp
         if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null
|| icmpType != null)) {
             throw new InvalidParameterValueException("Can specify icmpCode and icmpType for
ICMP protocol only");
@@ -142,8 +214,8 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
 
         if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (portStart != null
|| portEnd != null)) {
             throw new InvalidParameterValueException("Can't specify start/end port when protocol
is ICMP");
-        } 
-        
+        }
+
         //validate icmp code and type
         if (icmpType != null) {
             if (icmpType.longValue() != -1 && !NetUtils.validateIcmpType(icmpType.longValue()))
{
@@ -157,35 +229,33 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
             }
         }
 
-        validateNetworkACL(caller, network, portStart, portEnd, protocol);
+        validateNetworkACLItem(caller, portStart, portEnd, protocol);
 
         Transaction txn = Transaction.currentTxn();
         txn.start();
 
-        FirewallRuleVO newRule = new FirewallRuleVO(xId, null, portStart, portEnd, protocol.toLowerCase(),
networkId,
-                aclOwner.getAccountId(), aclOwner.getDomainId(), Purpose.NetworkACL, sourceCidrList,
icmpCode, icmpType, 
-                relatedRuleId, trafficType);
+        NetworkACLItemVO newRule = new NetworkACLItemVO(portStart, portEnd, protocol.toLowerCase(),
aclId, sourceCidrList, icmpCode, icmpType, trafficType);
         newRule.setType(type);
-        newRule = _firewallDao.persist(newRule);
+        newRule = _networkACLItemDao.persist(newRule);
 
-        if (type == FirewallRule.FirewallRuleType.User) {
-            detectNetworkACLConflict(newRule);
+        if (type == NetworkACLItem.NetworkACLType.User) {
+            //ToDo: Is this required now with??
+            //detectNetworkACLConflict(newRule);
         }
 
-        if (!_firewallDao.setStateToAdd(newRule)) {
+        if (!_networkACLItemDao.setStateToAdd(newRule)) {
             throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
         }
-        UserContext.current().setEventDetails("Rule Id: " + newRule.getId());
+        UserContext.current().setEventDetails("ACL Item Id: " + newRule.getId());
 
         txn.commit();
 
         return getNetworkACLItem(newRule.getId());
     }
-    
-    
-    protected void validateNetworkACL(Account caller, Network network, Integer portStart,
Integer portEnd, 
-            String proto) {
-        
+
+    protected void validateNetworkACLItem(Account caller, Integer portStart, Integer portEnd,
+                                          String proto) {
+
         if (portStart != null && !NetUtils.isValidPort(portStart)) {
             throw new InvalidParameterValueException("publicPort is an invalid value: " +
portStart);
         }
@@ -197,125 +267,35 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
         if (portStart != null && portEnd != null && portStart > portEnd)
{
             throw new InvalidParameterValueException("Start port can't be bigger than end
port");
         }
-        
-        if (network.getTrafficType() != Networks.TrafficType.Guest) {
-            throw new InvalidParameterValueException("Network ACL can be created just for
networks of type " + Networks.TrafficType.Guest);
-        }
-
-        // Verify that the network guru supports the protocol specified
-        Map<Network.Capability, String> caps = _networkMgr.getNetworkServiceCapabilities(network.getId(),
Service.NetworkACL);
-        
-
-        if (caps != null) {
-            String supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase();
-            if (!supportedProtocols.contains(proto.toLowerCase())) {
-                throw new InvalidParameterValueException("Protocol " + proto + " is not supported
by the network " + network);
-            }
-        } else {
-            throw new InvalidParameterValueException("No capabilities are found for network
" + network);
-        }
     }
-    
-    protected void detectNetworkACLConflict(FirewallRuleVO newRule) throws NetworkRuleConflictException
{
-        if (newRule.getPurpose() != Purpose.NetworkACL) {
-            return;
-        }
-        
-        List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficTypeAndNotRevoked(newRule.getNetworkId(),
-                Purpose.NetworkACL, newRule.getTrafficType());
-        assert (rules.size() >= 1) : "For network ACLs, we now always first persist the
rule and then check for " +
-                "network conflicts so we should at least have one rule at this point.";
-
-        for (FirewallRuleVO rule : rules) {
-            if (rule.getId() == newRule.getId() || !rule.getProtocol().equalsIgnoreCase(newRule.getProtocol()))
{
-                continue; // Skips my own rule and skip the rule if the protocol is different
-            }
-
-            // if one cidr overlaps another, do port veirficatino
-            boolean duplicatedCidrs = false;
-            // Verify that the rules have different cidrs
-            _firewallDao.loadSourceCidrs(rule);
-            List<String> ruleCidrList = rule.getSourceCidrList();
-            List<String> newRuleCidrList = newRule.getSourceCidrList();
 
-            if (ruleCidrList == null || newRuleCidrList == null) {
-                continue;
-            }
-            
-            for (String newCidr : newRuleCidrList) {
-                for (String ruleCidr : ruleCidrList) {
-                    if (NetUtils.isNetworksOverlap(newCidr, ruleCidr)) {
-                        duplicatedCidrs = true;
-                        break;
-                    }
-                    if (duplicatedCidrs) {
-                        break;
-                    }
-                }
-            }
-
-            if (newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO) 
-                    && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()))
{
-                if ((newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue()

-                        || rule.getIcmpCode().longValue() == -1 || newRule.getIcmpCode().longValue()
== -1)
-                        && (newRule.getIcmpType().longValue() == rule.getIcmpType().longValue()

-                        || rule.getIcmpType().longValue() == -1 || newRule.getIcmpType().longValue()
== -1)
-                        && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())
&& duplicatedCidrs) {
-                    throw new InvalidParameterValueException("New network ACL conflicts with
existing network ACL id=" + rule.getId());
-                }
-            }
-
-            boolean notNullPorts = (newRule.getSourcePortStart() != null && newRule.getSourcePortEnd()
!= null && 
-                    rule.getSourcePortStart() != null && rule.getSourcePortEnd()
!= null);
-            if (!notNullPorts) {
-                continue;
-            } else if (duplicatedCidrs
-                    && ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue()

-                    && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue())
-                            || (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue()

-                            && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue())
-                            || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue()

-                            && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue())
-                            || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue()

-                            && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue())))
{
-
-                throw new NetworkRuleConflictException("The range specified, " + newRule.getSourcePortStart()
+ "-" 
-                            + newRule.getSourcePortEnd() + ", conflicts with rule " + rule.getId()
-                            + " which has " + rule.getSourcePortStart() + "-" + rule.getSourcePortEnd());
-                
-            }
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("No network rule conflicts detected for " + newRule + " against
" + (rules.size() - 1) 
-                    + " existing network ACLs");
-        }
-    }
-    
     @Override
-    public boolean revokeNetworkACL(long ruleId, boolean apply) {
+    public boolean revokeNetworkACLItem(long ruleId, boolean apply) {
         Account caller = UserContext.current().getCaller();
         long userId = UserContext.current().getCallerUserId();
-        return revokeNetworkACL(ruleId, apply, caller, userId);
+        return revokeNetworkACLItem(ruleId, apply, caller, userId);
     }
-    
-    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking
firewall rule", async = true)
-    protected boolean revokeNetworkACL(long ruleId, boolean apply, Account caller, long userId)
{
 
-        FirewallRuleVO rule = _firewallDao.findById(ruleId);
-        if (rule == null || rule.getPurpose() != Purpose.NetworkACL) {
-            throw new InvalidParameterValueException("Unable to find " + ruleId + " having
purpose " + Purpose.NetworkACL);
+    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_DELETE, eventDescription = "revoking
network acl", async = true)
+    protected boolean revokeNetworkACLItem(long ruleId, boolean apply, Account caller, long
userId) {
+
+        NetworkACLItemVO rule = _networkACLItemDao.findById(ruleId);
+        if (rule == null) {
+            throw new InvalidParameterValueException("Unable to find network ACL Item" +
ruleId);
         }
-        
-        _accountMgr.checkAccess(caller, null, true, rule);
 
-        _firewallMgr.revokeRule(rule, caller, userId, false);
+       // _accountMgr.checkAccess(caller, null, true, rule);
+
+        revokeRule(rule, caller, userId, false);
 
         boolean success = false;
 
         if (apply) {
-            List<FirewallRuleVO> rules = _firewallDao.listByNetworkAndPurpose(rule.getNetworkId(),
Purpose.NetworkACL);
-            success = _firewallMgr.applyFirewallRules(rules, false, caller);
+            try {
+                success = applyNetworkACL(rule.getACLId(), caller);
+            } catch (ResourceUnavailableException e) {
+                e.printStackTrace();  //To change body of catch statement use File | Settings
| File Templates.
+            }
         } else {
             success = true;
         }
@@ -323,19 +303,9 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
         return success;
     }
 
-    
-    @Override
-    public FirewallRule getNetworkACLItem(long ACLId) {
-        FirewallRule rule = _firewallDao.findById(ACLId);
-        if (rule != null && rule.getPurpose() == Purpose.NetworkACL) {
-            return rule;
-        }
-        return null;
-    }
 
-    
     @Override
-    public Pair<List<? extends FirewallRule>,Integer> listNetworkACLItems(ListNetworkACLsCmd
cmd) {
+    public Pair<List<? extends NetworkACLItem>, Integer> listNetworkACLItems(ListNetworkACLsCmd
cmd) {
         Long networkId = cmd.getNetworkId();
         Long id = cmd.getId();
         String trafficType = cmd.getTrafficType();
@@ -344,7 +314,7 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
         Account caller = UserContext.current().getCaller();
         List<Long> permittedAccounts = new ArrayList<Long>();
 
-        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject
= 
+        Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject
=
                 new Ternary<Long, Boolean, ListProjectResourcesCriteria>(cmd.getDomainId(),
cmd.isRecursive(), null);
         _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(),
permittedAccounts,
                 domainIdRecursiveListProject, cmd.listAll(), false);
@@ -352,15 +322,14 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
         Boolean isRecursive = domainIdRecursiveListProject.second();
         ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
 
-        Filter filter = new Filter(FirewallRuleVO.class, "id", false, cmd.getStartIndex(),
cmd.getPageSizeVal());
-        SearchBuilder<FirewallRuleVO> sb = _firewallDao.createSearchBuilder();
-        _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
+        Filter filter = new Filter(NetworkACLItemVO.class, "id", false, cmd.getStartIndex(),
cmd.getPageSizeVal());
+        SearchBuilder<NetworkACLItemVO> sb = _networkACLItemDao.createSearchBuilder();
+      //  _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria);
 
         sb.and("id", sb.entity().getId(), Op.EQ);
-        sb.and("networkId", sb.entity().getNetworkId(), Op.EQ);
-        sb.and("purpose", sb.entity().getPurpose(), Op.EQ);
+        //sb.and("networkId", sb.entity().getNetworkId(), Op.EQ);
         sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ);
-        
+
         if (tags != null && !tags.isEmpty()) {
             SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
             for (int count=0; count < tags.size(); count++) {
@@ -373,8 +342,8 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
             sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(),
JoinBuilder.JoinType.INNER);
         }
 
-        SearchCriteria<FirewallRuleVO> sc = sb.create();
-        _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria);
+        SearchCriteria<NetworkACLItemVO> sc = sb.create();
+        // _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts,
listProjectResourcesCriteria);
 
         if (id != null) {
             sc.setParameters("id", id);
@@ -383,11 +352,11 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
         if (networkId != null) {
             sc.setParameters("networkId", networkId);
         }
-        
+
         if (trafficType != null) {
             sc.setParameters("trafficType", trafficType);
         }
-        
+
         if (tags != null && !tags.isEmpty()) {
             int count = 0;
             sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.NetworkACL.toString());
@@ -395,57 +364,15 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
                 sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
                 sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
                 count++;
-            }   
-        }
-
-        sc.setParameters("purpose", Purpose.NetworkACL);
-
-        Pair<List<FirewallRuleVO>, Integer> result = _firewallDao.searchAndCount(sc,
filter);
-        return new Pair<List<? extends FirewallRule>, Integer>(result.first(),
result.second());
-    }
-
-
-    @Override
-    public List<? extends FirewallRule> listNetworkACLs(long guestNtwkId) {
-        return _firewallDao.listByNetworkAndPurpose(guestNtwkId, Purpose.NetworkACL);
-    }
-
-    
-    @Override
-    public boolean revokeAllNetworkACLsForNetwork(long networkId, long userId, Account caller)
throws ResourceUnavailableException {
-
-        List<FirewallRuleVO> ACLs = _firewallDao.listByNetworkAndPurpose(networkId,
Purpose.NetworkACL);
-        
-        if (ACLs.isEmpty()) {
-            s_logger.debug("Found no network ACLs for network id=" + networkId);
-            return true;
-        }
-        
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + ACLs.size() + " Network ACLs for network id=" +
networkId);
-        }
-
-        for (FirewallRuleVO ACL : ACLs) {
-            // Mark all Network ACLs rules as Revoke, but don't revoke them yet - we have
to revoke all rules for ip, no
-            // need to send them one by one
-            revokeNetworkACL(ACL.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
-        }
-        
-        List<FirewallRuleVO> ACLsToRevoke = _firewallDao.listByNetworkAndPurpose(networkId,
Purpose.NetworkACL);
-
-        // now send everything to the backend
-        boolean success = _firewallMgr.applyFirewallRules(ACLsToRevoke, false, caller);
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Successfully released Network ACLs for network id=" + networkId
+ " and # of rules now = " 
-                                + ACLs.size());
+            }
         }
 
-        return success;
+        Pair<List<NetworkACLItemVO>, Integer> result = _networkACLItemDao.searchAndCount(sc,
filter);
+        return new Pair<List<? extends NetworkACLItem>, Integer>(result.first(),
result.second());
     }
 
     @Override
-    public NetworkACL createNetworkACL(CreateNetworkACLListCmd cmd){
+    public NetworkACL createNetworkACL(CreateNetworkACLListCmd cmd) {
         NetworkACLVO acl = new NetworkACLVO(cmd.getName(), cmd.getDescription(), cmd.getVpcId());
         _networkACLDao.persist(acl);
         return acl;
@@ -470,4 +397,41 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
         return new Pair<List<? extends NetworkACL>, Integer>(acls.first(), acls.second());
     }
 
+    @Override
+    public boolean replaceNetworkACL(long aclId, long networkId) {
+        NetworkVO network = _networkDao.findById(networkId);
+        network.setNetworkACLId(aclId);
+        return _networkDao.update(networkId, network);
+    }
+
+    @Override
+    @DB
+    public void revokeRule(NetworkACLItemVO rule, Account caller, long userId, boolean needUsageEvent)
{
+        if (caller != null) {
+            //_accountMgr.checkAccess(caller, null, true, rule);
+        }
+
+        Transaction txn = Transaction.currentTxn();
+        boolean generateUsageEvent = false;
+
+        txn.start();
+        if (rule.getState() == State.Staged) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Found a rule that is still in stage state so just removing
it: " + rule);
+            }
+            _networkACLItemDao.remove(rule.getId());
+            generateUsageEvent = true;
+        } else if (rule.getState() == State.Add || rule.getState() == State.Active) {
+            rule.setState(State.Revoke);
+            _networkACLItemDao.update(rule.getId(), rule);
+            generateUsageEvent = true;
+        }
+
+/*        if (generateUsageEvent && needUsageEvent) {
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_RULE_DELETE, rule.getAccountId(),
0, rule.getId(),
+                    null, rule.getClass().getName(), rule.getUuid());
+        }*/
+
+        txn.commit();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2449cfc/server/src/com/cloud/network/vpc/NetworkACLVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/NetworkACLVO.java b/server/src/com/cloud/network/vpc/NetworkACLVO.java
index 29afc00..374ba15 100644
--- a/server/src/com/cloud/network/vpc/NetworkACLVO.java
+++ b/server/src/com/cloud/network/vpc/NetworkACLVO.java
@@ -75,4 +75,14 @@ public class NetworkACLVO implements NetworkACL{
     public String getName() {
         return name;
     }
+
+    @Override
+    public long getAccountId() {
+        return 0;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public long getDomainId() {
+        return 0;  //To change body of implemented methods use File | Settings | File Templates.
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2449cfc/server/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java b/server/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java
new file mode 100644
index 0000000..69810e0
--- /dev/null
+++ b/server/src/com/cloud/network/vpc/dao/NetworkACLItemDaoImpl.java
@@ -0,0 +1,147 @@
+// 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 com.cloud.network.vpc.dao;
+
+import com.cloud.network.dao.FirewallRulesCidrsDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.NetworkACLItem.State;
+import com.cloud.network.vpc.NetworkACLItemDao;
+import com.cloud.network.vpc.NetworkACLItemVO;
+import com.cloud.server.ResourceTag.TaggedResourceType;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
+import com.cloud.utils.db.JoinBuilder;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.Transaction;
+import org.springframework.stereotype.Component;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import java.util.List;
+
+@Component
+@Local(value = NetworkACLItemDao.class)
+@DB(txn = false)
+public class NetworkACLItemDaoImpl extends GenericDaoBase<NetworkACLItemVO, Long> implements
NetworkACLItemDao {
+
+    protected final SearchBuilder<NetworkACLItemVO> AllFieldsSearch;
+    protected final SearchBuilder<NetworkACLItemVO> NotRevokedSearch;
+    protected final SearchBuilder<NetworkACLItemVO> ReleaseSearch;
+    protected SearchBuilder<NetworkACLItemVO> VmSearch;
+    protected final SearchBuilder<NetworkACLItemVO> SystemRuleSearch;
+    protected final GenericSearchBuilder<NetworkACLItemVO, Long> RulesByIpCount;
+
+    @Inject protected FirewallRulesCidrsDao _firewallRulesCidrsDao;
+    @Inject ResourceTagDao _tagsDao;
+    @Inject IPAddressDao _ipDao;
+
+    protected NetworkACLItemDaoImpl() {
+        super();
+
+        AllFieldsSearch = createSearchBuilder();
+        AllFieldsSearch.and("protocol", AllFieldsSearch.entity().getProtocol(), Op.EQ);
+        AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
+        AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
+        AllFieldsSearch.and("aclId", AllFieldsSearch.entity().getACLId(), Op.EQ);
+        AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), Op.EQ);
+        AllFieldsSearch.done();
+
+        NotRevokedSearch = createSearchBuilder();
+        NotRevokedSearch.and("state", NotRevokedSearch.entity().getState(), Op.NEQ);
+        NotRevokedSearch.and("protocol", NotRevokedSearch.entity().getProtocol(), Op.EQ);
+        NotRevokedSearch.and("sourcePortStart", NotRevokedSearch.entity().getSourcePortStart(),
Op.EQ);
+        NotRevokedSearch.and("sourcePortEnd", NotRevokedSearch.entity().getSourcePortEnd(),
Op.EQ);
+        NotRevokedSearch.and("aclId", NotRevokedSearch.entity().getACLId(), Op.EQ);
+        NotRevokedSearch.and("trafficType", NotRevokedSearch.entity().getTrafficType(), Op.EQ);
+        NotRevokedSearch.done();
+
+        ReleaseSearch = createSearchBuilder();
+        ReleaseSearch.and("protocol", ReleaseSearch.entity().getProtocol(), Op.EQ);
+        ReleaseSearch.and("ports", ReleaseSearch.entity().getSourcePortStart(), Op.IN);
+        ReleaseSearch.done();
+
+        SystemRuleSearch = createSearchBuilder();
+        SystemRuleSearch.and("type", SystemRuleSearch.entity().getType(), Op.EQ);
+        SystemRuleSearch.done();
+
+        RulesByIpCount = createSearchBuilder(Long.class);
+        RulesByIpCount.select(null, Func.COUNT, RulesByIpCount.entity().getId());
+        RulesByIpCount.done();
+    }
+
+
+    @Override
+    public List<NetworkACLItemVO> listByACLAndNotRevoked(long aclId) {
+        return null;  //To change body of implemented methods use File | Settings | File
Templates.
+    }
+
+    @Override
+    public boolean setStateToAdd(NetworkACLItemVO rule) {
+        SearchCriteria<NetworkACLItemVO> sc = AllFieldsSearch.create();
+        sc.setParameters("id", rule.getId());
+        sc.setParameters("state", State.Staged);
+
+        rule.setState(State.Add);
+
+        return update(rule, sc) > 0;
+    }
+
+    @Override
+    public boolean revoke(NetworkACLItemVO rule) {
+        return false;  //To change body of implemented methods use File | Settings | File
Templates.
+    }
+
+    @Override
+    public boolean releasePorts(long ipAddressId, String protocol, int[] ports) {
+        return false;  //To change body of implemented methods use File | Settings | File
Templates.
+    }
+
+    @Override
+    public List<NetworkACLItemVO> listByACL(long aclId) {
+        SearchCriteria<NetworkACLItemVO> sc = AllFieldsSearch.create();
+        sc.setParameters("aclId", aclId);
+
+        return listBy(sc);
+    }
+
+    @Override
+    public List<NetworkACLItemVO> listSystemRules() {
+        return null;  //To change body of implemented methods use File | Settings | File
Templates.
+    }
+
+    @Override
+    public List<NetworkACLItemVO> listByACLTrafficTypeAndNotRevoked(long aclId, NetworkACLItem.TrafficType
trafficType) {
+        return null;  //To change body of implemented methods use File | Settings | File
Templates.
+    }
+
+    @Override
+    public List<NetworkACLItemVO> listByACLTrafficType(long aclId, NetworkACLItem.TrafficType
trafficType) {
+        return null;  //To change body of implemented methods use File | Settings | File
Templates.
+    }
+
+    @Override
+    public void loadSourceCidrs(NetworkACLItemVO rule) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2449cfc/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index ec19942..b7085af 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -2882,6 +2882,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
         cmdList.add(CreateNetworkACLListCmd.class);
         cmdList.add(DeleteNetworkACLListCmd.class);
         cmdList.add(ListNetworkACLListsCmd.class);
+        cmdList.add(ReplaceNetworkACLListCmd.class);
         return cmdList;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2449cfc/setup/db/db/schema-410to420.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql
index f641993..6c8a3dd 100644
--- a/setup/db/db/schema-410to420.sql
+++ b/setup/db/db/schema-410to420.sql
@@ -1191,23 +1191,18 @@ CREATE TABLE `cloud`.`network_acl` (
 CREATE TABLE `cloud`.`network_acl_item` (
   `id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
   `uuid` varchar(40),
-  `network_acl_id` bigint unsigned NOT NULL COMMENT 'network acl id',
+  `acl_id` bigint unsigned NOT NULL COMMENT 'network acl id',
   `start_port` int(10) COMMENT 'starting port of a port range',
   `end_port` int(10) COMMENT 'end port of a port range',
   `state` char(32) NOT NULL COMMENT 'current state of this rule',
   `protocol` char(16) NOT NULL default 'TCP' COMMENT 'protocol to open these ports for',
-  `account_id` bigint unsigned NOT NULL COMMENT 'owner id',
-  `domain_id` bigint unsigned NOT NULL COMMENT 'domain id',
-  `xid` char(40) NOT NULL COMMENT 'external id',
   `created` datetime COMMENT 'Date created',
   `icmp_code` int(10) COMMENT 'The ICMP code (if protocol=ICMP). A value of -1 means all
codes for the given ICMP type.',
   `icmp_type` int(10) COMMENT 'The ICMP type (if protocol=ICMP). A value of -1 means all
types.',
   `type` varchar(10) NOT NULL DEFAULT 'USER',
   `traffic_type` char(32) COMMENT 'the traffic type of the rule, can be Ingress or Egress',
   PRIMARY KEY  (`id`),
-  CONSTRAINT `fk_network_acl_item__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`)
ON DELETE CASCADE,
-  CONSTRAINT `fk_network_acl_item__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`)
ON DELETE CASCADE,
-  CONSTRAINT `fk_network_acl_item__acl_id` FOREIGN KEY(`network_acl_id`) REFERENCES `network_acl`(`id`)
ON DELETE CASCADE,
+  CONSTRAINT `fk_network_acl_item__acl_id` FOREIGN KEY(`acl_id`) REFERENCES `network_acl`(`id`)
ON DELETE CASCADE,
   CONSTRAINT `uc_network_acl_item__uuid` UNIQUE (`uuid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 


Mime
View raw message